Skip to content
▚ evestack docs

The dashboard as MCP tools

Point Claude Code at your fleet and ask it questions in English. Read-only until you say otherwise.

@evestack/mcp speaks MCP on top of the dashboard's HTTP routes, so an agent can answer "why did last night's run stop?" against your own Postgres instead of you opening nine tabs.

It is a thin client, deliberately. No database connection, no SQL, no price table, no copy of eve's protocol — every tool is a projection of a route @evestack/dashboard already serves. The alternative is a second implementation of the cost calculation that disagrees with the UI you are looking at within a week. The consequence is stated rather than hidden: if the dashboard has no route for something, this package has no tool for it.

Setup

// .mcp.json, or claude_desktop_config.json
{
  "mcpServers": {
    "evestack": {
      "command": "npx",
      "args": ["-y", "@evestack/mcp"],
      "env": { "EVESTACK_MCP_DASHBOARD_URL": "http://localhost:4000" }
    }
  }
}
VariableDefaultWhat it does
EVESTACK_MCP_DASHBOARD_URLhttp://localhost:4000Where the dashboard is.
EVESTACK_MCP_DASHBOARD_AUTH—user:password for the dashboard. Every route is behind it.
EVESTACK_MCP_ALLOW_CONTROLunset1 advertises the four mutating tools. See below.
EVESTACK_MCP_APPROVER—The name recorded in the audit log for decisions this server makes.
EVESTACK_MCP_TIMEOUT_MS—Per-request timeout against the dashboard.

The tools

Read-only, always available:

ToolAnswers
list_sessionsWhat has run recently.
get_sessionOne session: live waiting state, pending approval requests, usage, and the verbatim budget-stop reason.
list_approvalsWho approved or denied what, and how that identity was established.
get_costsCaps, per-principal daily spend, stops, lifetime totals.
promote_session_to_evalGenerates eval source from a real session. Writes nothing.

Advertised only with EVESTACK_MCP_ALLOW_CONTROL=1:

ToolEffect
start_sessionStarts a real run. Spends money.
send_messageAnother turn on a live session. Spends money.
approve_or_denyRuns the gated tool for real. Audited.
cancel_runCooperative stop between steps; the in-flight model call still bills.

Why the default is read-only

approve_or_deny lets one model approve a tool call another model is parked on. That is the exact gate a human was asked to stand at — the whole reason eve pauses the turn — so enabling it by default would quietly delete the human from human-in-the-loop.

The mutating half is therefore withheld from tools/list entirely, not merely refused on call. A model cannot plan around a capability it has never been told exists, so there is no prompt that talks the server into using one.

Turning on EVESTACK_MCP_ALLOW_CONTROL means an agent can approve shell commands on your machine and start runs that cost money. Set EVESTACK_MCP_APPROVER with it, so the audit log on Approvals records which agent decided rather than unidentified.

What it tells you when a route is missing

This package and the dashboard version independently, so a tool can outrun the deployment it is pointed at. When that happens a 404 comes back as a tool-execution error naming the missing handler, never as an empty result — because an empty approval log and an absent approval log are opposite answers to "who approved this?", and a model handed the first when the second is true will report that nobody did.

If you see one, the fix is upgrading the dashboard image, not this package.

Provenance

Hand-rolled against the MCP spec: no SDK, no dependencies at all, node: builtins only — the same bet the rest of evestack makes, that a few hundred lines you can read beats a dependency you cannot. Read-only versus mutating is declared three ways, because different clients surface different ones: the first word of every description, annotations.readOnlyHint, and whether the tool appears in tools/list at all.

Source and the full tool reference: packages/evestack-mcp.