Skip to main content
Glama

SOMA MCP

One private memory. Every agent you trust, through the official Model Context Protocol.

CI Python MCP protocol Release License

What it is

SOMA MCP is a private, self-hosted reference implementation of an MCP server that puts one person's memory behind nine MCP tools. Claude, ChatGPT, Cursor, VS Code or your own agent can search, read, write, correct and audit that memory over an authenticated connection, with the same protocol and the same clients as any other MCP server.

This repository contains the transport shell (FastMCP), the FastMCP-free tool kernel with its security guards, and an Engine interface for the retrieval backend. A dependency-free InMemoryEngine ships so the server runs and its tests pass out of the box; plug in your own Engine to front your own memory.

Related MCP server: engram

What it is not

  • Not a hosted service. You run it, on hardware and keys you control.

  • Not multi-tenant. One instance is one person's memory.

  • Not an open endpoint. A valid OAuth token is necessary but not sufficient: the token's subject must also be on a fail-closed allowlist.

  • Not a retrieval engine. The bundled InMemoryEngine does substring search for demos and tests. Real retrieval is your Engine.

  • Not a fork of MCP. It is built on the official MCP Python SDK through FastMCP and speaks the standard wire protocol.

Why self-hosted memory

Agents get more useful as they remember more, and what they remember about you is among the most sensitive data you have. Most MCP servers wrap a vendor API; SOMA MCP wraps your own retrieval pipeline over your own data. The protocol is shared with the whole ecosystem; the substrate stays yours.

Typical hosted MCP server

SOMA MCP

Backend

A public or SaaS API

Your retrieval pipeline over your data

Hosting

Vendor cloud

Self-hosted

Tenancy

Often multi-tenant

One private memory per instance

Access

API key or shared auth

OAuth 2.1 plus a fail-closed subject allowlist

Protocol

Official MCP

Official MCP (same clients, same wire)

Supported stack

Component

Version

SOMA MCP

0.2.0 (changelog)

FastMCP

>=4.1,<5 (PrefectHQ/fastmcp)

MCP Python SDK

>=2.3,<3 (modelcontextprotocol/python-sdk)

MCP protocol

2026-07-28, plus the handshake revisions 2024-11-05, 2025-03-26, 2025-06-18 and 2025-11-25, negotiated per request by the SDK

Python

3.10, 3.11, 3.12, 3.13, 3.14

Transport

Streamable HTTP at /mcp

soma-mcp --version prints the exact versions installed. What is tested and what is delegated to the SDK is listed in docs/compliance.md.

Quick start (local, unauthenticated)

git clone https://github.com/odbgrowth/soma-mcp.git
cd soma-mcp
python -m venv .venv
source .venv/bin/activate
pip install -e .

export MCP_SINGLE_USER=1   # deliberate single-user mode; otherwise every call is denied
soma-mcp                   # Streamable HTTP at http://127.0.0.1:8000/mcp

Without the AUTH0_* variables the server runs unauthenticated, says so in its log, listens on 127.0.0.1 only and rejects requests whose Host or Origin is not local (DNS-rebinding protection). That is for experiments on your own machine, never for a network.

List and call the tools with the official MCP Inspector (Node 22.19+):

npx @modelcontextprotocol/inspector --server-url http://127.0.0.1:8000/mcp --transport http
npx @modelcontextprotocol/inspector --cli http://127.0.0.1:8000/mcp --transport http \
  --protocol-era modern --method tools/call --tool-name soma_whoami

or from Python with the MCP SDK client:

import anyio
from mcp import Client


async def main() -> None:
    async with Client("http://127.0.0.1:8000/mcp") as client:
        print(client.protocol_version)  # 2026-07-28
        tools = await client.list_tools()
        print([tool.name for tool in tools.tools])


anyio.run(main)

More clients and payloads: docs/examples.md.

Plug in your own memory

Implement the Engine protocol (src/soma_mcp/engine.py) over your own retrieval stack and inject it:

from my_stack import MyEngine  # your implementation of soma_mcp.Engine

from soma_mcp import serve

serve(MyEngine())  # same configuration, bind address and DNS-rebinding guard as soma-mcp

The Engine surface is nine methods (search, filter, get, assemble context, add/update/delete note, full note, log feedback). The tool kernel, guards and prompt-injection fence are reused unchanged. build_server(engine) returns the FastMCP server itself if you need to mount it elsewhere; then you own the transport settings, including the Host/Origin guard.

Production (authenticated)

Configure Auth0 and run behind a TLS-terminating proxy. All five Auth0 settings are required together; a partial configuration refuses to start instead of running unauthenticated. Details: docs/auth.md, .env.example.

Variable

Purpose

AUTH0_CONFIG_URL, AUTH0_CLIENT_ID, AUTH0_CLIENT_SECRET, AUTH0_AUDIENCE, BASE_URL

OAuth 2.1 through Auth0. All or none.

MCP_TOEGANG_SUBJECTS

Comma-separated allowlist of token subjects that may use the instance.

MCP_SCHRIJF_SUBJECTS

Allowlist of subjects that may write, update and delete.

MCP_SINGLE_USER

1 to run deliberately without an allowlist. Otherwise the guards fail closed. With Auth0, prefer an allowlist: single-user mode admits every account that can sign in to the Auth0 application.

MCP_RATE_LIMIT

Calls per minute per subject (default 30; 0 disables).

MCP_JWT_SIGNING_KEY, MCP_STORAGE_ENCRYPTION_KEY

Both or neither: encrypted OAuth state on the data volume, so connectors survive restarts (pip install ".[auth]").

MCP_HOST, MCP_PORT

Bind address. Default 0.0.0.0:8000 with Auth0, 127.0.0.1:8000 without.

SOMA_DATA

Data directory for the token store (mcp_oauth/) and the audit log.

Security model

  • Two keys: an OAuth 2.1 token and an allowlisted subject; a stricter allowlist for writes. Fail closed when an allowlist is missing.

  • Fail-closed configuration: partial Auth0 or token-storage settings stop the server at startup.

  • Encrypted token storage: Fernet-encrypted FileTreeStore with sanitized keys in a directory only the service user can write (0.1.x used the pickle-based DiskStore, CVE-2025-69872).

  • Prompt-injection fence: every memory text a tool returns is marked as data, not instructions.

  • Safety valves: per-subject rate limit, JSONL audit log of writes, two-step delete, size caps, masked internal errors.

Threat model: docs/security.md. Reporting vulnerabilities: SECURITY.md.

Public Python API

Supported imports: soma_mcp.Engine, soma_mcp.InMemoryEngine, soma_mcp.Kernel, soma_mcp.build_server, soma_mcp.serve, soma_mcp.main and soma_mcp.__version__. soma_mcp.config.ConfigurationError is what build_server and serve raise on a partial configuration. Everything else is internal and may change in a minor release.

Development

pip install -e ".[dev,auth]"
.devflows/verify            # ruff, mypy, pytest with coverage, release metadata, whitespace
python3 .devflows/run.py package   # build sdist and wheel, twine check

CI runs the same gates on Python 3.10 to 3.14, the declared dependency floors, pip-audit, gitleaks, a clean-wheel smoke test and the applicable scenarios of the official MCP conformance suite. Releases are tag-driven and documented in RELEASE.md; upgrade notes live in docs/upgrading.md. Contributor and agent rules: AGENTS.md.

Documentation

docs/README.md is the map: architecture, specification, tools, auth, security, compliance, examples, upgrading and the architecture decision records.

Note on language

SOMA is a Dutch-language personal system. The private production server uses Dutch tool parameter names (vraag, tekst, bevestig, diep, oordeel); this public reference uses English ones (question, text, confirm, deep, verdict) with identical semantics. Some result keys keep their Dutch names (tekst, bronnen, datum, herkomst), as do the allowlist variables (MCP_TOEGANG_SUBJECTS = access, MCP_SCHRIJF_SUBJECTS = write).

About the standard

MCP is an open standard introduced by Anthropic in November 2024 and, since December 2025, governed by the Agentic AI Foundation under the Linux Foundation. SOMA MCP targets the 2026-07-28 revision.

License

Apache-2.0.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    A
    maintenance
    Self-hosted MCP server giving AI agents persistent memory for personalization and context across conversations.
    143 PyPI
    279
    Apache 2.0
  • A
    license
    Not graded
    quality
    B
    maintenance
    A self-hosted MCP server that provides a personal semantic memory layer for AI tools. It enables storing, searching, and managing memories using hybrid vector and keyword search, allowing AI assistants to recall information by meaning.
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    A self-hosted server providing shared memory, RAG document search, project maps, and role-based prompts for all AI agents via MCP and REST, enabling persistent context across devices and tools.
    3
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    A self-hosted MCP server that provides any LLM with a graph-backed memory layer of your life—tasks, email, finance, contacts, calendar—plus autonomous agent offices that act on your behalf.
    3
    Apache 2.0