twin memory

n8n

The Twin Memory node for n8n - add and search memory in a workflow, or give an AI Agent long-term memory as a tool.

n8n-nodes-twinmemory is a community node for n8n. It is on npm Soon: this page describes version 0.1.0, and until it is published, n8n's HTTP Request node does the same job.

Install

In n8n, open Settings > Community Nodes > Install, enter n8n-nodes-twinmemory, and install. Self-hosted n8n can install it once it is on npm; n8n Cloud shows it once n8n has verified it.

Credential

Create a Twin Memory API credential:

FieldValue
API Keya key from the console, under API keys. A key that writes, to add, forget or correct
Base URLhttps://api.twinmemory.dev. For a stack on your machine, with n8n in Docker: http://host.docker.internal:8210

Test checks the key with GET /v1/me.

Operations

Every operation has an End User field: your ID for the person whose memory it is, usually an expression from the trigger, such as {{ $json.message.from.id }}. See End users.

OperationRoute
AddAdd
SearchSearch
Get HistoryHistory
Get LatestLatest
Find PhraseGrep
Read / ListRead / Ls
Get Surrounding PassagesAround
Get OverviewOverview
Get VersionsVersions
Get StatusStatus
Get LineageLineage
ForgetForget
CorrectCorrect
  • Add takes the text, a kind (message, note or document), and optional fields: item ID, session, role, author, title, about, when, expires and metadata. Input items for the same end user are sent together, up to 500 per request, and each comes back as its own output item. Wait Until Searchable continues only once they can be found.
  • Search returns context, ready to paste into a prompt (known lines, then dated facts, then passages, up to 4,000 characters), beside the full answer. Fast skips the model filter: free and quicker, a little less precise.
  • Every other operation returns the API's answer as one item.

Errors carry the API's own message. For a 429 or 503, turn on Retry On Fail in the node's settings.

Give an AI Agent long-term memory

The node is usable as a tool. In an AI Agent, add Twin Memory Tool twice: once with Search, once with Add.

  1. End User: set it from the trigger, such as {{ $('Telegram Trigger').item.json.message.from.id }}. Never leave it to the model, so a model can't reach another person's memory.
  2. Query (Search) and Text (Add): let the model fill them, such as {{ $fromAI('query', 'A plain-words question about this person', 'string') }}.
  3. Tool Description: n8n describes a tool by its operation unless you choose Set Manually. For the Add tool, paste this, so the agent saves without being asked:
Tool Description for Add
Save to this person's long-term memory (twin memory), which their other apps read too. Call this on your own, without being asked, on every turn where they say anything new: about themselves, their work, or the people, places, projects and things around them - preferences, facts, opinions, decisions, plans, dates, names and numbers, small details and passing remarks. Also save what was asked, tried, decided or built together, and why. When in doubt, save.

One fact per call, as a note, in their words. Never save secrets, passwords, keys or payment details, or your own suggestions as facts about them.

Keep n8n's Simple Memory for the last few messages of the chat; twin memory keeps everything else, across chats and days.

Template: Telegram assistant with long-term memory

Download the workflow, then in n8n choose Workflows > Import from File.

Telegram Trigger ──► AI Agent ──────────────────────────────► Send Reply
                       ├─ OpenAI Chat Model
                       ├─ Simple Memory      the last 10 messages of this chat
                       ├─ Search Memory      twin memory, End User = the Telegram user
                       └─ Save to Memory     twin memory, with the description above
  1. Create a bot with @BotFather and add its token to Telegram Trigger and Send Reply.
  2. Add your OpenAI key to OpenAI Chat Model.
  3. Add your Twin Memory API credential to Search Memory and Save to Memory.
  4. Activate the workflow and message the bot.

Each Telegram user is their own end user, by their Telegram user ID, so one bot keeps every person's memory apart.

Use the MCP server instead

n8n's MCP Client Tool can reach the hosted MCP server at https://api.twinmemory.dev/v1/mcp with HTTP Streamable transport, authenticated with either:

  • Multiple Headers Auth: Authorization: Bearer tm_... and X-Twin-Account: <end user>. One end user per credential.
  • MCP OAuth2: sign in to twin memory and choose the end user.

Use the node when the end user changes from item to item, and MCP for one person's agent.

Until it is on npm

n8n's built-in HTTP Request node calls the REST API directly. Create a Header Auth credential with name Authorization and value Bearer tm_..., then:

SettingValue
MethodPOST
URLhttps://api.twinmemory.dev/v1/memory/search, or /add
AuthenticationGeneric credentials, Header Auth
Send HeadersOn. Name X-Twin-Account, value {{ $json.userId }}
Send BodyOn, JSON, Using JSON
JSON{ "query": {{ JSON.stringify($json.message) }} } for search

For an add, the JSON is { "items": [{ "text": {{ JSON.stringify($json.message) }} }] }. JSON.stringify quotes the text, so quotes and line breaks stay valid JSON. Set the {{ }} fields to Expression mode.

On this page