Agent harness
Hermes Agent
Give Hermes Agent memory that survives the session. Declare the Korely MCP server in your profile with a static API-key header: no package to install, just your key.
Hermes Agent (Nous Research) keeps its own memory files, loaded at the start of each session. Connect Korely's MCP server and Hermes can also 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). Hermes only calls the tools.
Prerequisites
- A Korely API key (
kor_live_...) without theadminpermission. Make it on the dashboard's API keys page, which ticksmemories:readandmemories:writeand leavesadminoff. A key from agent signup hasadminuntil you connect it to a dashboard login, and with it a tool can manage the account's projects and close the account; connecting takesadminaway, and the key keeps working. The hobby plan is free; Pricing lists its limits. - Hermes Agent installed (run
hermes setupto configure it).
Add the Korely MCP server
Korely's agent memory is a remote MCP server at
https://api.korely.ai/agent/mcp over Streamable HTTP, authenticated
with your key in a header, no browser login. Add it with the CLI:
hermes mcp add korely --url https://api.korely.ai/agent/mcp --auth header
The --url flag tells Hermes this is a remote HTTP server (vs
--command for stdio), and --auth header selects a
static header for authentication (the other choice is oauth).
The command is interactive: it asks for your key and which tools to enable.
Hermes keeps secrets in the profile's .env, and the entry in
config.yaml refers to the key with a ${...}
placeholder; open config.yaml afterwards to see the exact names
it used. The options are listed in
Hermes's CLI reference.
Or edit your profile's config.yaml directly, remote servers live under mcp_servers:, keyed by name:
mcp_servers: korely: url: "https://api.korely.ai/agent/mcp" headers: Authorization: "Bearer ${KORELY_API_KEY}"
A url field (rather than command) marks this as a
remote Streamable-HTTP server; the static bearer token is supplied via the
headers: mapping. Keep the key out of the file by storing it as a
placeholder and putting the real value in the profile's .env,
alongside config.yaml:
# <profile dir>/.env (~/.hermes/.env for the default profile)KORELY_API_KEY=kor_live_...
Hermes resolves ${KORELY_API_KEY} from the profile's
.env at connection time. You can also inline the literal key in
config.yaml if you prefer:
Authorization: "Bearer kor_live_...". The default profile's
directory is ~/.hermes/; a named profile's is
~/.hermes/profiles/<name>/. Run hermes profile list
to see which profile is active (it is marked with *).
Korely MCP also supports OAuth, so Hermes can sign you in instead of using a key. The Hermes documentation describes OAuth for remote MCP servers. Korely tested OAuth with Hermes. See Connect with OAuth.
What Hermes Agent can do
The Korely server offers six memory tools:
| Tool | What it does |
|---|---|
korely_get_context | The 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_add | Store 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_search | Search by meaning over the stored memories, best match first. |
korely_get_facts | The 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_fact | Fix 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_memory | Forget 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 Hermes 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 laterYou › How do we deploy this? → korely_get_context("deploy") → "This repo deploys to Hetzner..."Hermes › 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". It is a tool argument the agent passes at call time, not a config field, so no config.yaml change is needed. On a write, pass a user_id or an agent_id. With neither, the remote server stores the memory in the project's shared memory, with no end user, under the name your client gave when it connected (a key confined to one end user writes to that one); details. 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
- Korely MCP, the full MCP surface and other clients.
- Get context, the call behind
korely_get_context. - Memory as a tool, the same pattern when you build the agent loop yourself.