TeleMem MCP Server

August 15, 2026 · View on GitHub

TeleMem ships a Model Context Protocol (MCP) server that exposes its long-term memory operations as MCP tools. Any MCP-compatible client — DeepSeek Harness, Claude Desktop, Claude Code, Cursor, or a custom agent — can store and retrieve memories through a local TeleMem instance.

Installation

pip install "telemem[mcp]"

This installs the MCP Python SDK v2 on top of TeleMem and provides the telemem-mcp console command. The server implements the current MCP specification (2026-07-28) and transparently serves older (initialize-handshake) clients as well, so any MCP client — old or new — can connect.

Running the server

telemem-mcp                                      # stdio (default)
telemem-mcp --transport streamable-http          # Streamable HTTP on :8421
TELEMEM_CONFIG=config/config.yaml telemem-mcp    # custom TeleMem config
python -m telemem.mcp                            # equivalent module form
OptionDefaultDescription
--transportstdioOne of stdio, streamable-http, sse (deprecated by the MCP spec)
--host127.0.0.1Bind host for the HTTP transports
--port8421Bind port for the HTTP transports
--configTeleMem YAML/JSON config (overrides TELEMEM_CONFIG)

Environment variables

VariableDefaultDescription
TELEMEM_CONFIGPath to a TeleMem YAML/JSON config file. Without it, TeleMem's default configuration is used (OpenAI models, local vector store), which needs OPENAI_API_KEY.
TELEMEM_DEFAULT_USER_IDtelemem-mcpMemory scope used when a tool call provides no user_id/agent_id/run_id.

The TeleMem Memory instance is created lazily on the first tool call, so the server starts instantly and configuration problems surface as structured tool errors instead of crashes.

Tools

ToolDescription
add_memoryStore a fact (text) or conversation (messages) in long-term memory.
search_memoriesSemantic search; returns one consolidated text passage (TeleMem fuses related memories).
get_memoriesList stored memories with their memory_ids for a user/agent/run.
get_memoryFetch a single memory by memory_id.
update_memoryOverwrite the text of an existing memory.
delete_memoryDelete a single memory by memory_id.
delete_all_memoriesWipe a scope. Destructive — requires an explicit user_id, agent_id, or run_id.
memory_historyShow the ADD/UPDATE/DELETE history of a memory.

Every tool carries the standard MCP metadata clients use for display and safety decisions: a human-readable title, behavior annotations (readOnlyHint/destructiveHint/idempotentHint; openWorldHint is false everywhere — the memory store is local), and an output schema. Results are emitted as structuredContent (wrapped under a "result" key) alongside the equivalent JSON text content.

Errors are returned as structured JSON ({"error": ..., "detail": ...}) so agents can self-correct instead of failing opaquely.

TeleMem semantics worth knowing

  • search_memories returns a single fused text passage, not ranked rows — this is TeleMem's design (related memories are clustered and merged).
  • Conversation-level event memories live under the pseudo-user "events" and are searched automatically alongside the requested user. Use get_memories with user_id="events" to list them.
  • When no scope is given, reads and writes default to TELEMEM_DEFAULT_USER_ID; delete_all_memories deliberately never assumes a default.

Client configuration

DeepSeek Harness

DeepSeek Harness (dsh) connects to external tools through its @deepseek-ai/dsh-mcp-client plugin. TeleMem ships an opt-in Cordis patch that starts the pinned TeleMem release with uvx, discovers all eight memory tools, and registers them in DSH as mcp__telemem__<tool>.

With uv installed, use DeepSeek for TeleMem's extraction LLM and OpenAI for embeddings from a TeleMem checkout:

export DEEPSEEK_API_KEY="your-deepseek-api-key"  # shared by DSH and TeleMem's LLM
export OPENAI_API_KEY="your-openai-api-key"      # embeddings (DeepSeek has no embedding API)
export TELEMEM_CONFIG="$PWD/config/config.deepseek.yaml"
export TELEMEM_DEFAULT_USER_ID="your-handle"

npx @deepseek-ai/dsh web --patch "$PWD/examples/deepseek-harness.cordis.yml"

config.deepseek.yaml uses ${DEEPSEEK_API_KEY} and ${OPENAI_API_KEY} references; load_config() expands them after parsing and fails clearly if either variable is missing. DeepSeek Harness deliberately removes credential-shaped ambient variables before starting MCP children, so the patch forwards these variables explicitly without embedding their values in the file.

For a fully local memory stack, point TELEMEM_CONFIG at config/config.ollama.yaml instead; no OpenAI key is then required. The DSH project is in developer preview, so this integration is tested against its public Cordis/MCP configuration contract as of 0.1.0-rc.5.

Claude Desktop / Cursor

Add to claude_desktop_config.json (or Cursor's mcp.json) — see examples/mcp_config.json:

{
  "mcpServers": {
    "telemem": {
      "command": "telemem-mcp",
      "args": [],
      "env": {
        "TELEMEM_CONFIG": "/absolute/path/to/config/config.yaml",
        "TELEMEM_DEFAULT_USER_ID": "your-handle",
        "OPENAI_API_KEY": "sk-..."
      }
    }
  }
}

Claude Code

claude mcp add telemem -e TELEMEM_CONFIG=/absolute/path/to/config/config.yaml -- telemem-mcp

Python client

examples/mcp_client.py drives the server programmatically over stdio — the quickstart flow (add a conversation, search it) expressed as MCP tool calls:

export OPENAI_API_KEY=sk-...        # or TELEMEM_CONFIG=config/config.yaml
python examples/mcp_client.py

Embedding in your own server

from telemem.mcp import create_server

server = create_server()
server.run(transport="stdio")
# or: server.run(transport="streamable-http", host="127.0.0.1", port=8421)

create_server() returns an MCPServer from the official MCP Python SDK v2; transport settings are passed to run() (SDK v2 moved them out of the constructor).

Testing

The MCP layer has an offline test suite (no API key required) covering the tool registry, argument mapping, scoping rules, error surfacing, and a full client/server protocol round-trip:

python tests/test_mcp.py