Skip to content

MCP tool reference ​

Stoat serves 52 tools over one streamable-HTTP MCP endpoint:

http://localhost:5526/api/mcp

Stateless, so every call is a self-contained request — a dropped connection costs nothing, and several agents share one server with no sessions to keep straight.

Every tool is licence-gated. The rule is that each [McpServerTool] calls LicenseGuard first, and it is enforced behaviourally rather than by scanning for the guard's text: McpLicenseGateTests invokes every discovered tool with null for every reference parameter, so an ungated tool either answers with real data or dies on a null — both fail the test. It found one the day it was written (list_runs was expression-bodied, so the sweep that added the other eight guards had no brace to insert after). See Installation for the note that the check itself is temporarily disabled in this build.

Plans — 21 tools ​

A plan is a cross-repository DAG. Nodes are GitHub issues, PRs, NuGet publishes and consumes, test-run gates and Event Modeling slices; edges are dependencies; status is derived from observation, never asserted.

Reading ​

ToolWhat it does
list_plansEvery active plan. Use the slug with get_plan / plan_status.
get_planOne plan's full DAG — nodes, depends_on edges, and dependencyOrder (every node listed after everything it depends on).
plan_statusThe live view: each node's derived status — unrealized, unknown, missing, open, claimed, pr-open, abandoned, done, waiting, running, failed, mismatch.
plan_historyEvery change ever made to a plan, oldest first: who, when, what.
next_ready_nodesReady work across every plan or one — dependencies all done, not itself done/missing/running. Sorted by leverage (how many nodes it unblocks).

Authoring ​

ToolWhat it does
create_planAn empty plan. Status derives from observation immediately.
change_planTitle, anchor, repo aliases. Omitted values keep their current value.
add_plan_nodeKinds: issue, pr, publish, consume, test-run-gate, slice. An issue number is optional — unbound means unrealized. Refused with the reason when it would break the plan.
change_plan_nodeReplaces a node wholesale; anything omitted is cleared. Use link/unlink for edges only.
remove_plan_nodeRefused while others depend on it — dropping an edge is a decision, not a side effect.
link_plan_nodesAdd an edge. Refused if it would make a cycle.
unlink_plan_nodesRemove an edge.
bind_plan_nodeThe materialize step: bind an unrealized node to the GitHub thing you just created.
archive_planOut of the active set; history stays.
import_planA whole plan as YAML (schema 1). Diffs into an existing plan, so re-importing the same document records nothing.

Claims ​

ToolWhat it does
agent_rosterEvery Claude Code session on the box: running / idle / stopped (with cause), what each holds, and whether anyone is actually working. Same derivation as GET /api/agents.
claim_nodeClaim or renew. A lease (default 30 minutes), so a dead session does not hold a node forever. Refused with the holder's name when taken.
report_nodeAttach or replace your note and renew the lease. For decisions worth surfacing, not a transcript.
release_nodeStatus stays whatever observation says: finishing the work is proven by the issue closing, the version appearing, the suite passing.

Parking ​

ToolWhat it does
await_dependenciesBlock until every dependency of a node is done. Returns ready, or timeout with what is still outstanding.
await_package_versionBlock until a feed serves >= minVersion. Queries the feed directly, so it works for any package, not only ones a plan declares.

Repositories — 12 tools ​

The cross-plan knowledge base. Check here before asking a question a previous session answered.

ToolWhat it does
list_repositoriesEvery repository: slug, what it publishes and consumes, CI workflows, dependencies, note count.
get_repositoryOne in full, including every markdown note with who wrote it and when.
register_repositorySlug is owner/name — the same shape issue refs use.
describe_repositoryDescription or default branch.
declare_repository_packageThis repository publishes or consumes a package — the cross-repo edge planning runs on. Re-declaring a known fact is a no-op.
retract_repository_packageRemoves it from publishes and consumes both.
declare_repository_ciA gating check name — the expected-check list PR status is read against.
retract_repository_ci
declare_repository_dependencyRepository-to-repository, independent of any one package edge. Say why in reason.
retract_repository_dependency
add_repository_noteA gotcha, a convention, a decision. Append-only, recorded with who and when.
archive_repositoryOut of the active set. The stream — and every note — stays.

Memory — 10 tools ​

What one session learned, the next one recalls.

ToolWhat it does
recallFree-text search, best match first. Call it before starting a node, and before asking something a previous agent may already have answered.
get_memoryOne in full — and, when asked, every version from its stream with who changed it and why.
list_memoriesBrowse without a search term: filter by scope, kind, tags; newest change first, paged.
record_memoryWhat the next session should know. Not a progress note — that is report_node, and it is about the node you hold right now.
revise_memoryOnly what you pass changes; earlier versions stay on the history.
refile_memoryMove to another scope — session → repository, once it turns out to be about the repository.
link_memoriesA typed edge: example-of, supersedes, explains, contradicts. Recorded on the first, readable from both.
archive_memoryHidden from recall and listings; history stays.
restore_memoryBack into recall and listings.
await_memoriesBlock until a memory is recorded or changed in a scope — how an agent hears what another session just learned, without calling recall in a loop.

Recall has a full-text leg always, and a semantic leg when an embedding provider is configured; the vector projection runs on the async daemon, so semantic recall needs Stoat:LiveUpdates on.

Runs and evidence — 9 tools ​

These arrived with the run console on 2026-09-18. They read the same registry the board does, through its locked Read/ReadAll, so live ingestion can never hand a tool a torn scenario collection.

ToolWhat it does
list_runsEvery run: running, finished, and orphaned (rehydrated from an archive after its publisher died). Newest first.
run_statusPer-scenario outcomes, the executing scenario's live steps, retry activity — and for a supervised run the worker lanes, recycles, faults, stalls and progress.
failing_testsFailed and aborted scenarios with error messages and failing steps. An empty list means nothing has failed so far — check run_status for whether it is done.
flaky_ledgerScenarios that passed only after retrying. Green builds hiding real instability; spans every known run unless narrowed.
await_run_completionBlock until a suite settles. Returns finished, orphaned or timeout with the final summary.
export_runctrf (rich — retries, flakiness, steps) or junit (lossy, for CI ingestion).
event_modelEvery slice with its command, handler, aggregates, emitted events, read models, messages and bound specifications. Empty until a producer pushes one.
slice_coverageWhat is untested per slice, and the two gaps are kept apart because they imply different actions: no-spec (nothing bound — scaffold scenarios) and no-evidence (bound, but no run has exercised it).
failing_specEverything failing_tests summarizes away: every step of the final attempt with status, duration and error, plus prior attempts — the input for writing the code a red spec describes.

TIP

With several publishers active, a no-runId await_run_completion honestly latches whichever run is in flight — which may be another session's supervisor worker. Pass the runId from list_runs.

See also ​

Source-available under the Business Source License 1.1.