Sanctum Letta MCP — SMCP — is the protocol server that turns plugins into tools an agent can actually call. Today we merged dev → master and tagged v3.1.0 on sanctumos/smcp. This is an omnibus production release: months of hardening on the Sanctum fork, not a single hotfix.
If you run SMCP anywhere agents touch real infrastructure, read the security section first, then skim what changed for operators and plugin authors.
Why this release matters
SMCP sits between Letta agents (and other MCP clients) and everything else — Tasks, Gmail, GitHub, provisioning APIs, custom product backends. When the core is sloppy, the failure modes are subtle: wrong tools in context, malformed argv, silent plugin skips, or an HTTP listener that should never have been world-readable.
3.1.0 is the line where we treat SMCP as production infrastructure, not a clever demo:
- Session attach governor with config-driven profiles — product-specific tool allowlists live in JSON, not hardcoded in core.
- Versioned plugin
--describecontract validated at discovery — bad metadata fails loudly with field paths, not mystery empty catalogs. - Structured tool errors — clients can tell timeout from plugin_error from invalid_tool_name without parsing prose.
- Installable packaging —
pip install .exposessmcpandsmcp-stdioconsole entrypoints; import collisions fixed. - CI + 90% coverage gate on Python 3.10–3.13 — 354 tests, ~99% line coverage on the release branch.
ServerContext— governor state and plugin registries are per-context, not process-global singletons.
Deep-dive on the governor philosophy (attach/detach as protocol): SMCP Tool Governance: Attach, Detach, and Help as a Protocol.
Critical security patch (HTTP/SSE transport)
Operators: this section is mandatory if you expose SMCP over the network.
SMCP 3.1.0 carries the HTTP authentication hardening we introduced on the dev line (issue #39, first documented in 3.0.3):
- Shared-secret auth via
MCP_API_KEY/MCP_API_KEYS— clients sendAuthorization: BearerorX-API-Key:. --allow-externalfails closed — binding beyond localhost refuses to start without a configured key, unless you explicitly setMCP_AUTH_DISABLED=1(logged as unsafe).- Loopback clients skip auth by default; use
--require-authwhen you want keys even on127.0.0.1. - Auth runs as raw ASGI middleware so SSE streaming is never buffered by a broken auth wrapper.
- STDIO transport is unchanged — no network surface, no keys required.
This is a critical security patch for any deployment that listens on a non-loopback interface. Upgrade, generate a long random key, set MCP_API_KEY, and restart before you bind externally. We are not publishing incident-specific details here; the fix is in the release, and the operator action is: upgrade + configure auth.
Quick reference:
export MCP_API_KEY="$(openssl rand -hex 32)"
smcp --allow-external --port 8000
export MCP_API_KEY="$(openssl rand -hex 32)" smcp --allow-external --port 8000
Full tables: SMCP deployment guide and API reference.
Governor profiles: tools the agent should see, not everything you could expose
The catalog plane (what plugins can do) and the attach plane (what this session may call) are different problems. 3.1.0 makes the attach plane data-driven:
- Load profiles from
SMCP_PROFILES— a JSON file or directory of.jsonconfigs. - Built-ins:
full(entire catalog) and optionaladminwhenSMCP_ADMIN_PREFIXis set. - Stale profile names fall back to
fullinstead of bricking the server. - Example config ships at
docs/examples/governor-profiles.json.
The sanctum__tools namespace (attach, detach, list-attached, help, profile management) is how agents and harnesses curate exposure without rewriting plugins.
Plugin authors: describe contract v1
Plugins should implement --describe returning JSON validated against docs/plugin-contract/v1.json. Invalid describe payloads are skipped at discovery with an explicit validation error — no silent half-registration.
Bundled demo_math and demo_text plugins demonstrate the contract. The retired botfather / devops samples are gone from core; real integrations live in standalone plugin repos under plugins/.
Structured array and object tool arguments now round-trip as clean JSON on argv (issue #56) — fixing a class of “the model sent valid JSON but the plugin got Python repr” failures in production plugins.
Operator checklist
- Pin
v3.1.0(or mergemaster) on your deployment branch. pip install .or use the newsmcp/smcp-stdioconsole scripts.- If the server is reachable off-box:
MCP_API_KEY+ verify--allow-externalwithout a key exits with code 2. - Point
SMCP_PROFILESat your product allowlists (Tasks chatter vs admin, etc.). - Set
MCP_PLUGIN_TIMEOUTif you run long subprocess tools. - Read the updated SanctumOS SMCP module doc on this site.
What's next
God-module decomposition (#43) stays deferred — the instance refactor (#46) bought us isolation without a risky file split. Plugin ecosystem work continues in satellite repos; core stays product-agnostic.
Questions and production reports: GitHub issues on sanctumos/smcp.
SMCP is AGPLv3 code, CC BY-SA docs. Maintained by the Sanctum team as a SanctumOS core module.*