a9script

Docs / Agents: CLI, MCP, skill

The same loop, with nothing installed

Everything in this skill is about what you do, not how you reach it. There are two ways to reach it, and they are the same surface:

  • a terminal, where you run a9script <command> and your files are on the disk that command can see;
  • a remote door, where a URL and a token are pasted into your harness and every command is a tool.

The loop, the folder model, the refusals and the exit codes are identical, because a tool call IS the command — the same words, parsed the same way, with the same answers. What follows is only what differs.

The tools are the commands

  • whoami
  • filestore
  • entity
  • apply
  • describe
  • lock
  • run
  • probe
  • sessions
  • position
  • continue
  • abort
  • history
  • inspect
  • authoring-pack

A tool’s arguments are that command’s own words and flags, by name: where a terminal takes run on-order --debug, a tool call takes { "script": "on-order", "debug": true }. A flag that stands alone is a boolean; everything else is text.

Spell a flag exactly as the flag is spelled. A flag of two words keeps its hyphen — dry-run, no-wait, to-end, acknowledge-write — and a key that matches no word and no flag is refused, naming the key and what that tool takes. It is refused rather than ignored on purpose: writing dryRun where the flag is dry-run would otherwise drop the very switch holding something back, and your lint would have been a real apply.

Three commands are not tools

  • login — it stores a token in a profile file, and your connection already carries its token in the header it arrived on.
  • setup — it turns a setup token into the first account, which is the one state a door behind a credential cannot be in.
  • files — it moves bytes between the caller’s own disk and the store, and a remote caller’s disk is not the server’s. Both halves matter: bytes would cross this door as text, so anything that is not text would be corrupted without saying so, and a destination path would name a file on the server.

You can still see what an environment holds: the store list crosses, and reports every store with the number of files and bytes in it.

Your files are yours, so they travel

A terminal passes a path because the file is on the disk the command can read. Your disk is not the server’s, so where a terminal names a path, a tool call carries the content:

  • apply takes the folder itself — a list of { "path": …, "content": … }, exactly the files you would have written out. There are caps on how much may travel at once, and crossing one is refused by name, saying which file and which cap, so you are told what to split rather than quietly truncated.
  • run takes the test input as the document itself, not a filename.

Nothing you send is written to the server’s filesystem, and nothing you name is read from it.

The authoring pack is already there

The pack this skill points at is served as a resource, so a harness that reads resources on connect has it before you ask — at the version that environment is running, which is the one that matters. You can also call authoring-pack as a tool; it is the same document either way.

run starts the run and answers

Over a terminal run follows the run through any pause and exits on its outcome. Over this door it does not: nobody is holding the call open, and the harness on your side gives up long before a parked run comes back. So the tool starts the run and answers with it — which is a success, not a failure — and you read the outcome afterwards:

run { "script": "on-order", "debug": true }   → the run, still going
history <run>                                 → the calls it has made

Every answer says what to do next where there is something to do, so the exact follow-up is in the reply rather than in your memory. If you want the tool to wait after all, ask for it: { "script": "on-order", "wait": "30s" }.

Asking twice starts twice

A tool call is not a request you can safely repeat. There is no session and no de-duplication key, so a run sent again starts a SECOND run, and a probe with acknowledge-write fires a second write at the far end. If a call times out or an answer goes missing, read what happened — sessions for a paused run, history <run> for one you have an id for — before you send it again.

Everything else is the same

The token is still the context: it is bound to one environment, everything you do happens there, and a second environment means a second token. Reads are free, a write needs a full-scope token, and a credential’s VALUE is still entered by a person in the browser — your files leave a blank where it goes.

Rendered from docs/skills/a9script-authoring/reference/over-mcp.md in the product's own repository, at build time. Found a problem on this page? Write to the address in the footer.