Skip to content

Memory layer for AI applications

Connect it once. Ask it months later. 

Nothing to file, nothing to tag, nothing to remember to do. This is the whole thing, start to finish.

0things it has read

WhatsApp · your memoryCurrent

when does my insurance renew and what am I paying?

1 June, £412, with Aviva.

then, in May

switched to Direct Line in May, £388

Now: £388 with Direct Line, renewing 1 June.
£412 with Aviva

kept, and true until 12 May

Ask what you were paying in April and it still knows.
GmailDriveSlackCalendarMeet & TeamsTelegramWhatsAppChatGPTClaudeCursor & CodexTerminalYour own computer

You have explained this before

The constraint you described on Monday is described again on Thursday. The approach the team abandoned in March is proposed as a fresh idea in August, because the abandoning happened in a pull request comment. The price a supplier quoted is in a photograph on your phone, and the assistant has never seen it.

None of that is a reasoning failure. The model is not wrong; it was never told.

A bigger window does not fix it

Every increase in context length brings the suggestion that memory is now unnecessary. Resending a year of history on every turn to use four facts from it costs more each month, and models are measurably worse at material buried in the middle of a very long context than at either end.

And a window belongs to one conversation. Whatever its size, the next one starts empty, and so does a different application.

Why models forget

The pipeline

Scroll it like a tape.

Four stages. A forwarded email, an uploaded PDF, a voice note and a Slack message all leave the first one in the same shape, carrying the authorisation they came with.

01 / 04
Normalise

Normalise

Extract

Resolve

Embed

01

Whatever arrived becomes a document

A forwarded email, an uploaded PDF, a voice note and a Slack message all leave this stage in the same shape. Everything downstream reads one format.

02

Discrete memories are pulled out

With the entities they mention and the relationships between them. One paragraph may produce several memories, or none — which is why writing returns a job rather than a memory.

03

It meets what you already know

The same person named three ways becomes one entity. A fact already known is not stored twice. A fact that contradicts a stored one becomes a conflict holding both sides, rather than overwriting it.

04

Vectors are written last

Separately, and after everything else, so a model change means re-embedding in the background rather than a migration that stops writes.

The whole thing

Start to finish.

Six moments, and you are only present for two of them.

It is all written down somewhere. That is the problem.

An insurance letter from March. A doc someone shared. A message in a thread. A date you half remember.

So you connect what you already use. Once, and never again.

This is the part you do. It takes about a minute.

Then months go by, and you do nothing.

Nothing to file, nothing to tag, nothing to remember to do.

And one day you just ask.

In your own words, from wherever you already are.

Then something changes — and the old answer is kept, not lost.

Superseded, with the dates it was true between. Ask what was true in March and it still knows.

Everything you already had, and everything it used to be.

One memory, behind every assistant you connect.

Retrieval, then resolution

Ask it something the answer changed on.

One decision over three weeks: considered, decided, implemented, then replaced. Both columns below are handed all four memories. The left one does what a search does and stops; the right one is what this actually assembles and hands to an assistant.

Pick a question

Four memories match, and every one of them is real

Ranked by similarity

24 Aug0.95

Team later moved to another provider.

1:1 with John

18 Aug0.90

Bedrock implementation shipped.

Standup notes

10 Aug0.81

Decided: Amazon Bedrock.

Planning doc

2 Aug0.62

Bedrock raised as an option for model access.

#eng-infra · Slack

A plain search returns

The best-matching line.

Team later moved to another provider.

1:1 with John · 24 Aug · 0.95

End of result

True, and it does not say what was moved away from, when it was chosen, or that anything shipped on it. The three memories that explain the sentence scored lower and were left behind.

PersistMemory returns

All four, and which one is now.

RELEVANT MEMORY

Current

Team later moved to another provider.

1:1 with John · valid: 24 Aug — still true

NO LONGER TRUE — these WERE true and have since changed

Bedrock raised as an option for model access.

#eng-infra · Slack · valid: 2 Aug10 Aug

Decided: Amazon Bedrock.

Planning doc · valid: 10 Aug24 Aug

Bedrock implementation shipped.

Standup notes · valid: 18 Aug24 Aug

Kept in the order they happened, so a question about August is still answerable in September. Nothing was overwritten to get here.

And so the assistant answers

Not Bedrock any more. It was chosen on 10 August, shipped on the 18th, and replaced on the 24th.

Four questions a memory should answer

Retrieval answers the first. The other three are what separate a memory from a search index, and they are the reason the rest of this system exists.

What database are we using?

AWS PostgreSQL, since 14 August.

The current answer, not the loudest match.

What had we originally chosen?

Supabase, from January until August.

Superseded, not overwritten. March is still there.

When did we switch, and why?

14 August. The decision cites connection pooling under load and the cost of a second datastore.

Read from the decision, with its date.

Where did that come from?

A message in the architecture channel, and the meeting the week before.

Every memory carries the source it was extracted from.

Behaviour

An assistant forgets. This does not.

Every chat starts from nothing. PersistMemory sits underneath, keeping what matters and handing it back when it is relevant.

Built for the way memory actually behaves

Memories, not documents

Decisions, tasks, commitments and the people involved — a claim with evidence behind it, and the window it was true for. Search returns the claim, not the paragraph it hid in — a set of claims you can query, not a transcript you have to search.

Conflicts surface

When two sources disagree, you are told, rather than served whichever ranked higher.

It shows its working

Confidence and importance are kept as a score and as the factors behind it, so something said once in passing is distinguishable from something three sources agree on.

Spaces

A Space is a rule, not a folder.

A filing rule, an audience and a retention policy — a way of looking at memories you already have. Nothing is moved into one, so the same memory sits in three at once, and correcting it is one correction rather than three.

One memory

Current

The vector index runs on pgvector.

#architecture · valid: 14 Aug — still true

Filed in three Spaces · space_memberships

Startup

audience: shared · retention: none · rule

The vector index runs on pgvector.

reason: mentions PersistMemory

Engineering

audience: private · retention: 365 days · inferred

The vector index runs on pgvector.

reason: type: decision

Vector search

audience: shared · retention: none · explicit

The vector index runs on pgvector.

reason: mentions pgvector

Correcting this memory changes what all three Spaces return, because none of them holds a copy of it.

Universal is not one of them. It is the base layer rather than a Space, so there is deliberately no membership row saying a memory is in it — that row would exist once per memory and carry no information. Asking Universal is asking your memories; asking Universal and two Spaces is that, unioned.

And a Space can now be shared.

A collaborator sees the owner’s memories through the Space. Nothing is copied into their account, which is what keeps two hard things simple — revocation, and whose contradiction is whose.

  1. 01

    invited_at

    Someone puts a Space in front of you

    With their name on it. An invitation with no author is one nobody can refuse meaningfully.

  2. 02

    accepted_at

    Nothing happens until you say yes

    Null grants nothing. Anyone can put your address on a meeting invite, so being named is not consent — otherwise a stranger could put their material inside your assistant by scheduling a call with you.

  3. 03

    revoked_at

    Taking it back is one column

    Ended, not deleted, so a re-share is visibly a re-share. The memories leave their retrieval on the next query, because nothing was ever copied into their account.

Sight, never ownership. There is no writer and no admin. Every row means one thing — this person may read this Space — because that is the only thing anything honours.

Your record stays yours. Because nothing is copied, their memory never enters your conflict set, so someone else’s reading of a meeting can never supersede a belief you hold. Your assistant can still cite theirs.

In code

Two calls to remember and recall.

First-party SDKs for TypeScript and Python, an HTTP API underneath both, and an MCP server for assistants that would rather do it themselves.

SDK reference
import { PersistMemory } from "@persistmemory/sdk";

const pm = new PersistMemory({ apiKey: process.env.PM_KEY });

await pm.memories.remember({
  text: "We moved the vector index onto pgvector. Priya raised egress cost.",
  spaceIds: ["architecture"]
});

const { results } = await pm.search.query({
  query: "why did we leave the hosted index"
});

Use it from where you already are

You do not have to change how you work. Message it like a person, add it to the assistant you already talk to, or drive it from a terminal. It is the same memory behind all of them.

Message it, like a person

In the assistant you already use

On your own machine

Send it things as they happen — a photo of a letter, a voice note in the car, a line you want to remember. Nothing to install.

  1. Sign up, then open Dashboard → Connections → Telegram. It gives you a personal link.
  2. Tap the link. Telegram opens the bot with your code already in it — press Start and the chat is joined to your account. Nothing to copy or paste.
  3. Send or forward anything. Text, photos, PDFs, voice notes. Photos and documents are read, not just filed.
  4. Type /machines to see the computers you have connected, or /get ~/notes/rent.pdf to ask one of them for a file.

Everything Telegram reads, and what it does not

Telegram is where things go IN. To ask questions, use it from your assistant or the dashboard — the bot confirms what it saved, it does not answer from your memory.

boiler service booked for the 14th, engineer is Tom

Saved.

[photo] insurance renewal letter

Read it — 2 pages. Saved.

/machines

macbook: connected

Message PersistMemory…

From a terminal

Three commands, and it is useful.

The CLI signs in through your browser with PKCE, so your password is never typed into a terminal and never passes through it. What comes back is a token scoped to what you approved.

The root is a ceiling, not a suggestion. pm agent start --root ~/Desktop — nothing outside it gets out, and the server cannot widen it.
pm — zsh

It can reach back

Every other memory tool is somewhere to put things. Ask this one for a file off your own desk and it goes and gets it — after it asks you.

  1. You ask from wherever you are

    A Telegram message, an assistant, the command line. No terminal required, and nothing to install on the phone.

  2. It stops, and waits for you

    A request a model made never reads anything on its own. Everything this system ingests — including other people's email — is in the same context that chose the path, so a person approves the exact one.

  3. The file comes back the way it came

    Into the same chat, as the file itself. Not a link to a dashboard, not a summary of it.

The approval

You see the exact line, before it runs.

Nothing ever calls into your machine. pm agent dials out from it, and anything it is asked to do waits on a page only you can reach. What is shown there is the argv itself, derived from the list that will be executed — not a description written beside it, because approving a description is not approving a command.

A connected app (MCP) asked to RUN

$ rg --files-with-matches "quarterly forecast" /Users/priya/Documents

2 minutes ago · expires in 8 minutes

This runs on your computer. Read the whole line — approving it approves exactly that, not a description of it. Your machine still refuses anything that reaches the network or runs a language, whatever you say here.

On your machine

Nothing yet.

It waits, and expires on its own if you never answer. A request arriving is not evidence anybody wanted it — everything this account has taken in, including other people’s email, is read into the same context that decided to ask.

Why the network is never allowed. Private data, untrusted content and a way out is exfiltration. Each is survivable alone; together, no approval dialog catches them, because the person approving cannot see where the bytes go.

Why a language is never allowed. bash -c is not one command, it is every command at once, and so is find -exec. The line you read would not be the line that ran.

It reads what you already have

Not a second place to write things down. The memory is built from where the work already happens, and a permission attached to a source is carried through rather than reapplied.

Assistants

Claude, ChatGPT and Cursor, over MCP.

Telegram

Forward a message, send a voice note or a photo.

Email

Forward anything to your own ingest address.

Your own computer

Ask for a file off your desk. It waits for your yes.

Documents

PDFs and scans read for text, not filenames.

Uploads

Anything else, straight to the API or the CLI.

Not yet — being built

Drive

Documents and their revisions, not just their names.

Slack

Channels you connect, with their access rules intact.

Teams

Messages and the files shared in them.

Meetings

Recordings transcribed, with who said what.

One memory, every assistant

Connected over MCP, so what you record in one is available in the next. The config is a URL and a transport, and no API key: authorisation happens in your browser, so a copied config is not a copied credential.

What it does not do

It does not make an assistant correct

One that reasons badly with no memory will reason badly with a good one. Memory makes it consistent with what was actually said, which is a different property from being right.

It does not read your codebase

Your assistant already does that well. Duplicating it would mean a stale second copy of something accurate by definition. This holds what the code cannot say about itself.

It does not organise anything

Nothing here decides what matters, sets a reminder, or files things into a system. It remembers what it was given and answers questions about it.

It is not a backup

Keep your own copies of anything you cannot afford to lose. This is a memory for your assistants, not a system of record.

Common questions

How is this different from Mem0, Supermemory or the other memory servers?
Those are memory for developers: you install an MCP server or call an SDK, and the memory lives inside your AI tools. This is reachable from the places you already are — a Telegram message, a forwarded email, the command line — by somebody who has never opened a terminal. And it can reach back: ask it for a file from your own laptop and it fetches it, after you say yes. Nothing else in that list does either.
Can it really read files off my own computer?
Yes, and only ever with your permission. You run `pm agent` and name the folders it may read; nothing outside them can be touched. A request made by a model always waits for you to approve the exact path, because everything this system ingests — including other people's email — is in the same context that chose it. A path you typed yourself in your own chat does not wait, because you already made that decision.
Is this a vector database?
No, though it runs on one. A vector database stores and searches embeddings; the work between a document and a searchable fact is what this adds: deciding what is worth remembering, resolving that two mentions are one person, noticing that today contradicts March, and carrying the permissions the source came with.
Do I have to move off my current tools?
No. It connects to what you already use over MCP and through connectors, and it is queried rather than migrated into. Nothing has to be re-entered.
What happens when two sources disagree?
Both are kept, with their sources and dates, and the newer supersedes the older rather than replacing it. You can see that the question is open instead of getting one confident answer with no record that anything was replaced.
Can I get my data out?
Everything stored about you is readable through the API under your own key, so an export is something you run rather than something you request. Deleting works the same way.
Does it work with a self-hosted or local model?
Yes. MCP sits between the client and this server; which model is behind the client is the client's business.
How is it priced?
Free to start, with no card. Usage-based pricing beyond that is not published yet, and inventing a number here would be worse than saying so.

Give your assistants a memory.