원클릭으로
configuring-your-harness
// Configure deterministic Letta Code harness behavior, such as permission rules, lifecycle hooks, and model configuration.
// Configure deterministic Letta Code harness behavior, such as permission rules, lifecycle hooks, and model configuration.
| name | configuring-your-harness |
| description | Configure deterministic Letta Code harness behavior, such as permission rules, lifecycle hooks, and model configuration. |
Use this skill to configure deterministic Letta Code harness behavior, primarily permissions and lifecycle hooks. It can also help with local per-agent settings like toolset, model, context window, name, and description.
Keep these layers separate:
| Layer | What it is | How to change it |
|---|---|---|
| Memory | Learned state, memfs files, conversation recall, skills | Edit $MEMORY_DIR, use memory tooling, create/update skill files |
| Harness | Deterministic runtime config around the agent | Edit Letta settings JSON or call the Letta API |
Edit memory when the agent should remember or learn something. Edit the harness when runtime behavior should deterministically change.
Do not edit harness settings for ordinary preferences like “remember I prefer concise answers.” Store those in memory. Do edit harness settings for deterministic behavior like “always ask before shell commands,” “add a hook to block unsafe edits,” or “change this agent’s toolset.”
Decision rule: if the LLM is responsible for choosing the behavior, store the instruction in memory. If the harness should enforce the behavior outside the LLM, use this skill.
Examples:
| User asks for... | Use |
|---|---|
“Auto-approve safe git diff commands” | Harness permission rule |
“Deny all rm -rf shell commands” | Harness permission rule or hook |
| “Run a script before every Bash call” | Harness hook |
| “Notify me when you finish a response” | Harness hook |
| “Always sign commits like XYZ” | Memory, because the LLM writes commit messages |
| “Prefer short answers” | Memory, because the LLM controls response style |
| “Remember this repo’s PR checklist” | Memory or project docs, because the LLM applies it |
| File | Scope | Typical contents |
|---|---|---|
~/.letta/settings.json | User/global | Permissions, hooks, user-wide env vars, agents[] entries |
./.letta/settings.json | Project/shared | Project permissions and hooks, committed with the repo |
./.letta/settings.local.json | Project-local | Personal project overrides, gitignored |
Precedence for settings scopes is local > project > user, but list-like entries such as permissions and hooks are merged. For hooks, project-local hooks run first, then project hooks, then user hooks.
Use project or local scope only when the current working directory is intentionally the project root.
Name, description, model, and context window are server-side agent fields. Change them with PATCH /v1/agents/{agent_id}.
Required environment:
export LETTA_API_KEY=...
export LETTA_AGENT_ID=...
Example:
curl -X PATCH "https://api.letta.com/v1/agents/$LETTA_AGENT_ID" \
-H "Authorization: Bearer $LETTA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "new-name"}'
Load the letta-api-client skill for richer SDK examples.
Permissions decide which tool calls are allowed, denied, or require approval.
Bash(npm install:*), Bash(git:*), Bash(curl:*)Read(src/**), Edit(**/*.ts), Write(*.md)*, Bash, Read — use sparinglypython3 <skill-dir>/scripts/add_permission.py \
--rule "Bash(curl:*)" \
--type allow \
--scope user
{
"permissions": {
"allow": ["Bash(npm:*)", "Read(src/**)"],
"deny": ["Bash(rm -rf:*)"],
"ask": []
}
}
Permissions loaded from settings files are signature-checked and can update during a running session. If behavior does not update immediately, start a fresh session.
Hooks run shell commands or LLM prompt checks in response to Letta Code events. Use them to audit actions, inject context, enforce policy, auto-format after edits, notify on completion, or block unsafe actions.
Before adding hooks, inspect existing config to avoid duplicates or contradictory policy:
python3 <skill-dir>/scripts/show_config.py
Read references/hooks.md when adding, debugging, or explaining hooks. It covers scopes, merge order, events, matchers, command hooks, prompt hooks, input JSON, exit codes, direct JSON format, and practical patterns.
Quick examples:
# Log every Bash tool call
python3 <skill-dir>/scripts/add_hook.py \
--event PreToolUse \
--matcher Bash \
--type command \
--command 'python3 ~/.letta/hooks/log-bash.py' \
--scope user
# Gate edits with an LLM prompt hook
python3 <skill-dir>/scripts/add_hook.py \
--event PreToolUse \
--matcher "Edit|Write" \
--type prompt \
--prompt 'Allow only edits under src/ unless the user explicitly requested otherwise. Input: $ARGUMENTS' \
--scope project
External edits to hook settings through scripts or direct JSON may require a fresh session because hooks are read through the settings manager cache. Hooks changed through in-app hook management APIs update in-memory settings immediately.
Agent config splits between the Letta server and local settings.
Use PATCH /v1/agents/{agent_id} with $LETTA_AGENT_ID.
Change your model and context window:
curl -X PATCH "https://api.letta.com/v1/agents/$LETTA_AGENT_ID" \
-H "Authorization: Bearer $LETTA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "anthropic/claude-sonnet-4-5-20250929",
"context_window_limit": 200000
}'
Do not patch llm_config directly; the Letta API rejects deprecated
llm_config updates. Use model and context_window_limit instead. After the
patch, read the agent back and verify the effective llm_config.context_window
reported by the server.
Rename yourself:
curl -X PATCH "https://api.letta.com/v1/agents/$LETTA_AGENT_ID" \
-H "Authorization: Bearer $LETTA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "draft-v2"}'
Update your description:
curl -X PATCH "https://api.letta.com/v1/agents/$LETTA_AGENT_ID" \
-H "Authorization: Bearer $LETTA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"description": "..."}'
For Python / TypeScript SDK usage, see docs.letta.com/api-overview/introduction or load the letta-api-client skill.
~/.letta/settings.json)The agents[] array stores per-agent harness preferences you can edit directly:
{
"agents": [
{
"agentId": "agent-abc123",
"baseUrl": "https://api.letta.com",
"pinned": true,
"toolset": "default"
}
]
}
toolset — which tool set to load for this agentpinned — quick-switch visibilityFind your own entry by matching agentId === $LETTA_AGENT_ID, then edit the fields you need.
| Goal | Command/change |
|---|---|
| Auto-approve curl | add_permission.py --rule "Bash(curl:*)" --type allow --scope user |
Block rm -rf | Add "Bash(rm -rf:*)" to permissions.deny, or add a PreToolUse hook |
| Log all Bash calls | add_hook.py --event PreToolUse --matcher Bash --type command --command '...' --scope user |
| Auto-format after edits | `add_hook.py --event PostToolUse --matcher "Edit |
| Gate edits with LLM | `add_hook.py --event PreToolUse --matcher "Edit |
| Notify when done | add_hook.py --event Stop --type command --command 'say done' --scope user |
| Show config | python3 <skill-dir>/scripts/show_config.py |
| Change model | PATCH /v1/agents/$LETTA_AGENT_ID with model |
| Change context window | PATCH /v1/agents/$LETTA_AGENT_ID with context_window_limit; verify returned llm_config.context_window |
| Rename | PATCH /v1/agents/$LETTA_AGENT_ID with name |
| Update description | PATCH /v1/agents/$LETTA_AGENT_ID with description |
| Change toolset | Edit agents[].toolset in ~/.letta/settings.json |
| Script | Purpose |
|---|---|
scripts/add_permission.py | Add an allow/deny/ask rule to any scope |
scripts/add_hook.py | Add a command or prompt hook to any event |
scripts/show_config.py | Show merged permissions, hooks, and per-agent settings across all scopes |
All three accept --scope user|project|local. Run --help for full usage.
Creates and edits trusted local Letta Code extensions, including extension tools, slash commands, lifecycle/turn events, scoped conversation helpers, panels, status values, and capability-gated behavior. Use when the user asks to make an extension, add a tool the agent can call, add a slash command, transform turns, react to app events, or add lightweight extension UI outside the dedicated /statusline flow.
Creates, edits, and enables Letta Code extension-provided slash commands. Use when the user asks to add a custom /command, slash command, command shortcut, scoped conversation-backed command, or command-driven panel behavior.
Creates, edits, and migrates Letta Code statusline extensions. Use when handling the /statusline command or continuing work started by /statusline.
Guides users through an interactive Letta Code onboarding/tutorial. Use when the user is new, unsure what to do, says "start", asks "what can you do?", "how does Letta work?", "help me get started", or needs a walkthrough of memory, skills, tools, search, subagents, or schedules.
Comprehensive guide for initializing or reorganizing agent memory. Load this skill when running /init, when the user asks you to set up your memory, or when you need guidance on creating effective memory files.
Guide for safely discovering and installing skills from external repositories. Use when a user asks for something where a specialized skill likely exists (browser testing, PDF processing, document generation, etc.) and you want to bootstrap your understanding rather than starting from scratch.