heliograph
OfficialThis server exposes the heliograph CLI as MCP tools for publishing and inspecting remote execution runs across configured estates.
heliograph_estates: list configured estates and their transports
heliograph_doctor: verify transport connectivity before starting, without changing anything
heliograph_send: publish a step for the station to run; returns immediately, does not wait
heliograph_status: check current station state (running, idle, cancelled, refused, stopped)
heliograph_logs: list captured logs, newest first
heliograph_read_log: read a captured log whole, with UTC timestamps
heliograph_gaps: analyse timestamp gaps to find where a run stalled, attributing delays to the line before each gap
Allows using a Git repository as the transport for sending commands to a remote machine and receiving timestamped execution logs, including gap analysis for stalls.
heliograph
Remote, captured, auditable execution on a machine you cannot log into
A free, open-source tool by DBHQ
Someone can reach the machine. You cannot, and you are the one who knows what to ask it. heliograph runs that gap as a loop rather than a relay: you publish a step, it runs on the far side, and the whole run comes back as a log with every line timestamped in UTC, whether it passed or failed.
you heliograph send net-probe ────────────────▶ transport
station picks it up within seconds, runs it
pushes status, then the log ──────────────▶ transport
you heliograph logs --last --gaps ◀────────────The three ways across
heliograph carries a request to a machine you cannot log into, and brings the log back. There are three ways across the gap, and they differ in one thing: what stays held, and for how long.
Beacon. You cannot reach the machine and it cannot reach you - but you can both reach one agreed place. You leave the request there and walk away. Later the machine passes by, picks it up, runs it, and leaves the log for you to collect. Nobody is ever connected; a message waits in the middle. It is the safest of the three, because the code being run is already on the far side and can be read before anything happens - and the slowest, because you wait for the next visit.
Flare. You can reach the machine's door directly. You knock, hand over the request, wait on the step while it runs, and take the log away in the same visit. Nothing waits in the middle and no line stays open. Faster, because there is no pickup to wait for. The trade: you bring the code with you, so the machine trusts the door rather than vetting the code in advance.
Beam. You and the machine bring up a connection and hold it open. Either side can speak at any moment and the other hears it at once, until you hang up. A real session, not a message or a knock - and the most exposed, because while the line is open anything can travel down it. You turn it on deliberately and close it when you are done. It is designed, and not yet a transport you can pick.
In one line: a beacon holds a message, a flare is a single exchange, a beam holds the connection itself.
Related MCP server: ssh-mcp-server
Does this sound familiar
You have no SSH access to production, and you are not going to be given any.
The environment is air-gapped, or behind a bastion, a jump host or a VPN you are not on.
It is a client-owned or customer-managed estate. Only their staff can log in.
Access is blocked by policy, not capability: restricted, change-controlled, somebody else's sign-off.
You are on the fourth round of "can you run this and paste the output", and what came back was a screenshot of half a terminal.
You are an AI coding agent driving an investigation, and you need the evidence rather than somebody's summary of it.
If you can just SSH in, you do not need this.
Three roles, one boundary
The boundary is the gap, and the layout states it once:
control | your machine: the |
transport | the channel: git, relay, file share, bundle, object store - all behind one interface, so the read-only gates live in one place and cannot drift per transport |
station | the far side: |
Nothing is ever installed on the far side. The station is plain text you
can read before you run - bash 4+, or PowerShell 5.1 for a Windows estate that
has no bash and will not be given any - and no Go will ever appear under
station/ beyond the one file that lets the CLI carry the payload. CI
enforces it. That constraint is the entire proposition on a locked-down
box where installing anything is its own change request.
Install
# Linux and macOS, from a release
curl -sSL https://github.com/dbhq-uk/heliograph/releases/latest/download/heliograph-linux-amd64 \
-o /usr/local/bin/heliograph && chmod +x /usr/local/bin/heliograph
# or from source
go install github.com/dbhq-uk/heliograph/cmd/heliograph@latestA single static binary, no runtime. Checksums are published with each release, and the binary carries the station payload it was built with.
The build is reproducible: packaging/reproduce.sh v0.4.0 rebuilds every
released artefact from the tag and arrives at the published hashes, so "the
binary in the path is the source you read" is something you check rather than
something we say. Full account, including what is not yet covered, at
docs.heliograph.io/provenance.
The agent skill - the same loop, driven from Claude Code, Codex, Cursor and friends:
/plugin marketplace add dbhq-uk/marketplace
/plugin install heliograph@dbhq # Claude Code
./install-codex.sh # Codex, from a clone
./install.sh # Claude Code, from a clone
npx skills add dbhq-uk/heliograph # any agent, via skills.shUse
heliograph bootstrap ~/transport/payments # plant the station payload
heliograph init payments --dir ~/transport/payments # git, the default
heliograph plant # what to send the operator
heliograph send net-probe HOSTS="sql01 sql02" # publish a request
heliograph watch # follow it
heliograph logs --last # read the whole log
heliograph logs --last --gaps # where it stalled
heliograph doctor # will this work from here
heliograph mcp # serve all of the above as toolsThe operator's whole job is what plant prints: clone the transport repo,
run ./start.sh, walk away. The loop is read-only unless the operator said
otherwise: every step declares itself (# heliograph-mode: read-only or
action), one that declares neither does not run, and the station refuses an
action unless it was started with --allow-actions. It will not run as root
either.
For an agent, heliograph mcp is the same CLI as typed MCP tools:
claude mcp add heliograph -- heliograph mcpThe gates do not move. A tool call publishes a request; the station still decides whether to run it.
--gaps is the one worth knowing about. "Scan the timestamp column for gaps
before reading the content" is the most valuable instruction in the method,
and it is arithmetic:
$ heliograph logs --last --gaps
demo-20260906T183628Z.txt
5 captured lines
1 interval(s) of 10s or more, longest first.
Each is attributed to the line BEFORE it, which is what was running.
3m12s after 09:14:02 | Refreshing state...The gap belongs to the line before it: the stamp on a line is when that line was produced, so a long interval means the operation named on the preceding line is what took the time. A log where every line carries the same timestamp is reported as an error, not as "no gaps".
Status
control CLI over git | works, tested end to end against a stock station |
| works: the binary plants the station it was built with |
| works |
MCP server ( | works |
bash station | in use over git: the loop, the gates, the capture, Azure hosts, Kubernetes, the Windows launcher |
relay | half a transport. The station side is written and complete - it fetches requests, publishes status and delivers the finished log - and the relay server is deployed. No CLI command can select it |
file share, bundle, object store | control side only. The CLI implements all three; the station has no transport for any of them |
Azure Blob | works end to end, through |
PowerShell station | planned: A8 |
documentation site | docs.heliograph.io: the CLI, the transports, and the far side - the station, the runner, steps, hosts, Azure, Windows, containers, services, secrets, security and the capture contract |
A transport that works on one side of the gap is not a transport, so this table names both sides. Git is the one the CLI drives end to end; what the others still need, and in what order, is the roadmap.
The relay
Both sides dial out over ordinary HTTPS, so an estate needs no git host, no storage account and no VNet. Hosted, and self-hostable from the same binary.
Not yet usable end to end. The station side is complete and the server is deployed; no CLI command can select it, so the near side is the missing half.
The relay cannot read your logs, and cannot make a station run anything.
That second half is the one that matters: a relay able to forge a request
would be code execution inside every estate at once. Content is end-to-end
encrypted with keys the relay never holds, and every message is signed.
Nothing bespoke - age primitives plus
Ed25519. The full account, including what DBHQ can and cannot honestly claim,
is in
docs/specs/2026-09-06-relay-encryption-design.md.
The relay server is its own repository,
dbhq-uk/heliograph-relay,
because it holds no keys and must be publicly, obviously incapable of reading
anything it carries.
What the beam is, and what it costs
The beam is designed and not yet built; what follows is what it will do when it lands.
Two of the three shapes never hold a connection open. A beacon leaves a message where both sides can reach it, and needs nothing to be reachable, ever - no inbound port, no endpoint, no tunnel. A flare knocks, waits and leaves; what it does not do is hold the line open once the answer is back, and between the two of them an estate that will not have a held-open line at all still gets the whole job done.
The beam does hold a line open, live and two-way, and that is a tunnel. A blue team will read a held-open channel as one, because it is one. So it is off unless it is explicitly enabled on both ends, it is sealed and signed, and the station refuses to establish one unless it was started to allow it. Where an estate forbids a reverse connection, the beacon and the flare are the answer and nothing is lost but latency.
Every command still runs on the far side because someone with legitimate access chose to let it.
Layout
cmd/heliograph/ the control CLI, and `heliograph mcp`
cmd/heliograph-seal/ key generation for the relay transport
cmd/heliograph-site/ the static site generator
internal/transport/ git | relay | share | bundle | objstore
internal/bootstrap/ `heliograph bootstrap`: plants the embedded station
internal/wire/ the request and status documents that cross the gap
internal/seal/ sign-then-encrypt, for the relay
internal/logfile/ gap analysis
internal/mcp/ JSON-RPC over stdio, no dependencies
internal/estate/ which transport a name refers to
internal/plant/ what to send the operator
station/bash/ the bash station: everything that runs on the far side
station/bootstrap.sh the no-CLI bootstrap: clone this repo, run it by hand
skills/heliograph/ the agent skill: drives the CLI, and nothing else
tests/ the station's own suite, conformance contract included
site/content/ the documentation, one source, three renderings
infra/ terraform: DNS, Pages, R2 state
docs/specs/ the designs, written before the codeThe two halves used to be separate repositories, split along Go-versus-bash
rather than along the gap, and every reader had to work out which half they
were looking at. dbhq-uk/heliograph-skill was merged in on 2026-09-08 with
its full history; the reasoning is in
docs/specs/2026-09-08-station-and-skill-merge.md.
Development
PLAN.md is where the work stands: what has landed, what is next,
and which defects are known and unfixed.
CONTRIBUTING.md covers working on it and
AGENTS.md is for an AI agent doing so. The skill is
skills/heliograph/SKILL.md;
docs/dev-setup.md sets it up from source with live
edits.
Licence
MIT (c) 2026 DBHQ Consulting Ltd
Available Tools
7 toolsheliograph_doctorA
Check whether the transport works from here, and change nothing. Run this before a long step: read access is not write access, and finding out afterwards costs a whole round trip through somebody who cannot debug the machine.
| Name | Required | Description | Default |
|---|---|---|---|
| estate | No | Which estate. Optional when only one is configured. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral disclosure burden. It explicitly states the operation is non-mutating ('change nothing') and read-only ('read access is not write access'), and explains why discovering failure later is costly. It does not describe the exact output or any network side effects, but for a read-only check this is strong coverage.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences with the main action and constraint front-loaded: 'Check whether the transport works from here, and change nothing.' The rationale in the second sentence earns its place by explaining when and why to run the tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple tool with one optional parameter and no output schema, the description adequately covers purpose, safety, and timing. The main gap is that the exact return value or result format is not described, but 'check whether it works' makes the outcome reasonably inferable.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema fully documents the single optional 'estate' parameter, so schema coverage is 100%. The description adds no parameter-specific meaning beyond the schema, placing it at the baseline score of 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Check whether the transport works from here,' and adds a clear non-mutating constraint: 'change nothing.' This makes the tool readable as a connectivity diagnostic and distinguishes it from send-type tools, though it does not explicitly contrast with siblings like heliograph_status.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives an explicit trigger condition: 'Run this before a long step.' It also conveys an important exclusion: this is read access, not write access, so it should not be used as a substitute for a mutation. It does not name alternative tools, but the guidance is clear enough for selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
heliograph_estatesA
List the configured estates and the transport each uses. Call this first when you do not know which estate to act on.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The verb 'List' strongly implies a read-only operation, and the description states what information is returned: estates and their transports. However, with no annotations provided, the description does not explicitly disclose side-effect-free behavior, error conditions, or dependencies, leaving some behavioral transparency burden unmet.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences with no filler. It front-loads the action and resource, then immediately adds the most important usage guidance. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a parameterless list tool without an output schema, the description covers what the tool does, what it returns at a high level, and when to call it. It could be more explicit about the exact output shape or failure behavior, but the core contextual needs for invoking this tool are met.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has zero parameters and 100% schema description coverage, so there is no parameter meaning for the description to add. The baseline of 4 applies because the tool has no parameters and the description does not need to compensate for schema gaps.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('List') and names a distinct resource ('configured estates') plus the additional detail of transport each uses. The phrase 'Call this first when you do not know which estate to act on' further distinguishes it from the sibling tools, making the purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit guidance on when to use the tool: 'Call this first when you do not know which estate to act on.' It does not name specific sibling alternatives or exclusion conditions, so it falls short of a 5, but it provides clear and actionable usage context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
heliograph_gapsA
Where a run stalled. Returns the intervals in the log's timestamp column, longest first, each attributed to the line BEFORE it, which is what was running. Do this before reading a long log: a hang and slow progress are indistinguishable without it. If every line carries the same timestamp the capture was buffered and the log cannot answer the question at all, which this reports as an error.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | Log filename. Omit for the most recent. | |
| estate | No | Which estate. Optional when only one is configured. | |
| min_seconds | No | Shortest interval worth reporting. Default 10. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full behavioral burden. It reveals key behavior: returns intervals sorted longest first, attributes each gap to the line before it, and reports an error when timestamps are all identical. It also explains the diagnostic rationale. It stops short of explicitly stating read-only semantics or exact output shape, but covers the most important behavioral traits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four sentences, each carrying distinct value: concise purpose statement, return behavior, usage timing with rationale, and edge-case failure mode. No filler or repetition. The most decision-relevant information is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema and no annotations, the description covers the essential contract: what is returned, ordering, attribution, and error condition. It does not specify the exact structured return format, but for an analysis tool of this complexity the description is nearly complete. An agent can correctly decide when to call it and interpret its result.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the 3 parameters (name, estate, min_seconds) are already fully documented in the schema. The description adds semantic context around the log/timestamp concept but does not meaningfully extend parameter understanding beyond the schema. Baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a precise verb+resource statement ('Where a run stalled. Returns the intervals in the log's timestamp column') and clearly distinguishes itself from log-reading by positioning itself as the pre-reading analysis: 'Do this before reading a long log.' This makes the tool's identity and scope immediately obvious and separate from siblings like heliograph_read_log.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit when-to-use guidance: 'Do this before reading a long log: a hang and slow progress are indistinguishable without it.' It also explains when the tool cannot answer the question (buffered capture with identical timestamps). It does not explicitly name alternative tools or state when not to use it, but the timing guidance is clear enough.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
heliograph_logsA
List the captured logs, newest first. Each name carries the request id that produced it, so the log for a run you sent is the one whose name matches the id heliograph_send returned. Use this to find a log; use heliograph_read_log to read one.
| Name | Required | Description | Default |
|---|---|---|---|
| estate | No | Which estate. Optional when only one is configured. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the behavioral disclosure burden. It meaningfully discloses the sort order ('newest first') and the naming convention linking log names to request ids returned by heliograph_send. It does not mention output shape or limitations, but the core behaviors needed for correct use are present.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two compact sentences carry the essential information: what the tool lists, ordering, the naming convention, and how to route to a sibling. Every sentence earns its place with no redundant filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description tells the agent what will be returned (log names), the ordering, and how names relate to prior send requests, while pointing to the read tool for content. Since there is no output schema, this is adequate for a simple listing tool, though a note about pagination or absence of logs would make it fully complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the single 'estate' parameter is already fully explained by the schema: 'Which estate. Optional when only one is configured.' The description adds no parameter-level meaning, but none is needed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'List the captured logs, newest first.' It also clearly distinguishes this tool from its siblings by noting that it is for finding a log while heliograph_read_log is for reading one.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit routing guidance: 'Use this to find a log; use heliograph_read_log to read one.' This tells the agent exactly when to select this tool versus its most relevant sibling.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
heliograph_read_logA
Read a captured log whole. Every line carries a UTC timestamp. Read all of it, including the parts that worked: a passing probe beside a failing one is the control that says what the failure means. A green exit means the probes that ran passed, not that the work happened.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | Log filename. Omit for the most recent. | |
| estate | No | Which estate. Optional when only one is configured. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The verb 'Read' signals a non-mutating operation, and the description explains the meaning of exit statuses. No annotations are present, so the description carries the behavioral burden; it does so reasonably well.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is somewhat verbose and includes repeated emphasis ('Read all of it') and a metaphorical control comparison. It conveys useful context but could be tightened.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema is provided, so the description should clarify the return format. It mentions UTC timestamps and exit semantics, but does not specify the full output structure or error behavior.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already fully describes both parameters ('name' and 'estate') with clear defaults and optionality. The description adds no further parameter detail, so baseline is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'Read' and the resource 'captured log whole', making the primary purpose obvious. It does not explicitly differentiate from sibling tools like heliograph_logs, but the intent is still clear.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides interpretive guidance about reading the whole log and the meaning of a green exit, but does not explicitly state when to prefer this tool over alternatives like heliograph_logs or heliograph_status.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
heliograph_sendA
Publish a step for the station to run, and return immediately. This does NOT wait for the result: poll heliograph_status until it reports a terminal state, then read the log. The station decides whether to run it at all: a step that declares no mode is refused, and one that changes state needs CONFIRM=yes and a station started with --allow-actions.
| Name | Required | Description | Default |
|---|---|---|---|
| env | No | Environment for the run, for example {"HOSTS":"sql01 sql02"} | |
| note | No | Free text for the next human. The station ignores it. | |
| step | Yes | A step registered in the station's run.sh, or a path such as steps/net-probe.sh | |
| estate | No | Which estate. Optional when only one is configured. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations exist, so the description carries the full burden. It discloses several non-obvious behaviors: the call is fire-and-forget, the station has discretion whether to execute the step, mode-less steps are refused, and state-changing steps require CONFIRM=yes plus a station started with --allow-actions. The mong these (publish success vs execution success) is a genuinely important behavioral trait an agent would otherwise discover only after a failed run.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, zero filler. The core action is front-loaded, then the async consequence, then the execution conditions. Every sentence earns its place and the most decision-relevant constraints appear last without being buried.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with no annotations and no output schema, the description is thorough: it explains the non-blocking contract, how to obtain the result (poll status, read log), and refusal conditions. The remaining gap is that it never states what the immediate response contains (e.g., a run identifier needed to correlate with heliograph_status), which an agent needs since no output schema exists.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3; all four parameters (env, note, step, estate) are already documented. The description adds semantic value by explaining what the station does with the step parameter — refusal if no mode is declared, and extra authorization requirements for state-changing steps — which clarifies meaningfully how step and env interact.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first sentence names a specific verb and resource ('Publish a step for the station to run') plus the key behavioral trait (returns immediately). It explicitly differentiates from siblings by saying it does NOT wait and directing the reader to poll heliograph_status and read the log, which distinguishes it from at least two sibling tools without needing to open their schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives an explicit post-call workflow: do not wait, poll heliograph_status until terminal, then read the log. It also states the conditions under which this tool is effective (step must declare a mode; state-changing steps need CONFIRM=yes and --allow-actions), so the agent knows when the call will have no effect. Vivid routing to named siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
heliograph_statusA
What the station is doing now. State is one of running, idle, cancelled, refused or stopped. An empty state means the station has published nothing yet, which usually means it has not been started. refused is not a failure: it means the station would not run the step, and the reason names the flag that would permit it.
| Name | Required | Description | Default |
|---|---|---|---|
| estate | No | Which estate. Optional when only one is configured. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the behavioral burden and does well: it explains the state enum, the meaning of an empty state, and that 'refused' is not a failure and that the reason names the flag that would permit it. This adds material beyond the schema and prevents misinterpreting a failure-like state.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences with no filler: the core purpose is front-loaded, and each sentence adds a distinct state or semantic clarification. It is easy to scan and every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
This is a low-complexity tool with one optional parameter fully documented and no output schema. The description conveys the result vocabulary (one of five states or empty) and explains ambiguous states. It does not describe the exact payload shape, but the state-based output is sufficiently implied.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The single optional parameter 'estate' is fully documented in the schema, and the description adds no parameter-level detail. With 100% schema description coverage, score 3 is the appropriate baseline even though the description omits param specifics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly describes a status/state retrieval for a station and enumerates the possible state values, so an agent knows what this tool reports. It does not use an explicit verb like 'get' and does not explicitly distinguish itself from siblings, but its resource and state vocabulary make the function evident.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance about when to call this tool rather than a sibling such as heliograph_logs or heliograph_send, and no preconditions or exclusions are given. Usage context must be inferred from the word 'status' and the sibling names.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
7 tool updates
v0.1.0- First observed
heliograph_doctor - First observed
heliograph_estates - First observed
heliograph_gaps - First observed
heliograph_logs - First observed
heliograph_read_log - First observed
heliograph_send - First observed
heliograph_status
TDQS
Scored across 7 tools
Each tool targets a distinct concern: transport health, estate discovery, stall analysis, log listing, log reading, step submission, and station state. The only closely related pair, logs and read_log, is clearly split into finding vs reading, and gaps is explicitly positioned as a precursor to reading a long log.
All names share the heliograph_ prefix and snake_case, but the pattern is mixed: most are nouns (estates, logs, gaps, status) while send and read_log are verb-based. This is readable but not as predictable as a uniform verb_noun convention.
Seven tools cover the observable workflows of the server without bloat. Each tool has a clear rationale: doctor, estates, send, status, logs, read_log, and gaps all earn their place.
The core lifecycle is well covered: discover estates, check transport, send a step, poll status, identify stalls, and find and read the resulting log. Minor gaps exist around operational controls such as explicitly cancelling a run or managing estate configuration, but these do not block the main described workflow.
Maintenance
Related MCP Connectors
Remote shell and detached long-running jobs on your own machines — no SSH, open ports or VPN.
Scoped, audited SSH exec, sessions, and SFTP on your saved servers without exposing credentials
Operate Linux, macOS and Windows from your LLM. Every action runs through an auditable allowlist.
Dead-man switch monitors for cron & AI agents with dependency-cascade alerts. No account needed.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceRemote execution layer for agentic systems exposing 64 production tools via MCP for file, network, system, text, git, crypto, and monitoring operations.MIT
- AlicenseNot gradedqualityDmaintenanceEnables SSH command execution, file uploads/downloads, and multi-server management with zero-config inline credentials, supporting async jobs and AI-readable output.15 npm2AGPL 3.0
- FlicenseAqualityAmaintenanceExactly-once execution for irreversible agent actions: an agent claims the right to run an effect, and a retry after a lost response returns the sealed result instead of charging again. 12 tools over stdio, including a gateway mode where the agent holds a single-use ticket and never the provider key.9-
- FlicenseNot gradedqualityCmaintenanceEnables parallel agent tasks on disposable Arch Linux drones by providing a local stdio gateway for batch job submission, status monitoring, log retrieval, artifact fetching, and cancellation across SSH-connected runners.-