MCP Server
MemoryRouter's remote MCP server — protocol support, OAuth scopes, tools, vault model, and platform setup.
MemoryRouter runs a remote Model Context Protocol server that gives any MCP-capable client durable, portable memory. One vault, many AI apps.
https://mcp.memoryrouter.ai/mcpThis is the address you paste into ChatGPT, Claude, Claude Cowork, Codex, or any other MCP client. Authentication is OAuth 2.1 with PKCE — you never paste an API key into a connector.
Protocol support
| Version | |
|---|---|
| Current revision | 2026-07-28 |
| Also accepted | 2025-11-25, 2025-06-18, 2025-03-26 |
The server implements the 2026-07-28 revision, which is stateless: every request
describes itself, and there is no session handshake to lose. Concretely:
server/discoverreports supported versions, capabilities, and cache hints.- Each modern request carries
_metaprotocol version and client capabilities, mirrored byMCP-Protocol-Version,Mcp-Method, andMcp-Nameheaders. - Every successful result carries a
resultTypediscriminator and per-response server info. - Tool and resource catalogs are deterministic and cacheable.
Older handshake-era clients still work: they send initialize, and the server negotiates a
legacy version without ever claiming a modern one. No client is dropped.
2026-07-28 is deployed. Verified live on 2026-07-31: server/discover negotiates
2026-07-28, initialize still serves handshake-era clients, and no request depends on a
session id.
Why stateless matters for memory
Session-based MCP couples your memory to a live connection. If the connection drops or the client restarts, the session is gone. MemoryRouter's durability lives in the vault, not in a session — so a stateless protocol is the right fit. Any request, from any client, at any time, reaches the same memories.
Tools
The server exposes exactly five tools. If a client shows you something else, it is not coming from MemoryRouter.
| Tool | Requires | What it does |
|---|---|---|
search_memories | memories:read | Semantic recall from the connected vault |
store_memory | memories:write | Saves one concise durable memory |
memory_status | memories:read | Connection state, opaque vault reference, counts, granted scopes |
forget_all_memories | memories:delete | Deletes every memory in the connected vault |
search | memories:read | Compatibility alias for clients that require a tool named search |
Two MCP resources are also available when the host exposes resources:
memory://vault/stats and memory://vault/recent.
Deletion: what is and is not possible
forget_all_memories is whole-vault only. It cannot delete a single memory.
To prevent accidents it requires all of the following:
- The
memories:deletescope, which is never granted by read or write access. - The exact confirmation phrase
DELETE ALL MEMORIES. - A tool result confirming both primary and mirrored storage were cleared.
Anything short of that returns "nothing was deleted" and never reaches storage.
For removing individual memories, use the dashboard at
app.memoryrouter.ai. There is no per-memory delete tool, and
no per-memory deletion IDs exist. A store_memory receipt is not a deletion handle.
Authentication and scopes
MemoryRouter runs a full OAuth 2.1 authorization server with PKCE (S256), dynamic client registration, Client ID Metadata Documents, refresh-token rotation, and revocation.
Three scopes exist, and they are independent:
| Scope | Grants |
|---|---|
memories:read | Recall and status |
memories:write | Saving new memories |
memories:delete | Whole-vault deletion |
There is deliberately no hierarchy and no admin scope. memories:write does not grant
recall, and delete authority is never inherited from write. A connector configured to save
notes therefore cannot erase your vault.
Authorization defaults to read-only. Clients request more only when they need it, and the server answers an under-scoped call with a reauthorization challenge instead of performing the action.
Read-only enforcement is layered
A read-only OAuth token is also downgraded at the downstream API-key layer, so even an
internal routing mistake cannot turn a read connection into a write. Existing read-only key
conventions (mk_ro_, mk-ro-, and :read/:off modes) keep working and are never widened.
Vaults: personal, project, and organization
One OAuth connection is bound to one vault, chosen during sign-in.
That is the entire isolation model, and it is worth being precise about:
- Personal, project, and organization vaults are separate vaults. You pick which one a connection uses when you authorize it.
- To switch vaults, disconnect and reconnect the connector and choose a different vault.
- Project and organization "handles" that appear inside a conversation are behavioral labels for compatibility, not server-verified arguments. The MCP tools do not currently accept a project or vault parameter, so a model cannot select or escape a scope by asking.
If you need strict isolation, use a separate vault and a separate connection. Do not rely on conversational scope labels as a security boundary.
Setting it up per platform
| Platform | Path | Automatic? |
|---|---|---|
| Claude Code | npx memoryrouter-claude init | Yes — lifecycle hooks |
| Codex | Secure key on stdin + package init + browser OAuth | Yes — lifecycle hooks |
| ChatGPT | Custom connector | No — model-directed |
| Claude Cowork | Custom connector (+ optional Skill/plugin) | No — model-directed |
| Claude browser chat | Custom connector | No — model-directed |
"Model-directed" means the AI decides when to search or save. It is genuinely useful, but it is not a guarantee on every turn. Claude Code and Codex use deterministic hooks instead, so their retrieval and capture do not depend on the model choosing to act. Codex's hooks require a MemoryRouter API key in addition to the remote MCP browser OAuth session; the Codex guide shows the safe stdin/clipboard commands.
See the platform comparison for the full matrix.
Troubleshooting
The client says authentication is required.
Expected on first use. The server answers unauthenticated protected calls with a 401 and a
WWW-Authenticate challenge so your client opens the connect flow. Sign in and retry.
A save or delete is refused as insufficient scope.
The connection lacks memories:write or memories:delete. This is not retriable — disconnect,
reconnect, and approve the scope. ChatGPT surfaces this as a reauthorization prompt.
Recall returns nothing.
Confirm with memory_status that you are connected to the vault you expect. A common cause is
being connected to a different vault than the one holding the memories.
Claude or ChatGPT never uses memory. On those surfaces, tool use is model-directed. Ask explicitly ("check my memory for…"), or use Claude Code / Codex where hooks make it deterministic.
A tool you read about does not exist. Only the five tools above exist. Per-memory deletion and server-side project arguments are not implemented.
For clients with a doctor command, run npx memoryrouter-claude doctor or
npx memoryrouter-codex doctor for a local diagnosis.
Discovery endpoints
| Endpoint | Purpose |
|---|---|
/.well-known/oauth-protected-resource/mcp | RFC 9728 protected resource metadata |
/.well-known/oauth-authorization-server | RFC 8414 authorization server metadata |
The advertised resource value is the full /mcp URL, matching what you type into the
client, and access tokens are bound to that same RFC 8707 resource.
Privacy and deletion
- Memories are stored in the vault you selected during OAuth; they are not shared between vaults.
memory_statusreturns an opaque vault reference. Your memory key is never exposed to the model, in tool output, or in a client-readable token claim.- Whole-vault deletion is permanent and confirmed against both primary and mirrored storage.
- Per-memory deletion happens in the dashboard.