Skip to content

MCP server

memoturn ships a Model Context Protocol server that exposes a project’s traces & metrics, prompts, datasets, and review queues as tools for agent IDEs (Claude Desktop, Cursor, etc.). It talks to the same server logic the REST API uses, so it reads and writes the live project.

There are two ways to connect, backed by the same tool registry:

  • Local stdio server (apps/mcp) — runs next to your datastores, ideal for self-host.
  • Remote Streamable HTTP endpoint — served by the API at /v1/mcp/{projectId}, one MCP resource per project.
ToolPurpose
query_tracesList recent traces with filters (environment, user, session, level, tag, score name, free-text search, day window); returns summaries with cost/token/latency rollups.
get_traceFull trace detail: metadata, observation tree (spans/generations), scores.
get_metricsProject metrics over the last N days (default 30): totals + per-day/per-model breakdowns of traces, generations, errors, tokens, cost.
list_scoresScores attached to a trace (name, value, source).
run_evaluatorRun an existing LLM-as-judge evaluator over a trace and record an EVAL score (write).
list_promptsList prompts (name, folder, versions, channels).
get_promptFull prompt detail with every version.
resolve_promptResolve a channel (default production) to compiled content + config.
create_prompt_versionCreate a new prompt version (and the prompt if new).
list_datasetsList datasets with item/run counts.
get_datasetDataset items + runs.
create_datasetCreate a dataset (idempotent on name).
add_dataset_itemsAppend items (input / expectedOutput / metadata).
list_review_queuesList review queues with pending/done counts.
create_review_queueCreate a queue bound to a score name + data type.
add_review_itemsEnqueue traces by id.
list_review_itemsList queue items (default PENDING) with trace I/O.
submit_review_scoreScore a review item (numeric/boolean value or categorical stringValue).

The server is scoped to a single project, resolved at startup from a project API key pair (the same pk-mt-… / sk-mt-… keys the SDK uses):

  • MEMOTURN_PUBLIC_KEY
  • MEMOTURN_SECRET_KEY

It also needs the datastore connection env (DATABASE_URL, REDIS_URL, DORIS_HOST, …) since it queries them directly.

Terminal window
bun --filter @memoturn/mcp start # stdio; logs to stderr, JSON-RPC on stdout

The server speaks stdio. Point your IDE’s MCP config at it, e.g.:

{
"mcpServers": {
"memoturn": {
"command": "bun",
"args": ["run", "/path/to/memoturn/apps/mcp/src/index.ts"],
"env": {
"MEMOTURN_PUBLIC_KEY": "pk-mt-…",
"MEMOTURN_SECRET_KEY": "sk-mt-…",
"DATABASE_URL": "postgresql://…",
"REDIS_URL": "redis://…",
"DORIS_HOST": ""
}
}
}
}

The API serves the same tool registry over Streamable HTTP. Each project is its own MCP resource, so clients connect per-project. RBAC is per-tool (not per-method — every call is a POST): a tool’s mutating flag maps to a read/write permission, and write tools are audited.

Two auth paths resolve to the same per-project authorization:

  • API-key Basic (pk-mt-…:sk-mt-…, self-host / headless) — the key must belong to the {projectId} in the URL; the tool’s permission is checked against the key’s read/write scope.
  • OAuth 2.1 bearer (memoturn cloud, IDE click-through) — memoturn is its own OAuth 2.1 authorization server: PKCE (S256) is mandatory, IDE clients self-register via dynamic client registration (RFC 7591), and refresh tokens rotate. Access tokens are JWTs verified statelessly (signature against the server’s JWKS, strict issuer {AUTH_BASE_URL}/auth + audience binding to the API origin — no DB hit per call). The token’s sub resolves to a user, who is then authorized against {projectId} (org membership → role): any member may run read tools; only non-VIEWER roles may run write tools. Clients discover the flow via the .well-known documents below; an unauthenticated request returns 401 with WWW-Authenticate: Bearer resource_metadata="…".
MethodPathDescription
GET / POST / DELETE/v1/mcp/{projectId}Streamable-HTTP MCP endpoint scoped to {projectId}. 401 (advertising Bearer + Basic) when auth is missing/invalid or the caller isn’t authorized for the project.
GET/.well-known/oauth-authorization-serverOAuth authorization-server metadata.
GET/.well-known/openid-configurationOpenID Connect discovery metadata.
GET/.well-known/oauth-protected-resourceOAuth protected-resource metadata (RFC 9728) — names the API origin as the canonical resource and points clients at the authorization server.

Behind Caddy (the single-VM production stack), these .well-known/* paths are routed to the API — they’re served at the domain root, not the console. The OAuth authorize flow bounces users to the console sign-in and consent pages (MCP_LOGIN_PAGE / MCP_CONSENT_PAGE, defaults <first AUTH_TRUSTED_ORIGINS>/login and …/consent). The endpoint also applies a per-IP rate limit before auth, so unauthenticated clients don’t get free credential-check tries.

See the API reference for the full route surface.