Korely

Coding agents

OpenCode

Give OpenCode memory that survives the session. Add the Korely MCP server to one config file: no package to install, just your API key in a header.

Connect Korely's MCP server and OpenCode can ask Korely for the current facts and the relevant memories before it answers, and save new ones as you work. Korely does the heavy part on its own servers: it reads each memory, writes the facts, closes an older fact when a newer one contradicts it, and keeps both dates of a fact (bi-temporal). OpenCode only calls the tools.

Prerequisites

Add the Korely MCP server

Korely's agent memory is a remote MCP server at https://api.korely.ai/agent/mcp, authenticated with your key in a header, no browser login. OpenCode configures MCP servers in opencode.json, so add the server under mcp with type: "remote" and a static bearer header:

{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"korely": {
"type": "remote",
"url": "https://api.korely.ai/agent/mcp",
"enabled": true,
"headers": {
"Authorization": "Bearer kor_live_..."
}
}
}
}

Put this in your global config at ~/.config/opencode/opencode.json, or in a project-local opencode.json at the repo root. Replace kor_live_... with the real key from agent signup. The "type": "remote" transport is Streamable HTTP, matching Korely's agent endpoint. JSONC comments are supported if you prefer to annotate the block.

To keep the key out of the file, write "Authorization": "Bearer {env:KORELY_API_KEY}" and export KORELY_API_KEY before you start OpenCode. If you keep the key in a project-local opencode.json, do not commit that file.

Restart OpenCode so that it reads the file. A call without a valid key gets a 401, and OpenCode answers a 401 by starting a browser sign-in. If you see a sign-in prompt, check that the key is correct and not revoked. To stop OpenCode from ever starting one for this server, add "oauth": false to the entry. Both options are described in OpenCode's MCP docs.

Korely MCP also supports OAuth, so OpenCode can sign you in instead of using a key. The OpenCode documentation describes OAuth for remote MCP servers. Korely has not tested OAuth with OpenCode. See Connect with OAuth.

What OpenCode can do

The Korely server offers six memory tools:

ToolWhat it does
korely_get_contextThe recall call: returns the current facts plus the most relevant memories as one block of text, ready to put in a prompt (the context block). It does not call a language model.
korely_addStore a memory. Korely writes facts from it on its servers, each as (subject, predicate, object), and closes an earlier fact, with its end date, when a model decides a new one replaces it.
korely_searchSearch by meaning over the stored memories, best match first.
korely_get_factsThe facts known about an end user, with point-in-time queries: as_of (what was true then) and known_as_of (what the store knew then).
korely_correct_factFix or end one fact by its id. Give a new subject, predicate or object and the old fact is closed and a corrected one is written, both kept in history. With close=true the fact is only closed, which is how you forget a fact. Needs a key with the memories:write permission.
korely_forget_memoryForget one memory by its id. It drops out of every read and the facts only it stated are closed; with erase=true it is removed for good. Needs memories:write.

Use it

Korely MCP sends its client short instructions: call korely_get_context before answering, and korely_add once a decision or preference is settled. If OpenCode follows them, a session looks like this (an example, not a recording):

You › Remember that this repo deploys to Hetzner, not Render.
→ korely_add("This repo deploys to Hetzner, not Render")
# next session, days later
You › How do we deploy this?
→ korely_get_context("deploy") → "This repo deploys to Hetzner..."
OpenCode › This repo deploys to Hetzner (you told me earlier), not Render. ...

Scoping

The four tools korely_get_context, korely_add, korely_search and korely_get_facts accept an optional user_id so one key can serve many end users: a read that names "user-b" never returns a memory written for "user-a". Omit it on a write and the memory belongs to no end user (a key confined to one end user writes to that one). Omit it on a read and the read covers every end user the key can see. korely_add and the three read tools also accept an optional agent_id. korely_correct_fact and korely_forget_memory take the id of a fact or a memory instead, and treat an id from another project (or, for a confined key, from another end user) as not found. The Korely MCP page lists every argument.

Why this is more than a notepad. Korely keeps each memory's text as written and also extracts typed facts with bi-temporal validity from it. When something changes ("this repo now deploys to Hetzner, not Render"), Korely closes the old fact with its end date instead of overwriting it, so korely_get_context returns what's true now, and as_of can still replay what was true before. The Cloud runs on servers in Helsinki; Data and governance says where text is processed.

Related