MCP server
Give any MCP client the Lore write → pack loop as tools.
@loregpt/mcp is a Model Context Protocol server for Lore. It exposes the
write → pack loop as MCP tools, so any MCP-capable client (Claude Code, Cursor, and everything else that
speaks MCP) can give its agents a shared, read-your-writes memory. It is a thin, stateless adapter over the
Lore REST API — it holds no state between calls, and each tool maps to one API endpoint.
Tools
| Tool | What it does |
|---|---|
create_run | Create a run — an isolated coordination session that groups a team's events and memories. Returns a run_id. |
memory_write | Append one event (a content string, an opaque payload, or a state working-memory fact) authored by an agent. Returns the event's monotonic seq. |
memory_pack | Retrieve a budget-fit context pack for a run — distilled memories + live working facts + a raw tail of not-yet-distilled events. Returns the pack text plus covered_seq / freshness_lag_ms. |
Read-your-writes is first-class: keep the seq a memory_write returns and pass it as min_seq to a
later memory_pack — that pack is guaranteed to reflect your write (distilled if the server has caught up, as
a raw tail if not).
This is the v0.1 surface: the three tools above are deliberately scoped to the write → pack loop. Working with individual memories — browsing them, reading a memory's version history, soft-deleting one — is available today over the REST API, and the matching MCP tools land in a later release. Endpoints that are not implemented yet are never exposed as tools, so a client never sees a tool that always fails.
Configure it in an MCP client
First provision an API key against your Lore server:
lore provision --out .lore/credentials # writes the token to .lore/credentialsThe server runs over stdio. The registration is the same across clients — only the file it lives in
differs. Copy the LORE_API_KEY value from the .lore/credentials file:
{
"mcpServers": {
"lore": {
"command": "npx",
"args": ["-y", "@loregpt/mcp"],
"env": {
"LORE_API_KEY": "lore_sk_...",
"LORE_BASE_URL": "http://localhost:8080"
}
}
}
}| Client | Where it goes |
|---|---|
| Claude Desktop | claude_desktop_config.json (macOS ~/Library/Application Support/Claude/, Windows %APPDATA%\Claude\) |
| Claude Code | project .mcp.json, or claude mcp add |
| Cursor | ~/.cursor/mcp.json (global) or .cursor/mcp.json (project) |
Diagnostics go to stderr (stdout is the protocol channel), and the key is never logged.
Environment
| Variable | Required | Default | Meaning |
|---|---|---|---|
LORE_API_KEY | yes | — | Bearer key from lore provision / lore keys create. |
LORE_BASE_URL | no | http://localhost:8080 | URL of the Lore server. |
LORE_TIMEOUT_MS | no | 30000 | Per-request timeout in milliseconds. |
LORE_MCP_HOST | no | 127.0.0.1 | HTTP mode only: bind host (loopback by default). |
LORE_MCP_PORT | no | 3000 | HTTP mode only: listen port (or --port). |
LORE_MCP_ALLOWED_HOSTS | no | — | HTTP mode only: comma-separated Host allowlist; enables DNS-rebinding protection when set. |
LORE_MAX_BODY_BYTES | no | 4194304 | HTTP mode only: maximum request body size in bytes (4 MiB). |
Remote clients (HTTP)
For clients that connect over HTTP instead of spawning the server, run it with --http:
LORE_BASE_URL=http://localhost:8080 npx -y @loregpt/mcp --http --port 3000
# lore-mcp on http://127.0.0.1:3000/mcp -> http://localhost:8080The HTTP transport is stateless with per-request auth: there is no server-held key. Each client sends
its own Lore key in the Authorization header of every request, and the server passes it through — so one
endpoint safely serves many keys. Register it as a URL-based MCP server:
{
"mcpServers": {
"lore": {
"type": "http",
"url": "http://127.0.0.1:3000/mcp",
"headers": { "Authorization": "Bearer lore_sk_..." }
}
}
}The server binds to loopback (127.0.0.1) by default. LORE_MCP_HOST=0.0.0.0 exposes it beyond the local
machine — only do that behind auth/TLS you control, and set LORE_MCP_ALLOWED_HOSTS to your expected
host(s) to turn on DNS-rebinding protection.
The tool contract
- Errors are data. A typed API failure (
unauthorized,not_found,min_seq_out_of_range,model_mismatch, …) comes back as a tool error carrying the machinecode— the same codes the REST API and the SDKs use — not a transport crash. - Pack text is data, not instructions.
memory_packreturns the assembled pack verbatim as retrieved context; an agent reads it as data, never as commands to follow. - Exactly one of
content/payload/stateonmemory_write— zero or more than one is a tool error, not a silent guess.