MCP
Give Claude, VS Code, Cursor, Codex and other MCP clients persistent memory — through the remote Streamable HTTP endpoint or the local stdio server.
Agent Memory speaks the Model Context Protocol. There are two ways to connect:
| Remote HTTP endpoint | Local stdio server | |
|---|---|---|
| Runs | Inside the Agent Memory API | As a process on your machine (AgentMemory.Mcp) |
| Transport | Streamable HTTP (stateless) | stdio |
| Auth | API key header, or OAuth sign-in | API key (remote mode) or direct database access (local mode) |
| Best for | Almost everyone | Clients without HTTP support, and operators on the database host |
Both expose the same 20 tools.
Remote endpoint
URLs
| URL | Workspace | Use it when |
|---|---|---|
/v1/mcp | The API key's workspace — or, for OAuth sign-ins, your own account's workspace | The default. One URL, no IDs to copy. |
/v1/mcp/<app-name> | As above, scoped to the named application | OAuth sign-ins that want app-specific memory. The application is created on first use. Names are letters, digits and -. |
/v1/workspaces/<workspaceId>/mcp | The workspace in the URL | Shared team workspaces. Your grant (or the key's workspace) must match the URL. |
With an API key, the key's own workspace and application decide the scope: create the key for an application in the console to get application-scoped memory. See Scoping.
The endpoint is stateless Streamable HTTP: every POST is self-contained, with no session handshake.
Authentication
- API key — send
Authorization: Bearer amk_…. Works on every deployment, with no identity provider required. - OAuth — when the deployment runs its built-in OAuth 2.1 server, an unauthenticated request gets a
401whoseWWW-Authenticateheader points at the protected-resource metadata (/.well-known/oauth-protected-resource). Clients such as Claude Desktop, Claude Code and VS Code then run the sign-in flow automatically (with dynamic client registration), and you sign in with your Agent Memory account. See Authentication.
Connect a client
Replace https://memory.example.com with your deployment's URL.
With an API key:
claude mcp add --transport http agent-memory https://memory.example.com/v1/mcp \
--header "Authorization: Bearer amk_..."Or keyless — Claude Code opens a browser window to sign in on first use:
claude mcp add --transport http agent-memory https://memory.example.com/v1/mcpFor a ready-made setup with the memory tools, see the Claude Code plugin.
The console's API Keys page shows a ready-made mcpServers block for each new key.
How the agent knows when to use memory
MCP tools are model-driven: the client shows the tools to the model, and the model decides when to call them. Agent Memory steers that in two ways:
- Server instructions. The
initializeresponse carries a usage protocol that compliant clients inject into the model's context: search at the start of a task, add a memory the moment something durable happens (with the right type and one stablerunId), consolidate at the end, and report the outcome when the result is known. - Directive tool descriptions.
search_memorysays to call it at the start of a task,add_memoryduring it,consolidateat the end.
Some clients ignore server instructions. For the most reliable behaviour, add a short rule to the client's own instructions file (for example AGENTS.md for Codex, .cursorrules for Cursor, .clinerules for Cline, .github/copilot-instructions.md for VS Code Copilot, or a project instruction in Claude):
A persistent memory MCP server is connected. Use it as a loop:
- At the START of every task, call search_memory and follow prior decisions,
corrections, violations and approved patterns.
- When you make a decision, the user corrects you, a rule is broken or a solution
is approved, call add_memory with the matching type. Use one runId per task.
- When the task is done, call consolidate with that runId.
Prefer recalling memory over asking the user to repeat themselves.Tools
| Tool | Capability | What it does |
|---|---|---|
search_memory | read | Recall a context for a query. Options: facet, runId, userId, includeSuperseded, explain, tokenBudget, mode, rerank, agentId. Prints the receipt to pass to report_outcome. |
add_memory | write | Store a memory. Options: type, runId, facet, visibility, userId, idempotencyKey, sourceKind, sourceRef, observedAt, validFrom, validTo, supersedes, agentId. |
get_memory | read | Fetch one memory by ID, with its version. Use it for artifact_ref. |
update_memory | write | Replace a memory's content; pass version to refuse the write if it changed. |
supersede_memory | write | Mark one existing memory as replaced by another. |
delete_memory | delete | Delete a memory; refused with dependent IDs unless cascade=true. |
erasure_status | read | Where a deletion stands: none, pending, complete or dead. |
share_memory | share | Widen a memory's visibility. |
explain_memory | read | Source, lineage, what replaced it, contradictions, dependents, usage and trust. |
get_operation | read | What became of an add_memory call (pending, indexed, failed). |
get_changesets | read | The workspace change feed; pass the returned cursor back to continue. |
consolidate | curate | End a run: promote its entries, create the episode, learn procedures. Takes runId and optional goal. |
report_outcome | feedback | Report build, test, deploy and rating results for a run, with the receiptId. |
record_retrieval_feedback | feedback | Which recalled entries were used or ignored, and which procedures applied or skipped. |
list_procedures | read | Learned procedures, optionally filtered by query. |
search_episodes | read | Past runs similar to a goal. |
get_blocks | read | The curated memory blocks. |
curate_block | curate | Add, replace or remove one line of a block. |
search_files | read | Documented files by what they do. |
get_user_profile | read | An end user's profile. |
Notes:
runIddefaults tomcp-sessionon the remote endpoint. Pass one stablerunIdper task so entries group into one episode.- Tools that take a memory ID accept the full GUID or the short form (8+ characters) that search and explain print.
agentIdis optional everywhere and only needed when a key is bound to several agents; an agent the key isn't bound to returnsError: this credential is not bound to agent '…'. Naming auserIdneeds a key with act for users.- Failures come back as tool results starting with
Error:(for example a missing capability or an exhausted monthly quota), not as protocol errors.
Local stdio server
AgentMemory.Mcp is a .NET 10 console app that serves the same tools over stdio. It runs in one of two modes, chosen with MCP_MODE:
remote— the process holds no database credentials and calls the HTTP API with a bearer token. Use this on developer machines.local(default) — the process runs the memory engine in-process against PostgreSQL and Redis. It is a trusted mode for operators on the database host; identity comes from configuration, not from a token.
Configure
| Variable | Mode | Notes |
|---|---|---|
MCP_MODE | both | remote or local (default). |
MCP_API_URL | remote | The API base URL, e.g. https://memory.example.com. Required in remote mode. |
MCP_API_TOKEN | remote | An API key (amk_…) or access token. Required in remote mode. |
MCP_WORKSPACE_ID | both | The workspace GUID. |
MCP_TENANT_ID | both | Tenant GUID. In remote mode the server derives the tenant from the token. |
MCP_AGENT_ID | both | Remote: only sent when set — otherwise the key's bound agent acts. Local: labels the agent (default mcp-agent). |
MCP_APPLICATION_ID | both | Optional application scope. |
MCP_RUN_ID | both | Run ID for the whole process. Default: a new mcp-<guid> per process. |
In local mode, connection strings and provider settings come from the usual configuration keys (environment variables such as ConnectionStrings__SharedDb, ConnectionStrings__ControlPlaneDb, ConnectionStrings__PlatformDb and ConnectionStrings__Redis).
Register it with a client
{
"mcpServers": {
"agent-memory": {
"command": "dotnet",
"args": ["run", "--project", "/path/to/agent-memory/AgentMemory.Mcp"],
"env": {
"MCP_MODE": "remote",
"MCP_API_URL": "https://memory.example.com",
"MCP_API_TOKEN": "amk_...",
"MCP_WORKSPACE_ID": "<workspace-guid>"
}
}
}
}One stdio process is one session: every add_memory and search_memory call uses the process's run ID, so consolidating that run sweeps the whole session. Those two tools therefore take no runId, agentId or facet arguments; consolidate, report_outcome and record_retrieval_feedback still take an explicit runId.