Skip to content
Sign up
Configuration

Mods

Customize Letta Code with trusted local code

Mods run as fully trusted code inside your Letta Code process. They let your agent modify its own runtime — adding tools, commands, event hooks, permission policies, and provider adapters that take effect immediately on reload. This makes the harness self-modifying: your agent can extend its own capabilities, shape how turns and tools behave, and adapt the environment around itself over time.

Mods are for changing the harness itself. If you want to teach your agent how to do a task, ask it to write a skill. If you want to alter the limitations of the harness, ask it to write a mod.

Mods are designed to be written and modified by agents. Letta Code agents have access to the deeper mod documentation inside the codebase and can create or update mods far more efficiently than writing them by hand.

For example, ask:

Write a Letta Code mod that adds a /review command for reviewing my current git diff.

Your agent can inspect any existing files in ~/.letta/mods/, write the new mod, and tell you to run /reload when it is ready.

Mods live in your global Letta directory:

~/.letta/mods/

Each .js, .mjs, .ts, or .tsx file in that directory is loaded on startup. After editing a mod, run /reload to reload it without restarting Letta Code.

Mods are trusted code. They run locally with the same access as Letta Code, so only install or write mods you trust.

A mod exports an activate function. Inside activate, register the capabilities you want and return a cleanup function if the mod owns timers, UI, or subscriptions.

~/.letta/mods/whereami.ts
export default function activate(letta) {
if (!letta.capabilities.commands) return;
return letta.commands.register({
id: "whereami",
description: "Show the active agent and working directory",
run(ctx) {
return {
type: "output",
output: `Agent: ${ctx.agent.name ?? ctx.agent.id}\nCWD: ${ctx.cwd}`,
};
},
});
}

Now /whereami is available in Letta Code.

Here’s what’s possible:

Add custom /commands that send a prompt to the agent or run local logic and return output directly. Commands can also work in the background while the main agent is busy, using a forked conversation handle for their own model calls.

Register agent-callable tools that the model can invoke autonomously during a session. Mod tools run locally and can access your filesystem, run shell commands, or call local services — anything the process can reach. Tools can be conditionally registered so they only appear in context when relevant, keeping the tool surface lean.

Subscribe to lifecycle and execution events. Some events are observe-only; others accept a return value that influences what happens next.

EventWhat you can do
conversation_openInitialize mod state, log context, or branch on how the session started (startup, new, resume, fork, reload)
conversation_closePersist state, log session stats, or trigger cleanup
tool_startModify tool arguments before execution, or return a synthetic result to bypass the tool entirely
tool_endRewrite or redact the tool result before the agent sees it
turn_startInject context, rewrite messages, or augment what the model receives
turn_endChain another turn automatically by injecting a follow-up message
llm_startObserve each model request before it’s sent, including the model, message count, and context window
llm_endObserve each model response, including stop reason, token usage, and duration
compact_startCheckpoint important state before compaction evicts it
compact_endInspect what changed, log stats, or re-inject persistent context

llm_start, llm_end, compact_start, and compact_end fire only for local agents, where inference and compaction run on your machine. On Constellation/cloud agents this work happens server-side, so these events don’t fire there.

Add dynamic allow/ask/deny policies that evaluate before a tool call is executed. Useful for enforcing safety rules, auditing specific operations, or requiring confirmation for sensitive actions.

Register a custom model/API provider that local agents can use. Provider mods are local-only — they do not add providers for Constellation/cloud agents.

Surface custom UI in the terminal. Mods can show panels — live text around the input bar for things like status, progress, the current time, or your active git branch. The bottom statusline is one of these slots; set it up with the /statusline command (see Statusline below). Mods can also ask you a question — a prompt where you pick from options or type an answer, and the mod waits for your response before continuing. For example, a deploy mod could ask which environment to target before it runs.

Replace the bottom statusline in the TUI with a custom renderer. You can show anything that fits on one line — git branch, active agent, token usage, current working directory, or whatever is useful for your workflow. Ask your agent with /statusline or just describe what you want.

Beyond single mod files, mods can be distributed as npm packages. Packaged mods include their own dependencies and are installed into a managed registry so they can be enabled, disabled, or updated independently. Browse available mods at letta.com/agents/mods or explore the source at github.com/letta-ai/mods.

Install a packaged mod:

letta install npm:@scope/package-name

Manage installed packages:

letta mods list # show mod files and installed packages
letta mods enable <package-spec>
letta mods disable <package-spec>
letta mods update npm:@scope/package # update to the latest version in place
letta mods remove <package-spec>

Your agent can also scaffold a mod file into a distributable package:

letta mods package <mod-file> --name <package-name>

Mods can report diagnostics — structured messages your agent can read and act on. This is useful for surfacing setup errors, missing configuration, or runtime problems that the agent should investigate and fix.

Ask your agent to add diagnostics to a mod:

Add diagnostics to my review mod so I can see if it fails to find the git repo on startup.

Your agent can add letta.diagnostics.report() calls to the mod:

~/.letta/mods/review.ts
export default function activate(letta) {
const repoPath = process.env.REPO_PATH;
if (!repoPath) {
letta.diagnostics.report({
message: "REPO_PATH is not set — /review will not work",
severity: "error",
});
}
// ...
}

Diagnostics are written to:

~/.letta/mods/diagnostics/latest.json

Your agent has access to this file and can read it directly to investigate mod problems. If something is broken, just ask:

Check my mod diagnostics and fix whatever is wrong.

Errors in individual mods are caught automatically — a broken mod is skipped and its error recorded to diagnostics, so Letta Code still starts normally. To run without any mods at all for a clean baseline, use:

letta --no-mods

or:

LETTA_DISABLE_MODS=1 letta