How to Configure LETTA_SDK_TOOLS for Client-Side Tool Access in the Background Agent
Set the LETTA_SDK_TOOLS environment variable to read-only, full, or off before launching Claude Code to control which Letta SDK tools the background Subconscious agent can invoke.
The letta-ai/claude-subconscious repository implements a background Letta SDK session that runs alongside Claude Code. By default, this agent operates with restricted capabilities, but you can configure LETTA_SDK_TOOLS to adjust the breadth of client-side tool access available to the system.
Understanding the LETTA_SDK_TOOLS Environment Variable
The environment variable LETTA_SDK_TOOLS (also referenced internally as LETTA_SDK_TOOLS) determines the permission level for client-side tools in the Subconscious agent. When unset, the system defaults to a read-only mode that limits the agent to safe exploration capabilities.
According to the source code in scripts/conversation_utils.ts, the helper function getSdkToolsMode() handles the parsing logic at lines 83-86. This function reads process.env.LETTA_SDK_TOOLS, normalizes the value to lowercase, and returns one of three distinct modes: full, off, or the default read-only for any other value.
The Three Access Modes
The Claude Subconscious agent supports three distinct tool access configurations:
-
read-only (default): Enables safe read operations including
Read,Grep,Glob,web_search, andfetch_webpage. Explicitly blocks interactive tools likeAskUserQuestion,EnterPlanMode, andExitPlanMode. This is defined inscripts/conversation_utils.tsat lines 71-76. -
full: Grants unrestricted access to all Letta SDK tools, including interactive and state-modifying operations. Use this when the agent needs to execute actions affecting the environment.
-
off: Completely disables client-side tool access. The Subconscious agent can only perform Letta memory read/write operations, with no file system, web, or interactive tool access.
How the Configuration Flows Through the Codebase
The implementation spans multiple files to ensure the configuration is parsed, displayed, and enforced correctly.
Parsing the Variable in conversation_utils.ts
The getSdkToolsMode() function in scripts/conversation_utils.ts (lines 83-86) serves as the single source of truth for mode determination. It processes the environment variable and returns the normalized mode string that downstream components consume.
Displaying the Mode in session_start.ts
When a session initializes, scripts/session_start.ts provides user feedback by printing the current configuration. Lines 298-303 read the environment variable (falling back to read-only) and display it in the startup banner, allowing you to verify the active permission level before the agent begins processing.
Passing to the Worker in send_messages_to_letta.ts
The configuration propagates to the background worker through scripts/send_messages_to_letta.ts. Lines 9-12 build the payload for the worker and include the sdkToolsMode property. The worker then uses this flag when constructing the Letta SDK session via send_worker_sdk.ts, ensuring the Subconscious agent receives the exact tool set specified by your environment variable.
Configuration Methods
You can set LETTA_SDK_TOOLS through standard environment variable mechanisms before launching Claude Code.
Shell Environment
Export the variable directly in your shell:
export LETTA_SDK_TOOLS="read-only" # Options: "full", "off", "read-only"
As documented in the README at lines 122-124, this must be set before the Claude Code session begins to take effect.
Persistent Project Configuration
For project-specific settings, create a .envrc file (using direnv) in your project root:
export LETTA_SDK_TOOLS="full"
When you enter the directory, direnv automatically applies the setting, ensuring all Claude Subconscious sessions for that project maintain consistent tool access permissions.
Code Examples
Starting with Default Read-Only Access
export LETTA_API_KEY="your-key"
# LETTA_SDK_TOOLS not set; defaults to read-only
/plugin enable .
The startup banner displays:
SDK Tools: read-only
Enabling Full Tool Access
export LETTA_API_KEY="your-key"
export LETTA_SDK_TOOLS="full"
/plugin enable .
The background worker receives sdkToolsMode: "full", allowing the Subconscious agent to invoke any available Letta SDK tool without restrictions.
Disabling All Client-Side Tools
export LETTA_API_KEY="your-key"
export LETTA_SDK_TOOLS="off"
/plugin enable .
The agent operates in memory-only mode, interacting exclusively with Letta memory operations while all file, web, and interactive tools remain inaccessible.
Summary
LETTA_SDK_TOOLScontrols client-side tool permissions for the Claude Subconscious background agent in theletta-ai/claude-subconsciousrepository.- Three modes exist:
read-only(default),full, andoff, parsed bygetSdkToolsMode()inscripts/conversation_utils.ts. - The configuration flows from environment variable →
session_start.ts(display) →send_messages_to_letta.ts(worker payload). - Read-only mode permits
Read,Grep,Glob,web_search, andfetch_webpagewhile blocking interactive tools. - Set the variable in your shell or use
.envrcwith direnv for persistent project-level configuration.
Frequently Asked Questions
What happens if I don't set LETTA_SDK_TOOLS?
If the variable is unset or contains any value other than full or off, the system defaults to read-only mode. According to scripts/conversation_utils.ts, the getSdkToolsMode() function normalizes the input and returns read-only as the fallback, ensuring safe defaults.
Why are AskUserQuestion and other tools blocked in read-only mode?
The read-only whitelist defined at lines 71-76 in scripts/conversation_utils.ts specifically excludes interactive tools like AskUserQuestion, EnterPlanMode, and ExitPlanMode to prevent the background agent from interrupting your workflow or entering states requiring user interaction while operating autonomously.
Can I change the tool mode during an active session?
No. The sdkToolsMode is passed to the background worker during session initialization via send_messages_to_letta.ts (lines 9-12). To change permissions, you must set the environment variable and restart the Claude Code session so the new configuration propagates through session_start.ts and the worker initialization chain.
Where is the tool access actually enforced?
While getSdkToolsMode() in scripts/conversation_utils.ts determines the mode, the actual enforcement happens when the Letta SDK session is constructed in the background worker (referenced in send_worker_sdk.ts). The mode string flows from your environment through send_messages_to_letta.ts as part of the initialization payload, ensuring the Subconscious agent receives the correct tool set from the start.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →