Your agent memory as MCP tools, connect with a URL and a key.
Korely MCP exposes your agent memory store over the Model Context Protocol
(MCP), so
any MCP-capable client (Claude Code, Cursor, Windsurf, VS Code, Codex) can
recall and remember through tools. It's a hosted
Streamable HTTP endpoint, nothing to install, authenticated by your
API key, which starts with
kor_live_. What it stores are facts
with dates, not a transcript.
This is the agent store, keyed. Korely MCP lives at
https://api.korely.ai/agent/mcp and takes a
kor_live_ bearer, or an OAuth sign-in
(Connect with OAuth). Use exactly this URL:
/mcp on the API host is not an MCP server and answers
410.
That key has the admin permission until you connect it to a dashboard login, which takes it away (the key keeps working). Connect it first, or give your client a key made on the dashboard's API keys page, which has no admin: an admin key never goes in a tool your agent can call.
Then point your client at the endpoint with the key as a bearer token:
Restart the client and the six Korely tools appear.
For Claude Code, Codex and Cursor, korely init --tool also
installs hooks that save each work session to the repository's memory.
See Connect a coding assistant.
Connect with OAuth
Some MCP clients (the app you connect from, such as Claude or ChatGPT with a custom
connector) do not take a pasted key. They sign you in instead, with the standard sign-in
flow called OAuth (see MCP in the Glossary). Korely MCP
supports it at the same URL:
https://api.korely.ai/agent/mcp
Before you start: you need a login to the Korely dashboard (the web app at
agent.korely.ai). If you made your key with korely init --agent, you have no
login yet: sign in to the dashboard once, and on its Account page paste that key under
"Bring in a key made without a login". Skip this and the connected app would use a new,
empty account.
In your client, add a remote MCP server (some clients call it a custom connector) and paste the URL. Leave the key field empty: after you allow access, Korely gives the client its own key.
When the client asks, sign in to Korely in the browser window it opens, with the method you use for your account.
Korely shows a consent page named after the app. Choose the project the app may use and its permissions (memories:read, memories:write). You can also confine it to some end users. Click Allow.
Back in the client, the six tools listed below are available. Ask it to recall something to check.
The menu names differ from client to client, so follow your client's own guide for the
first step, for example Claude's
custom connectors guide.
Tested by Korely with Claude, ChatGPT, Hermes and Grok. Other clients that support remote
MCP with OAuth should work; we have not tested them all.
What the client receives. A key for the project you chose, with only the
permissions you allowed (never admin), so it reads and writes that project and
nothing else. The key lasts one hour, and the client asks Korely for a new one by itself. If the
client goes 90 days without asking, it is disconnected. The memories it writes go
to the project you chose.
Disconnect. Each connected app is one row in the API Keys page of the
dashboard, named "<app> via OAuth". Revoke that key and the app is disconnected. The app
can also disconnect itself.
Key or OAuth? Use OAuth when the client asks you to sign in or cannot take
a header. Use the pasted API key for scripts, servers
and anything that runs without a person at the keyboard.
Available tools
Tool
What it does
korely_get_context
The recall call. Assembles the end user's currently valid typed facts most relevant to the query plus the most relevant memories into a prompt-ready block. Call before answering. known_as_of (ISO date) rebuilds the block as Korely could have built it then.
korely_add
Remember a decision, preference, or fact, Korely extracts the typed triples. Call after something durable is settled.
korely_get_facts
Read the typed (subject, predicate, object) facts. as_of reconstructs what was true at a point in time; known_as_of what Korely knew then, so a change told later is not in it; include_invalidated shows superseded facts.
korely_search
Semantic vector search over the raw memories, when you want the source rather than the assembled block. Takes min_score like POST /v1/memories/search. types adds the facts true now: memories (the default), facts or memories,facts, one text where REST takes a list. full_text=true shows each result's whole text instead of its first 280 characters. Each line ends with the id of its result, mem_ or fct_; a fact's id is the one korely_correct_fact takes.
korely_correct_fact
Fix a wrong fact. Takes the fact_id and the new subject, predicate or object; the old fact is closed and a new one is written, never edited in place, so as_of and include_invalidated still show the old one. With close=true it closes the fact instead. Only a current fact can be corrected. The same as PATCH /v1/facts/{id}.
korely_forget_memory
Retract a wrong memory by memory_id. It drops out of every read and the facts only it stated are closed; with erase=true it is removed for good. The answer counts the facts closed or removed. The same as DELETE /v1/memories/{id}.
korely_search follows the rules of the REST search for types and full_text
(Facts and whole text): with
the facts, min_score is refused, and a memory comes first at equal rank. With
full_text=true an answer holds 8,000 tokens of whole texts at most, the size of the largest
korely_get_context block: past that, a result shows what is left (never less than its first 280
characters), its line says [cut], and a NOTE closes the answer. REST's
content has no such bound.
Line breaks in a text.korely_search, korely_get_facts and
korely_add (the facts it extracted) print one item a line. Every line of a memory's or a
fact's text after its first is indented by four spaces, with or without types and
full_text, so a line at the margin is always an item of its own: a text cannot add a line that
looks like a fact, a score or a NOTE. Only a text with a line break (a line feed, a carriage return, a form
feed, or Unicode's line and paragraph separators) reads differently from 1.0.12; the result's id stays at the
end of its last line. REST answers JSON and does not change. Since 1.0.16 the context block
(korely_get_context, GET /v1/context) follows the same rule for its memories and
facts: before, it printed a memory's line breaks as they were.
The first four tools take an optional user_id to scope to one end user. The two write tools, korely_correct_fact and
korely_forget_memory, need a key with the memories:write scope, as their
REST twins do, and treat the ids of another project (or, for a confined key, of another end user)
as not found. A client lists the tools again on its next session to see them. The three read tools, korely_get_context,
korely_search and korely_get_facts, also take an optional
agent_id, to read one agent's namespace, and korely_get_facts
takes predicate (for example works_at), as their REST twins do. korely_add takes an optional agent_id and run_id too, as its REST twin does. Under a
burst from one account, korely_search and korely_get_context wait
their turn, up to 20 seconds for a slot on the account and up to 20 more for the embedder (about 40 seconds at worst). If the wait runs out, korely_search answers a tool
error, search_unavailable, and korely_get_context answers the block it
could build, with a note that a part could not be read (an error only when the block is empty). A tool refuses an argument it
does not declare, as a REST body refuses an unknown field: it answers
error: invalid_request, <name> is not an argument of <tool>; it takes: ....
The tools map onto the same
REST endpoints the SDK uses, one
store, every surface.
Verify it
A quick reachability + auth check, the same key as a bearer:
In your client, ask it to recall something for a user, then to remember a new
fact, then recall again, it should call korely_get_context and
korely_add on its own.
Local stdio server (alternative)
Prefer a local process over the hosted endpoint, for a client that only
speaks stdio? The first four tools above ship as a stdio server,
korely-mcp, in the Python package. It is a thin client, not
an offline store: every tool call goes to the REST API at
api.korely.ai with your key, so it needs the network like the
hosted endpoint. Since 0.1.16 it needs no extra
dependency (the [mcp] extra is kept, empty) and runs on Python 3.9 or later:
Terminal window
pipinstall'korely-memory[mcp]'
Terminal window
claudemcpaddkorely--korely-mcp
korely-mcp reads the key from ~/.korely/config.json
(written by korely init) or KORELY_API_KEY. The
same four tools and the same store, with fewer options: the local reading
tools take no agent_id (korely_add does), no
predicate and no exclude_sessions, and
korely_search returns 10 hits by default.
The local stdio server does not send types or full_text yet.
Its korely_get_context and korely_get_facts take
known_as_of from version 0.1.22. On the remote server both tools take
reader since 1.0.15 (see Agent notices);
the local server does not send it yet. See
Vibecoding for the full coding-assistant
walkthrough.