Skip to content

MCP Server (Model Context Protocol) ​

Expose uteke memories as tools to AI coding agents — Claude Code, Claude Desktop, Cursor, Copilot, and any MCP-compatible client.

Quick Start ​

No daemon needed — uteke-mcp communicates over stdin/stdout:

jsonc
// Claude Code — .mcp.json or ~/.claude/settings.json
{
  "mcpServers": {
    "uteke": {
      "command": "uteke-mcp"
    }
  }
}

Option B: HTTP Transport (for remote/shared access) ​

Requires uteke-serve running. Uses Streamable HTTP transport:

jsonc
{
  "mcpServers": {
    "uteke": {
      "url": "http://127.0.0.1:8767/mcp"
    }
  }
}

Client Configuration ​

Claude Code ​

Create or edit .mcp.json in your project root, or ~/.claude/settings.json for global access:

jsonc
// Stdio (recommended)
{
  "mcpServers": {
    "uteke": {
      "command": "uteke-mcp"
    }
  }
}
jsonc
// HTTP (requires uteke-serve)
{
  "mcpServers": {
    "uteke": {
      "url": "http://127.0.0.1:8767/mcp"
    }
  }
}

Claude Desktop ​

Create or edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):

jsonc
{
  "mcpServers": {
    "uteke": {
      "command": "uteke-mcp"
    }
  }
}

Cursor ​

Create or edit .cursor/mcp.json in your project root:

jsonc
{
  "mcpServers": {
    "uteke": {
      "command": "uteke-mcp"
    }
  }
}

Hermes ​

Register uteke as an MCP server with the Hermes native client:

bash
# Stdio transport
hermes mcp add uteke --command uteke-mcp

# HTTP transport (requires uteke-serve running)
hermes mcp add uteke --url http://127.0.0.1:8767/mcp

MCP is Tool-Based (Not Automatic) ​

The MCP server exposes uteke as tools — the agent decides when to call uteke_recall, uteke_remember, etc. This means:

  • ✅ On-demand: The agent calls memory tools only when needed (e.g., "recall project context before coding")
  • ✅ Agent-controlled: The agent decides what to store and when to query
  • ❌ No auto recall: Memories are NOT automatically injected every turn
  • ❌ No auto extract: Facts are NOT automatically extracted from conversations

If you need automatic recall (memories injected every LLM call without the agent asking), use Mode C (shell hook) instead:

bash
uteke init --agent hermes  # Installs pre_llm_call hook

Which Integration Mode to Use? ​

NeedUse ThisHow
On-demand memory, coding agentsMCP (this page)uteke-mcp or POST /mcp
Automatic recall every turnMode C (shell hook)uteke init --agent hermes
Automatic recall + auto extractMode B (memory-provider)❌ Deprecated (removed 2026-06-29)
Multi-agent shared roomsMCP + Mode C comboMode C for auto recall, MCP for room operations

Tip: MCP and Mode C work great together. Use Mode C for automatic recall on every LLM call, and MCP for explicit tool-based operations like uteke_doc_create, uteke_graph, or uteke_room_recall.

Available Tools ​

Both transports expose the same 49 tools (MCP protocol version 2025-06-18):

ToolDescription
uteke_rememberStore a memory (supports type, room, author, tags)
uteke_recallSemantic search (supports tags filter, min_score, strategy: fusion/vector/fts5/hybrid/graph — default fusion since 0.16.0, and the explain flag showing why each result ranked where it did, #1160). pack: true returns a budgeted context pack {selected, skipped, budget_used, budget_chars} (#1281) — deterministic, LLM-free, rank-order preserving; pair with budget_chars and exclude_ids (IDs already injected this turn)
uteke_searchText search with optional tag filter
uteke_listList memories (supports pagination via offset, or include_meta: true for the {memories, total, has_more, next_offset} envelope, #1188)
uteke_getFetch a single memory's full record by id — no truncation (accepts UUID or unambiguous prefix)
uteke_updatePartial update — only provided fields change; content changes re-embed; accepts namespace to move a memory (#1181)
uteke_supersedeMark a memory superseded by a newer one — wires the edge pair, soft-deprecates the old row; recall flags stale results (⚠ superseded by …)
uteke_provenanceFull provenance report for a memory (#1172): author/source fields, trust tier, source hash at write vs live-recomputed content hash, and the timeline event chain with actor + evidence
uteke_contradictionsList the contradiction resolution ledger (#1172): superseded-but-not-restored memories with winner, reason, and timestamp
uteke_contradictions_undoUndo a contradiction resolution (#1172): restore the retired memory, remove the supersession edge pair, record supersession_undone events
uteke_timelineRead the audit-grade timeline for a memory (#1280, schema v20): id, optional limit. Includes deprecated events (with reason) and forgot tombstones of hard-forgotten memories — history is never deleted
uteke_forgetDelete a memory (accepts UUID or unambiguous prefix)
uteke_statsMemory store statistics
uteke_contextAI-optimized context output for prompts
uteke_dreamMaintenance pipeline (lint → backlinks → dedup → orphans → compact → verify). Dry-run by default — pass dry_run: false to apply; scope namespace or confirm_large for whole-store / >100-change runs
uteke_verifyReport SQLite row count vs vector index size with a match flag (#1272) — live audit without restarting uteke-serve (write-token surface)
uteke_repairRebuild the vector index from stored embeddings (#1272) — fixes the stale-index failure mode where rows exist in SQLite+FTS5 but go missing under fusion/hybrid recall
uteke_doc_createCreate a document (wiki/knowledge base entry)
uteke_doc_getRetrieve a document by ID
uteke_doc_listList all documents
uteke_doc_searchSearch documents
uteke_doc_deleteDelete a document
uteke_doc_updatePartial document update with chunk rebuild (#589)
uteke_doc_moveMove document to new parent (#438)
uteke_graphGet nodes + edges JSON for visualization
uteke_graph_add_edgeCreate a typed edge between two memories (#542)
uteke_graph_remove_edgeRemove an edge between two memories (#542)
uteke_room_recallSemantic recall within a room
uteke_room_memoriesList memories in a room (#569)
uteke_room_createCreate a room
uteke_room_deleteDelete a room
uteke_room_renameRename a room; rewrites the registry row and every reference in one transaction (#1202)
uteke_room_updateUpdate a room's title/description (#1202)
uteke_room_memory_moveMove a memory to another room, preserving link provenance (#1202)
uteke_room_listList all rooms
uteke_namespace_renameRename a namespace (#1181); when the target exists this is a merge, returns {from, to, moved, target_existed}
uteke_namespace_deleteDelete a namespace with an explicit strategy for its memories (#1181): refuse (default, 409 while referenced), merge into target, or deprecate (soft-delete, restorable)
uteke_room_statsRoom statistics
uteke_room_summaryRoom topic summary (tag clustering, no LLM)
uteke_room_summary_documentGenerate summary document from room (→ POST /room/summary-document)
uteke_room_add_documentLink an existing document to a room (#859)
uteke_room_remove_documentUnlink a document from a room (#859)
uteke_room_list_documentsList documents linked to a room (#859)
uteke_doc_list_roomsList rooms that reference a document (#859)
uteke_tags_listList all tags with counts (#566)
uteke_tags_renameRename a tag across all memories (#566)
uteke_tags_deleteDelete a tag from all memories (#566)
uteke_pinPin a memory (prevent decay) (#566)
uteke_unpinUnpin a memory (#566)

Transport Comparison ​

StdioHTTP
Binaryuteke-mcputeke-serve
Daemon neededNoYes
Remote accessNoYes
AuthenticationNone needed (a local process you start yourself)Static bearer token (UTEKE_AUTH_TOKEN)
ProtocolJSON-RPC over stdin/stdoutStreamable HTTP (POST /mcp)
Best forLocal agents, single machineShared/team, remote access

Tip: HTTP transport is recommended when uteke-serve is already running — it avoids subprocess overhead and works across machines. Stdio transport is simpler for local, single-agent setups where no daemon is desired.

Remote Access (VPS / Server / Domain) ​

Connect from a local agent to a remote uteke-serve ​

When uteke-serve runs on a VPS or remote server, your local MCP client connects over HTTP:

bash
# On the server — start uteke-serve with auth enabled
UTEKE_AUTH_TOKEN=your-secret uteke-serve --host 0.0.0.0 --port 8767

Note: In production, use environment variables for tokens — never commit secrets to config files. Some clients support env var substitution (e.g., $UTEKE_AUTH_TOKEN).

jsonc
// Claude Code — .mcp.json
{
  "mcpServers": {
    "uteke": {
      "url": "https://uteke.yourdomain.com/mcp",
      "headers": {
        "Authorization": "Bearer your-secret"
      }
    }
  }
}
jsonc
// Claude Desktop
{
  "mcpServers": {
    "uteke": {
      "url": "https://uteke.yourdomain.com/mcp",
      "headers": {
        "Authorization": "Bearer your-secret"
      }
    }
  }
}
jsonc
// Cursor
{
  "mcpServers": {
    "uteke": {
      "url": "https://uteke.yourdomain.com/mcp",
      "headers": {
        "Authorization": "Bearer your-secret"
      }
    }
  }
}

Keeping the token out of the client config ​

uteke-serve authenticates with a static bearer token. It does not implement OAuth sign-in, so an MCP client cannot start a browser login against it and no token is refreshed automatically. What you can do instead:

  • Same machine: use the stdio transport. uteke-mcp runs as a local process your client starts itself, so there is no network listener, no token and no Authorization header to store (Option A above).
  • Another machine: keep the secret out of git. Put the token in an environment variable and reference it from the client config if your client supports expanding environment variables (check its documentation for the exact syntax), or keep the client config file out of version control. Prefer UTEKE_READ_ONLY_TOKEN for clients that only need to recall.
  • Rotate by restarting. Change UTEKE_AUTH_TOKEN, restart uteke-serve, and update the clients; old tokens stop working immediately.

OAuth-based sign-in for MCP clients is not part of the self-hosted server.

Read-only tokens ​

A client authenticated with UTEKE_READ_ONLY_TOKEN can call these tools over POST /mcp: uteke_recall, uteke_search, uteke_list, uteke_get, uteke_provenance, uteke_timeline, uteke_contradictions, uteke_stats, uteke_doc_get, uteke_doc_list, uteke_doc_search, uteke_doc_list_rooms, uteke_graph, uteke_room_list, uteke_room_recall, uteke_room_memories, uteke_room_stats, uteke_room_summary, uteke_room_summary_document (alias uteke_room_document), uteke_room_list_documents and uteke_tags_list.

Every other tool is refused with a tool error (isError: true, text Read-only token cannot use <tool>) and nothing is written. tools/list still lists every tool. The stdio transport (uteke-mcp) has no tokens and is unaffected.

Docker on a VPS ​

bash
docker run -d --name uteke \
  -p 8767:8767 \
  -e UTEKE_AUTH_TOKEN=your-secret \
  -v uteke-data:/data \
  ghcr.io/codecoradev/uteke:latest

Point your MCP client at http://YOUR_VPS_IP:8767/mcp (or use a domain with TLS — see below).

For HTTPS with a domain, use a reverse proxy (Caddy, Nginx, or Cloudflare Tunnel) in front of uteke-serve:

bash
# uteke-serve still on localhost — the proxy handles TLS
UTEKE_AUTH_TOKEN=your-secret uteke-serve --host 127.0.0.1 --port 8767

See TLS & Reverse Proxy for full setup guides (Caddy, Nginx, Cloudflare Tunnel).

Important: Network Security ​

SettingValueWhy
--host127.0.0.1 (local) or 0.0.0.0 (remote)Bind to localhost unless you need remote access
UTEKE_AUTH_TOKENSet a strong tokenRequired for remote access — without it, anyone can read/write your memories
TLSUse reverse proxy + HTTPSEncrypts traffic in transit — strongly recommended for remote setups
FirewallAllow only port 8767/tcpRestrict access at the network level

Namespace Isolation ​

Deprecated. Namespaces will be removed in a future 0.x release; prefer rooms, tags and author. Writes to a non-default namespace (uteke_remember, uteke_update moves, uteke_room_create) return a deprecation warning. See Namespaces are deprecated.

The MCP server uses the default namespace by default. Each agent can use its own isolated namespace by passing a namespace argument to any tool call. Memories in one namespace are never visible to another.

This is the MCP equivalent of the CLI's --namespace flag — see Multi-Agent Isolation for details.

JSON-RPC 2.0 Compliance (#573/#576) ​

The MCP server implements strict JSON-RPC 2.0 compliance (v0.6.7):

  • Tagged union responses: The result field uses a tagged union ({"type": "result", "content": [...]}) per the MCP spec, not a bare array.
  • No notification response: JSON-RPC notifications (requests without id) receive no response body, as required by the spec. This fixes Claude Code connectivity issues where unexpected responses on notifications caused handshake failures.
  • Claude Code compatible: Tested and verified with Claude Code, Claude Desktop, Cursor, and Hermes MCP client.

Memory-Provider Integration (#575/#577) ​

For automatic recall (memories injected every LLM call without the agent asking), use the --memory-provider flag with uteke init:

bash
# pi (pi.dev)
uteke init --agent pi --memory-provider

# Claude Code
uteke init --agent claude --memory-provider

# Cursor
uteke init --agent cursor --memory-provider

This installs uteke as the agent's default memory provider — relevant memories are recalled and injected automatically every turn. No MCP server needed; talks to the uteke binary directly.

Note: The --memory-provider flag is only deprecated for Hermes (removed 2026-06-29). For pi, Claude Code, and Cursor, it is the recommended integration mode.

Docker ​

When running uteke in Docker, both transports are available:

  • HTTP: Start the container normally — the MCP endpoint is at http://localhost:8767/mcp via port mapping.
  • Stdio: Use --entrypoint uteke-mcp to run the MCP binary directly inside the container.

See Docker guide — MCP for full Docker-specific configuration and examples.

Troubleshooting ​

ProblemSolution
uteke-mcp: command not foundRun install.sh or cargo install -p uteke-mcp to install the binary
Permission deniedchmod +x $(which uteke-mcp) or ensure the binary is on your PATH
Connection refused (HTTP)Ensure uteke-serve is running: uteke-serve
Client can't see toolsVerify the MCP config JSON is valid and the client has been restarted
Slow first queryThe embedding model (~200MB) downloads on first use — subsequent calls are ~45ms

See also: Architecture — MCP Transport