Agent harness
Pi Agent
Pi Agent connects to MCP servers on its own over Streamable HTTP and lets you set a static Authorization header, so you point it straight at Korely's remote server, no bridge.
Pi connects to MCP servers on its own, over stdio or Streamable HTTP, and accepts a static Bearer header on a remote server, so you can connect to Korely's remote MCP endpoint directly. The intelligence (entity and typed-fact extraction, contradiction resolution, bi-temporal validity) runs server-side, and Pi just calls the tools.
Prerequisites
- A Korely API key (
kor_live_...). The hobby tier is free. - Pi Agent installed.
Connect Korely (recommended, native remote header)
Pi reads user-level servers from ~/.pi/agent/mcp.json and
project servers from .pi/mcp.json. Korely's agent memory is a
remote MCP server at https://api.korely.ai/agent/mcp (Streamable
HTTP), authenticated with your key in a static header, no browser login.
Keep the entry, which carries your key, in ~/.pi/agent/mcp.json;
Pi reads .pi/mcp.json only in a trusted project:
{ "mcpServers": { "korely": { "url": "https://api.korely.ai/agent/mcp", "headers": { "Authorization": "Bearer ${KORELY_API_KEY}" }, "exposure": "direct" } }}
Pi's default exposure, codemode, reaches MCP tools only from
codemode scripts; "exposure": "direct" declares the four Korely
tools to the model, registered as mcp__korely__korely_get_context,
mcp__korely__korely_add, mcp__korely__korely_search
and mcp__korely__korely_get_facts.
Set KORELY_API_KEY=kor_live_... in your environment, Pi
interpolates ${KORELY_API_KEY} in header values. Or let
Pi write the entry for you:
pi mcp add korely --url https://api.korely.ai/agent/mcp --bearer-token-env-var KORELY_API_KEY --exposure direct
Without --exposure direct Pi keeps the default
codemode and does not declare the four tools to the model.
With the community pi-mcp-adapter
pi-mcp-adapter
(MIT-licensed, authored by nicobailon, not an official Pi / pi.dev
product) is an alternative that replaces Pi's built-in MCP support
once installed (pi install npm:pi-mcp-adapter). The same
"headers" entry works with it. The adapter reads several config
files, and a later one wins over an earlier one:
~/.config/mcp/mcp.json (user-global, lowest),
~/.pi/agent/mcp.json, then the project's .mcp.json
and .pi/mcp.json, which override the user-global files. It reads
Pi's own ~/.pi/agent/mcp.json and .pi/mcp.json on
Pi 0.99 and later; see the adapter's
configuration doc
for the full list. The adapter also has a bearerToken field (see its authentication
doc); with Korely the "headers" object alone is enough. Verify the adapter against its
README
before relying on it.
By default the adapter routes all MCP tools through a single proxy tool to save
context. To expose korely_get_context, korely_add,
korely_search and korely_get_facts as first-class
tools, use the adapter's directTools config (for example
"directTools": ["korely_get_context", "korely_add", "korely_search", "korely_get_facts"]
on the server entry) to promote them.
Fallback, mcp-remote stdio bridge
Only if the native remote path misbehaves, you can route through the standard
mcp-remote proxy instead. It runs as a local stdio MCP server and
forwards every call to Korely over HTTP with your header attached, useful
because Pi also accepts command-based (stdio) servers.
Requires Node.js / npx on the machine.
{ "mcpServers": { "korely": { "command": "npx", "args": [ "-y", "mcp-remote", "https://api.korely.ai/agent/mcp", "--header", "Authorization:${KORELY_AUTH}" ], "env": { "KORELY_AUTH": "Bearer ${KORELY_API_KEY}" }, "exposure": "direct" } }}Pi interpolates env values, and mcp-remote reads KORELY_AUTH from its environment; the header is written without a space after the colon so that npx does not mangle it.
What Pi Agent can do
Once connected, Pi Agent has four memory tools:
| Tool | What it does |
|---|---|
korely_get_context | The recall path: assembles the active typed facts plus the most relevant memories into a prompt-ready block. Pure retrieval: the query is embedded once for the vector search, and no generative model runs on the read path. |
korely_add | Store a memory. Typed (subject, predicate, object) facts are extracted server-side, and a model judge closes the earlier fact, with its end date, when it decides a new one replaces it. |
korely_search | Semantic search over stored memories, ranked. |
korely_get_facts | The typed bi-temporal facts known about a user, with point-in-time queries: as_of (what was true then) and known_as_of (what the store knew then). |
Use it
Now Pi Agent reaches for memory on its own. Tell it something durable and it
calls korely_add; ask it something personal and it calls
korely_get_context first:
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..."Pi › This repo deploys to Hetzner (you told me earlier), not Render. ...Scoping
Every tool accepts 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.
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"), the judge 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. EU-hosted.
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.