heliograph

MCP server

heliograph mcp turns the CLI into a set of tools any MCP-capable agent can call. Claude Code, Claude Desktop, Cursor, Windsurf, Cline, Zed - anything that speaks the Model Context Protocol.

It is the same binary. There is nothing extra to install.

Configure it

Claude Code, one command:

claude mcp add heliograph -- heliograph mcp

Anything that takes a JSON config:

{
  "mcpServers": {
    "heliograph": {
      "command": "heliograph",
      "args": ["mcp"]
    }
  }
}

The server reads your existing estates. If heliograph estates lists it, the tools can reach it.

The tools

toolwhat it does
heliograph_estateswhat is configured here, and which transport each uses
heliograph_sendpublish a step, and return. It does not wait
heliograph_statuswhat the station is doing now
heliograph_logsthe captured logs, newest first
heliograph_read_logone log, whole
heliograph_gapswhere a run stalled, longest interval first
heliograph_doctorwill this work from here, changing nothing

Why tools and not just the skill

The skill teaches an agent to run the CLI, and that works. Every answer arrives as text it has to parse back out of a terminal.

A tool returns a result the agent did not have to scrape, with an argument list it cannot get subtly wrong. heliograph_gaps hands back the intervals already measured and attributed. The agent does not have to notice a stall in a column of timestamps; it is told.

What it does not change

Nothing about the gates. A tool call publishes a request. The station still decides whether to run it, still refuses a step that declares neither read-only nor action, and still refuses an action unless it was started with --allow-actions and the request carries CONFIRM=yes.

An MCP client asks. It does not get to answer.

A request passes three checks on the station: the step must declare read-only or action, an action needs CONFIRM equals yes, and the station must have been started with allow-actions. Failing any one publishes a refusal rather than running. request arrives declares a mode? CONFIRM=yes? --allow-actions? read-only or action for a state change how it was started runs Any no: refused, and the reason is published within seconds.
Three gates, all on the far side. The control side can ask for anything; the station decides.

Nothing about the far side. There is still no connection, no tunnel and nothing held open. Somebody with legitimate access started the loop, and they can stop it.

Reading a result

heliograph_send returns as soon as the request is published, which is before the run has started. An agent that treats the reply as the result will read the previous run's log and report it as this one's. The tool description says so, and the shape of the loop is:

1. heliograph_send 2. heliograph_status until the state is idle, cancelled, refused or stopped 3. heliograph_gaps to find where the time went 4. heliograph_read_log for the whole thing

refused is not a failure. It means the station would not run that step, and the reason says which flag would have permitted it. An agent that reads a refusal as a crash will retry the same step forever.