Headless mode
Run Letta Code non-interactively for scripting and automation
Headless mode allows you to run Letta Code non-interactively, making it easy to integrate into scripts, CI/CD pipelines, or compose with other UNIX tools.
Basic usage
Section titled “Basic usage”Use the -p flag to pass a prompt directly:
letta -p "Look around this repo and write a README.md documenting it"You can also pipe input to Letta Code:
echo "Explain this error" | letta -pOutput formats
Section titled “Output formats”Letta Code supports three output formats in headless mode:
Text (default)
Section titled “Text (default)”Returns the agent’s response as plain text:
letta -p "What files are in this directory?"Returns a structured JSON response with metadata:
letta -p "List all TypeScript files" --output-format json{ "type": "result", "result": "Found 15 TypeScript files...", "agent_id": "agent-abc123", "usage": { "prompt_tokens": 1250, "completion_tokens": 89 }}Stream JSON
Section titled “Stream JSON”Returns line-delimited JSON events for real-time streaming. This is useful for preventing timeouts and getting incremental progress:
letta -p "Explain this codebase" --output-format stream-jsonEach line is a JSON event:
{"type":"system","subtype":"init","agent_id":"agent-...","session_id":"agent-...","model":"claude-sonnet-4-5","tools":[...]}{"type":"message","message_type":"reasoning_message","reasoning":"The user is asking...","otid":"...","seq_id":1}{"type":"message","message_type":"assistant_message","content":"Here's an overview...","otid":"...","seq_id":5}{"type":"message","message_type":"stop_reason","stop_reason":"end_turn"}{"type":"message","message_type":"usage_statistics","prompt_tokens":294,"completion_tokens":97}{"type":"result","subtype":"success","result":"Here's an overview...","agent_id":"...","session_id":"...","uuid":"..."}Messages are streamed at the token level - each chunk has the same otid (output turn ID) and incrementing seq_id.
Bidirectional mode
Section titled “Bidirectional mode”For programmatic control, use --input-format stream-json to enable bidirectional JSON communication over stdin/stdout. This allows external programs to send messages and receive responses in a structured format.
letta -p --input-format stream-json --output-format stream-jsonInput message types
Section titled “Input message types”Send JSON messages to stdin (one per line):
{"type": "user", "message": {"role": "user", "content": "What files are here?"}}{"type": "control_request", "request_id": "init_1", "request": {"subtype": "initialize"}}{"type": "control_request", "request_id": "int_1", "request": {"subtype": "interrupt"}}Output message types
Section titled “Output message types”The CLI emits JSON messages to stdout:
{"type": "system", "subtype": "init", "agent_id": "agent-xxx", "session_id": "agent-xxx", "model": "...", "tools": [...]}{"type": "control_response", "response": {"subtype": "success", "request_id": "init_1", "response": {...}}}{"type": "message", "message_type": "assistant_message", "content": "Hello!", "session_id": "...", "uuid": "..."}{"type": "result", "subtype": "success", "result": "Hello!", "session_id": "...", "agent_id": "..."}Multi-turn conversations
Section titled “Multi-turn conversations”The process stays alive until stdin closes, allowing multi-turn conversations:
(echo '{"type": "user", "message": {"role": "user", "content": "Remember: secret is BANANA"}}'sleep 5echo '{"type": "user", "message": {"role": "user", "content": "What was the secret?"}}') | letta -p --input-format stream-json --output-format stream-jsonToken-level streaming
Section titled “Token-level streaming”Add --include-partial-messages to receive token-level streaming events:
letta -p --input-format stream-json --output-format stream-json --include-partial-messagesThis wraps each chunk in a stream_event:
{"type": "stream_event", "event": {"message_type": "assistant_message", "content": "Hel"}, "session_id": "...", "uuid": "..."}Agent selection
Section titled “Agent selection”By default, headless mode auto-resumes the last agent used in the current directory (just like interactive mode). This means your agent retains memory across headless runs.
letta -p "..." --newletta -p "..." --agent <agent-id>Model selection
Section titled “Model selection”Specify a model for the headless run:
letta -p "..." --model sonnet-4.5letta -p "..." -m gpt-5-codexletta -p "..." -m haikuSee Models for the full list of supported model IDs.
Permission control
Section titled “Permission control”Auto-allow all tools
Section titled “Auto-allow all tools”Use --yolo to bypass all permission prompts (use with caution):
letta -p "Refactor this file" --yoloRestrict available tools
Section titled “Restrict available tools”The --tools flag controls which tools are attached to the agent (removing them from the context window entirely):
letta -p "Analyze this codebase" --tools "Read,Glob,Grep"letta -p "What do you think about this approach?" --tools ""This is different from --allowedTools/--disallowedTools which control permissions but keep tools in context. See Permissions for more details.
Permission modes
Section titled “Permission modes”letta -p "Fix the type errors" --permission-mode acceptEditsletta -p "Review this PR" --permission-mode planAdvanced options
Section titled “Advanced options”Resume by name
Section titled “Resume by name”Use -n or --name to resume an agent by name (case-insensitive). Matches pinned agents or recent agents:
letta -p "Continue where we left off" --name myprojectSystem prompt configuration
Section titled “System prompt configuration”Customize the agent’s system prompt when creating new agents:
letta -p "..." --new --system letta-claudeletta -p "..." --new --system-custom "You are a Python expert who writes clean code."letta -p "..." --new --system letta-claude --system-append "Always respond in Spanish."Available presets:
default/letta-claude- Full Letta Code prompt (Claude-optimized)letta-codex- Full Letta Code prompt (Codex-optimized)letta-gemini- Full Letta Code prompt (Gemini-optimized)claude- Basic Claude (no skills/memory instructions)codex- Basic Codexgemini- Basic Gemini
Memory block configuration
Section titled “Memory block configuration”Customize which memory blocks the agent uses:
letta -p "..." --new --init-blocks "persona,project"letta -p "..." --new --init-blocks "persona,project" \ --block-value persona="You are a Go expert" \ --block-value project="CLI tool for Docker"letta -p "..." --new --memory-blocks '[ {"label": "context", "value": "API documentation for Acme Corp..."}, {"label": "rules", "value": "Always use TypeScript"}]'letta -p "..." --new --init-blocks ""Available preset blocks:
persona- Agent’s personality and behaviorhuman- Information about the userproject- Current project context
Core blocks (always included):
skills- Available skills directoryloaded_skills- Currently loaded skill instructions
Toolset override
Section titled “Toolset override”Force a specific toolset instead of auto-detection based on model:
letta -p "..." --toolset codex # Codex-style toolsletta -p "..." --toolset gemini # Gemini-style toolsletta -p "..." --toolset default # Default Letta toolsBase tools configuration
Section titled “Base tools configuration”When creating a new agent with --new, specify which base tools to attach:
letta -p "..." --new --base-tools "memory,web_search"Create from AgentFile
Section titled “Create from AgentFile”Create an agent from an AgentFile template:
letta -p "..." --from-af ./my-agent.afExamples
Section titled “Examples”Automated tasks
Section titled “Automated tasks”letta -p "Run the linter and fix any errors" --yoloStructured output for scripts
Section titled “Structured output for scripts”Use JSON output to parse results programmatically:
result=$(letta -p "What is the main entry point of this project?" --output-format json)echo $result | jq '.result'Read-only analysis
Section titled “Read-only analysis”Use --tools to restrict the agent to read-only operations:
letta -p "Review this codebase for potential security issues" --tools "Read,Glob,Grep"Scheduled tasks with cron
Section titled “Scheduled tasks with cron”Run Letta Code on a schedule using cron:
0 9 * * * cd /path/to/project && letta -p "Review recent changes and summarize any issues" --tools "Read,Glob,Grep" --output-format json >> /var/log/letta-review.log 2>&10 10 * * 1 cd /path/to/project && letta -p "Check for outdated dependencies and security vulnerabilities" --yolo >> /var/log/letta-deps.log 2>&1