twin memory

One URL for every MCP client.

Point Claude Code, Cursor, VS Code, Windsurf or Claude Desktop at the hosted server with your key and an end-user header, or add it to claude.ai or ChatGPT and sign in. The model gets 8 memory tools and asks for what it needs.

The endpointPOST
URL
https://api.twinmemory.dev/v1/mcp
Transport
Streamable HTTP, JSON responses
Auth
Authorization: Bearer <key>, or sign-in (OAuth)
End user
X-Twin-Account: <your user's id>, or chosen at sign-in
Tools
8 read; memory_add with a write key or Read and save

Connect in one step

A key from the console and the id of the user whose memory the agent should read. Nothing to install: the server is hosted, and speaks MCP over Streamable HTTP.

Keep the key in an environment variable. Cursor reads ${env:TWIN_MEMORY_API_KEY} from yours.

Every client, step by step →
Terminal
claude mcp add --transport http twin-memory \
  https://api.twinmemory.dev/v1/mcp \
  --header "Authorization: Bearer $TWIN_MEMORY_API_KEY" \
  --header "X-Twin-Account: user_42"

The tools

The same tools the REST API publishes, under the names a model calls them by. Only memory_search ranks and counts as a retrieval; everything that reads by address is free.

ToolWhat it answersArgumentsMetered
Find
memory_searchOne ranked search: dated facts read from what was added, then whole passagesquery, before?, after?, scope?1 retrieval
memory_grepExact substring match, for a quoted phrase similarity would blurpattern, scope?, limit?free
Read by address
memory_overviewWhat this memory holds: its shape, counts and indexnonefree
memory_lsThe children of one directory, before readingpathfree
memory_readOne file by exact path; a wrong path answers with its siblingspathfree
memory_aroundThe passages either side of one, in its own threadpassage_id, width?free
memory_latestThe most recent passages, newest firstk?, place?, after?, before?free
Change over time
memory_historyWhat was true of one subject, and when it stopped beingsubject, attribute?free
Write, with a write key or a Read and save connection
memory_addSaves anything new the person says, on its own, every turn; never secretsitems, wait?1 event per item

The account is never a tool argument

Which memory a call reads comes from the key and the X-Twin-Account header, set once in the client's config, or from the signed sign-in token of a claude.ai or ChatGPT connection. No tool has a field that could name another user.

A model that could name an account could name somebody else's.

Multi-tenant guide →
tools/call
POST /v1/mcp
Authorization: Bearer tm_AbC1234…
X-Twin-Account: user_42

{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "tools/call",
  "params": {
    "name": "memory_search",
    "arguments": { "query": "Where does Alice live?" }
  }
}
200 OK
{
  "jsonrpc": "2.0",
  "id": 2,
  "result": {
    "content": [{
      "type": "text",
      "text": "{\"query\": \"Where does Alice live?\", \"found\": 2, …}"
    }],
    "isError": false
  }
}

Writes need a key that writes

A read key lists only the read tools, so an agent handed one cannot change memory. Mint a write key when the agent should save what it learns, and memory_add appears in its tool list.

tools/list, by keyPOST /v1/mcp
KeyTools
Read key8
Write key9

Give your agent a memory in one command.

10,000 events and 1,000 retrievals a month on Free. No card needed.