Attestor — Claude Code MCP server: shared agent memory
A self-hosted memory service for agent teams: roles, write and forget permissions, version history, audit. Built for the case where several agents write to one store.
claude mcp add --env ATTESTOR_PATH=<ATTESTOR_PATH> --env ATTESTOR_DISABLE_LOCAL_EMBED=<ATTESTOR_DISABLE_LOCAL_EMBED> --env OPENAI_API_KEY=<OPENAI_API_KEY> --env OPENROUTER_API_KEY=<OPENROUTER_API_KEY> --transport stdio attestor -- uvx attestorWhat Attestor does
Attestor keeps each memory once in Postgres and derives vectors and a graph into Pinecone and Neo4j. Reads and writes pass through an AgentContext carrying the agent's identity, role, namespace and budget. Six roles exist: ORCHESTRATOR reads, writes and forgets; PLANNER, EXECUTOR and RESEARCHER read and write; REVIEWER and MONITOR only read. The read_only=True flag strips write and forget whatever the role, and a violation raises PermissionError before any backend is reached.
Ranking on the read path is deterministic: vector, BM25, RRF, graph, MMR, then budget fit, with no language model in scoring. The same query returns the same order, which makes it unit-testable. An optional reranker (bge, cohere or llm) stays off unless you turn it on. Every fact carries valid time and transaction time, so recall(as_of=...) reconstructs what the mesh believed at an earlier point. Contradictions supersede older facts instead of deleting them. One caveat: the Pinecone lane ignores as_of and logs a warning, so a historical view through vector retrieval is not guaranteed.
It ships as a Python library, a REST sidecar and an MCP server over one API. Role enforcement is an in-process guarantee; the REST and MCP surfaces hit the store directly and lean on their own auth. Install with pip install attestor; the MCP launch uses uvx. Version 4.1.11 is a greenfield rebuild, and there is no migration path from v3.
What it helps with
- decide which agents may write to a shared memory
- show what an answer was built from months later
- reconstruct memory state as of a past date
- delete a user's data with an audit trail
- keep tenants separated inside one store
Example prompts for the agent
- Add the auth schema decision to memory as agent
reviewer-1 - Show what the agent team believed last Friday
- Forget this user's data and show me the audit entry
How to install Attestor
Platform CLI
claude mcp add --env ATTESTOR_PATH=<ATTESTOR_PATH> --env ATTESTOR_DISABLE_LOCAL_EMBED=<ATTESTOR_DISABLE_LOCAL_EMBED> --env OPENAI_API_KEY=<OPENAI_API_KEY> --env OPENROUTER_API_KEY=<OPENROUTER_API_KEY> --transport stdio attestor -- uvx attestorReplace <…> with your own values. uvx runs the command named after the package; if the README names another one, use uvx --from attestor <command>
Platform CLI
codex mcp add attestor --env ATTESTOR_PATH=<ATTESTOR_PATH> --env ATTESTOR_DISABLE_LOCAL_EMBED=<ATTESTOR_DISABLE_LOCAL_EMBED> --env OPENAI_API_KEY=<OPENAI_API_KEY> --env OPENROUTER_API_KEY=<OPENROUTER_API_KEY> -- uvx attestorReplace <…> with your own values. uvx runs the command named after the package; if the README names another one, use uvx --from attestor <command>
Config file
{
"mcpServers": {
"attestor": {
"command": "uvx",
"args": [
"attestor"
],
"env": {
"ATTESTOR_PATH": "<ATTESTOR_PATH>",
"ATTESTOR_DISABLE_LOCAL_EMBED": "<ATTESTOR_DISABLE_LOCAL_EMBED>",
"OPENAI_API_KEY": "<OPENAI_API_KEY>",
"OPENROUTER_API_KEY": "<OPENROUTER_API_KEY>"
}
}
}
}Replace <…> with your own values. uvx runs the command named after the package; if the README names another one, use uvx --from attestor <command>
Config file
{
"servers": {
"attestor": {
"type": "stdio",
"command": "uvx",
"args": [
"attestor"
],
"env": {
"ATTESTOR_PATH": "<ATTESTOR_PATH>",
"ATTESTOR_DISABLE_LOCAL_EMBED": "<ATTESTOR_DISABLE_LOCAL_EMBED>",
"OPENAI_API_KEY": "<OPENAI_API_KEY>",
"OPENROUTER_API_KEY": "<OPENROUTER_API_KEY>"
}
}
}
}Replace <…> with your own values. uvx runs the command named after the package; if the README names another one, use uvx --from attestor <command>
Platform CLI
gemini mcp add -e ATTESTOR_PATH=<ATTESTOR_PATH> -e ATTESTOR_DISABLE_LOCAL_EMBED=<ATTESTOR_DISABLE_LOCAL_EMBED> -e OPENAI_API_KEY=<OPENAI_API_KEY> -e OPENROUTER_API_KEY=<OPENROUTER_API_KEY> attestor uvx attestorReplace <…> with your own values. uvx runs the command named after the package; if the README names another one, use uvx --from attestor <command>
Step by step, with commands for each platform: How to add an MCP server to Claude Code, Codex, Cursor, VS Code, Gemini CLI and more
Questions about Attestor
How do I install Attestor in Claude Code?
Run claude mcp add attestor -e OPENAI_API_KEY=<OPENAI_API_KEY> -e OPENROUTER_API_KEY=<OPENROUTER_API_KEY> -- uvx attestor. The other form adds ATTESTOR_PATH and ATTESTOR_DISABLE_LOCAL_EMBED and names the transport: `claude mcp add --env ATTESTOR_PATH=<ATTESTOR_PATH> --env ATTESTOR_DISABLE_LOCAL_EMBED=<ATTESTOR_DISABLE_LOCAL_EMBED> --env OPENAI_API_KEY=<OPENAI_API_KEY> --env OPENROUTER_API_KEY=<OPENROUTER_API_KEY> --transport stdio attestor -- uvx attestor`.
What does Attestor do?
It is a memory service shared by several agents at once. It enforces who may write and who may forget, keeps provenance on every memory, and lets you query the store as of any earlier moment.
How is Attestor different from a coding assistant's built-in memory?
Governance comes first here rather than recall: roles, write quotas, signed provenance and an audited forget path. Scoring stays deterministic, with no LLM in the ranking.