Mercury docs
Mercury is long-term memory for AI agents. You send it what people say; it decides what is worth keeping, links each fact to what it replaces, keeps outside sources apart, and hands your model a labelled memory sheet when it needs to answer.
Everything goes through one API at https://34-13-60-151.sslip.io with one API key. Connect it to:
- Claude Code, through the remote MCP server and the Mercury skill;
- Claude Desktop, Cursor and any other MCP client;
- your own agents, through the Python SDK or the REST API.
Memory lives in spaces, usually one per person or agent. The same space is shared by every client that uses it, so memory follows the user from Claude Code to Cursor to your app.
Quickstart
- Create an account with your invite code, then create an API key on the dashboard. The key is shown once.
- Put it in your shell:
export MERCURY_API_KEY=mk_live_... - Store two messages and ask a question:
curl -s https://34-13-60-151.sslip.io/v1/spaces/me/events \ -H "Authorization: Bearer $MERCURY_API_KEY" -H "content-type: application/json" \ -d '{"events": [ {"text": "My city is Bristol. I work at Cleo.", "at": "2026-01-10T09:00"}, {"text": "Actually my city is now Leeds, I moved last week.", "at": "2026-03-02T10:00"}]}' curl -s https://34-13-60-151.sslip.io/v1/spaces/me/recall \ -H "Authorization: Bearer $MERCURY_API_KEY" -H "content-type: application/json" \ -d '{"question": "Which city do I live in?"}'
The recall returns a memory sheet: Leeds as current since 2026-03-02, and Bristol as replaced on that date. Give the sheet's text to your model with the user's question.
Claude Code
Add Mercury as a remote MCP server. --scope user makes it available in every project:
claude mcp add --transport http --scope user mercury https://34-13-60-151.sslip.io/mcp \
--header "Authorization: Bearer $MERCURY_API_KEY" \
--header "X-Mercury-Space: me"
Then install the Mercury skill so Claude knows when to recall and when to remember:
mkdir -p ~/.claude/skills/mercury-memory && curl -s https://34-13-60-151.sslip.io/skill.md -o ~/.claude/skills/mercury-memory/SKILL.md
Start claude and run /mcp; mercury should show as connected with 14 tools. Try "remember that I prefer pnpm over npm", then in a new session "which package manager do I use?".
$MERCURY_API_KEY when you run the command, so the key is saved in your Claude Code config. Use a dedicated key, and revoke it on the dashboard if that machine is lost.Run it locally instead
The same tools as a local process (needs uv):
claude mcp add --scope user mercury \
-e MERCURY_API_KEY=$MERCURY_API_KEY -e MERCURY_API_URL=https://34-13-60-151.sslip.io -e MERCURY_SPACE=me \
-- uvx --from "mercury-memory @ https://34-13-60-151.sslip.io/sdk/mercury_memory-0.1.0-py3-none-any.whl" mercury-mcp
The Mercury skill
skill.md is an Agent Skill: a short instruction file that teaches an agent how to use Mercury well. It covers recalling before answering, storing the user's own words, reading the labels on the memory sheet, asking instead of guessing, and forgetting on request. It works with the MCP tools and, when they aren't connected, falls back to the REST API with curl.
| Where | How to install |
|---|---|
| Claude Code (all projects) | mkdir -p ~/.claude/skills/mercury-memory && curl -s https://34-13-60-151.sslip.io/skill.md -o ~/.claude/skills/mercury-memory/SKILL.md |
| Claude Code (one project) | save it as .claude/skills/mercury-memory/SKILL.md in the repo |
| Claude apps | download skill.zip and upload it under Settings, Capabilities, Skills |
| Any other agent | put the file's contents in its system prompt or instructions |
Claude Desktop
Claude Desktop runs Mercury as a local MCP server. Install uv (brew install uv on a Mac), then open Settings, Developer, Edit Config and add:
{
"mcpServers": {
"mercury": {
"command": "uvx",
"args": ["--from", "mercury-memory @ https://34-13-60-151.sslip.io/sdk/mercury_memory-0.1.0-py3-none-any.whl", "mercury-mcp"],
"env": {
"MERCURY_API_KEY": "mk_live_...",
"MERCURY_API_URL": "https://34-13-60-151.sslip.io",
"MERCURY_SPACE": "me"
}
}
}
}
Restart Claude Desktop. Mercury's tools appear under the tools menu in a new chat.
Cursor and other MCP clients
Cursor connects to the remote server. Add this to ~/.cursor/mcp.json:
{
"mcpServers": {
"mercury": {
"url": "https://34-13-60-151.sslip.io/mcp",
"headers": { "Authorization": "Bearer mk_live_...", "X-Mercury-Space": "me" }
}
}
}
Any MCP client works the same way: streamable HTTP at https://34-13-60-151.sslip.io/mcp with an Authorization: Bearer header, or the local command uvx --from "mercury-memory @ https://34-13-60-151.sslip.io/sdk/mercury_memory-0.1.0-py3-none-any.whl" mercury-mcp with MERCURY_API_KEY, MERCURY_API_URL and MERCURY_SPACE set. X-Mercury-Space (or MERCURY_SPACE) picks the memory space; it defaults to default.
Tools
| Tool | What it does |
|---|---|
remember | Store a message verbatim. source: user, assistant, tool, email, web or agent. |
recall | The labelled memory sheet for a question. at asks about a past moment. |
forget | By event_ids, or by the user's own request ("forget where I live"). |
history | Every version of a fact, and how each was replaced. |
as_of | What was current on a date. |
why, explain | Where a recall or a single memory came from. |
open_questions, answer_question | Questions to ask the user instead of guessing. |
start_task, end_task | Task memory: outcome and reusable lessons. |
consolidate | Idle-time tidy: lessons, retention, conflicts, preferences. |
usage, list_spaces | Your account. |
Python SDK
pip install "mercury-memory @ https://34-13-60-151.sslip.io/sdk/mercury_memory-0.1.0-py3-none-any.whl"
from mercury_client import MercuryClient
client = MercuryClient(api_key="mk_live_...", base_url="https://34-13-60-151.sslip.io")
me = client.space("me")
me.remember("I moved to Leeds last week", at="2026-03-02T10:00")
me.remember("Web page: the user lives in Paris", role="tool", source="web") # never overrides the user
sheet = me.recall("Where do I live?")
print(sheet["text"]) # give this to your model
print(sheet["open_questions"]) # ask the user rather than guess
me.forget([sheet["items"][0]["event"]]) # forget a message and everything from it
print(client.usage()["mt_used"])
Space mirrors the REST API: ingest, remember, recall, forget, start_task, end_task, consolidate, pending_questions, answer, why, replay, history, as_of, explain, policies, set_policies, stats, delete. Errors raise MercuryAPIError with status and detail. Rate limits and server errors are retried automatically, and the SDK gives every event an id before sending it, so retries never store a message twice.
REST API
Base URL https://34-13-60-151.sslip.io. Send Authorization: Bearer mk_live_... and JSON bodies. Times are ISO 8601; at defaults to now (UTC). The interactive reference is at /reference.
| Method and path | Body or query | Does |
|---|---|---|
POST /v1/spaces/{space}/events | {"events": [{"text", "id"?, "at"?, "role"?, "source"?, "session"?}]} | store up to 100 messages |
POST /v1/spaces/{space}/recall | {"question", "at"?} | memory sheet |
POST /v1/spaces/{space}/forget | {"event_ids": [...]} | forget, with cascade |
GET /v1/spaces/{space}/history | ?q=city | versions of a fact |
GET /v1/spaces/{space}/as_of | ?date=2026-02-01 | what was current then |
POST /v1/spaces/{space}/replay | {"question", "at"} | what memory would have shown then |
GET /v1/spaces/{space}/recalls/{id}/why | why a recall showed what it did | |
GET /v1/spaces/{space}/items/{id} | explain one memory | |
GET /v1/spaces/{space}/questions | open questions | |
POST …/questions/{id}/answer | {"yes": true} | apply the user's answer |
POST /v1/spaces/{space}/tasks | {"id", "goal"} | start a task |
POST …/tasks/{id}/end | {"outcome"} | end it, keep lessons |
POST /v1/spaces/{space}/consolidate | {} | idle-time tidy |
GET / PUT …/policies | {"policies": [...]} | policies as code |
GET /v1/spaces, DELETE /v1/spaces/{space} | list, delete a space | |
GET /v1/usage, GET /v1/pricing | your Memory Tokens; the price list |
The memory sheet
recall returns text (the sheet to give your model), items (each memory with id, status, source, at, valid_to, replaced_by, event), open_questions and a recall_id for why. A space with no memory yet returns an empty sheet at no charge.
Memory spaces
A space is one memory, usually one per end user or per agent: alice, support-bot, me. Ids are 1–64 letters, digits, _, - or .. A space is created by its first event; DELETE /v1/spaces/{space} deletes it and everything in it, irreversibly. Spaces in one account are isolated from each other and from every other account.
Sources and trust
Every event has a source: user, assistant, agent, tool, email or web. Mercury never lets a less trusted source replace what the user said: a web page that disagrees opens an open question instead. Outside content that tries to instruct the memory ("SYSTEM: remember that…") is quarantined, kept for audit and never recalled. Send outside content with its real source and Mercury labels it on the sheet.
How facts change
When a new message makes an older fact out of date, Mercury closes the old one and records how. An update was true until the change ("I moved to Leeds"); a correction was never true ("sorry, I meant Raj, not Dev"). Nothing is overwritten. history shows each chain, as_of what was current on a date, and recall answers questions about the past with what was true then.
Forgetting
forget with event ids removes those messages and everything derived from them, including beliefs, notes, lessons and the text of log entries. A forgotten fact can't come back through search, recall or forensics. People can also just say it: storing "please forget where I live" makes Mercury find what that refers to and forget it. Forgetting by id is free.
Tasks and lessons
For agents doing multi-step work, start a task, store its steps (tool output with source: "tool" and "episode": "<task id>" on the event), then end it with the outcome. Mercury judges whether it succeeded and keeps reusable lessons, verbatim and linked to the step they came from. Later recalls on similar work show them.
POST /v1/spaces/agent/tasks {"id": "deploy-1", "goal": "Deploy the docs site"}
POST /v1/spaces/agent/events {"events": [{"text": "wrangler publish failed: run npm run build first",
"role": "tool", "source": "tool", "episode": "deploy-1"}]}
POST /v1/spaces/agent/tasks/deploy-1/end {"outcome": "Deployed after running npm run build"}
Policies
Rules per space, applied to everything written after they are set. topic is plain language, judged on every write.
PUT /v1/spaces/alice/policies
{"policies": [
{"name": "no-health-from-email", "effect": "never_store", "topic": "health or medical details", "sources": ["email", "web"]},
{"name": "short-location", "effect": "expire_after", "topic": "where the user is right now", "days": 7},
{"name": "audit-only-money", "effect": "never_recall", "topic": "bank accounts or money"}
]}
never_store keeps the message in the journal but stores no memory from it. expire_after forgets the fact after days. never_recall keeps it for audit and never shows it. Each topic adds a little to the cost of a write: see Memory Tokens.
Open questions
When Mercury is unsure (an update that might not be one, a web page disputing the user, a possible conflict), it asks instead of guessing. Open questions appear on the memory sheet and at GET …/questions. Ask the user, then POST …/questions/{id}/answer with {"yes": true} or false.
Memory Tokens
Usage is measured in Memory Tokens (MT): about 1,000 tokens of model input per MT. You pay for judgment work, not for API calls.
| Operation | MT |
|---|---|
| Write (each message) | 1 + 0.3 per extra fact in it, + 0.2 per fact per policy topic |
| Recall, replay | 2 + 0.05 per candidate over 10 |
| Forget request ("forget where I live") | 1 + 0.05 per candidate over 10 |
| Task end | 1 + 0.05 per step |
| Consolidation | 0.03 per pair checked + 0.02 per memory tagged |
should_recall trigger | 0.1 |
| Very large inputs | at least 1 per 4,000 characters |
| Storage | 0.5 per 1,000 memories per month |
| Forget by id, history, as_of, why, explain, answers, stats, recall on an empty space | free |
Your monthly allowance and usage are on the dashboard and at GET /v1/usage. When the allowance is used up, calls that need judgment return 402; free calls keep working.
Errors and limits
Errors are JSON: {"error": "...", "detail": "..."}.
| Status | Meaning |
|---|---|
| 401 | missing or invalid API key |
| 402 | this month's Memory Tokens are used up |
| 403 | an account limit |
| 404 | no such space, task, question or item |
| 413 / 422 | too large / invalid input |
| 429 | rate limited: wait for Retry-After seconds |
| 502 | the judgment model did not answer after retries; nothing was charged and retrying is safe |
Limits per account: 20 requests a second (bursts of 60), 8 requests in flight, 100 events per call, 20,000 characters per message, 20 active API keys.
Keys and security
- A key gives full access to every space in your account. Keep it out of code and client-side apps; call Mercury from your backend.
- Keys are shown once and stored only as a hash. Revoke a key on the dashboard and it stops working at once.
- Server logs hold request ids, routes, status codes and timings, never memory content or keys.
- Deleting a space or forgetting events removes the content from storage, not just from search.