# How to Configure LETTA_SDK_TOOLS for Client-Side Tool Access in the Background Agent

> Configure LETTA_SDK_TOOLS for background agent access to Letta SDK tools. Set the environment variable to read-only, full, or off to control tool invocation.

- Repository: [Letta/claude-subconscious](https://github.com/letta-ai/claude-subconscious)
- Tags: how-to-guide
- Published: 2026-03-26

---

**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`](https://github.com/letta-ai/claude-subconscious/blob/main/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`, and `fetch_webpage`. Explicitly blocks interactive tools like `AskUserQuestion`, `EnterPlanMode`, and `ExitPlanMode`. This is defined in [`scripts/conversation_utils.ts`](https://github.com/letta-ai/claude-subconscious/blob/main/scripts/conversation_utils.ts) at 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`](https://github.com/letta-ai/claude-subconscious/blob/main/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`](https://github.com/letta-ai/claude-subconscious/blob/main/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`](https://github.com/letta-ai/claude-subconscious/blob/main/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`](https://github.com/letta-ai/claude-subconscious/blob/main/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:

```bash
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:

```bash
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

```bash
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

```bash
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

```bash
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_TOOLS`** controls client-side tool permissions for the Claude Subconscious background agent in the `letta-ai/claude-subconscious` repository.
- Three modes exist: **`read-only`** (default), **`full`**, and **`off`**, parsed by `getSdkToolsMode()` in [`scripts/conversation_utils.ts`](https://github.com/letta-ai/claude-subconscious/blob/main/scripts/conversation_utils.ts).
- The configuration flows from environment variable → [`session_start.ts`](https://github.com/letta-ai/claude-subconscious/blob/main/session_start.ts) (display) → [`send_messages_to_letta.ts`](https://github.com/letta-ai/claude-subconscious/blob/main/send_messages_to_letta.ts) (worker payload).
- Read-only mode permits `Read`, `Grep`, `Glob`, `web_search`, and `fetch_webpage` while blocking interactive tools.
- Set the variable in your shell or use `.envrc` with 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`](https://github.com/letta-ai/claude-subconscious/blob/main/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`](https://github.com/letta-ai/claude-subconscious/blob/main/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`](https://github.com/letta-ai/claude-subconscious/blob/main/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`](https://github.com/letta-ai/claude-subconscious/blob/main/session_start.ts) and the worker initialization chain.

### Where is the tool access actually enforced?

While `getSdkToolsMode()` in [`scripts/conversation_utils.ts`](https://github.com/letta-ai/claude-subconscious/blob/main/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`](https://github.com/letta-ai/claude-subconscious/blob/main/send_worker_sdk.ts)). The mode string flows from your environment through [`send_messages_to_letta.ts`](https://github.com/letta-ai/claude-subconscious/blob/main/send_messages_to_letta.ts) as part of the initialization payload, ensuring the Subconscious agent receives the correct tool set from the start.