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
| tool | what it does |
|---|---|
heliograph_estates | what is configured here, and which transport each uses |
heliograph_send | publish a step, and return. It does not wait |
heliograph_status | what the station is doing now |
heliograph_logs | the captured logs, newest first |
heliograph_read_log | one log, whole |
heliograph_gaps | where a run stalled, longest interval first |
heliograph_doctor | will 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.
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.