The Modular, Self-Hosted Agentic Operating System

Sanctum Letta MCP (SMCP)

Plugin-based Model Context Protocol server for Letta and MCP clients

Sanctum Letta MCP — SMCP — is the tool layer of SanctumOS. It discovers CLI plugins, exposes their commands as MCP tools, and speaks the protocol over SSE/HTTP (remote clients like Letta) or STDIO (local clients like Cursor).

Latest release: SMCP 3.1.0: The Tool Layer Ships — production merge on master, critical HTTP auth hardening, governor profiles, and structured tool errors. Repository: sanctumos/smcp · tag v3.1.0.

What SMCP does

  • Plugin architecture — drop a plugin directory under plugins/; its commands become MCP tools at startup.
  • Auto-discovery — preferred path is each plugin's --describe JSON contract; help-text scraping is the fallback.
  • Session attach governor — expose a curated subset of tools per session via sanctum__tools and config-driven profiles (SMCP_PROFILES).
  • Two transportssmcp.py (SSE/HTTP) and smcp_stdio.py (STDIO).
  • Optional API-key auth on HTTP — fail-closed when binding externally (--allow-external requires MCP_API_KEY unless explicitly disabled).

Quick installation

Prerequisites

  • Python 3.10+ (required by the mcp dependency)
  • pip and a virtual environment

Install and run (SSE)

git clone https://github.com/sanctumos/smcp.git
cd smcp
git checkout master   # production branch; v3.1.0+
python3 -m venv venv
source venv/bin/activate   # Windows: venv\Scripts\activate
pip install .

# Localhost-only SSE server (default — no API key required)
smcp
# or: python smcp.py

git clone https://github.com/sanctumos/smcp.git cd smcp git checkout master # production branch; v3.1.0+ python3 -m venv venv source venv/bin/activate # Windows: venv\Scripts\activate pip install .

Localhost-only SSE server (default — no API key required)

smcp

or: python smcp.py


The server listens on http://127.0.0.1:8000 by default.

### STDIO transport (Cursor, local MCP)

bash
smcp-stdio
# or: python smcp_stdio.py

The server listens on http://127.0.0.1:8000 by default.

STDIO transport (Cursor, local MCP)

git clone https://github.com/sanctumos/smcp.git
cd smcp
git checkout master   # production branch; v3.1.0+
python3 -m venv venv
source venv/bin/activate   # Windows: venv\Scripts\activate
pip install .

# Localhost-only SSE server (default — no API key required)
smcp
# or: python smcp.py

smcp-stdio

or: python smcp_stdio.py


The server listens on http://127.0.0.1:8000 by default.

### STDIO transport (Cursor, local MCP)

bash
smcp-stdio
# or: python smcp_stdio.py

Verify

Connect your MCP client to http://127.0.0.1:8000/sse (Letta) or run STDIO per your IDE's MCP config. On startup you should see discovered plugins (bundled demo_math and demo_text in a fresh clone).

Security and external binding

Default is safe: bind to localhost only.

If you must listen on all interfaces:

git clone https://github.com/sanctumos/smcp.git
cd smcp
git checkout master   # production branch; v3.1.0+
python3 -m venv venv
source venv/bin/activate   # Windows: venv\Scripts\activate
pip install .

# Localhost-only SSE server (default — no API key required)
smcp
# or: python smcp.py

export MCP_API_KEY="$(openssl rand -hex 32)" smcp --allow-external --port 8000


The server listens on http://127.0.0.1:8000 by default.

### STDIO transport (Cursor, local MCP)

bash
smcp-stdio
# or: python smcp_stdio.py

Rules:

  • --allow-external without MCP_API_KEY → process exits with code 2 (fail closed).
  • Clients must send Authorization: Bearer or X-API-Key: .
  • Loopback clients skip auth by default; use --require-auth to require keys locally too.
  • MCP_AUTH_DISABLED=1 is an explicit escape hatch (not recommended).

STDIO has no network auth surface.

Configuration

Environment variables (common)

Variable Default Description
MCP_PORT 8000 HTTP port
MCP_HOST 127.0.0.1 Bind address
MCP_PLUGINS_DIR plugins/ Plugin search path
MCP_API_KEY Shared secret for HTTP/SSE auth
MCP_API_KEYS Comma-separated keys (rotation)
MCP_PLUGIN_TIMEOUT Subprocess timeout in seconds (0 = none)
MCP_LOG_DIR logs/ Log directory (created at server start, not import)
SMCP_PROFILES Governor profile JSON file or directory
SMCP_ATTACH_PROFILE full Active attach profile name
SMCP_ADMIN_PREFIX Optional admin profile tool prefix (e.g. tasks__)

Full tables: upstream API reference.

Command-line flags

Flag Purpose
--allow-external Bind 0.0.0.0 (requires API key)
--require-auth Require API key even on loopback
--host / --port Override bind
--plugin-timeout Kill slow plugin subprocesses

Directory layout


The server listens on http://127.0.0.1:8000 by default.

### STDIO transport (Cursor, local MCP)

bash
smcp-stdio
# or: python smcp_stdio.py

smcp/ ├── smcp.py # SSE/HTTP entrypoint ├── smcp_stdio.py # STDIO entrypoint ├── governor.py # Session attach governor ├── plugins/ │ ├── demo_math/ # Bundled demo plugin │ └── demo_text/ # Bundled demo plugin │ └── gmail/ # Example: clone smcp-gmail here └── docs/ # Operator + plugin author guides


The server listens on http://127.0.0.1:8000 by default.

### STDIO transport (Cursor, local MCP)

bash
smcp-stdio
# or: python smcp_stdio.py

Product plugins (Tasks, Gmail, GitHub, etc.) are separate repositories cloned into plugins/. See SMCP Plugins.

Session attach governor

SMCP separates catalog (everything discovered) from attachment (what this session may call).

Plugin development

  1. Create plugins/your_plugin/cli.py with argparse commands.
  2. Implement --describe returning JSON per docs/plugin-contract/v1.json.
  3. Restart SMCP — valid plugins register; invalid describe payloads are skipped with a clear error.

Guide: Plugin Development.

Connecting Letta

Point your Letta MCP server URL at http://:/sse. If the server requires auth, configure the bearer key in Letta's MCP settings.

Step-by-step: Letta MCP Connection Guide.

Branches

  • master — production-stable (3.1.0+).
  • dev — day-to-day integration; merge to master` for releases.

Troubleshooting

Symptom Likely fix
Exit code 2 on --allow-external Set MCP_API_KEY or drop --allow-external
401 from client Send Bearer / X-API-Key header
Plugin missing from catalog Check --describe validates; read startup stderr
Tool timeout Set MCP_PLUGIN_TIMEOUT or --plugin-timeout

More: upstream troubleshooting and site troubleshooting guide.

License

  • Code: AGPLv3
  • Documentation: CC BY-SA 4.0

Sanctum Letta MCP — the MCP tool layer of SanctumOS.