MCP Server
PRME includes a Model Context Protocol (MCP) server that lets any MCP-compatible client use PRME as a memory backend. This includes Claude Desktop, Cursor, Claude Code, and other MCP clients.
Installation
pip install prme[mcp]Running the Server
prme-mcp --db-path ./my_memoriesOr as a Python module:
python -m prme.mcp --db-path ./my_memoriesOptions
| Flag | Default | Description |
|---|---|---|
--db-path | Current directory | Path to the memory directory, or to a single-file pack when the name ends in .prme |
--transport | stdio | Transport protocol: stdio, or streamable-http (listens on 127.0.0.1:8000 only and requires PRME_MCP_USER_KEYS). sse is rejected. |
Client Configuration
Claude Desktop
Add to ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):
{
"mcpServers": {
"prme": {
"command": "prme-mcp",
"args": ["--db-path", "/path/to/my/memories"]
}
}
}Claude Code
Add to your project’s .mcp.json or global MCP settings:
{
"mcpServers": {
"prme": {
"command": "prme-mcp",
"args": ["--db-path", "./memories"]
}
}
}Cursor
Add to .cursor/mcp.json in your project root:
{
"mcpServers": {
"prme": {
"command": "prme-mcp",
"args": ["--db-path", "./memories"]
}
}
}Using uv (development)
If running from source:
{
"mcpServers": {
"prme": {
"command": "uv",
"args": ["--directory", "/path/to/prism", "run", "prme-mcp", "--db-path", "./memories"]
}
}
}Environment Variables
Pass configuration via environment variables:
{
"mcpServers": {
"prme": {
"command": "prme-mcp",
"args": ["--db-path", "./memories"],
"env": {
"PRME_EXTRACTION__PROVIDER": "openai",
"PRME_EXTRACTION__MODEL": "gpt-4o-mini",
"OPENAI_API_KEY": "sk-..."
}
}
}
}Available Tools
The MCP server exposes 7 tools that LLMs can call:
memory_store
Store a memory node with vector embedding and full-text indexing.
| Parameter | Type | Default | Description |
|---|---|---|---|
content | string | required | Text content to store |
user_id | string | required | Owner of this memory |
node_type | string | "note" | One of: entity, fact, decision, preference, task, instruction, summary, note |
scope | string | "personal" | One of: personal, project, organisation |
role | string | "user" | user (the memory’s owner), participant (another human in the conversation), assistant, tool or system |
speaker | string | optional | Name of who said it, shown by the reader context |
Returns JSON: {"event_id": "...", "node_id": "..."}
memory_retrieve
Search memories using 6-signal hybrid retrieval.
| Parameter | Type | Default | Description |
|---|---|---|---|
query | string | required | Natural language search query |
user_id | string | required | User whose memories to search |
scope | string | optional | Filter by scope |
knowledge_at | string | optional | ISO datetime for point-in-time queries |
min_score | number | optional | Inclusive floor on each result’s score; under rank fusion, on its semantic_relevance |
Returns JSON: {"results": [...], "count": N, "metrics": {...}}
With rank fusion (PRME_SCORING__FUSION=rrf, the default), a result’s score says
where it ranks among the candidates rather than how relevant it is. Each result
then also carries semantic_relevance, the semantic cosine similarity of the
memory behind it, and min_score is compared with that instead. A floor tuned
on weighted scores does not carry over. If vector search is failing or the
embedding model changed without a rebuild, no result has a cosine, so the floor
is skipped rather than returning nothing: metrics.backend_failures names the
vector failure and metrics.min_score_skipped is true.
memory_ingest
Ingest content with LLM-powered entity/fact extraction. Requires an LLM API key.
| Parameter | Type | Default | Description |
|---|---|---|---|
content | string | required | Text to ingest |
user_id | string | required | Owner |
role | string | "user" | user (the memory’s owner), participant (another human in the conversation), assistant, tool or system |
speaker | string | optional | Name of who said it, shown by the reader context |
scope | string | "personal" | Scope |
Returns JSON: {"event_id": "..."}
memory_organize
Run maintenance jobs (promotion, decay, deduplication, etc.).
| Parameter | Type | Default | Description |
|---|---|---|---|
user_id | string | optional | Scope to user |
jobs | string | optional | Comma-separated job names |
budget_ms | integer | 5000 | Time budget in ms |
Returns JSON: {"jobs_run": [...], "duration_ms": N}
memory_get_node
Get full details of a memory node by UUID.
| Parameter | Type | Description |
|---|---|---|
node_id | string | UUID of the node |
Returns JSON with all node fields, or {"error": "..."}.
memory_promote_node
Promote a node’s lifecycle state (tentative to stable).
| Parameter | Type | Description |
|---|---|---|
node_id | string | UUID of the node |
Returns the updated node as JSON.
memory_archive_node
Archive a node (terminal state, excluded from retrieval).
| Parameter | Type | Description |
|---|---|---|
node_id | string | UUID of the node |
Returns the updated node as JSON.
Available Resources
Resources provide read-only data access:
| URI | Description |
|---|---|
memory://health | Engine health status and version |
memory://stats | Node count, backend type, version |
memory://nodes/{node_id} | Get a specific node by ID |
How It Works
The MCP server wraps the PRME MemoryEngine directly. When the server starts:
- It reads configuration from environment variables (
PRME_*prefix) - The
--db-pathflag setsPRME_DB_PATH,PRME_VECTOR_PATH, andPRME_LEXICAL_PATHfor a directory, and clearsPRME_PACK_PATHso an ambient single-file pack cannot replace it; for a path ending in.prmeit setsPRME_PACK_PATHinstead - A
MemoryEngineis initialized with the configuration - Tools and resources delegate to engine methods
- On shutdown, the engine is closed cleanly
The server uses the stdio transport by default — the client launches it as a subprocess and communicates via stdin/stdout.
Source: documentation/mcp-server.md in PRME at 58caddb1.