No description
  • Python 98.9%
  • Makefile 1.1%
Find a file
2026-05-18 14:55:01 -05:00
src/letta_manager Feat: Add update-prompt command to modify existing agent system prompts 2026-05-18 14:55:01 -05:00
.gitignore Initial commit: letta-manager CLI with full SDK compliance 2026-05-18 11:26:28 -05:00
.woodpecker.yml On branch master 2026-05-18 11:58:51 -05:00
File-Structure Initial commit: letta-manager CLI with full SDK compliance 2026-05-18 11:26:28 -05:00
Makefile On branch master 2026-05-18 11:58:51 -05:00
pyproject.toml Add MCP tool refresh and binding commands 2026-05-18 13:12:51 -05:00
README.md Feat: Add update-prompt command to modify existing agent system prompts 2026-05-18 14:55:01 -05:00

Figuring out output format

Im realizing that using a code fence for the outer answer might cause a conflict with the instructions I received. They specified to output only the code without explanations. So, the final should just be the raw file content in plain text. Ill keep it straightforward and ensure that follows whats needed without any added commentary. Alright, let's produce that!Figuring out output format

Im realizing that using a code fence for the outer answer might cause a conflict with the instructions I received. They specified to output only the code without explanations. So, the final should just be the raw file content in plain text. Ill keep it straightforward and ensure that follows whats needed without any added commentary. Alright, let's produce that!# letta-manager / lumi

lumi mcp remove

Remove an MCP server by ID.

Patching Letta to allow internal/Docker MCP URLs (lab/dev only)

If you run a private self-hosted Letta instance and want to use Docker DNS names (e.g. http://mcp-qdrant-personal-memory:8000/sse), you can patch the Letta container to disable the private-IP check.

Quick live patch (running container):

letta-manager is an interactive Python CLI for managing a self-hosted Letta server from the terminal. It is designed for day-to-day agent administration without opening the Letta ADE or writing one-off Python scripts.

The installed console commands are:

  • lumi
  • letta-manager

Both commands point to the same Typer application.

Current Status

This project currently supports:

  • Local connection configuration
  • Secure-mode Letta password/token storage
  • Agent listing
  • Interactive agent creation using documented model, embedding, llm_config, embedding_config, memory_blocks, tools, tool_ids, and enable_sleeptime SDK parameters
  • Per-agent LLM/provider configuration, including endpoint type, endpoint URL, context window, and parallel tool-call behavior
  • Per-agent embedding/provider configuration, including endpoint type, endpoint URL, and embedding dimension
  • Agent deletion
  • Agent LLM model switching
  • Interactive persona/human core memory editing using documented agent_id and block_label SDK parameters
  • Letta model listing through client.models.list()
  • Embedding model listing through client.models.embeddings.list()
  • Global tool listing, inspection, creation, upsert, update, and deletion through client.tools.*
  • Agent tool listing, attach, detach, run, and approval configuration through client.agents.tools.*
  • MCP server listing, creation, tool refresh/sync, MCP tool listing, agent binding, and removal through client.mcp_servers.*
  • Table and JSON output where implemented

Planned but not yet implemented:

  • models add, models update, and models delete because the installed/documented Python SDK exposes model listing only
  • embedding-models add, embedding-models update, and embedding-models delete because the installed/documented Python SDK exposes embedding model listing only
  • folder/file attachment commands
  • agent message send/stream commands

Target Environment

The default Letta server URL is:

http://10.10.30.204:8283

The CLI is intended for a secure-mode self-hosted Letta server. The configured password is sent as a Bearer token through the Letta Python SDK.

For the installed letta-client==1.11.0 SDK, the client wrapper uses:

from letta_client import Letta

client = Letta(base_url=URL, api_key=PASSWORD)

letta-client maps api_key to:

Authorization: Bearer <PASSWORD>

The client wrapper also supports SDK variants that expose:

create_client(base_url=URL, token=PASSWORD)

Tech Stack

  • Python >=3.10
  • Typer for CLI commands, prompts, and confirmations
  • Rich for terminal tables and styled output
  • PyYAML for config file persistence
  • Official letta-client SDK for server communication

Project Layout

letta-manager/
├── README.md
├── pyproject.toml
└── src/
    └── letta_manager/
        ├── __init__.py
        ├── cli.py
        ├── client.py
        ├── config.py
        ├── formatting.py
        └── commands/
            ├── __init__.py
            ├── agents.py
            ├── config_cmds.py
            ├── mcp.py
            ├── models.py
            └── tools.py

Important Files

File Purpose
src/letta_manager/cli.py Root Typer app and command registration.
src/letta_manager/client.py Letta SDK initialization and API wrapper methods.
src/letta_manager/config.py Config model, YAML load/save, default server URL.
src/letta_manager/formatting.py Shared table and JSON output helpers.
src/letta_manager/commands/agents.py Agent-related CLI commands.
src/letta_manager/commands/config_cmds.py Local config commands.
src/letta_manager/commands/models.py Model inspection commands.
src/letta_manager/commands/mcp.py MCP server management commands.
src/letta_manager/commands/tools.py Global tool management commands.

Installation

From the project root:

cd letta-manager
pip install -e .

Verify installation:

lumi --help

Or:

letta-manager --help

Configuration

Connection settings are stored in:

~/.config/letta-manager/config.yaml

The CLI attempts to save this file with owner-only permissions:

0600

The config file contains:

server_url: http://10.10.30.204:8283
password: your-secure-mode-password

When displayed through the CLI, the password is masked.

Command Reference

Global Commands and Options

lumi --help

Show root help.

lumi --help

lumi --version

Show the installed package version.

lumi --version

Parameters:

Option Type Default Description
--version flag False Print the letta-manager version and exit.

config Commands

Manage local connection settings.

lumi config --help

lumi config show

Display current connection settings.

lumi config show

JSON output:

lumi config show --output json

Parameters:

Option Short Type Default Description
--output -o string table Output format. Supported values: table, json.

Table output includes:

  • Config file path
  • Server URL
  • Masked password

JSON output includes:

{
  "config_path": "/home/user/.config/letta-manager/config.yaml",
  "server_url": "http://10.10.30.204:8283",
  "password": "************abcd",
  "password_configured": true
}

lumi config set

Update the Letta server URL and/or secure-mode password.

Interactive usage:

lumi config set

Non-interactive usage:

lumi config set --server-url http://10.10.30.204:8283 --password YOUR_PASSWORD

Parameters:

Option Short Type Default Description
--server-url -u string Prompted interactively Letta server base URL.
--password -p string Prompted interactively Letta secure-mode password/token.

Interactive behavior:

  • If --server-url is omitted, the CLI prompts for it.
  • If --password is omitted, the CLI prompts securely with hidden input.
  • If a password is already configured and the password prompt is left blank, the existing password is kept.

agents Commands

Manage Letta agents.

lumi agents --help

lumi agents list

List all Letta agents with their Agent ID, name, LLM model, and embedding model.

lumi agents list

JSON output:

lumi agents list --output json

Parameters:

Option Short Type Default Description
--output -o string table Output format. Supported values: table, json.

Table columns:

Column Description
ID Letta Agent ID.
Name Agent name.
Model Current LLM model handle.
Embedding Current embedding model handle.

Example:

lumi agents list -o table
lumi agents list -o json

lumi agents create

Interactively provision a new Letta agent.

Interactive usage:

lumi agents create

Non-interactive usage:

lumi agents create \
  --name Lumi-Coding \
  --system "You are Lumi-Coding, a focused software engineering assistant." \
  --model openai/gpt-4o-mini \
  --embedding openai/text-embedding-3-small \
  --persona "My name is Lumi-Coding, a helpful software engineering assistant." \
  --human "The human is a developer who prefers concise, actionable help." \
  --tool web_search \
  --tool run_code

Skip final confirmation:

lumi agents create \
  --name Lumi-Work \
  --system "You are Lumi-Work, a concise professional work assistant." \
  --model openai/gpt-4o-mini \
  --embedding openai/text-embedding-3-small \
  --persona "My name is Lumi-Work, a focused professional assistant." \
  --human "The human needs help with work planning and execution." \
  --enable-sleeptime \
  --yes

Parameters:

Option Short Type Default Description
--name -n string Prompted; interactive default Lumi-Coding New agent name.
--system -s string Prompted; blank allowed Optional system prompt for the new agent.
--system-file none path none Read the system prompt from a UTF-8 text file.
--model -m string Prompted unless --llm-model is used Simple LLM model handle.
--embedding -e string Prompted unless --embedding-model is used Simple embedding model handle.
--llm-model none string none Advanced per-agent LLM config model name.
--llm-endpoint-type none string openai when advanced LLM config is used Advanced LLM endpoint type. Stored as model_endpoint_type.
--llm-endpoint none string none Advanced LLM endpoint URL. Stored as model_endpoint.
--context-window none integer none Advanced LLM context window.
--parallel-tool-calls / --no-parallel-tool-calls none flag pair False Advanced LLM parallel tool-call setting.
--embedding-model none string none Advanced per-agent embedding config model name.
--embedding-endpoint-type none string openai when advanced embedding config is used Advanced embedding endpoint type.
--embedding-endpoint none string none Advanced embedding endpoint URL.
--embedding-dim none integer none Advanced embedding vector dimension.
--persona none string Prompted; blank allowed Initial persona memory block value.
--human none string Prompted; blank allowed Initial human memory block value.
--tool -t repeatable string none Tool name to attach, e.g. web_search; can be passed multiple times.
--tool-id none repeatable string none Tool ID to attach; can be passed multiple times.
--enable-sleeptime none flag False Enable a sleep-time/background memory agent.
--yes -y flag False Create without final confirmation.

Implementation details:

For letta-client==1.11.0, this command calls:

client.agents.create(
    name=name,
    system=system,
    model=model,
    embedding=embedding,
    llm_config={
        "model": "grok-4.3-medium",
        "model_endpoint_type": "openai",
        "model_endpoint": "http://litellm:4000/v1",
        "context_window": 32000,
        "parallel_tool_calls": False,
    },
    embedding_config={
        "embedding_model": "bge-m3",
        "embedding_endpoint_type": "openai",
        "embedding_endpoint": "http://ollama:11434/v1",
        "embedding_dim": 1024,
    },
    memory_blocks=[
        {"label": "human", "value": human},
        {"label": "persona", "value": persona},
    ],
    tools=tools,
    tool_ids=tool_ids,
    enable_sleeptime=enable_sleeptime,
)

When the advanced options are used, lumi sends llm_config and/or embedding_config directly to Letta. This is how you reproduce the behavior of scripts that create agents with custom endpoints such as LiteLLM for LLMs and Ollama for embeddings.

Example matching the existing Lumi TrueNAS stack pattern:

lumi agents create \
  --name Lumi-Brain-Stateful \
  --system-file /path/to/SOUL.md \
  --llm-model grok-4.3-medium \
  --llm-endpoint-type openai \
  --llm-endpoint http://litellm:4000/v1 \
  --context-window 32000 \
  --no-parallel-tool-calls \
  --embedding-model bge-m3 \
  --embedding-endpoint-type openai \
  --embedding-endpoint http://ollama:11434/v1 \
  --embedding-dim 1024

Recommended model naming with LiteLLM:

openai/gpt-5.5-high
openai/claude-opus-4.7
openai/grok-4.3-low

lumi agents update-model

Change the LLM model for an existing agent.

Interactive usage:

lumi agents update-model

By agent name:

lumi agents update-model Lumi-Coding --model openai/claude-opus-4.7

By Agent ID:

lumi agents update-model agent-xxxxxxxx --model openai/grok-4.3-low

Skip confirmation:

lumi agents update-model Lumi-Coding --model openai/gpt-5.5-high --yes

Arguments and options:

Argument / Option Short Type Default Description
agent n/a string argument Prompted if omitted Agent ID or exact agent name.
--model -m string Prompted; interactive default openai/claude-opus-4.7 New LLM model handle.
--yes -y flag False Update without final confirmation.

Implementation details:

For letta-client==1.11.0, this command calls:

client.agents.update(agent_id, model=model)

A fallback path exists for SDK variants that expose agents.modify(...).

lumi agents configure-llm

Replace one agent's full per-agent LLM/provider configuration.

lumi agents configure-llm Lumi-Brain-Stateful \
  --llm-model grok-4.3-medium \
  --llm-endpoint-type openai \
  --llm-endpoint http://litellm:4000/v1 \
  --context-window 32000 \
  --no-parallel-tool-calls

Skip confirmation:

lumi agents configure-llm Lumi-Brain-Stateful \
  --llm-model grok-4.3-medium \
  --llm-endpoint http://litellm:4000/v1 \
  --yes

Parameters:

Argument / Option Type Default Description
agent string argument required Agent ID or exact agent name.
--llm-model string required LLM model name.
--llm-endpoint-type string openai Endpoint type. Stored as model_endpoint_type.
--llm-endpoint string http://litellm:4000/v1 LLM endpoint URL. Stored as model_endpoint.
--context-window integer 32000 LLM context window.
--parallel-tool-calls / --no-parallel-tool-calls flag pair False Parallel tool-call setting.
--yes flag False Update without confirmation.

Implementation details:

client.agents.update(
    agent_id,
    llm_config={
        "model": llm_model,
        "model_endpoint_type": llm_endpoint_type,
        "model_endpoint": llm_endpoint,
        "context_window": context_window,
        "parallel_tool_calls": parallel_tool_calls,
    },
)

lumi agents configure-embedding

Replace one agent's full per-agent embedding/provider configuration.

lumi agents configure-embedding Lumi-Brain-Stateful \
  --embedding-model bge-m3 \
  --embedding-endpoint-type openai \
  --embedding-endpoint http://ollama:11434/v1 \
  --embedding-dim 1024

Parameters:

Argument / Option Type Default Description
agent string argument required Agent ID or exact agent name.
--embedding-model string required Embedding model name.
--embedding-endpoint-type string openai Embedding endpoint type.
--embedding-endpoint string http://ollama:11434/v1 Embedding endpoint URL.
--embedding-dim integer 1024 Embedding vector dimension.
--yes flag False Update without confirmation.

Implementation details:

client.agents.update(
    agent_id,
    embedding_config={
        "embedding_model": embedding_model,
        "embedding_endpoint_type": embedding_endpoint_type,
        "embedding_endpoint": embedding_endpoint,
        "embedding_dim": embedding_dim,
    },
)

lumi agents update-prompt

Update the system prompt of an existing agent.

lumi agents update-prompt Lumi-Personal --system "You are Lumi..."

From a file:

lumi agents update-prompt Lumi-Personal --system-file ./new_prompt.md

lumi agents update-memory

Interactively view and update the persona and human core memory blocks of an agent.

Interactive usage:

lumi agents update-memory

By agent name:

lumi agents update-memory Lumi-Personal

By Agent ID:

lumi agents update-memory agent-xxxxxxxx

Skip final confirmation:

lumi agents update-memory Lumi-Personal --yes

Arguments and options:

Argument / Option Short Type Default Description
agent n/a string argument Prompted if omitted Agent ID or exact agent name.
--yes -y flag False Apply memory changes without final confirmation.

Interactive behavior:

  1. Resolves the agent by exact Agent ID or exact name.
  2. Displays current persona core memory.
  3. Displays current human core memory.
  4. Prompts for new persona text.
  5. Prompts for new human text.
  6. If a prompt is left blank, that memory block is unchanged.
  7. Shows pending changes.
  8. Requires confirmation unless --yes is used.

Implementation details:

For letta-client==1.11.0, memory is read using:

client.agents.blocks.retrieve(agent_id=agent_id, block_label="persona")
client.agents.blocks.retrieve(agent_id=agent_id, block_label="human")

Memory is updated using:

client.agents.blocks.update(agent_id=agent_id, block_label="persona", value=new_persona)
client.agents.blocks.update(agent_id=agent_id, block_label="human", value=new_human)

Fallback paths exist for SDK variants that expose agents.core_memory, agents.memory, or top-level memory methods.

lumi agents delete

Delete an agent by Agent ID or exact agent name.

lumi agents delete Lumi-Coding

Skip confirmation:

lumi agents delete agent-xxxxxxxx --yes

Arguments and options:

Argument / Option Short Type Default Description
agent n/a string argument Prompted if omitted Agent ID or exact agent name.
--yes -y flag False Delete without final confirmation.

Implementation details:

client.agents.delete(agent_id)

models Commands

Inspect model registrations exposed by the Letta server.

lumi models list

List registered LLM models using the documented SDK method client.models.list().

lumi models list

JSON output:

lumi models list --output json

Parameters:

Option Short Type Default Description
--output -o string table Output format. Supported values: table, json.

Implementation details:

models = client.models.list()

lumi models embeddings

List registered embedding models using the documented SDK method client.models.embeddings.list().

lumi models embeddings

JSON output:

lumi models embeddings --output json

lumi models explain-crud

Explain why global model and embedding model add/update/delete commands are not implemented and point to per-agent config commands.

lumi models explain-crud

Model and Embedding Model CRUD Limitations

The installed letta-client==1.11.0 SDK exposes these model APIs:

client.models.list()
client.models.embeddings.list()

It does not expose these methods:

client.models.create()
client.models.update()
client.models.delete()
client.models.embeddings.create()
client.models.embeddings.update()
client.models.embeddings.delete()

Because of that, lumi cannot safely implement add/modify/delete operations for LLM models or embedding models via the Letta Python SDK.

For this deployment, LLM and embedding model availability should be managed at the provider/router layer, for example in your LiteLLM configuration. After a model is available to Letta, use:

lumi models list

to inspect what Letta can see.


tools Commands

Manage global Letta tools exposed by client.tools.*.

lumi tools list

List globally available tools.

lumi tools list

JSON output:

lumi tools list --output json

Parameters:

Option Short Type Default Description
--output -o string table Output format. Supported values: table, json.

Table columns:

Column Description
ID Global Letta tool ID.
Name Tool name.
Description First 50 characters of the tool description.

Implementation details:

tools = client.tools.list()

lumi tools show

Show one global tool as JSON.

lumi tools show TOOL_ID

lumi tools create

Create a global tool from a source-code file.

lumi tools create \
  --source-file ./my_tool.py \
  --description "My custom tool" \
  --source-type python \
  --tag custom

Useful options:

Option Description
--source-file, -f Tool source code file. Required.
--description, -d Tool description.
--source-type Tool source type. Default: python.
--json-schema-file JSON schema file for the tool.
--args-json-schema-file Args JSON schema file for the tool.
--tag Tag. Can be repeated.
--return-char-limit Return character limit.
--requires-approval / --no-requires-approval Default approval requirement.
--parallel-execution / --no-parallel-execution Parallel execution setting.
--upsert Use client.tools.upsert() instead of client.tools.create().

lumi tools update

Update a global tool by ID.

lumi tools update TOOL_ID --source-file ./my_tool.py --description "Updated description"

lumi tools delete

Delete a global tool by tool ID.

lumi tools delete TOOL_ID

Skip confirmation:

lumi tools delete TOOL_ID --yes

Arguments:

Argument Type Description
tool_id string Global Letta tool ID to delete.

Implementation details:

client.tools.delete(tool_id)

Agent-attached tool commands

List tools attached to an agent:

lumi tools agent-list Lumi-Brain-Stateful

Attach a global tool to an agent:

lumi tools attach Lumi-Brain-Stateful TOOL_ID

Detach a tool from an agent:

lumi tools detach Lumi-Brain-Stateful TOOL_ID

Run an attached tool:

lumi tools run Lumi-Brain-Stateful tool_name --args-json '{"key":"value"}'

Update approval policy for an attached tool:

lumi tools approval Lumi-Brain-Stateful tool_name --body-requires-approval

Implementation details:

client.tools.create(source_code=...)
client.tools.upsert(source_code=...)
client.tools.update(tool_id, ...)
client.tools.delete(tool_id)
client.agents.tools.list(agent_id)
client.agents.tools.attach(tool_id, agent_id=agent_id)
client.agents.tools.detach(tool_id, agent_id=agent_id)
client.agents.tools.run(tool_name, agent_id=agent_id, args={...})
client.agents.tools.update_approval(tool_name, agent_id=agent_id, body_requires_approval=True)

mcp Commands

Manage Model Context Protocol servers using the documented Letta Python SDK methods.

lumi mcp list

List configured MCP servers.

lumi mcp list

JSON output:

lumi mcp list --output json

Parameters:

Option Short Type Default Description
--output -o string table Output format. Supported values: table, json.

Implementation details:

servers = client.mcp_servers.list()

lumi mcp add

Create an MCP server. The command maps directly to the documented Python SDK parameters server_name and config.

Streamable HTTP example:

lumi mcp add \
  --server-name weather-server \
  --type streamable_http \
  --server-url https://weather-mcp.example.com/mcp

SSE example:

lumi mcp add \
  --server-name sse-tools \
  --type sse \
  --server-url https://tools.example.com/sse

stdio example:

lumi mcp add \
  --server-name local-tools \
  --type stdio \
  --command npx \
  --args "-y @modelcontextprotocol/server-filesystem /tmp" \
  --env NODE_ENV=production

Parameters:

Option Short Type Default Description
--server-name -n string Prompted MCP server name.
--type -t string Prompted; interactive default streamable_http MCP server type, e.g. streamable_http, sse, or stdio.
--server-url -u string Prompted for HTTP/SSE types MCP HTTP/SSE server URL.
--command -c string Prompted for stdio type Command for stdio MCP servers.
--args none string none Shell-style argument string for stdio command.
--env none repeatable string none Environment variable in KEY=VALUE format; can be repeated.
--yes -y flag False Create without final confirmation.

Implementation details:

client.mcp_servers.create(
    server_name=server_name,
    config={
        "mcp_server_type": "streamable_http",
        "server_url": "https://weather-mcp.example.com/mcp",
    },
)

lumi mcp tools

List tools discovered for one MCP server. The argument can be an MCP server ID or exact MCP server name.

lumi mcp tools qdrant-personal-memory

JSON output:

lumi mcp tools qdrant-personal-memory --output json

Implementation details:

client.mcp_servers.tools.list(mcp_server_id)

lumi mcp refresh

Ask Letta to refresh/sync tools from an MCP server. The argument can be an MCP server ID or exact MCP server name.

lumi mcp refresh qdrant-personal-memory

Refresh for a specific agent:

lumi mcp refresh qdrant-personal-memory --agent Lumi-Brain-Stateful

Implementation details:

client.mcp_servers.refresh(mcp_server_id, agent_id=agent_id)

lumi mcp bind-tools

Refresh one MCP server and attach all discovered MCP tools to an agent.

lumi mcp bind-tools qdrant-personal-memory Lumi-Brain-Stateful

Implementation details:

client.mcp_servers.refresh(mcp_server_id, agent_id=agent_id)
tools = client.mcp_servers.tools.list(mcp_server_id)
for tool in tools:
    client.agents.tools.attach(tool.id, agent_id=agent_id)

lumi mcp bind-all

Refresh and bind tools from all configured MCP servers to one agent.

lumi mcp bind-all Lumi-Brain-Stateful

Bind selected MCP servers only:

lumi mcp bind-all Lumi-Brain-Stateful \
  --server qdrant-personal-memory \
  --server qdrant-conversation-history \
  --server qdrant-documents

Local MCP URL Security Note

Letta validates MCP HTTP/SSE URLs for SSRF protection. In current Letta server builds, MCP refresh/connect rejects URLs whose host resolves to non-public IPs, including Docker bridge IPs and IPv6 ULA addresses. A server can be created with a Docker DNS URL but fail during refresh with an error like:

Hostname resolves to non-public IP: fdd0:0:0:7::f

If this happens, expose the MCP service through a public HTTPS reverse proxy or another hostname that resolves to a public IP accepted by Letta, then update/recreate the MCP server with that URL before running lumi mcp refresh, lumi mcp bind-tools, or lumi mcp bind-all.

lumi mcp remove

Remove an MCP server by ID.

lumi mcp remove mcp-server-id

Skip confirmation:

lumi mcp remove mcp-server-id --yes

Arguments and options:

Argument / Option Short Type Default Description
mcp_server_id n/a string argument Prompted if omitted MCP server ID.
--yes -y flag False Remove without final confirmation.

Implementation details:

client.mcp_servers.delete(mcp_server_id)

Safety Behavior

The CLI is intentionally conservative:

  • agents create asks for confirmation unless --yes is used.
  • agents update-model asks for confirmation unless --yes is used.
  • agents configure-llm asks for confirmation unless --yes is used.
  • agents configure-embedding asks for confirmation unless --yes is used.
  • agents update-memory asks for confirmation unless --yes is used.
  • agents delete asks for confirmation unless --yes is used.
  • mcp add asks for confirmation unless --yes is used.
  • mcp remove asks for confirmation unless --yes is used.
  • tools delete asks for confirmation unless --yes is used.
  • Blank memory prompts do not erase memory; they keep the current block unchanged.
  • Password display is masked in config show.

Output Formats

Commands that support --output currently accept:

Format Description
table Rich terminal table intended for humans.
json JSON output intended for scripts and automation.

Currently supported JSON commands:

lumi config show --output json
lumi agents list --output json
lumi models list --output json
lumi models embeddings --output json
lumi tools list --output json
lumi mcp list --output json
lumi mcp tools MCP_SERVER_ID --output json

Common Workflows

First-Time Setup

cd letta-manager
pip install -e .
lumi config set
lumi config show
lumi agents list

Create the Planned Lumi Agents

lumi agents create --name Lumi-Personal
lumi agents create --name Lumi-Work
lumi agents create --name Lumi-Coding

Each command will prompt for the optional system prompt, model, embedding, initial persona memory, initial human memory, and confirmation.

Switch an Agent Between LiteLLM-Routed Models

lumi agents update-model Lumi-Coding --model openai/grok-4.3-low
lumi agents update-model Lumi-Coding --model openai/claude-opus-4.7

Edit Core Memory

lumi agents update-memory Lumi-Personal

At each prompt, press Enter to keep the existing value.

Inspect and Delete Global Tools

lumi tools list
lumi tools delete tool-xxxxxxxx

Bind MCP Tools to Lumi

After registering reachable MCP servers, bind every discovered MCP tool to the Lumi agent:

lumi mcp bind-all Lumi-Brain-Stateful

Or bind only the Qdrant MCP servers:

lumi mcp bind-all Lumi-Brain-Stateful \
  --server qdrant-personal-memory \
  --server qdrant-conversation-history \
  --server qdrant-documents

Verify attached tools:

lumi tools agent-list Lumi-Brain-Stateful

Inspect Available Models

lumi models list

Global model and embedding model add/update/delete operations are managed outside this CLI, typically in LiteLLM or the upstream model provider configuration. Per-agent LLM and embedding provider settings can be changed with lumi agents configure-llm and lumi agents configure-embedding.

Error Handling

The CLI catches Letta client wrapper errors and prints Rich-formatted messages such as:

Error: No Letta password configured. Run: lumi config set

or:

Error: Failed to list agents: <details from SDK/server>

If the SDK shape changes, most compatibility changes should be isolated to:

src/letta_manager/client.py

Development Notes

Run syntax checks:

python -m compileall src

Run CLI help without reinstalling, from the project root:

PYTHONPATH=src python -m letta_manager.cli --help

After code changes, reinstall the editable package if needed:

pip install -e .

Version

Current package version:

0.1.0