Agent access
akari serves a remote Model Context Protocol
endpoint, so a coding agent can read your whole session history without opening a
browser. It exposes the same surface the web UI shows (the overview analytics, the
projects index, the session feed, and a session’s full transcript) plus the raw
data behind it: tool-call bodies from the content store, and the lossless bytes a
session was ingested from. Tools are read-only except assign_session_project,
which pins an orphaned session onto a known project.
The endpoint is at /mcp on your server, over Streamable HTTP:
https://akari.example.com/mcp
Connecting with a browser (recommended)
Connect it once from your harness. In Claude Code:
claude mcp add --transport http akari https://akari.example.com/mcp
On first use the harness opens your browser to akari, which recognizes the session you are already signed in to and asks you to approve the connection. The browser sign-in is the authentication; no credential is passed to the agent.
Behind that click is the OAuth 2.1 flow MCP defines, with akari acting as both the resource and the authorization server. The agent registers itself, redirects through a PKCE-protected authorization request, and exchanges the result for a read-only access token that refreshes on its own. The token carries the read scope. You can revoke it any time from the Account page’s Connected apps section, which disconnects the agent and invalidates its tokens at once.
For the flow to advertise correct URLs behind a reverse proxy, set
AKARI_PUBLIC_URL to the server’s external origin
(Self-hosting).
Connecting without a browser
A harness that cannot run the browser flow authenticates with a read-scope API
token instead. Create one on the account page (the read scope is the
counterpart of the push-only ingest and the read-write full) and pass it
as a bearer token:
claude mcp add --transport http akari https://akari.example.com/mcp \
--header "Authorization: Bearer <read-token>"
A read token reaches only the MCP endpoint: it cannot push sessions or drive the browser write surface. It does not expire until you revoke it.
The tools
Every tool sees every internal session, the same surface a signed-in user sees.
Fetch data top-down: overview and list_projects for the lay of the land,
list_sessions to find runs, get_session for a transcript, then
read_tool_body or get_session_raw to go deeper on one. assign_session_project
pins an orphaned session onto a project when the worktree is gone.
| Tool | Returns |
|---|---|
whoami | The account the credential authenticates as: user id, username, and whether it is an admin. |
overview | Fleet usage for a trailing window: cost, tokens by class, session count, a daily series, and by-model and by-agent breakdowns. Also lists the accounts present, so their ids can scope later calls. |
list_projects | Every project, most recently active first, each with its session count and token and cost totals. |
get_project | One project’s identity, its windowed analytics (optionally narrowed by agent, user, or machine), and the agents, users, and machines that ran in it. |
list_sessions | The cross-project session feed with filters and a facet rail, paged. |
get_session | One session’s header and a window of its transcript: messages, thinking, tool-call metadata, attachments, and subagents. |
read_tool_body | A tool call’s input or result body from the content store, by the hash the tool call carries. |
get_session_raw | The lossless bytes a session was ingested from, behind the parsed projection. |
assign_session_project | Pin an orphaned session onto a project. Survives reparse and later orphaned announces. Owner or admin. |
Parameters that govern paging through a large history:
- Trailing windows.
overview,get_project, andlist_sessionstakedays;0or omitted means all of history. - Paging the feed.
list_sessionsreturns up to 500 rows and anext_cursor; pass it back ascursorto walk the whole feed. It also returns a facet rail (busiest agents, users, machines, projects) whose values are the exact strings to pass back as filters. A row with an outlier field (an unusually longgit_branch, say) that alone would blow the response budget is never dropped; its string fields are shortened in place, each with a...[truncated]suffix, and it carriestruncated: true. - Paging a transcript.
get_sessionreturns a bounded window of messages (setinclude_transcript: falsefor just the header). Whentranscript.has_moreis true, pass the window’snext_afterastranscript_afterto fetch the next page.byte_budget_truncatedreports that the encoded response limit ended the page beforetranscript_limit. If one message field cannot fit, the message carries a preview, its stored byte length, and anakari://resource link. Reading that resource returns the full text through the same authenticated MCP connection. Revoking the connection or API token also revokes access to previously returned links. - Fetching bodies. Tool bodies are not inlined in
get_session; take theinput_sha256orresult_sha256off a tool call and pass it, with thesession_idthat references it, toread_tool_body. Text returns as text, binary as base64, capped bymax_bytesand the server’s encoded response budget.
Tool results carry the complete DTO in structuredContent. The text content is
a compact status and paging summary that includes the integer ids later tools
require (session_id, project_id, user_id). A client that only reads text
can still go from a list to get_session or get_project. The text is not a
second copy of the JSON payload.
What the MCP sees
The MCP surface mirrors the web UI: the same sessions, the same visibility rule
(every internal session, exactly what a signed-in user sees), plus get_session_raw
for the ingested bytes, which the web UI does not surface. It exposes no account or
token management and no way to publish or delete; those stay on the full-scope web
surface. assign_session_project is the matching write on the HTTP API
(PUT /api/v1/app/sessions/{id}/project) and the CLI (akari assign-project).
Next: Self-hosting -> run the server yourself.