MartinLoop — Stop Runaway Loops, Bad Code & Token Waste
The server governs, verifies, and audits AI coding-agent runs with budgets, stop conditions, and receipts.
Execute governed coding runs (
martin_run) with budgets, iteration caps, scope, and verifiers.Plan and preflight runs (
martin_plan,martin_preflight,martin_estimate) before spend.Inspect run status, budget, cost, and pressure (
martin_status,martin_get_run,martin_inspect).Review full dossiers, attempts, verification evidence, artifacts, and integrity (
martin_run_dossier,martin_dossier,martin_get_verification_results,martin_get_attempt).Triage failed or attention-worthy runs (
martin_triage_runs,martin_list_runs,martin_logs).Grade merge-readiness across six dimensions (
martin_eval) and generate PR summaries (martin_pr_summary).Create or review PRs against run evidence (
martin_create_pr,martin_review_pr).Control runs with pause, cancel, and continue receipts (
martin_pause,martin_cancel,martin_continue).Run environment diagnostics (
martin_doctor).Open the presentation-only Arcade (
martin_arcade,martin_arcade_status).
MartinLoop
Your coding agent says it's done. MartinLoop makes it prove it.
One system to control, verify and understand coding-agent work.
MartinLoop gives AI coding agents budgets, stop conditions, rollback rules, and receipts.
Built from thousands of agent runs where the problem was not intelligence -- it was uncontrolled execution.
Get started: npx -y martin-loop@latest start
Try the demo: npx -y martin-loop@latest demo
MartinLoop is part of the NVIDIA Inception program.
Start Here
Install — run npx -y martin-loop@latest start, or install it globally with npm install -g martin-loop@latest.
Governed run — define an objective, verifier, budget, and iteration cap with martin run.
Verifier — completion requires fresh verifier evidence bound to the active run and workspace. A configured verifier proves only the checks it runs; VERIFIED is not a claim that the code is bug-free or automatically safe to merge.
Budget — set a hard spend ceiling with --budget-usd and an attempt ceiling with --max-iterations.
Receipts — inspect the latest result with martin dossier --latest and validate stored integrity with martin runs verify --latest.
MCP — install @martinloop/mcp@latest in a supported host or generate host configuration with martin mcp print-config.
Documentation — continue with the quickstart, CLI reference, or MCP setup.
When --model is provided, MartinLoop passes it through unchanged. Without --model, the authenticated host runtime chooses its own default. MartinLoop does not inject a hidden fallback model.
Related MCP server: Playwright MCP
For AI Agents
MartinLoop is the execution-control system around coding agents. The coding agent still writes the code. MartinLoop governs the run and makes completion prove itself.
Use MartinLoop when a coding task needs one or more of these controls:
preflight readiness before agent spend
hard budget and iteration limits
allowed or denied edit scope
controlled retries and stop conditions
independent verifier commands
recovery and rollback evidence
a finite completion decision
run receipts, dossiers, history, failure classification, and post-run analysis
one control layer across Codex, Claude Code, and other coding-agent environments
Canonical lifecycle:
DEFINE
-> PREFLIGHT
-> CONTROL
-> VERIFY
-> RECOVER
-> PROVE
-> ANALYZEThe product-level flow is Definition of Done -> Controlled Run -> Verified Handoff.
For machine-readable context start with llms.txt, llms-full.txt, and MartinLoop for AI Agents.
One System Around the Run
Teams should not need to stitch together a separate script or point tool for every part of coding-agent execution. MartinLoop connects the control path around the agent from preflight through post-run evidence.
Stage | MartinLoop role |
Define | Capture the objective, verifier, budget, scope, and finish line. |
Preflight | Check readiness and required workflow evidence before agent spend. |
Control | Enforce budgets, attempts, path boundaries, policy, and stop conditions while the coding agent works. |
Verify | Run configured checks and bind the evidence to the active run and workspace. |
Recover | Preserve recovery and rollback state when another attempt or human review is required. |
Prove | Produce the authoritative |
Analyze | Inspect run history, cost provenance, failure classes, dossiers, and shareable evidence after execution. |
MartinLoop does not replace Git, GitHub, CI, dedicated security scanners, observability platforms, code review, or the coding agent itself. It gives those workflows one governed execution record to inspect.
Why MartinLoop
AI coding agents are useful, but unbounded retry loops are expensive.
A task that looked like a small fix can become dozens of attempts, a blown token budget, and a diff nobody trusts. MartinLoop gives every run an explicit contract: objective, verifier, budget, scope, receipts, and a clear stop condition.
Use it when AI coding work needs to stay bounded, inspectable, and safe to review before it becomes expensive or destructive.
Why Teams Adopt MartinLoop
It turns agent behavior into inspectable run receipts you can actually review.
It enforces hard stop conditions before runaway retries spend more money.
It adds rollback-aware rules so failed attempts do not silently leave unsafe changes behind.
It helps teams compare outcomes across agents under one governed flow.
Teams use MartinLoop when they need governed agent execution that can be reviewed and trusted.
2-Minute Install Path
npx -y martin-loop@latest start
npx -y martin-loop@latest demo
cd martin-loop-demo
npm install
npx -y martin-loop@latest run "Summarize the demo workspace and prove tests still pass" --verify "npm test" --budget-usd 2 --max-iterations 1Quick Start
Try MartinLoop in a disposable demo workspace:
npx -y martin-loop@latest start
npx -y martin-loop@latest demo
npx -y martin-loop@latest --version
cd martin-loop-demo
npm install
npx -y martin-loop@latest run "Summarize the demo workspace and prove tests still pass" --verify "npm test" --budget-usd 2 --max-iterations 1
npx -y martin-loop@latest dossier --latest
npx -y martin-loop@latest share --latestOptional global install:
npm install -g martin-loop
martin-loop --versionIf this flow is useful, open an issue with feedback so we can keep improving the public experience.
start prints the first-run guided path. run auto-checks doctor, session-start, and preflight, then executes when the environment is ready. Use --proof only when you intentionally want an explicit no-spend lane.
Inspect-first flow:
npx -y martin-loop@latest doctor
npx -y martin-loop@latest session-start
npx -y martin-loop@latest preflight "Summarize the demo workspace and prove tests still pass" --verify "npm test"share --latest writes three files into the selected run directory under share/: run-receipt.json, run-receipt.md, and proof-card.svg.
Release notes for MartinLoop 0.6.5: MartinLoop 0.6.5.
Release notes for MartinLoop 0.6.6: MartinLoop 0.6.6.
Model and Engine Support
MartinLoop governs the job independently of the coding worker.
Native agent CLIs: Codex, Claude Code, Gemini CLI
OpenAI-compatible endpoints: Kimi K2, NVIDIA Nemotron, DeepSeek, Qwen/Qwen Coder, Mistral/Codestral, OpenRouter/Together/Fireworks routes, Ollama, LM Studio, llama.cpp, and other compatible endpoints
Use
--engine openaifor OpenAI-compatible model endpoints.
The worker changes; MartinLoop's budget, scope, verifier, receipt, and integrity contract does not.
More detail: Model and engine support
The Run From Start to Handoff
MartinLoop's terminal presentation is built around the governed lifecycle, not around a single verifier command.
Governed Run Plan shows the configured finish line before work starts, including the task, budget posture, verifier plan, scope, and execution boundaries.
Controlled Run keeps the coding agent working inside those boundaries while MartinLoop tracks attempts, cost, stop conditions, and recovery state.
Verified Handoff closes the loop with one authoritative outcome:
VERIFIEDwhen the configured evidence supports the Definition of DoneSTOPPEDwhen a configured hard boundary ends the runNEEDS REVIEWwhen completion cannot be established from the available evidence
The handoff can include verifier steps, scope state, attempt count, cost provenance, unresolved evidence, recovery state, receipt integrity, and the next safe action. The exact fields depend on what the run actually established.
Visual Proof
MartinLoop turns an AI coding run into an inspectable execution record: budget used, verifier result, changed files, rollback evidence, and final receipt.
Ungoverned agents can retry until cost and scope drift. MartinLoop adds budget caps, verifier gates, and audit evidence so the run has a clear stop condition.
MartinLoop Arcade
Long governed runs do not have to mean staring at a spinner. In an interactive terminal, MartinLoop Arcade can be offered while the coding agent continues working in the background.
Arcade is presentation-only. It cannot change the agent, budget, verifier, policy decision, run outcome, or receipt evidence. It stays out of JSON, CI, non-interactive, and other machine-readable execution paths.
Use --arcade to offer Arcade immediately for a supported interactive run, or --no-arcade to suppress it for that run.
Proof Receipts
Proof receipts are local share bundles for governed AI coding runs. They show the task, spend, budget, verifier result, receipt integrity, and any evidence boundary that should not be rounded into confidence.
This real governed run spent $0.51 against a $3.00 budget. The verifier passed and the receipt integrity was signed, but the proof stayed at EVIDENCE_BOUNDARY because rollback evidence was not recorded.
Generate your own receipt after a governed run:
npx -y martin-loop@latest run "Summarize the demo workspace and prove tests still pass" --proof --verify "npm test"
npx -y martin-loop@latest runs verify --latest
npx -y martin-loop@latest share --latestExample receipt files: Markdown and JSON.
Run This Audit Yourself
Use this lane from a clean temp directory to verify the public CLI flow exactly as shipped:
npx -y martin-loop@0.6.6 --version
npx -y martin-loop@0.6.6 start
npx -y martin-loop@0.6.6 demo
cd martin-loop-demo
npm install
npx -y martin-loop@0.6.6 run "Summarize the demo workspace and prove tests still pass" --verify "npm test" --budget-usd 2 --max-iterations 1 --json
npx -y martin-loop@0.6.6 dossier --latest --json
npx -y martin-loop@0.6.6 share --latest --jsonFor deterministic installs, pin the package line (martin-loop@0.6.6) or use martin-loop@latest. Plain npx martin-loop can resolve a stale local cache on some machines.
Expected share bundle outputs:
share/run-receipt.jsonshare/run-receipt.mdshare/proof-card.svg
See It In Action
The point is not that every governed run is always cheaper. The point is that every run becomes inspectable and enforceable: budget policy, verifier result, stop reason, and evidence are explicit.
For a deterministic public repro lane, use the benchmark workspace and compare governed execution to unbounded retry behavior:
npx martin-loop bench --suite under-3-challengenpx martin-loop bench --suite ralphy-engineering-50
Ralph-Style Loops
A Ralph-style loop is the failure mode where an AI coding agent keeps trying without knowing when continuing is unsafe, uneconomical, or unlikely to succeed.
MartinLoop keeps the useful part of the loop, then adds brakes:
stop before budget overspend
classify unsafe or invalid actions before execution
write an audit record for every attempt
preserve rollback and verifier evidence for review
reduce runaway context growth with compact run summaries
Failure Taxonomy (13 Runtime Classes)
Public governed runs use one canonical taxonomy: the 13 runtime FailureClass values from @martin/contracts.
See the canonical table: Failure Taxonomy (13 Runtime Classes).
What It Does
Budget caps stop the next attempt before a configured USD, token, or iteration limit is exceeded.
Verifier gates require a real check, such as
npm test, before a run can count as complete.Policy checks block unsafe verifier commands, risky path changes, and secret-like task inputs before execution.
Failure classification uses canonical runtime classes for triage and reporting. See Failure Taxonomy (13 Runtime Classes).
Run receipts capture stop reason, verifier evidence, budget posture, integrity state, and the next safe action.
martin share --latestturns the latest governed run into a local share bundle with a redacted JSON receipt, Markdown recap, and proof-card SVG.MCP integration gives hosts one write-capable execution entrypoint plus richer planning, inspection, and review helpers.
How It Works
Layer | Purpose |
Task contract | Objective, verifier plan, repo root, allowed paths, denied paths, acceptance criteria, workspace, project, and budget. |
Policy and budget | Defaults come from |
Agent adapters | Claude CLI, Codex CLI, Gemini CLI, and direct-provider adapters normalize execution results. |
Safety and verification | Scope checks, verifier command checks, prompt integrity, and grounding decide whether work can continue. |
Persistence | JSONL run records, evidence summaries, and repo-backed artifacts make every run inspectable later. Each loop record is locally signed (HMAC, per-runs-root key) and |
Trust Boundaries
Cost and token outputs always include provenance (
actual,calculated,estimated, orunavailable).For Codex specifically, MartinLoop reports authoritative usage only when the host exposes it; otherwise MartinLoop labels usage as estimated and avoids presenting it as settled accounting.
Receipt integrity must be
verifiedbefore a run is treated as trustworthy evidence for external review.
CLI
martin-loop doctor
martin-loop demo
martin-loop session-start [--host <claude|codex|gemini|generic>]
martin-loop phase status|contract|session-start|preflight|run [--execute]
martin-loop preflight <objective> [options]
martin-loop run <objective> [options]
martin-loop bench --suite <suiteId>
martin-loop triage
martin-loop dossier (--latest | --loop-id <id> | --file <path>)
martin-loop runs list|get|attempt|verify ...
martin-loop mcp print-config --host <codex|claude|gemini|cursor|vscode|generic>
martin-loop mcp install --host <codex|claude|gemini|cursor|vscode|generic>
martin-loop mcp verify-install --host <name> [--scope <user|project|local>]
martin-loop mcp rollback --host <name> [--scope <user|project|local>]
martin-loop mcp uninstall --host <name> [--scope <user|project|local>]
martin-loop challenge [--loop-id <id> | --file <path> | --latest]
martin-loop share (--loop-id <id> | --file <path> | --latest) [--out-dir <path>]
martin-loop badge [--format svg|json] [--runs-dir <path>]
Common options:
--budget <n> Hard cost cap in USD
--budget-usd <n> Alias for --budget
--soft-limit-usd <n> Soft budget threshold in USD
--verify <cmd> Verifier command after each attempt
--proof Run verifier-only evidence checks without claiming governed execution
--max-iterations <n> Maximum number of attempts
--max-tokens <n> Maximum token budget
--engine <name> Adapter to use: claude, codex, gemini, or openai
--cwd <path> Repo root for the run
--allow-path <glob> Restrict writes to this path pattern; repeatable
--deny-path <glob> Block this path pattern; repeatable
--runs-dir <path> Override the local Martin runs rootExamples below use npx martin-loop so they work without a global install. If you install martin-loop globally, the martin alias works too.
Use martin-loop share --latest after dossier when you want a redacted bundle you can hand to another person without sending raw run-store files.
More detail: CLI reference and configuration reference.
Benchmarks
MartinLoop ships a public deterministic benchmark workspace in benchmarks/ plus the installed-package bench command.
From an installed package:
npx martin-loop bench --suite under-3-challenge
npx martin-loop bench --suite ralphy-engineering-50From a clean public clone:
pnpm install --frozen-lockfile
pnpm bench:build
pnpm bench:eval
pnpm bench:report:ralphyEquivalent workspace-filter commands:
pnpm --filter @martin/benchmarks build
pnpm --filter @martin/benchmarks test
pnpm --filter @martin/benchmarks eval
pnpm --filter @martin/benchmarks report:ralphyThe installed-package command reads the shipped public fixtures. The repo-clone workflow runs the public benchmark workspace directly.
MCP
Run the standalone MCP package directly:
npx -y @martinloop/mcpAdd it to common hosts:
codex mcp add martin-loop -- npx -y @martinloop/mcp
claude mcp add --transport stdio --scope user martin-loop -- npx -y @martinloop/mcp
claude mcp add --transport stdio --scope user martin-loop -- cmd /c npx -y @martinloop/mcpGenerate host config from the root CLI:
npx martin-loop mcp print-config --host codex --transport stdio --profile minimal
npx martin-loop mcp print-config --host claude --transport stdio --profile diagnostic
npx martin-loop mcp print-config --host gemini --transport stdio --profile full-local
npx martin-loop mcp print-config --host generic --transport stdio --profile github-reviewThe root martin-loop package, standalone @martinloop/mcp package, plugin metadata, and MCPB product version are aligned at 0.6.6. The MCPB manifest schema remains 0.3.
The public MCP release train labels are:
0.1.4operator foundation0.2.0cockpit expansion0.2.5public MCP package line0.2.7usability and review release0.3.0host adoption and onboarding release0.3.1review and handoff release0.5.3execution-control and host-compatibility release0.5.5governed-autonomous execution and proof-surface release0.5.6hosted run sync, fail-closed rollback, and verified-completion hardening
The standalone MCP registry/server identifier is io.github.Keesan12/martin-loop.
More detail: MCP setup, MCP tool reference, and MCP compatibility.
SDK
npm install martin-loopimport { MartinLoop, createClaudeCliAdapter } from "martin-loop";
const loop = new MartinLoop({
adapter: createClaudeCliAdapter({ workingDirectory: process.cwd() }),
defaults: {
workspaceId: "my-workspace",
projectId: "my-project",
budget: {
maxUsd: 3,
softLimitUsd: 2.25,
maxIterations: 3,
maxTokens: 20_000,
},
},
});
const result = await loop.run({
task: {
title: "Fix auth regression",
objective: "Fix the failing auth regression tests",
verificationPlan: ["pnpm test"],
repoRoot: process.cwd(),
},
});
console.log(result.decision.status);The root SDK also exports createCodexCliAdapter, createGeminiCliAdapter, createDirectProviderAdapter, and createOpenAiCompatibleAdapter.
More detail: SDK reference and package map.
Examples
Development
Requirements:
Node.js 20+
pnpm 10.x
git clone https://github.com/Keesan12/martin-loop.git
cd martin-loop
pnpm install --frozen-lockfile
pnpm lint
pnpm test
pnpm build
pnpm public:copy-scan
pnpm public:git-surface
pnpm oss:validate
pnpm public:smoke
pnpm release:matrix:localStandalone MCP validation:
pnpm --filter @martinloop/mcp lint
pnpm --filter @martinloop/mcp test
pnpm --filter @martinloop/mcp build
pnpm --filter @martinloop/mcp smoke:pack
pnpm --filter @martinloop/mcp smoke:published:pack
pnpm --filter @martinloop/mcp verify:releaseContributing
Issues, bug reports, workflow feedback, and focused pull requests are welcome. Public-facing docs should stay concise, user-centered, and accurate.
git checkout -b feat/your-feature
pnpm lint
pnpm test
git commit -m "feat: describe what you built"
git push -u origin feat/your-featureTelemetry & Privacy
MartinLoop sends minimal anonymous usage data to help improve reliability and prioritize development. A first-run notice appears before any data is transmitted. No data is sent on that first run.
What is sent:
Random installation ID (generated locally, never linked to your identity)
Per-process session ID
CLI version, Node version, OS and architecture
Event name and timestamp
Command category, run duration, success/failure category
Whether a receipt was generated; whether recovery occurred
Opaque remote-experience ID/type after a click
What is never sent:
Source code, prompts, task text, repository contents, file names, file paths
Environment variables, secrets, provider/model output
Receipt contents, ledger contents, approval details, verifier evidence
Email addresses, workspace, project, or organization identifiers
Raw exception messages or stack traces
Endpoint: https://tupopqvqnyyjuxseyxkr.supabase.co/functions/v1/product-events
Headers sent: Content-Type: application/json, User-Agent: MartinLoop-CLI/<version>
No authorization header, API key, or direct table access.
Opt out anytime:
martin telemetry offInspect what is sent:
martin telemetry explainEnvironment variables that disable telemetry: MARTIN_TELEMETRY_DISABLED=1, DO_NOT_TRACK=1, CI=1
MartinLoop continues to work normally with telemetry disabled. No features are gated on telemetry consent.
License
Apache-2.0. See LICENSE.
Available Tools
24 toolsmartin_arcadeA
Open the presentation-only MartinLoop Arcade when the host supports MCP Apps. The Arcade cannot change governed execution or evidence.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden, and it does so well. 'Presentation-only' and 'cannot change governed execution or evidence' accurately disclose both what the tool does and what it will not do, giving the agent clear safety expectations.
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 compact sentences with no filler. The first sentence front-loads the action and preconditions, and the second adds the essential limitation. 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 zero-parameter tool with no output schema, the description provides everything needed: what happens, when it should happen, and what side effects it cannot have. No important invocation information is missing.
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 tool has zero parameters and the schema is already fully covered. With no parameters to document, the description does not need to add parameter explanations; the baseline for zero-parameter tools 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 names a specific action ('Open') and a distinct resource ('MartinLoop Arcade') and scopes it as presentation-only. It differentiates the tool from the run/eval/status siblings by emphasizing it is strictly a display surface, not a control surface.
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 explicitly states the condition under which the tool should be used ('when the host supports MCP Apps'). It also tells the agent not to use it for mutating or governed workflows by clarifying that the Arcade 'cannot change governed execution or evidence'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
martin_arcade_statusARead-onlyIdempotent
Read the read-only evidence projection used by the Arcade view. Provide loopId for one exact run or omit it to load the latest run. Use only for Arcade rendering; use martin_status for budget pressure or martin_run_dossier for full evidence. This tool reads persisted evidence and never changes run state.
| Name | Required | Description | Default |
|---|---|---|---|
| loopId | No | Optional MartinLoop run identifier. Omit it to read the latest persisted run. |
Output Schema
| Name | Required | Description |
|---|---|---|
| cost | Yes | |
| budget | Yes | |
| loopId | Yes | Run identifier represented by this Arcade snapshot. |
| attempts | Yes | Number of recorded attempts. |
| warnings | Yes | Evidence or interpretation warnings for the Arcade view. |
| completed | Yes | Whether the run is outside an active lifecycle state. |
| verification | Yes | Persisted verifier evidence summary. |
| displayOutcome | Yes | Terminal verified-handoff outcome, or null while the run is active. |
| lifecycleState | Yes | Current persisted lifecycle state. |
| receiptIntegrity | Yes | Persisted receipt-integrity verdict. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover readOnly, idempotent, and non-destructive behavior. The description adds useful context by clarifying that the tool reads 'persisted evidence' and that omitting loopId dynamically loads the latest run. The closing sentence reinforces the read-only guarantee, though it is somewhat redundant with the annotations.
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 four sentences with no filler. It front-loads the core purpose, then covers parameter behavior, usage boundaries, and read-only safety, with every sentence earning 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?
Given a single optional parameter, an output schema, and annotations covering safety, the description is complete. It provides purpose, usage constraints, alternatives, parameter guidance, and state-change guarantees, so an agent can select and invoke the tool correctly.
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% and the schema already documents loopId as optional with the 'omit to read latest run' behavior. The description restates this logic but adds no new semantic detail beyond the input schema.
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 ('Read'), names a precise resource ('read-only evidence projection used by the Arcade view'), and explicitly distinguishes itself from sibling tools like martin_status and martin_run_dossier. An agent can immediately understand what this tool does and how it differs from alternatives.
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 states 'Use only for Arcade rendering' and explicitly redirects to martin_status for budget pressure and martin_run_dossier for full evidence. It also explains the loopId behavior clearly: provide it for an exact run or omit it for the latest run.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
martin_cancelADestructive
Write a durable cancellation receipt for one canonical MartinLoop run. Provide exactly one selector: file, loopId, or latest; runsDir changes the run-store root, while reason and requestedBy add audit context. Use when work must be abandoned, not temporarily held. This records a request and does not kill a process; use martin_pause for a reversible hold.
| Name | Required | Description | Default |
|---|---|---|---|
| file | No | Path to one canonical run record or directory. Mutually exclusive with loopId and latest. | |
| latest | No | When true, targets the latest canonical run. Mutually exclusive with file and loopId. | |
| loopId | No | Canonical MartinLoop run identifier. Mutually exclusive with file and latest. | |
| reason | No | Optional non-empty reason recorded in the cancellation receipt. | |
| runsDir | No | Optional run-store root override used to resolve loopId or latest. | |
| requestedBy | No | Optional human or runtime identity label recorded for audit context. |
Output Schema
| Name | Required | Description |
|---|---|---|
| action | Yes | The control action that was recorded. |
| loopId | Yes | MartinLoop run identifier the control was applied to. |
| reason | No | Human-readable reason for the control, if provided. |
| controlId | Yes | Unique receipt ID for this control action. |
| requestedAt | Yes | ISO 8601 timestamp when the control was recorded. |
| requestedBy | No | Identity that requested the control, if provided. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark the tool as destructive and non-idempotent, and the description adds useful context beyond that: the receipt is durable, the operation records a request rather than killing a process, and reason/requestedBy provide audit context. This helps an agent understand the side-effect profile without contradicting the annotations.
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 compact, front-loaded with the core purpose, and every sentence earns its place. It covers purpose, selector rule, usage condition, alternative, and a key non-behavior without repetition.
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 definition is complete for a cancellation tool of this complexity: it explains the selector constraint, the audit parameters, the durable nature of the receipt, and the distinction from pausing. Since an output schema is present, the description need not detail return values.
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, but the description adds meaningful parameter semantics: it states that exactly one selector (file, loopId, or latest) must be provided, explains that runsDir changes the run-store root, and clarifies that reason and requestedBy are audit context. This goes beyond the schema's individual property descriptions.
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 names a specific action ('Write a durable cancellation receipt') and a specific resource ('one canonical MartinLoop run'), and it differentiates this tool from martin_pause by stating that cancellation is for abandoned work, not temporary holds. The selector options are also clearly summarized.
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 explicitly says when to use the tool ('when work must be abandoned, not temporarily held') and identifies the alternative ('use martin_pause for a reversible hold'). It also clarifies a non-goal: this records a request and does not kill a process.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
martin_continueADestructive
Record a durable continue or resume request for a Martin run after a human pause or approval checkpoint.
| Name | Required | Description | Default |
|---|---|---|---|
| file | No | ||
| latest | No | ||
| loopId | No | ||
| reason | No | ||
| runsDir | No | ||
| requestedBy | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| action | Yes | The control action that was recorded. |
| loopId | Yes | MartinLoop run identifier the control was applied to. |
| reason | No | Human-readable reason for the control, if provided. |
| controlId | Yes | Unique receipt ID for this control action. |
| requestedAt | Yes | ISO 8601 timestamp when the control was recorded. |
| requestedBy | No | Identity that requested the control, if provided. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide idempotentHint=false and destructiveHint=true, so the description does not need to restate those. It adds useful context about durability and the pause/approval timing, but does not explain side effects such as what state is changed or whether this actually resumes execution. No contradiction with annotations.
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 a single, front-loaded sentence with no filler. Every part earns its place, and the key action and timing are clear immediately.
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?
Despite having an output schema, the tool has six undocumented parameters and no parameter descriptions. One sentence describing purpose is not enough for an agent to invoke it correctly without guessing at parameter semantics.
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 0%, and the description offers no explanation for any of the six parameters: file, latest, loopId, reason, runsDir, and requestedBy. An agent has no guidance about what values are expected or how they relate to a continue request.
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 ('Record') with a clear resource ('a durable continue or resume request for a Martin run') and a precise context ('after a human pause or approval checkpoint'). This semantically distinguishes it from sibling tools like martin_pause, martin_cancel, and martin_run even without naming them.
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 clearly states when to use the tool: after a human pause or approval checkpoint. It does not explicitly name alternatives or exclusion cases, but the context is specific enough to guide invocation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
martin_create_prADestructive
Create or preview a GitHub PR with a MartinLoop dossier body. Use execute=true to actually call gh.
| Name | Required | Description | Default |
|---|---|---|---|
| base | No | ||
| file | No | ||
| title | No | ||
| format | No | ||
| latest | No | ||
| loopId | No | ||
| execute | No | ||
| runsDir | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| body | Yes | GitHub-flavoured Markdown PR body containing the run dossier. |
| grade | Yes | Verification grade assigned to the run. |
| score | Yes | Numeric verification score from 0–100. |
| title | Yes | Suggested GitHub pull-request title. |
| loopId | Yes | MartinLoop run identifier used to generate the summary. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds meaningful behavior beyond annotations by revealing that the default action is preview, and that the external gh command is only invoked when execute=true. Annotations already declare destructiveHint=true and idempotentHint=false, so the lack of extra destructiveness detail is acceptable.
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 tightly written sentences deliver the core purpose first and the critical execution gate second. Every word earns its place; there is no filler or repetition.
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?
Despite a clear high-level purpose and an output schema, the tool has eight optional parameters with zero documentation and a 0% schema description coverage. An agent lacks necessary context about file/runsDir semantics, latest/loopId coupling, format effects, and what happens without execute.
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 0%, so the prose must compensate, but it only explains execute. The remaining parameters (base, file, title, format, latest, loopId, runsDir) are left entirely undefined in both the schema and the description, making it hard for an agent to populate them correctly.
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 names a concrete operation ('Create or preview a GitHub PR') with a specific body source ('MartinLoop dossier'). It is immediately distinguishable from siblings like martin_review_pr and martin_pr_summary because it clearly targets PR creation rather than review or summarization.
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?
There is no guidance on when to choose this tool over alternatives among the many PR- and dossier-related siblings. The only directive is 'Use execute=true to actually call gh,' which is parameter-level execution guidance rather than a tool-selection criterion.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
martin_doctorARead-onlyIdempotent
Read-only environment, engine, workspace, and run-store diagnostics for MartinLoop. Use first for software work, fresh installs, suspicious state, or before retries. Do not use as proof that a task is complete. Next: call martin_estimate or martin_triage_runs depending on whether this is new work or failed prior work.
| Name | Required | Description | Default |
|---|---|---|---|
| engine | No | Optional engine to highlight in diagnostics. | |
| runsDir | No | Optional runs-root override resolved under the default Martin runs root. | |
| workingDirectory | No | Optional repo-root override for doctor context. |
Output Schema
| Name | Required | Description |
|---|---|---|
| server | Yes | |
| status | Yes | |
| engines | Yes | |
| summary | Yes | |
| runStore | Yes | |
| warnings | Yes | |
| environment | Yes | |
| receiptScope | Yes | |
| requestedEngine | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and idempotentHint, and the description's 'Read-only' phrasing reinforces this without adding conflict. It adds behavioral value by scoping the diagnostic domains and by warning that the output is not proof of completion, which is a meaningful non-obvious trait. With annotations covering safety, this is strong but not maximal.
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 concise sentences deliver purpose, usage timing, exclusions, and next steps with no filler. The most important information is front-loaded, and every sentence earns its place. Reusing 'Read-only' from annotations is minor redundancy but not harmful to an agent scanning prose.
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 zero required parameters, a complete output schema, and read-only/idempotent annotations, the description covers all essential decision-making context. It includes scope, when to invoke, what not to infer, and which sibling to call next. An agent can safely invoke this tool correctly without further clarification.
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%, with all three optional parameters already thoroughly described in the input schema. The description itself adds no parameter-specific guidance, but the schema carries the full burden. This meets the baseline for a fully covered schema.
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 identifies the tool as read-only diagnostics for environment, engine, workspace, and run-store data, which is specific about resources and scope. It lacks an explicit active verb like 'get' or 'run', instead using the noun phrase 'diagnostics', though the intent is unmistakable. It distinguishes from siblings by positioning itself as a first-step diagnostic rather than a completion check.
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 explicitly states when to use the tool: 'Use first for software work, fresh installs, suspicious state, or before retries.' It also provides a clear exclusion: 'Do not use as proof that a task is complete.' It routes the agent to the appropriate next tool based on whether the work is new or failed, making the decision tree explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
martin_dossierARead-onlyIdempotent
Read a formatted evidence summary for one MartinLoop run. Provide exactly one selector: file, loopId, or latest; runsDir changes the run-store root. Set format to json, md, or github-pr; json is the default. Use after martin_run, before merge or release claims, or when sharing what happened. Do not use as a substitute for missing verifier evidence; use martin_run_dossier for the full structured record. Next: review verification results, retry, or hand off the receipt.
| Name | Required | Description | Default |
|---|---|---|---|
| file | No | Path to one run record or directory. Mutually exclusive with loopId and latest. | |
| format | No | Output format. Defaults to json. | |
| latest | No | When true, loads the latest run. Mutually exclusive with file and loopId. | |
| loopId | No | MartinLoop run identifier. Mutually exclusive with file and latest. | |
| runsDir | No | Optional run-store root override used to resolve loopId or latest. |
Output Schema
| Name | Required | Description |
|---|---|---|
| cost | Yes | |
| loop | Yes | |
| budget | Yes | |
| source | Yes | |
| related | Yes | |
| attempts | Yes | |
| warnings | Yes | |
| artifacts | Yes | |
| inspection | Yes | |
| sourceKind | Yes | |
| recentEvents | Yes | |
| verification | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true, so the safety profile is covered. The description adds behavioral context: it requires exactly one selector, explains that runsDir changes the run-store root, and notes that json is the default format. It doesn't describe the return shape, but the output schema exists and the description's added constraints are useful.
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 compact and front-loaded: it states the core action in the first sentence, then selector/format rules, then usage context, then an exclusion. Every sentence earns its place, and the structure moves from what to how to when.
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 read-only, idempotent tool with a full output schema and 100% parameter coverage, the description is complete. It covers selector semantics, format options, default behavior, runsDir override, when to use it, and when not to use it. The only minor gap is not describing the exact content of the formatted summary, but the output schema and the phrase 'evidence summary' cover that sufficiently.
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 schema already documents all five parameters. The description adds value by clarifying the mutual exclusivity of selectors ('Provide exactly one selector') and by explaining that runsDir is a root override for resolving loopId or latest. It also names the format enum values and the default, which reinforces the schema without repeating it verbatim.
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 tool reads a formatted evidence summary for a MartinLoop run, with specific selector options (file, loopId, latest) and format options. It distinguishes itself from martin_run_dossier by explicitly saying it is not a substitute for the full structured record, and it names the sibling tool for that purpose.
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: 'Use after martin_run, before merge or release claims, or when sharing what happened.' It also provides a clear exclusion: 'Do not use as a substitute for missing verifier evidence; use martin_run_dossier for the full structured record.' This is strong routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
martin_estimateARead-onlyIdempotent
Read-only cost, route, and pre-work burn estimate for a software objective. Use before planning/preflight when a change may spend agent time or exceed budget. Do not use for casual questions or as permission to execute. Next: call martin_plan if the estimate is acceptable, or ask for consent if budget/risk is high.
| Name | Required | Description | Default |
|---|---|---|---|
| engine | No | Which agent CLI would be used. Defaults to claude. | |
| budgetUsd | No | Budget ceiling for estimation. Defaults to 5. | |
| fileScope | No | Optional file paths to scope the estimate. | |
| objective | Yes | The coding task to estimate. | |
| workingDirectory | No | Optional workspace path for recording the estimate receipt against the same task root you plan to run. |
Output Schema
| Name | Required | Description |
|---|---|---|
| engine | Yes | |
| reason | Yes | |
| budgetUsd | Yes | |
| objective | Yes | |
| compressed | No | |
| confidence | Yes | |
| blockedSteps | No | |
| selectedMode | Yes | |
| expectedCostUsd | Yes | |
| compressionSummary | No | |
| recommendedBudgetUsd | No | |
| expectedPreworkBurnPct | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true, and the description reinforces this with 'Read-only' and 'not as permission to execute.' It adds context about producing a pre-work burn estimate and warns about budget/risk consent, going beyond the bare annotation flags. No contradictions with annotations.
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 deliver purpose, usage conditions, exclusions, and next-step guidance with zero filler. The most important information—read-only estimation—is front-loaded, and every clause 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?
Given that annotations cover read-only and idempotent behavior, the schema covers all parameters, and an output schema exists, the description fills the remaining gaps: when to use it, what it is for, and what to do next. Nothing needed for correct invocation is missing.
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 schema itself documents all parameters. The description adds general context about 'software objective' and 'budget/risk' but does not provide new meaning for individual parameters beyond the schema. Baseline 3 is appropriate; the description does not carry the parameter documentation burden.
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 specific verb and resource: 'Read-only cost, route, and pre-work burn estimate for a software objective.' This clearly distinguishes the tool from planning, execution, and run-management siblings like martin_plan and martin_run. It also communicates the operative scope—estimating, not executing.
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 explicitly says when to use it ('before planning/preflight when a change may spend agent time or exceed budget') and when not to ('Do not use for casual questions or as permission to execute'). It also provides a concrete next step: call martin_plan if acceptable, or ask for consent for high budget/risk. This is exemplary routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
martin_evalARead-onlyIdempotent
Grade a MartinLoop run across six dimensions — task completion, verifier health, diff discipline, regression risk, security risk, and reviewability — and return a scored merge-readiness verdict. Use after a governed run completes to decide whether the result is safe to merge or promote. Use before martin_pr_summary or martin_create_pr to confirm the run is merge-ready. Do not use to retrieve raw verification command output — use martin_get_verification_results for that. Do not use to review an existing PR body — use martin_review_pr instead. This tool reads saved run evidence and inspects local git signals; it does not modify state or contact GitHub.
| Name | Required | Description | Default |
|---|---|---|---|
| file | No | Absolute or relative path to a loop-record.json file or run directory. Mutually exclusive with loopId and latest. | |
| latest | No | When true, evaluates the most recently updated run in the run store. Mutually exclusive with file and loopId. | |
| loopId | No | MartinLoop run identifier from the run store. Mutually exclusive with file and latest. | |
| runsDir | No | Override the default run-store root directory. Optional. |
Output Schema
| Name | Required | Description |
|---|---|---|
| grade | Yes | Overall merge readiness grade derived from the six check dimensions. |
| score | Yes | Numeric evaluation score from 0–100. |
| checks | Yes | |
| loopId | Yes | Unique MartinLoop run identifier. |
| source | Yes | Resolved path to the loop-record source file. |
| summary | Yes | One-paragraph plain-English evaluation summary. |
| warnings | Yes | Non-blocking advisory warnings from the evaluation. |
| sourceKind | Yes | How the run was identified. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, and the description reinforces this by stating it 'reads saved run evidence and inspects local git signals' and 'does not modify state or contact GitHub.' It adds valuable context beyond the annotations by revealing that the tool operates on local signals only and does not reach out to GitHub, which is not inferable from structured fields alone.
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 dense but well-structured, front-loading the core purpose before usage guidance and exclusions. Every sentence earns its place: purpose, when to use, workflow placement, what not to use it for, and behavioral guarantees. It avoids fluff and provides substantial decision-relevant information in a compact form.
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 that the tool has an output schema and strong annotations, the description covers the remaining context an agent needs: the domain of operation (MartinLoop run grading), the six dimensions, merge-readiness interpretation, workflow ordering, alternatives, and side-effect guarantees. The optional parameter selection is already documented in the schema, and the output schema covers return-value expectations, so no critical context is missing.
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 parameters already have clear descriptions in the schema, including mutual exclusivity between file, latest, and loopId. The description itself does not add much parameter-level detail beyond saying it grades a run, but with complete schema coverage this is acceptable and does not require compensation.
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 specific verb and resource: 'Grade a MartinLoop run across six dimensions' and clearly states the output is 'a scored merge-readiness verdict.' It distinguishes the tool from siblings by explicitly listing what it is not for, such as retrieving raw verification output and reviewing PR bodies, so an agent can tell it apart without opening 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 explicit timing guidance ('Use after a governed run completes'), workflow placement ('Use before martin_pr_summary or martin_create_pr'), and two explicit negative use cases with named alternatives (martin_get_verification_results and martin_review_pr). This leaves little ambiguity about when to invoke this tool versus its siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
martin_get_attemptBRead-onlyIdempotent
Load one Martin attempt summary with artifact directory references for a canonical run.
| Name | Required | Description | Default |
|---|---|---|---|
| file | No | Path to a canonical loop-record.json file or run directory. | |
| loopId | No | Loop ID under the run store. | |
| runsDir | No | Optional runs-root override. | |
| attemptIndex | No | Attempt index to inspect. Defaults to the latest attempt. |
Output Schema
| Name | Required | Description |
|---|---|---|
| loop | Yes | |
| source | Yes | |
| attempt | Yes | |
| warnings | Yes | |
| sourceKind | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true, so the safety and idempotency are covered. The description adds that the tool returns a 'summary with artifact directory references', which is useful but does not elaborate on what those references are or how they are structured. Given the read-only and idempotent hints, the bar is lower, and the description provides some additional context, so a 3 is appropriate.
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 a single, concise sentence that front-loads the main purpose and includes key details (attempt summary, artifact directory references, canonical run). It is efficient and readable, with no unnecessary fluff.
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 tool has four parameters, an output schema exists, and annotations cover safety. The description provides a high-level purpose but does not clarify which parameters are required or how they interact (e.g., the relationship between file and loopId). Given the complexity and available schema, the description is sufficient for basic understanding but not fully complete for edge cases.
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%, meaning each parameter has a description in the schema. The tool's description adds limited value beyond the schema, mainly implying that the tool focuses on a single attempt and that attemptIndex defaults to the latest. It does not explain how the parameters interplay (e.g., file versus loopId). Baseline 3 is correct because the schema already documents parameters adequately.
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 action ('Load'), a specific resource ('one Martin attempt summary'), and the key scope ('for a canonical run'). It is clear what the tool does at a high level, but it does not explicitly differentiate from sibling tools like martin_get_run or martin_get_verification_results, which also appear to retrieve run-related data.
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 does not specify when to use this tool versus its siblings. For instance, it does not indicate that this tool is for inspecting a specific attempt within a run, while martin_get_run might be for whole-run details. There is no explicit guidance on which scenarios warrant this tool over alternatives, leaving the agent to infer from the name.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
martin_get_runBRead-onlyIdempotent
Load one Martin run and return its budget, cost, verification, artifact, and canonical path summary.
| Name | Required | Description | Default |
|---|---|---|---|
| file | No | Path to a canonical loop-record.json, legacy file, or run-store directory. | |
| latest | No | When true, loads the most recently updated loop record in the run store. | |
| loopId | No | Loop ID under the run store. | |
| runsDir | No | Optional runs-root override. |
Output Schema
| Name | Required | Description |
|---|---|---|
| cost | Yes | |
| loop | Yes | |
| budget | Yes | |
| source | Yes | |
| warnings | Yes | |
| artifacts | Yes | |
| inspection | Yes | |
| sourceKind | Yes | |
| verification | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and idempotentHint, covering safety and repetition behavior. The description adds that the tool returns a specific summary of fields, but it does not disclose any additional behavioral traits such as error behavior, how missing runs are handled, or constraints on parameter combinations. With annotations in place, this is an acceptable baseline.
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 a single, well-structured sentence that leads with the action and then lists the output components. Every word earns its place, and there is no redundant or vague phrasing.
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 that an output schema and readOnly/idempotent annotations exist, the description adequately summarizes what the tool does and returns. However, it does not clarify that exactly one of file, latest, or loopId should be used, or whether these are mutually exclusive. This is a minor gap for a read-only retrieval tool.
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 provides descriptions for all 4 parameters, so schema coverage is 100%. The tool description itself adds no parameter-level meaning, and the baseline of 3 is appropriate because the schema carries the burden.
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 ('Load') and names the resource ('one Martin run'), then enumerates the returned fields (budget, cost, verification, artifact, canonical path summary). This makes the core purpose clear, but it does not explicitly differentiate from siblings like martin_get_attempt or martin_get_verification_results, aside from the field listing.
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 no guidance on when to choose this tool over alternatives, nor does it mention parameter selection rules (e.g., file vs latest vs loopId). Agents are left to infer usage from the schema alone, and no exclusions or sibling comparisons are provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
martin_get_verification_resultsARead-onlyIdempotent
Load structured verification evidence for a MartinLoop run — verifier commands, pass/fail outcomes, and contradiction signals — from stored loop events and ledger entries. Use after a run completes to confirm whether automated verifiers passed before merging or promoting the result. Do not use to get a merge-readiness grade — use martin_eval for a scored grade with six check dimensions. Do not use for live run status — use martin_get_status instead. This tool only reads persisted run files and does not execute commands, modify state, or contact GitHub.
| Name | Required | Description | Default |
|---|---|---|---|
| file | No | Absolute or relative path to a loop-record.json file or run directory. Mutually exclusive with loopId. | |
| loopId | No | MartinLoop run identifier from the run store. Mutually exclusive with file. | |
| runsDir | No | Override the default run-store root directory. Optional. |
Output Schema
| Name | Required | Description |
|---|---|---|
| loop | Yes | |
| source | Yes | |
| warnings | Yes | |
| sourceKind | Yes | |
| verification | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Even though annotations already mark readOnly and non-destructive, the description adds behavior beyond annotations: it reads persisted run files, does not execute commands, modify state, or contact GitHub. This is valuable operational context and does not contradict annotations.
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, each earning its place: core purpose, when to use, exclusions, and behavioral boundary. The alternatives and constraints are front-loaded and the prose is tight.
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?
With a rich output schema, fully described parameters, and annotations, the description is nearly complete. It does not explicitly state that at least one of file or loopId should be supplied despite the schema listing none as required, which is a small but real invocation gap.
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 input schema already documents file, loopId, and runsDir with their meaning and mutual exclusivity. The description adds no further parameter-level detail, which is acceptable because the schema carries the burden.
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 names a specific verb (Load), resource (structured verification evidence for a MartinLoop run), and content (verifier commands, pass/fail outcomes, contradiction signals). It explicitly distinguishes itself from martin_eval and martin_get_status, so an agent can tell it apart without opening 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?
It gives explicit when-to-use ('after a run completes' to confirm verifiers passed before merging/promoting) and explicit when-not-to-use with named alternatives (martin_eval for merge-readiness, martin_get_status for live status). These exclusions leave no ambiguity about routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
martin_inspectBRead-onlyIdempotent
Summarise Martin Loop run records from a saved loop file or run-store directory.
| Name | Required | Description | Default |
|---|---|---|---|
| file | No | Optional path under the Martin runs root to a loop-record.json file, a legacy .jsonl file, or a run-store directory. | |
| runsDir | No | Optional runs-root override resolved under the default Martin runs root. |
Output Schema
| Name | Required | Description |
|---|---|---|
| source | Yes | |
| warnings | Yes | |
| latestRun | No | |
| loopCount | Yes | |
| portfolio | Yes | |
| inspection | Yes | |
| recentRuns | Yes | |
| statusBreakdown | Yes | |
| lifecycleBreakdown | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true, so the safety profile is covered. The description does not contradict those annotations, but it adds little beyond the verb 'Summarise'—no detail about what gets read, potential output size, or any other behavioral traits. This meets the baseline with annotations 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?
A single, front-loaded sentence with no filler: verb, object, and source are all in the first clause. It is scannable and every word 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 read-only tool with full annotations, an output schema, and two fully described optional parameters. The description adequately captures the operation and input source. The main gap is the lack of selection guidance among siblings, but that is less critical given how simple and safe the operation is.
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 schema fully documents both parameters. The description mentions 'saved loop file or run-store directory', which mirrors the file parameter's schema description and adds no new format, syntax, or precedence information. Baseline 3 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 a specific verb ('Summarise') and resource ('Martin Loop run records') plus the input source. It implies an aggregate, read-oriented operation distinct from siblings like martin_list_runs or martin_get_run, but does not explicitly differentiate itself by name, so it stops short of a perfect score.
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?
No guidance is given on when to use this tool versus the many sibling inspection tools (e.g., martin_get_run, martin_list_runs, martin_triage_runs, martin_run_dossier). The only implicit usage context is the accepted input types in the description, but there are no exclusions, conditions, or alternative routing hints.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
martin_list_runsARead-onlyIdempotent
List recent Martin runs from the run store with lightweight filters for status, lifecycle, engine metadata, and recency.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of runs to return. Defaults to 20. | |
| model | No | Filter by attempt model. | |
| status | No | Filter by loop status. | |
| runsDir | No | Optional runs-root override. | |
| adapterId | No | Filter by attempt adapter ID. | |
| updatedAfter | No | Optional ISO-8601 timestamp for recency filtering. | |
| lifecycleState | No | Filter by lifecycle state. |
Output Schema
| Name | Required | Description |
|---|---|---|
| source | Yes | |
| filters | Yes | |
| runsRoot | Yes | |
| warnings | Yes | |
| latestRun | No | |
| loopCount | Yes | |
| recentRuns | Yes | |
| statusBreakdown | Yes | |
| lifecycleBreakdown | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover readOnlyHint and idempotentHint, so the safety profile is established. The description adds scope context ('run store', 'recent', 'lightweight filters') but discloses little beyond what the annotations and parameter schemas already imply; there is no contradiction.
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?
A single, front-loaded sentence names the operation and then summarizes the filter dimensions without any filler. Every word contributes to the agent's understanding.
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?
With no required parameters, fully described schema entries, safe annotations, and an existing output schema, the description is largely sufficient for correct invocation. It lacks only explicit alternative routing to siblings, which is more of a usage-guidance gap than a completeness gap.
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 baseline is 3. The description adds a useful conceptual grouping—status, lifecycle, engine metadata, and recency—that helps an agent map the seven optional filter parameters into meaningful categories beyond the flat schema entries.
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 ('List') and resource ('Martin runs from the run store'), making it clear this is a listing operation distinct from run/get/inspect/status siblings. It does not explicitly contrast itself with martin_triage_runs, so it falls just short of full sibling differentiation.
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 implies usage: call this when you need a recent list of runs with lightweight filters, but it gives no explicit guidance about when to prefer a sibling like martin_get_run or martin_triage_runs. The context is clear enough to infer, but no exclusions or alternatives are stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
martin_logsARead-onlyIdempotent
Read recent MartinLoop events, ledger entries, and operator control receipts for a single run. Use to observe live or completed run activity, diagnose stuck or failed runs, or audit operator actions. Do not use to check run completion status — use martin_get_status instead. Do not use to retrieve verification evidence — use martin_get_verification_results instead. This tool only reads persisted run files and does not execute commands, modify state, or contact GitHub.
| Name | Required | Description | Default |
|---|---|---|---|
| file | No | Absolute or relative path to a loop-record.json file or run directory. Mutually exclusive with loopId and latest. | |
| limit | No | Maximum number of log entries to return, sorted by timestamp descending. Defaults to 20. | |
| latest | No | When true, loads the most recently updated run in the run store. Mutually exclusive with file and loopId. | |
| loopId | No | MartinLoop run identifier from the run store. Mutually exclusive with file and latest. | |
| runsDir | No | Override the default run-store root directory. Optional; defaults to the MartinLoop runs directory. |
Output Schema
| Name | Required | Description |
|---|---|---|
| live | Yes | |
| loopId | Yes | Unique MartinLoop run identifier. |
| source | Yes | Resolved path to the loop-record source file. |
| entries | Yes | Log entries sorted by timestamp descending, capped at limit. |
| logCount | Yes | Number of log entries returned after applying the limit. |
| sourceKind | Yes | How the run was identified: by file path, loop ID, latest flag, or runs directory. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false. The description adds operational context beyond those flags: it only reads persisted run files, does not execute commands, does not modify state, and does not contact GitHub. This network-isolation and no-execution detail is valuable behavioral context not present in annotations. No contradiction.
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 with zero waste: core purpose, use cases, two exclusions, and a behavioral guarantee. The verb+resource is front-loaded, 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?
Complete for a read-only observational tool. The description covers purpose, usage context, exclusions, and behavior; the output schema explains return values; and annotations cover the safety profile. Nothing an agent needs to invoke it correctly is missing.
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 all five parameters (file, limit, latest, loopId, runsDir) are fully documented in the schema. The description hints at the single-run scope that maps to the mutual-exclusion constraints, but it does not add parameter-level detail beyond the schema. Baseline 3 is appropriate when the schema carries the full burden.
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 ('Read'), a precise resource ('MartinLoop events, ledger entries, and operator control receipts'), and a scope ('for a single run'). It distinguishes itself from siblings by naming what it is not (martin_get_status, martin_get_verification_results), so an agent can select it confidently without opening 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?
Explicitly states when to use ('observe live or completed run activity, diagnose stuck or failed runs, or audit operator actions') and when not to use, naming two alternatives with the conditions that route elsewhere. Nothing is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
martin_pauseADestructive
Write a durable pause receipt for one canonical MartinLoop run. Provide exactly one selector: file, loopId, or latest; runsDir changes the run-store root, while reason and requestedBy add audit context. Use for a temporary hold before risky follow-up work. This records a request and does not kill a process; use martin_cancel to abandon work or martin_continue to resume.
| Name | Required | Description | Default |
|---|---|---|---|
| file | No | Path to one canonical run record or directory. Mutually exclusive with loopId and latest. | |
| latest | No | When true, targets the latest canonical run. Mutually exclusive with file and loopId. | |
| loopId | No | Canonical MartinLoop run identifier. Mutually exclusive with file and latest. | |
| reason | No | Optional non-empty reason recorded in the pause receipt. | |
| runsDir | No | Optional run-store root override used to resolve loopId or latest. | |
| requestedBy | No | Optional human or runtime identity label recorded for audit context. |
Output Schema
| Name | Required | Description |
|---|---|---|
| action | Yes | The control action that was recorded. |
| loopId | Yes | MartinLoop run identifier the control was applied to. |
| reason | No | Human-readable reason for the control, if provided. |
| controlId | Yes | Unique receipt ID for this control action. |
| requestedAt | Yes | ISO 8601 timestamp when the control was recorded. |
| requestedBy | No | Identity that requested the control, if provided. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds useful behavioral context beyond the annotations: it clarifies that the tool 'records a request' and 'does not kill a process,' which tempers the destructiveHint and prevents the agent from expecting process termination. It also conveys durability and audit-context behavior. It does not fully explain what side effects the destructiveHint refers to, but it does not contradict the annotations.
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 compact and front-loaded: purpose first, then the central selection constraint, then the usage context, then behavioral clarification and sibling routing. Every sentence contributes information; there is no filler or redundant repetition of the schema.
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?
With six parameters, a one-of selection requirement, an output schema, and many sibling tools, the description is sufficient for an agent to call the tool correctly. It covers the selection constraint, the effect of each parameter group, the appropriate use case, and how this tool differs from cancel/continue. The output schema removes the need to describe return values.
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 schema already documents each parameter. The description adds value by grouping parameters into functional roles: selectors (file/loopId/latest), run-store override (runsDir), and audit context (reason/requestedBy). It also communicates the critical 'exactly one selector' rule, which the schema only fragments through mutual-exclusion notes.
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 specific verb and resource: 'Write a durable pause receipt for one canonical MartinLoop run.' It immediately distinguishes this tool from cancel/continue by defining the artifact it produces, and the 'exactly one selector' constraint sharpens the operational intent. No ambiguity about what the tool is for.
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?
It explicitly states when to use the tool: 'for a temporary hold before risky follow-up work.' It also gives direct routing guidance by naming martin_cancel and martin_continue as alternatives for abandoning or resuming work, so an agent can choose between siblings without guessing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
martin_planARead-onlyIdempotent
Read-only planning step that turns an objective into bounded scope, verifier proposal, policy pack, and risk recommendation. Use for authorized software changes before preflight/run. Do not use to mutate files or replace the verifier. Next: call martin_preflight with the chosen scope, budget, and verifier.
| Name | Required | Description | Default |
|---|---|---|---|
| maxUsd | No | ||
| context | No | Optional extra issue or bug context. | |
| maxTokens | No | ||
| objective | Yes | The coding objective to plan. | |
| maxMinutes | No | ||
| policyPack | No | ||
| deniedPaths | No | ||
| maxCommands | No | ||
| allowedPaths | No | ||
| maxIterations | No | ||
| maxFilesChanged | No | ||
| verificationPlan | No | ||
| workingDirectory | No | Optional repo-root override resolved under the MCP workspace root. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint and idempotentHint. The description reinforces the read-only nature, adds what the tool produces, and clarifies that it does not mutate files or replace the verifier. This adds useful behavioral context beyond the annotations, though idempotence is not explicitly discussed.
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 the core purpose front-loaded and no filler. Every sentence adds useful information about scope, usage boundaries, or next steps.
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?
Despite having an output schema and safety annotations, the tool is complex with 13 input parameters. The description gives a good workflow overview but does not explain how to choose or set the many constraint parameters, which are mostly undocumented at 23% schema coverage. An agent would struggle to construct a well-formed planning request.
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 only 23%, so the description must compensate for the many undocumented parameters. It mentions 'objective', 'scope', 'budget', and 'verifier', but does not map these to specific fields such as maxUsd, verificationPlan, policyPack, allowedPaths, or deniedPaths. Most parameters remain unexplained in both schema and description.
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 identifies this as a read-only planning step that converts an objective into concrete artifacts: bounded scope, verifier proposal, policy pack, and risk recommendation. It also differentiates itself from preflight and run by explicitly positioning itself before those phases.
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 explicitly says when to use it ('before preflight/run' for 'authorized software changes'), when not to use it ('Do not use to mutate files or replace the verifier'), and what to do next ('call martin_preflight with the chosen scope, budget, and verifier'). This is exemplary guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
martin_preflightARead-onlyIdempotent
Read-only validation of the exact run contract before execution or spend. Use after planning and before martin_run to check engine, verifier, path scope, and budget. Do not use as execution or completion proof. Next: call martin_run if allowed, otherwise resolve the reported blocker.
| Name | Required | Description | Default |
|---|---|---|---|
| model | No | Model override passed to the CLI. | |
| engine | No | Which agent CLI would be used. Defaults to claude. | |
| maxUsd | No | Hard budget ceiling in USD. | |
| context | No | Optional issue context carried into the run contract. | |
| maxTokens | No | Maximum total tokens across all attempts. | |
| objective | Yes | The coding task to validate. | |
| projectId | No | ||
| maxMinutes | No | Estimated wall-clock minutes allowed for the run contract. | |
| policyPack | No | ||
| deniedPaths | No | Repo-relative path globs Martin must never modify. | |
| maxCommands | No | Estimated maximum commands allowed for the run contract. | |
| workspaceId | No | ||
| allowedPaths | No | Repo-relative path globs Martin may modify. | |
| maxIterations | No | Maximum number of loop attempts. | |
| maxFilesChanged | No | Estimated maximum files changed for the run contract. | |
| verificationPlan | No | Commands that must all exit 0 for completion. | |
| workingDirectory | No | Optional repo-root override resolved under the MCP workspace root. |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | |
| summary | Yes | |
| warnings | Yes | |
| execution | Yes | |
| readiness | Yes | |
| normalized | Yes | |
| receiptScope | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true, so the safety profile is covered. The description adds meaningful context beyond that by specifying exactly what the validation covers (engine, verifier, path scope, budget) and clarifying it is not a proof of execution or completion. This enriches the behavioral contract without contradicting the annotations.
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 sentences deliver the purpose, usage timing, checks performed, exclusion, and next step. Every clause earns its place, and the most critical info (purpose) is front-loaded. There is no fluff or redundancy.
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 preflight validation tool with 17 parameters, an output schema, and read-only/idempotent annotations, the description fully covers the needed context: what it validates, when to call it, what it is not, and what to do next. The output schema handles return specifics, so no additional return-value explanation is needed. An agent can invoke this tool correctly with no missing information.
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 82%, and most parameters have clear descriptions (e.g., engine enum, maxUsd, maxTokens, deniedPaths). The description does not add parameter-specific details beyond what the schema already provides. With high coverage, the description is not required to elaborate on each parameter, so a baseline score of 3 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 states a specific action ('Read-only validation of the exact run contract') on a specific resource (the run contract) and explicitly distinguishes it from execution by noting 'before execution or spend' and naming the sibling martin_run. It also makes clear it is not a proof of completion, removing any ambiguity about its role.
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 timing ('Use after planning and before martin_run'), states the checks it performs (engine, verifier, path scope, budget), and directs the next action ('call martin_run if allowed, otherwise resolve the reported blocker'). It also says 'Do not use as execution or completion proof,' which is a clear when-not-to-use condition. No exclusions or alternatives are left unstated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
martin_pr_summaryARead-onlyIdempotent
Generate a GitHub-ready pull-request title and Markdown body from a completed MartinLoop run dossier, including its verification grade and score. Use after a governed run completes when you need PR copy without creating the PR. Use martin_create_pr instead to actually open the PR on GitHub. Use martin_review_pr to evaluate an existing PR body against run evidence. Use martin_eval first if you need a merge-readiness grade before generating the PR body. This tool only reads saved run evidence and does not modify the repository or contact GitHub.
| Name | Required | Description | Default |
|---|---|---|---|
| file | No | Absolute or relative path to a loop-record.json file or run directory. Mutually exclusive with loopId and latest. | |
| format | No | Dossier rendering format. Defaults to github-pr for PR body generation. Use md for plain Markdown or json for structured output. | |
| latest | No | When true, generates the summary for the most recently updated run. Mutually exclusive with file and loopId. | |
| loopId | No | MartinLoop run identifier from the run store. Mutually exclusive with file and latest. | |
| runsDir | No | Override the default run-store root directory. Optional. |
Output Schema
| Name | Required | Description |
|---|---|---|
| body | Yes | GitHub-flavoured Markdown PR body containing the run dossier. |
| grade | Yes | Verification grade assigned to the run. |
| score | Yes | Numeric verification score from 0–100. |
| title | Yes | Suggested GitHub pull-request title. |
| loopId | Yes | MartinLoop run identifier used to generate the summary. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already carry readOnlyHint, idempotentHint, and destructiveHint, and the description adds useful concrete context: it only reads saved run evidence, does not modify the repository, and does not contact GitHub. This goes beyond the annotations by explicitly ruling out network side effects and repo mutations.
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 main purpose is front-loaded, the alternative routing is compressed into clear usage guidance, and the no-side-effect statement earns its place. Every sentence contributes to selection, invocation, or safety clarification.
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?
With an output schema present and strong annotations, the description covers when to use it, what it consumes, what it produces, and what it does not do. An agent has enough information to invoke it correctly without guessing.
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 schema already documents all five parameters, their mutual exclusivity, and format defaults. The description does not add parameter-level detail, but it does not need to since the schema covers it.
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?
Opens with a specific verb ('Generate') and names the concrete artifacts: a GitHub-ready PR title and Markdown body from a completed MartinLoop run dossier. It also distinguishes itself from martin_create_pr, martin_review_pr, and martin_eval, so an agent can tell which sibling to pick.
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?
Explicitly states when to use the tool: after a governed run completes when PR copy is needed without creating the PR. It also names the alternatives for actually opening the PR, reviewing an existing PR, and obtaining a merge-readiness grade first.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
martin_review_prARead-onlyIdempotent
Review a PR body or draft against the MartinLoop run dossier and evaluation evidence, and return a verdict with specific findings. Use when you have an existing PR body and want to check whether it accurately represents the governed run evidence. Supply prBody to review a specific body string; omit it to evaluate the auto-generated dossier body. Do not use to generate a PR body from scratch — use martin_pr_summary instead. Do not use to open or create a PR — use martin_create_pr instead. This tool only reads saved run evidence and does not modify the repository or contact GitHub.
| Name | Required | Description | Default |
|---|---|---|---|
| file | No | Absolute or relative path to a loop-record.json file or run directory. Mutually exclusive with loopId and latest. | |
| format | No | Dossier format used when generating the reference body for comparison. Defaults to github-pr. | |
| latest | No | When true, reviews against the most recently updated run. Mutually exclusive with file and loopId. | |
| loopId | No | MartinLoop run identifier from the run store. Mutually exclusive with file and latest. | |
| prBody | No | The PR body text to review. If omitted, the auto-generated dossier body is evaluated instead. | |
| runsDir | No | Override the default run-store root directory. Optional. |
Output Schema
| Name | Required | Description |
|---|---|---|
| loopId | Yes | MartinLoop run identifier the review was performed against. |
| summary | Yes | Plain-English review summary. |
| verdict | Yes | Merge verdict: approve_with_review means safe to merge with human review; needs_changes requires fixes; blocked means do not merge. |
| findings | Yes | Specific findings that informed the verdict. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false, and idempotentHint=true, so the safety profile is well-covered. The description adds valuable context beyond annotations: it clarifies the tool 'only reads saved run evidence and does not modify the repository or contact GitHub,' which is a specific behavioral guarantee not present in the annotations. It also explains the behavior of omitting prBody (evaluates the auto-generated body). This adds meaningful behavioral transparency without contradicting any annotations.
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 front-loaded with the core purpose, then provides usage guidance, exclusions, and a safety note in a logical flow. Every sentence serves a distinct function—purpose, when-to-use, exclusions, and behavioral transparency—with no filler or redundancy. It is appropriately sized for the tool's complexity.
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 the tool has an output schema and rich annotations, the description covers all essential aspects: it explains what the tool does, when to use it, when not to use it (with alternatives), the key parameter behavior (prBody omission), and its non-destructive nature. No critical information is missing for an agent to select and invoke this tool correctly.
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 100% description coverage, so each parameter's purpose is already well-documented. The description adds minimal additional parameter semantics: it reiterates the prBody behavior (supply to review a specific body; omit to evaluate the auto-generated one) which duplicates the schema's description. No other parameters receive additional explanation in the description, so it does not exceed the baseline expected for high schema coverage.
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 ('Review'), a specific resource ('PR body or draft against the MartinLoop run dossier and evaluation evidence'), and a specific output ('a verdict with specific findings'). It also differentiates itself from siblings by naming martin_pr_summary and martin_create_pr as alternatives for different tasks, making the tool's distinct role 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 explicitly states when to use this tool ('Use when you have an existing PR body and want to check whether it accurately represents the governed run evidence') and when not to use it, naming the exact alternative tools ('Do not use to generate a PR body from scratch — use martin_pr_summary instead. Do not use to open or create a PR — use martin_create_pr instead.'). This provides clear routing with no ambiguity.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
martin_runADestructive
Execute a governed MartinLoop coding run after MCP workflow admission is satisfied. Use when the user has authorized implementation, bug fixing, tests, or refactoring and doctor/estimate/plan/preflight receipts match this task. Do not use for question-only diagnosis or when policy, budget, credentials, or scope still need consent. Next: read martin_dossier and verifier evidence.
| Name | Required | Description | Default |
|---|---|---|---|
| model | No | Optional model override passed to the CLI. | |
| engine | No | Which agent CLI to use. Defaults to claude. | |
| maxUsd | No | Hard budget ceiling in USD. | |
| maxTokens | No | Maximum total tokens across all attempts. | |
| objective | Yes | The coding task to complete. Be specific about what needs to change. | |
| projectId | No | Project identifier for telemetry. | |
| deniedPaths | No | Repo-relative path globs Martin must never modify. | |
| workspaceId | No | Workspace identifier for telemetry. | |
| allowedPaths | No | Repo-relative path globs Martin may modify. | |
| maxIterations | No | Maximum number of loop attempts. | |
| verifyTimeoutMs | No | Hard timeout for each verifier command in milliseconds. | |
| verificationPlan | No | Commands that must all exit 0 for the task to be considered complete. | |
| workingDirectory | No | Optional repo-root override resolved under the MCP workspace root. Must stay within that safe root. | |
| providerExecutionTimeoutMs | No | Hard timeout for each provider coding process in milliseconds. |
Output Schema
| Name | Required | Description |
|---|---|---|
| budget | Yes | |
| engine | Yes | |
| loopId | Yes | |
| reason | Yes | |
| status | Yes | |
| costUsd | Yes | |
| attempts | Yes | |
| pressure | Yes | |
| inspection | Yes | |
| shouldStop | Yes | |
| lifecycleState | Yes | |
| remainingTokens | No | |
| workingDirectory | Yes | |
| remainingBudgetUsd | Yes | |
| verificationPassed | Yes | |
| remainingIterations | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, openWorldHint=false, idempotentHint=false. The description adds context about governance and prerequisites ('governed', 'after MCP workflow admission is satisfied') but does not disclose additional behavioral traits such as file modification scope, side effects, or failure modes beyond what annotations imply. It neither contradicts nor enriches beyond the annotations significantly, so a 3 is appropriate.
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 three sentences, front-loaded with the purpose, then usage conditions, then next steps. Every sentence earns its place; there is no redundancy or filler. It is concise and well-structured.
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 the 14-parameter schema (fully documented) and presence of an output schema, the description covers the essential operational context: when to invoke, prerequisites, and next steps. It lacks explicit detail on the execution behavior (e.g., that it modifies files and runs verification), but this is implied by 'coding run' and the verificationPlan parameter. Minor gap, so 4.
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 all 14 parameters are fully documented in the input schema. The description does not add any parameter-specific meaning or clarify usage of individual parameters. Since the schema carries the full load, the description adds no value here, justifying 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 clearly states the action ('Execute a governed MartinLoop coding run') and the resource (MartinLoop coding run). It specifies the verb and resource, and the context of 'after MCP workflow admission is satisfied' adds specificity. It differentiates from question-only diagnosis, though it doesn't name specific sibling tools. This is clear and near-excellent, but lacking explicit sibling distinction.
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?
Explicitly states when to use: 'when the user has authorized implementation, bug fixing, tests, or refactoring and doctor/estimate/plan/preflight receipts match this task.' And when not to use: 'Do not use for question-only diagnosis or when policy, budget, credentials, or scope still need consent.' Also provides next steps. This is exemplary usage guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
martin_run_dossierARead-onlyIdempotent
Read the full structured execution dossier for one MartinLoop run, including attempts, events, artifacts, verification, integrity, cost, and related discovery surfaces. Provide exactly one selector: file, loopId, or latest; runsDir changes the run-store root. Use for comprehensive evidence review. Do not use for a compact state check; use martin_get_run, or use martin_dossier when formatted sharing output is required.
| Name | Required | Description | Default |
|---|---|---|---|
| file | No | Path to a canonical loop-record.json, legacy file, or run-store directory. Mutually exclusive with loopId and latest. | |
| latest | No | When true, loads the most recently updated loop record. Mutually exclusive with file and loopId. | |
| loopId | No | Loop ID under the run store. Mutually exclusive with file and latest. | |
| runsDir | No | Optional run-store root override used to resolve loopId or latest. |
Output Schema
| Name | Required | Description |
|---|---|---|
| cost | Yes | |
| loop | Yes | |
| budget | Yes | |
| source | Yes | |
| related | Yes | |
| attempts | Yes | |
| warnings | Yes | |
| artifacts | Yes | |
| inspection | Yes | |
| sourceKind | Yes | |
| recentEvents | Yes | |
| verification | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true, so the description carries a lower burden. It adds some context about the tool reading a comprehensive dossier, but no additional behavioral traits such as return format or side effects. This is adequate but not rich.
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 three sentences with no filler: the main purpose, the selector constraint, and the usage routing. It is front-loaded with the core action 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?
For a read-only tool with annotations covering safety and an output schema covering return values, the description is complete. It explains the selectors, the run-store root override, and routes to the correct sibling when the use case differs. An agent has everything needed to invoke it correctly.
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 schema already documents each parameter and their mutual exclusivity. The description reiterates the selector concept and runsDir override but adds no information beyond what the schema provides. Baseline 3 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 opens with a specific verb and resource: 'Read the full structured execution dossier for one MartinLoop run' and enumerates the contents (attempts, events, artifacts, verification, integrity, cost, discovery surfaces). It also names siblings it is not ('use martin_get_run' and 'use martin_dossier'), clearly differentiating this tool from alternatives.
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?
Explicit when-to-use and when-not-to-use guidance is provided: 'Use for comprehensive evidence review' and 'Do not use for a compact state check; use martin_get_run, or use martin_dossier when formatted sharing output is required.' This gives the agent a decision rule, not just context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
martin_statusARead-onlyIdempotent
Read the current budget, cost, remaining limits, and stop pressure for one MartinLoop run. Provide exactly one selector: loopJson for an inline record, file for a saved record, loopId for a run-store ID, or latest for the newest run; runsDir only changes the run-store root. Use for a compact budget check. Do not use for full events or artifacts; use martin_get_run or martin_run_dossier instead.
| Name | Required | Description | Default |
|---|---|---|---|
| file | No | Path under the Martin runs root to a loop-record.json file, a legacy .jsonl file, or a run-store directory. Mutually exclusive with loopJson, loopId, and latest. | |
| latest | No | When true, loads the most recently updated loop record. Mutually exclusive with loopJson, file, and loopId. | |
| loopId | No | Loop ID resolved as <runsDir>/<loopId>/loop-record.json. Mutually exclusive with loopJson, file, and latest. | |
| runsDir | No | Optional runs-root override resolved under the default Martin runs root. | |
| loopJson | No | JSON-serialized LoopRecord. |
Output Schema
| Name | Required | Description |
|---|---|---|
| budget | Yes | |
| loopId | Yes | |
| source | Yes | |
| status | Yes | |
| costUsd | Yes | |
| attempts | Yes | |
| pressure | Yes | |
| avoidedUsd | Yes | |
| inspection | Yes | |
| shouldStop | Yes | |
| lifecycleState | Yes | |
| remainingTokens | No | |
| remainingBudgetUsd | Yes | |
| remainingIterations | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare readOnlyHint and idempotentHint, so the safety profile is covered. The description adds a useful boundary beyond that: it returns only a compact budget snapshot for one run and not full events/artifacts, and clarifies that runsDir only changes the run-store root. No behavioral contradiction with the annotations.
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: purpose first, selector rule second, usage boundary third. Every sentence earns its place and the most important operational constraint ('exactly one selector') is stated prominently.
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 the output schema, annotations, and fully covered parameters, the description covers the remaining operational rules: exactly one selector, what each selector points to, runsDir's scoped effect, and when to route to siblings. There is no critical missing information an agent would need to invoke it correctly.
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, but the description adds semantic meaning by mapping each selector to its intended source: 'inline record' for loopJson, 'saved record' for file, 'run-store ID' for loopId, and 'newest run' for latest. It also explains the non-selector role of runsDir, which helps an agent avoid treating it as a fifth mutually exclusive option.
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 names a specific verb ('Read') and resource ('current budget, cost, remaining limits, and stop pressure for one MartinLoop run'), and proactively distinguishes from siblings by saying it is not for full events/artifacts (martin_get_run or martin_run_dossier). It is immediately clear what this tool does and what it is not.
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?
It gives a compact use case ('Use for a compact budget check') and explicit exclusions with named alternatives ('Do not use for full events or artifacts; use martin_get_run or martin_run_dossier instead'). The selector rule ('Provide exactly one selector...') also tells the agent how to choose an input path.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
martin_triage_runsARead-onlyIdempotent
Read-only prioritization of saved Martin runs that need attention. Use when the user says a prior attempt failed, asks what to fix next, or resumes an interrupted session. Do not use for a brand-new objective with no relevant run history. Next: inspect the selected run or dossier before retrying.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of runs to triage. Defaults to 20. | |
| model | No | Filter by attempt model. | |
| status | No | Filter by loop status. | |
| runsDir | No | Optional runs-root override. | |
| adapterId | No | Filter by attempt adapter ID. | |
| updatedAfter | No | Optional ISO-8601 timestamp for recency filtering. | |
| includeHealthy | No | When true, include healthy runs instead of only attention-worthy findings. | |
| lifecycleState | No | Filter by lifecycle state. |
Output Schema
| Name | Required | Description |
|---|---|---|
| source | Yes | |
| filters | Yes | |
| findings | Yes | |
| runsRoot | Yes | |
| warnings | Yes | |
| findingCount | Yes | |
| evaluatedRuns | Yes | |
| severityBreakdown | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description labels the operation 'read-only', which aligns with readOnlyHint and idempotentHint, and adds non-obvious selection behavior by saying only runs 'that need attention' are prioritized. It also provides the workflow cue to inspect the selected run or dossier before retrying, which is useful context beyond the annotations.
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 short sentences cover purpose, usage triggers, and next step with no filler. The key selection signal, that this is for attention-worthy runs and not brand-new objectives, 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?
With readOnly and idempotent annotations, a fully described 8-parameter schema, and an output schema present, the description supplies what structured fields cannot: selection rationale and follow-up workflow. It is complete enough for an agent to decide when to invoke and what to do next.
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% and each parameter has a meaningful description, including default behavior for limit and the includeHealthy filter. The tool description itself adds no parameter-level detail, which is acceptable given the high-coverage baseline.
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 resource ('saved Martin runs'), the action ('prioritization'), and the filtering criterion ('that need attention'). This clearly positions it against siblings like martin_list_runs or martin_status, which imply plain listing or status checks rather than attention-based triage.
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?
It gives concrete positive triggers ('prior attempt failed', 'asks what to fix next', 'resumes an interrupted session') and an explicit exclusion ('Do not use for a brand-new objective with no relevant run history'). It also names the next action, so an agent knows both when to call and what to do afterward.
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.
14 tool updates
v0.6.6- Changed
martin_cancel1 field changed- removed
Input schema / oneOfRemoved value: -[ - { - "required": [ - "file" - ] - }, - { - "required": [ - "loopId" - ] - }, - { - "required": [ - "latest" - ] - } -]
- Changed
martin_continue1 field changed- removed
Input schema / oneOfRemoved value: -[ - { - "required": [ - "file" - ] - }, - { - "required": [ - "loopId" - ] - }, - { - "required": [ - "latest" - ] - } -]
- Changed
martin_create_pr1 field changed- removed
Input schema / oneOfRemoved value: -[ - { - "required": [ - "file" - ] - }, - { - "required": [ - "loopId" - ] - }, - { - "required": [ - "latest" - ] - } -]
- Changed
martin_dossier1 field changed- removed
Input schema / oneOfRemoved value: -[ - { - "required": [ - "file" - ] - }, - { - "required": [ - "loopId" - ] - }, - { - "required": [ - "latest" - ] - } -]
- Changed
martin_eval1 field changed- removed
Input schema / oneOfRemoved value: -[ - { - "required": [ - "file" - ] - }, - { - "required": [ - "loopId" - ] - }, - { - "required": [ - "latest" - ] - } -]
- Changed
martin_get_attempt1 field changed- removed
Input schema / oneOfRemoved value: -[ - { - "required": [ - "file" - ] - }, - { - "required": [ - "loopId" - ] - } -]
- Changed
martin_get_run1 field changed- removed
Input schema / oneOfRemoved value: -[ - { - "required": [ - "file" - ] - }, - { - "required": [ - "loopId" - ] - }, - { - "required": [ - "latest" - ] - } -]
- Changed
martin_get_verification_results1 field changed- removed
Input schema / oneOfRemoved value: -[ - { - "required": [ - "file" - ] - }, - { - "required": [ - "loopId" - ] - } -]
- Changed
martin_logs1 field changed- removed
Input schema / oneOfRemoved value: -[ - { - "required": [ - "file" - ] - }, - { - "required": [ - "loopId" - ] - }, - { - "required": [ - "latest" - ] - } -]
- Changed
martin_pause1 field changed- removed
Input schema / oneOfRemoved value: -[ - { - "required": [ - "file" - ] - }, - { - "required": [ - "loopId" - ] - }, - { - "required": [ - "latest" - ] - } -]
- Changed
martin_pr_summary1 field changed- removed
Input schema / oneOfRemoved value: -[ - { - "required": [ - "file" - ] - }, - { - "required": [ - "loopId" - ] - }, - { - "required": [ - "latest" - ] - } -]
- Changed
martin_review_pr1 field changed- removed
Input schema / oneOfRemoved value: -[ - { - "required": [ - "file" - ] - }, - { - "required": [ - "loopId" - ] - }, - { - "required": [ - "latest" - ] - } -]
- Changed
martin_run_dossier1 field changed- removed
Input schema / oneOfRemoved value: -[ - { - "required": [ - "file" - ] - }, - { - "required": [ - "loopId" - ] - }, - { - "required": [ - "latest" - ] - } -]
- Changed
martin_status1 field changed- removed
Input schema / oneOfRemoved value: -[ - { - "required": [ - "loopJson" - ] - }, - { - "required": [ - "file" - ] - }, - { - "required": [ - "loopId" - ] - }, - { - "required": [ - "latest" - ] - } -]
11 tool updates
v0.6.5- Changed
martin_doctor1 field changed- added
Output schema / properties / runStore / properties / latestRun / properties / activeAttemptIdAdded value: +{ + "description": "ID of the currently active attempt, when a run is in progress.", + "type": "string" +}
- Changed
martin_dossier1 field changed- added
Output schema / properties / loop / properties / activeAttemptIdAdded value: +{ + "description": "ID of the currently active attempt, when a run is in progress.", + "type": "string" +}
- Changed
martin_get_attempt1 field changed- added
Output schema / properties / loop / properties / activeAttemptIdAdded value: +{ + "description": "ID of the currently active attempt, when a run is in progress.", + "type": "string" +}
- Changed
martin_get_run1 field changed- added
Output schema / properties / loop / properties / activeAttemptIdAdded value: +{ + "description": "ID of the currently active attempt, when a run is in progress.", + "type": "string" +}
- Changed
martin_get_verification_results1 field changed- added
Output schema / properties / loop / properties / activeAttemptIdAdded value: +{ + "description": "ID of the currently active attempt, when a run is in progress.", + "type": "string" +}
- Changed
martin_inspect2 fields changed- added
Output schema / properties / latestRun / properties / activeAttemptIdAdded value: +{ + "description": "ID of the currently active attempt, when a run is in progress.", + "type": "string" +} - added
Output schema / properties / recentRuns / items / properties / activeAttemptIdAdded value: +{ + "description": "ID of the currently active attempt, when a run is in progress.", + "type": "string" +}
- Changed
martin_list_runs2 fields changed- added
Output schema / properties / latestRun / properties / activeAttemptIdAdded value: +{ + "description": "ID of the currently active attempt, when a run is in progress.", + "type": "string" +} - added
Output schema / properties / recentRuns / items / properties / activeAttemptIdAdded value: +{ + "description": "ID of the currently active attempt, when a run is in progress.", + "type": "string" +}
- Changed
martin_run1 field changed- added
Output schema / properties / inspection / properties / loop / properties / activeAttemptIdAdded value: +{ + "description": "ID of the currently active attempt, when a run is in progress.", + "type": "string" +}
- Changed
martin_run_dossier1 field changed- added
Output schema / properties / loop / properties / activeAttemptIdAdded value: +{ + "description": "ID of the currently active attempt, when a run is in progress.", + "type": "string" +}
- Changed
martin_status1 field changed- added
Output schema / properties / inspection / properties / loop / properties / activeAttemptIdAdded value: +{ + "description": "ID of the currently active attempt, when a run is in progress.", + "type": "string" +}
- Changed
martin_triage_runs1 field changed- added
Output schema / properties / findings / items / properties / loop / properties / activeAttemptIdAdded value: +{ + "description": "ID of the currently active attempt, when a run is in progress.", + "type": "string" +}
6 tool updates
v0.5.9- Changed
martin_arcade_status2 fields changed- added
Input schema / properties / loopId / descriptionAdded value: +"Optional MartinLoop run identifier. Omit it to read the latest persisted run." - changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": false, + "properties": { + "attempts": { + "description": "Number of recorded attempts.", + "minimum": 0, + "type": "integer" + }, + "budget": { + "additionalProperties": false, + "properties": { + "maxUsd": { + "type": "number" + }, + "remainingUsd": { + "type": "number" + } + }, + "required": [ + "maxUsd", + "remainingUsd" + ], + "type": "object" + }, + "completed": { + "description": "Whether the run is outside an active lifecycle state.", + "type": "boolean" + }, + "cost": { + "additionalProperties": false, + "properties": { + "actualUsd": { + "type": "number" + }, + "provenance": { + "type": "string" + } + }, + "required": [ + "actualUsd", + "provenance" + ], + "type": "object" + }, + "displayOutcome": { + "anyOf": [ + { + "enum": [ + "VERIFIED", + "STOPPED", + "NEEDS REVIEW" + ], + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Terminal verified-handoff outcome, or null while the run is active." + }, + "lifecycleState": { + "description": "Current persisted lifecycle state.", + "type": "string" + }, + "loopId": { + "description": "Run identifier represented by this Arcade snapshot.", + "type": "string" + }, + "receiptIntegrity": { + "additionalProperties": true, + "description": "Persisted receipt-integrity verdict.", + "type": "object" + }, + "verification": { + "additionalProperties": true, + "description": "Persisted verifier evidence summary.", + "type": "object" + }, + "warnings": { + "description": "Evidence or interpretation warnings for the Arcade view.", + "items": { + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "loopId", + "lifecycleState", + "completed", + "displayOutcome", + "verification", + "receiptIntegrity", + "attempts", + "cost", + "budget", + "warnings" + ], + "type": "object" +}
- Changed
martin_cancel6 fields changed- added
Input schema / properties / file / descriptionAdded value: +"Path to one canonical run record or directory. Mutually exclusive with loopId and latest." - added
Input schema / properties / latest / descriptionAdded value: +"When true, targets the latest canonical run. Mutually exclusive with file and loopId." - added
Input schema / properties / loopId / descriptionAdded value: +"Canonical MartinLoop run identifier. Mutually exclusive with file and latest." - added
Input schema / properties / reason / descriptionAdded value: +"Optional non-empty reason recorded in the cancellation receipt." - added
Input schema / properties / requestedBy / descriptionAdded value: +"Optional human or runtime identity label recorded for audit context." - added
Input schema / properties / runsDir / descriptionAdded value: +"Optional run-store root override used to resolve loopId or latest."
- Changed
martin_dossier5 fields changed- added
Input schema / properties / file / descriptionAdded value: +"Path to one run record or directory. Mutually exclusive with loopId and latest." - added
Input schema / properties / format / descriptionAdded value: +"Output format. Defaults to json." - added
Input schema / properties / latest / descriptionAdded value: +"When true, loads the latest run. Mutually exclusive with file and loopId." - added
Input schema / properties / loopId / descriptionAdded value: +"MartinLoop run identifier. Mutually exclusive with file and latest." - added
Input schema / properties / runsDir / descriptionAdded value: +"Optional run-store root override used to resolve loopId or latest."
- Changed
martin_pause6 fields changed- added
Input schema / properties / file / descriptionAdded value: +"Path to one canonical run record or directory. Mutually exclusive with loopId and latest." - added
Input schema / properties / latest / descriptionAdded value: +"When true, targets the latest canonical run. Mutually exclusive with file and loopId." - added
Input schema / properties / loopId / descriptionAdded value: +"Canonical MartinLoop run identifier. Mutually exclusive with file and latest." - added
Input schema / properties / reason / descriptionAdded value: +"Optional non-empty reason recorded in the pause receipt." - added
Input schema / properties / requestedBy / descriptionAdded value: +"Optional human or runtime identity label recorded for audit context." - added
Input schema / properties / runsDir / descriptionAdded value: +"Optional run-store root override used to resolve loopId or latest."
- Changed
martin_run_dossier4 fields changed- changed
Input schema / properties / file / descriptionPrevious value: -"Path to a canonical loop-record.json, legacy file, or run-store directory."New value: +"Path to a canonical loop-record.json, legacy file, or run-store directory. Mutually exclusive with loopId and latest." - changed
Input schema / properties / latest / descriptionPrevious value: -"When true, loads the most recently updated loop record in the run store."New value: +"When true, loads the most recently updated loop record. Mutually exclusive with file and loopId." - changed
Input schema / properties / loopId / descriptionPrevious value: -"Loop ID under the run store."New value: +"Loop ID under the run store. Mutually exclusive with file and latest." - changed
Input schema / properties / runsDir / descriptionPrevious value: -"Optional runs-root override."New value: +"Optional run-store root override used to resolve loopId or latest."
- Changed
martin_status3 fields changed- changed
Input schema / properties / file / descriptionPrevious value: -"Optional path under the Martin runs root to a loop-record.json file, a legacy .jsonl file, or a run-store directory."New value: +"Path under the Martin runs root to a loop-record.json file, a legacy .jsonl file, or a run-store directory. Mutually exclusive with loopJson, loopId, and latest." - changed
Input schema / properties / latest / descriptionPrevious value: -"When true, loads the most recently updated loop record in the runs directory."New value: +"When true, loads the most recently updated loop record. Mutually exclusive with loopJson, file, and loopId." - changed
Input schema / properties / loopId / descriptionPrevious value: -"Loop ID resolved as <runsDir>/<loopId>/loop-record.json."New value: +"Loop ID resolved as <runsDir>/<loopId>/loop-record.json. Mutually exclusive with loopJson, file, and latest."
20 tool updates
v0.5.6- Changed
martin_cancel3 fields changed- changed
Output schema / additionalPropertiesPrevious value: -trueNew value: +false - added
Output schema / propertiesAdded value: +{ + "action": { + "description": "The control action that was recorded.", + "enum": [ + "pause", + "cancel", + "continue" + ], + "type": "string" + }, + "controlId": { + "description": "Unique receipt ID for this control action.", + "type": "string" + }, + "loopId": { + "description": "MartinLoop run identifier the control was applied to.", + "type": "string" + }, + "reason": { + "description": "Human-readable reason for the control, if provided.", + "type": "string" + }, + "requestedAt": { + "description": "ISO 8601 timestamp when the control was recorded.", + "type": "string" + }, + "requestedBy": { + "description": "Identity that requested the control, if provided.", + "type": "string" + } +} - added
Output schema / requiredAdded value: +[ + "loopId", + "action", + "controlId", + "requestedAt" +]
- Changed
martin_continue3 fields changed- changed
Output schema / additionalPropertiesPrevious value: -trueNew value: +false - added
Output schema / propertiesAdded value: +{ + "action": { + "description": "The control action that was recorded.", + "enum": [ + "pause", + "cancel", + "continue" + ], + "type": "string" + }, + "controlId": { + "description": "Unique receipt ID for this control action.", + "type": "string" + }, + "loopId": { + "description": "MartinLoop run identifier the control was applied to.", + "type": "string" + }, + "reason": { + "description": "Human-readable reason for the control, if provided.", + "type": "string" + }, + "requestedAt": { + "description": "ISO 8601 timestamp when the control was recorded.", + "type": "string" + }, + "requestedBy": { + "description": "Identity that requested the control, if provided.", + "type": "string" + } +} - added
Output schema / requiredAdded value: +[ + "loopId", + "action", + "controlId", + "requestedAt" +]
- Changed
martin_create_pr3 fields changed- changed
Output schema / additionalPropertiesPrevious value: -trueNew value: +false - added
Output schema / propertiesAdded value: +{ + "body": { + "description": "GitHub-flavoured Markdown PR body containing the run dossier.", + "type": "string" + }, + "grade": { + "description": "Verification grade assigned to the run.", + "enum": [ + "mergeable", + "mergeable_with_review", + "needs_review", + "blocked", + "insufficient_evidence" + ], + "type": "string" + }, + "loopId": { + "description": "MartinLoop run identifier used to generate the summary.", + "type": "string" + }, + "score": { + "description": "Numeric verification score from 0–100.", + "type": "number" + }, + "title": { + "description": "Suggested GitHub pull-request title.", + "type": "string" + } +} - added
Output schema / requiredAdded value: +[ + "loopId", + "title", + "body", + "grade", + "score" +]
- Changed
martin_doctor1 field changed- changed
Output schema / properties / runStore / properties / latestRun / requiredPrevious value: -[ - "loopId", - "title", - "objective", - "status", - "lifecycleState", - "attempts", - "costUsd", - "avoidedUsd", - "pressure", - "shouldStop", - "remainingBudgetUsd", - "remainingIterations", - "remainingTokens" -]New value: +[ + "loopId", + "title", + "objective", + "status", + "lifecycleState", + "attempts", + "costUsd", + "avoidedUsd", + "pressure", + "shouldStop", + "remainingBudgetUsd", + "remainingIterations" +]
- Changed
martin_dossier2 fields changed- changed
Output schema / properties / budget / requiredPrevious value: -[ - "maxUsd", - "softLimitUsd", - "maxIterations", - "maxTokens" -]New value: +[ + "maxUsd", + "softLimitUsd", + "maxIterations" +] - changed
Output schema / properties / loop / requiredPrevious value: -[ - "loopId", - "title", - "objective", - "status", - "lifecycleState", - "attempts", - "costUsd", - "avoidedUsd", - "pressure", - "shouldStop", - "remainingBudgetUsd", - "remainingIterations", - "remainingTokens" -]New value: +[ + "loopId", + "title", + "objective", + "status", + "lifecycleState", + "attempts", + "costUsd", + "avoidedUsd", + "pressure", + "shouldStop", + "remainingBudgetUsd", + "remainingIterations" +]
- Changed
martin_eval7 fields changed- added
Input schema / properties / file / descriptionAdded value: +"Absolute or relative path to a loop-record.json file or run directory. Mutually exclusive with loopId and latest." - added
Input schema / properties / latest / descriptionAdded value: +"When true, evaluates the most recently updated run in the run store. Mutually exclusive with file and loopId." - added
Input schema / properties / loopId / descriptionAdded value: +"MartinLoop run identifier from the run store. Mutually exclusive with file and latest." - added
Input schema / properties / runsDir / descriptionAdded value: +"Override the default run-store root directory. Optional." - changed
Output schema / additionalPropertiesPrevious value: -trueNew value: +false - added
Output schema / propertiesAdded value: +{ + "checks": { + "additionalProperties": false, + "properties": { + "diffDiscipline": { + "description": "Whether file-scope discipline was maintained.", + "enum": [ + "passed", + "warning", + "failed" + ], + "type": "string" + }, + "regressionRisk": { + "description": "Whether regression risk signals were detected.", + "enum": [ + "passed", + "warning", + "failed" + ], + "type": "string" + }, + "reviewability": { + "description": "Whether the PR body and dossier are reviewer-ready.", + "enum": [ + "passed", + "warning", + "failed" + ], + "type": "string" + }, + "securityRisk": { + "description": "Whether security risk signals were detected.", + "enum": [ + "passed", + "warning", + "failed" + ], + "type": "string" + }, + "taskCompletion": { + "description": "Whether the run reached a completed status.", + "enum": [ + "passed", + "warning", + "failed" + ], + "type": "string" + }, + "verifier": { + "description": "Whether automated verifiers passed.", + "enum": [ + "passed", + "warning", + "failed" + ], + "type": "string" + } + }, + "required": [ + "taskCompletion", + "verifier", + "diffDiscipline", + "regressionRisk", + "securityRisk", + "reviewability" + ], + "type": "object" + }, + "grade": { + "description": "Overall merge readiness grade derived from the six check dimensions.", + "enum": [ + "mergeable", + "mergeable_with_review", + "needs_review", + "blocked", + "insufficient_evidence" + ], + "type": "string" + }, + "loopId": { + "description": "Unique MartinLoop run identifier.", + "type": "string" + }, + "score": { + "description": "Numeric evaluation score from 0–100.", + "type": "number" + }, + "source": { + "description": "Resolved path to the loop-record source file.", + "type": "string" + }, + "sourceKind": { + "description": "How the run was identified.", + "enum": [ + "file", + "loop_id", + "latest", + "runs_root" + ], + "type": "string" + }, + "summary": { + "description": "One-paragraph plain-English evaluation summary.", + "type": "string" + }, + "warnings": { + "description": "Non-blocking advisory warnings from the evaluation.", + "items": { + "type": "string" + }, + "type": "array" + } +} - added
Output schema / requiredAdded value: +[ + "source", + "sourceKind", + "loopId", + "score", + "grade", + "checks", + "warnings", + "summary" +]
- Changed
martin_get_attempt1 field changed- changed
Output schema / properties / loop / requiredPrevious value: -[ - "loopId", - "title", - "objective", - "status", - "lifecycleState", - "attempts", - "costUsd", - "avoidedUsd", - "pressure", - "shouldStop", - "remainingBudgetUsd", - "remainingIterations", - "remainingTokens" -]New value: +[ + "loopId", + "title", + "objective", + "status", + "lifecycleState", + "attempts", + "costUsd", + "avoidedUsd", + "pressure", + "shouldStop", + "remainingBudgetUsd", + "remainingIterations" +]
- Changed
martin_get_run2 fields changed- changed
Output schema / properties / budget / requiredPrevious value: -[ - "maxUsd", - "softLimitUsd", - "maxIterations", - "maxTokens" -]New value: +[ + "maxUsd", + "softLimitUsd", + "maxIterations" +] - changed
Output schema / properties / loop / requiredPrevious value: -[ - "loopId", - "title", - "objective", - "status", - "lifecycleState", - "attempts", - "costUsd", - "avoidedUsd", - "pressure", - "shouldStop", - "remainingBudgetUsd", - "remainingIterations", - "remainingTokens" -]New value: +[ + "loopId", + "title", + "objective", + "status", + "lifecycleState", + "attempts", + "costUsd", + "avoidedUsd", + "pressure", + "shouldStop", + "remainingBudgetUsd", + "remainingIterations" +]
- Changed
martin_get_verification_results4 fields changed- changed
Input schema / properties / file / descriptionPrevious value: -"Path to a canonical loop-record.json file or run directory."New value: +"Absolute or relative path to a loop-record.json file or run directory. Mutually exclusive with loopId." - changed
Input schema / properties / loopId / descriptionPrevious value: -"Loop ID under the run store."New value: +"MartinLoop run identifier from the run store. Mutually exclusive with file." - changed
Input schema / properties / runsDir / descriptionPrevious value: -"Optional runs-root override."New value: +"Override the default run-store root directory. Optional." - changed
Output schema / properties / loop / requiredPrevious value: -[ - "loopId", - "title", - "objective", - "status", - "lifecycleState", - "attempts", - "costUsd", - "avoidedUsd", - "pressure", - "shouldStop", - "remainingBudgetUsd", - "remainingIterations", - "remainingTokens" -]New value: +[ + "loopId", + "title", + "objective", + "status", + "lifecycleState", + "attempts", + "costUsd", + "avoidedUsd", + "pressure", + "shouldStop", + "remainingBudgetUsd", + "remainingIterations" +]
- Changed
martin_inspect2 fields changed- changed
Output schema / properties / latestRun / requiredPrevious value: -[ - "loopId", - "title", - "objective", - "status", - "lifecycleState", - "attempts", - "costUsd", - "avoidedUsd", - "pressure", - "shouldStop", - "remainingBudgetUsd", - "remainingIterations", - "remainingTokens" -]New value: +[ + "loopId", + "title", + "objective", + "status", + "lifecycleState", + "attempts", + "costUsd", + "avoidedUsd", + "pressure", + "shouldStop", + "remainingBudgetUsd", + "remainingIterations" +] - changed
Output schema / properties / recentRuns / items / requiredPrevious value: -[ - "loopId", - "title", - "objective", - "status", - "lifecycleState", - "attempts", - "costUsd", - "avoidedUsd", - "pressure", - "shouldStop", - "remainingBudgetUsd", - "remainingIterations", - "remainingTokens" -]New value: +[ + "loopId", + "title", + "objective", + "status", + "lifecycleState", + "attempts", + "costUsd", + "avoidedUsd", + "pressure", + "shouldStop", + "remainingBudgetUsd", + "remainingIterations" +]
- Changed
martin_list_runs2 fields changed- changed
Output schema / properties / latestRun / requiredPrevious value: -[ - "loopId", - "title", - "objective", - "status", - "lifecycleState", - "attempts", - "costUsd", - "avoidedUsd", - "pressure", - "shouldStop", - "remainingBudgetUsd", - "remainingIterations", - "remainingTokens" -]New value: +[ + "loopId", + "title", + "objective", + "status", + "lifecycleState", + "attempts", + "costUsd", + "avoidedUsd", + "pressure", + "shouldStop", + "remainingBudgetUsd", + "remainingIterations" +] - changed
Output schema / properties / recentRuns / items / requiredPrevious value: -[ - "loopId", - "title", - "objective", - "status", - "lifecycleState", - "attempts", - "costUsd", - "avoidedUsd", - "pressure", - "shouldStop", - "remainingBudgetUsd", - "remainingIterations", - "remainingTokens" -]New value: +[ + "loopId", + "title", + "objective", + "status", + "lifecycleState", + "attempts", + "costUsd", + "avoidedUsd", + "pressure", + "shouldStop", + "remainingBudgetUsd", + "remainingIterations" +]
- Changed
martin_logs8 fields changed- added
Input schema / properties / file / descriptionAdded value: +"Absolute or relative path to a loop-record.json file or run directory. Mutually exclusive with loopId and latest." - added
Input schema / properties / latest / descriptionAdded value: +"When true, loads the most recently updated run in the run store. Mutually exclusive with file and loopId." - added
Input schema / properties / limit / descriptionAdded value: +"Maximum number of log entries to return, sorted by timestamp descending. Defaults to 20." - added
Input schema / properties / loopId / descriptionAdded value: +"MartinLoop run identifier from the run store. Mutually exclusive with file and latest." - added
Input schema / properties / runsDir / descriptionAdded value: +"Override the default run-store root directory. Optional; defaults to the MartinLoop runs directory." - changed
Output schema / additionalPropertiesPrevious value: -trueNew value: +false - added
Output schema / propertiesAdded value: +{ + "entries": { + "description": "Log entries sorted by timestamp descending, capped at limit.", + "items": { + "additionalProperties": false, + "properties": { + "kind": { + "description": "Event type or control action name.", + "type": "string" + }, + "payload": { + "additionalProperties": true, + "description": "Event-specific payload data.", + "type": "object" + }, + "source": { + "description": "Origin stream: loop event bus, governance ledger, or operator control receipts.", + "enum": [ + "event", + "ledger", + "control" + ], + "type": "string" + }, + "timestamp": { + "description": "ISO 8601 timestamp of the event, if present.", + "type": "string" + } + }, + "required": [ + "source", + "kind", + "payload" + ], + "type": "object" + }, + "type": "array" + }, + "live": { + "additionalProperties": false, + "properties": { + "approvalState": { + "description": "Whether the run is waiting at a human-approval checkpoint.", + "enum": [ + "not_required", + "resume_requested" + ], + "type": "string" + }, + "lifecycleState": { + "description": "Current run lifecycle state (e.g. running, completed, cancelled).", + "type": "string" + }, + "pauseState": { + "description": "Whether the run is active, paused, or has a pending cancellation.", + "enum": [ + "active", + "paused", + "cancellation_requested" + ], + "type": "string" + } + }, + "required": [ + "lifecycleState", + "pauseState", + "approvalState" + ], + "type": "object" + }, + "logCount": { + "description": "Number of log entries returned after applying the limit.", + "type": "integer" + }, + "loopId": { + "description": "Unique MartinLoop run identifier.", + "type": "string" + }, + "source": { + "description": "Resolved path to the loop-record source file.", + "type": "string" + }, + "sourceKind": { + "description": "How the run was identified: by file path, loop ID, latest flag, or runs directory.", + "enum": [ + "file", + "loop_id", + "latest", + "runs_root" + ], + "type": "string" + } +} - added
Output schema / requiredAdded value: +[ + "source", + "sourceKind", + "loopId", + "logCount", + "live", + "entries" +]
- Changed
martin_pause3 fields changed- changed
Output schema / additionalPropertiesPrevious value: -trueNew value: +false - added
Output schema / propertiesAdded value: +{ + "action": { + "description": "The control action that was recorded.", + "enum": [ + "pause", + "cancel", + "continue" + ], + "type": "string" + }, + "controlId": { + "description": "Unique receipt ID for this control action.", + "type": "string" + }, + "loopId": { + "description": "MartinLoop run identifier the control was applied to.", + "type": "string" + }, + "reason": { + "description": "Human-readable reason for the control, if provided.", + "type": "string" + }, + "requestedAt": { + "description": "ISO 8601 timestamp when the control was recorded.", + "type": "string" + }, + "requestedBy": { + "description": "Identity that requested the control, if provided.", + "type": "string" + } +} - added
Output schema / requiredAdded value: +[ + "loopId", + "action", + "controlId", + "requestedAt" +]
- Changed
martin_pr_summary8 fields changed- added
Input schema / properties / file / descriptionAdded value: +"Absolute or relative path to a loop-record.json file or run directory. Mutually exclusive with loopId and latest." - added
Input schema / properties / format / descriptionAdded value: +"Dossier rendering format. Defaults to github-pr for PR body generation. Use md for plain Markdown or json for structured output." - added
Input schema / properties / latest / descriptionAdded value: +"When true, generates the summary for the most recently updated run. Mutually exclusive with file and loopId." - added
Input schema / properties / loopId / descriptionAdded value: +"MartinLoop run identifier from the run store. Mutually exclusive with file and latest." - added
Input schema / properties / runsDir / descriptionAdded value: +"Override the default run-store root directory. Optional." - changed
Output schema / additionalPropertiesPrevious value: -trueNew value: +false - added
Output schema / propertiesAdded value: +{ + "body": { + "description": "GitHub-flavoured Markdown PR body containing the run dossier.", + "type": "string" + }, + "grade": { + "description": "Verification grade assigned to the run.", + "enum": [ + "mergeable", + "mergeable_with_review", + "needs_review", + "blocked", + "insufficient_evidence" + ], + "type": "string" + }, + "loopId": { + "description": "MartinLoop run identifier used to generate the summary.", + "type": "string" + }, + "score": { + "description": "Numeric verification score from 0–100.", + "type": "number" + }, + "title": { + "description": "Suggested GitHub pull-request title.", + "type": "string" + } +} - added
Output schema / requiredAdded value: +[ + "loopId", + "title", + "body", + "grade", + "score" +]
- Changed
martin_preflight1 field changed- changed
Output schema / properties / normalized / properties / budget / requiredPrevious value: -[ - "maxUsd", - "softLimitUsd", - "maxIterations", - "maxTokens" -]New value: +[ + "maxUsd", + "softLimitUsd", + "maxIterations" +]
- Changed
martin_review_pr9 fields changed- added
Input schema / properties / file / descriptionAdded value: +"Absolute or relative path to a loop-record.json file or run directory. Mutually exclusive with loopId and latest." - added
Input schema / properties / format / descriptionAdded value: +"Dossier format used when generating the reference body for comparison. Defaults to github-pr." - added
Input schema / properties / latest / descriptionAdded value: +"When true, reviews against the most recently updated run. Mutually exclusive with file and loopId." - added
Input schema / properties / loopId / descriptionAdded value: +"MartinLoop run identifier from the run store. Mutually exclusive with file and latest." - added
Input schema / properties / prBody / descriptionAdded value: +"The PR body text to review. If omitted, the auto-generated dossier body is evaluated instead." - added
Input schema / properties / runsDir / descriptionAdded value: +"Override the default run-store root directory. Optional." - changed
Output schema / additionalPropertiesPrevious value: -trueNew value: +false - added
Output schema / propertiesAdded value: +{ + "findings": { + "description": "Specific findings that informed the verdict.", + "items": { + "type": "string" + }, + "type": "array" + }, + "loopId": { + "description": "MartinLoop run identifier the review was performed against.", + "type": "string" + }, + "summary": { + "description": "Plain-English review summary.", + "type": "string" + }, + "verdict": { + "description": "Merge verdict: approve_with_review means safe to merge with human review; needs_changes requires fixes; blocked means do not merge.", + "enum": [ + "approve_with_review", + "needs_changes", + "blocked" + ], + "type": "string" + } +} - added
Output schema / requiredAdded value: +[ + "loopId", + "verdict", + "findings", + "summary" +]
- Changed
martin_run3 fields changed- changed
Output schema / properties / budget / requiredPrevious value: -[ - "maxUsd", - "softLimitUsd", - "maxIterations", - "maxTokens" -]New value: +[ + "maxUsd", + "softLimitUsd", + "maxIterations" +] - changed
Output schema / properties / inspection / properties / loop / requiredPrevious value: -[ - "loopId", - "title", - "objective", - "status", - "lifecycleState", - "attempts", - "costUsd", - "avoidedUsd", - "pressure", - "shouldStop", - "remainingBudgetUsd", - "remainingIterations", - "remainingTokens" -]New value: +[ + "loopId", + "title", + "objective", + "status", + "lifecycleState", + "attempts", + "costUsd", + "avoidedUsd", + "pressure", + "shouldStop", + "remainingBudgetUsd", + "remainingIterations" +] - changed
Output schema / requiredPrevious value: -[ - "status", - "lifecycleState", - "reason", - "attempts", - "costUsd", - "verificationPassed", - "loopId", - "pressure", - "shouldStop", - "remainingBudgetUsd", - "remainingIterations", - "remainingTokens", - "engine", - "workingDirectory", - "budget", - "inspection" -]New value: +[ + "status", + "lifecycleState", + "reason", + "attempts", + "costUsd", + "verificationPassed", + "loopId", + "pressure", + "shouldStop", + "remainingBudgetUsd", + "remainingIterations", + "engine", + "workingDirectory", + "budget", + "inspection" +]
- Changed
martin_run_dossier2 fields changed- changed
Output schema / properties / budget / requiredPrevious value: -[ - "maxUsd", - "softLimitUsd", - "maxIterations", - "maxTokens" -]New value: +[ + "maxUsd", + "softLimitUsd", + "maxIterations" +] - changed
Output schema / properties / loop / requiredPrevious value: -[ - "loopId", - "title", - "objective", - "status", - "lifecycleState", - "attempts", - "costUsd", - "avoidedUsd", - "pressure", - "shouldStop", - "remainingBudgetUsd", - "remainingIterations", - "remainingTokens" -]New value: +[ + "loopId", + "title", + "objective", + "status", + "lifecycleState", + "attempts", + "costUsd", + "avoidedUsd", + "pressure", + "shouldStop", + "remainingBudgetUsd", + "remainingIterations" +]
- Changed
martin_status3 fields changed- changed
Output schema / properties / budget / requiredPrevious value: -[ - "maxUsd", - "softLimitUsd", - "maxIterations", - "maxTokens" -]New value: +[ + "maxUsd", + "softLimitUsd", + "maxIterations" +] - changed
Output schema / properties / inspection / properties / loop / requiredPrevious value: -[ - "loopId", - "title", - "objective", - "status", - "lifecycleState", - "attempts", - "costUsd", - "avoidedUsd", - "pressure", - "shouldStop", - "remainingBudgetUsd", - "remainingIterations", - "remainingTokens" -]New value: +[ + "loopId", + "title", + "objective", + "status", + "lifecycleState", + "attempts", + "costUsd", + "avoidedUsd", + "pressure", + "shouldStop", + "remainingBudgetUsd", + "remainingIterations" +] - changed
Output schema / requiredPrevious value: -[ - "source", - "loopId", - "status", - "lifecycleState", - "attempts", - "costUsd", - "avoidedUsd", - "pressure", - "shouldStop", - "remainingBudgetUsd", - "remainingIterations", - "remainingTokens", - "budget", - "inspection" -]New value: +[ + "source", + "loopId", + "status", + "lifecycleState", + "attempts", + "costUsd", + "avoidedUsd", + "pressure", + "shouldStop", + "remainingBudgetUsd", + "remainingIterations", + "budget", + "inspection" +]
- Changed
martin_triage_runs1 field changed- changed
Output schema / properties / findings / items / properties / loop / requiredPrevious value: -[ - "loopId", - "title", - "objective", - "status", - "lifecycleState", - "attempts", - "costUsd", - "avoidedUsd", - "pressure", - "shouldStop", - "remainingBudgetUsd", - "remainingIterations", - "remainingTokens" -]New value: +[ + "loopId", + "title", + "objective", + "status", + "lifecycleState", + "attempts", + "costUsd", + "avoidedUsd", + "pressure", + "shouldStop", + "remainingBudgetUsd", + "remainingIterations" +]
13 tool updates
v0.5.5- Added
martin_arcade - Added
martin_arcade_status - Changed
martin_doctor2 fields changed- removed
Output schema / properties / runStore / properties / latestRun / properties / costProvenanceRemoved value: -{ - "enum": [ - "actual", - "calculated", - "estimated", - "unavailable" - ], - "type": "string" -} - changed
Output schema / properties / runStore / properties / latestRun / requiredPrevious value: -[ - "loopId", - "title", - "objective", - "status", - "lifecycleState", - "attempts", - "costUsd", - "costProvenance", - "avoidedUsd", - "pressure", - "shouldStop", - "remainingBudgetUsd", - "remainingIterations", - "remainingTokens" -]New value: +[ + "loopId", + "title", + "objective", + "status", + "lifecycleState", + "attempts", + "costUsd", + "avoidedUsd", + "pressure", + "shouldStop", + "remainingBudgetUsd", + "remainingIterations", + "remainingTokens" +]
- Changed
martin_dossier2 fields changed- removed
Output schema / properties / loop / properties / costProvenanceRemoved value: -{ - "enum": [ - "actual", - "calculated", - "estimated", - "unavailable" - ], - "type": "string" -} - changed
Output schema / properties / loop / requiredPrevious value: -[ - "loopId", - "title", - "objective", - "status", - "lifecycleState", - "attempts", - "costUsd", - "costProvenance", - "avoidedUsd", - "pressure", - "shouldStop", - "remainingBudgetUsd", - "remainingIterations", - "remainingTokens" -]New value: +[ + "loopId", + "title", + "objective", + "status", + "lifecycleState", + "attempts", + "costUsd", + "avoidedUsd", + "pressure", + "shouldStop", + "remainingBudgetUsd", + "remainingIterations", + "remainingTokens" +]
- Changed
martin_get_attempt2 fields changed- removed
Output schema / properties / loop / properties / costProvenanceRemoved value: -{ - "enum": [ - "actual", - "calculated", - "estimated", - "unavailable" - ], - "type": "string" -} - changed
Output schema / properties / loop / requiredPrevious value: -[ - "loopId", - "title", - "objective", - "status", - "lifecycleState", - "attempts", - "costUsd", - "costProvenance", - "avoidedUsd", - "pressure", - "shouldStop", - "remainingBudgetUsd", - "remainingIterations", - "remainingTokens" -]New value: +[ + "loopId", + "title", + "objective", + "status", + "lifecycleState", + "attempts", + "costUsd", + "avoidedUsd", + "pressure", + "shouldStop", + "remainingBudgetUsd", + "remainingIterations", + "remainingTokens" +]
- Changed
martin_get_run2 fields changed- removed
Output schema / properties / loop / properties / costProvenanceRemoved value: -{ - "enum": [ - "actual", - "calculated", - "estimated", - "unavailable" - ], - "type": "string" -} - changed
Output schema / properties / loop / requiredPrevious value: -[ - "loopId", - "title", - "objective", - "status", - "lifecycleState", - "attempts", - "costUsd", - "costProvenance", - "avoidedUsd", - "pressure", - "shouldStop", - "remainingBudgetUsd", - "remainingIterations", - "remainingTokens" -]New value: +[ + "loopId", + "title", + "objective", + "status", + "lifecycleState", + "attempts", + "costUsd", + "avoidedUsd", + "pressure", + "shouldStop", + "remainingBudgetUsd", + "remainingIterations", + "remainingTokens" +]
- Changed
martin_get_verification_results2 fields changed- removed
Output schema / properties / loop / properties / costProvenanceRemoved value: -{ - "enum": [ - "actual", - "calculated", - "estimated", - "unavailable" - ], - "type": "string" -} - changed
Output schema / properties / loop / requiredPrevious value: -[ - "loopId", - "title", - "objective", - "status", - "lifecycleState", - "attempts", - "costUsd", - "costProvenance", - "avoidedUsd", - "pressure", - "shouldStop", - "remainingBudgetUsd", - "remainingIterations", - "remainingTokens" -]New value: +[ + "loopId", + "title", + "objective", + "status", + "lifecycleState", + "attempts", + "costUsd", + "avoidedUsd", + "pressure", + "shouldStop", + "remainingBudgetUsd", + "remainingIterations", + "remainingTokens" +]
- Changed
martin_inspect4 fields changed- removed
Output schema / properties / latestRun / properties / costProvenanceRemoved value: -{ - "enum": [ - "actual", - "calculated", - "estimated", - "unavailable" - ], - "type": "string" -} - changed
Output schema / properties / latestRun / requiredPrevious value: -[ - "loopId", - "title", - "objective", - "status", - "lifecycleState", - "attempts", - "costUsd", - "costProvenance", - "avoidedUsd", - "pressure", - "shouldStop", - "remainingBudgetUsd", - "remainingIterations", - "remainingTokens" -]New value: +[ + "loopId", + "title", + "objective", + "status", + "lifecycleState", + "attempts", + "costUsd", + "avoidedUsd", + "pressure", + "shouldStop", + "remainingBudgetUsd", + "remainingIterations", + "remainingTokens" +] - removed
Output schema / properties / recentRuns / items / properties / costProvenanceRemoved value: -{ - "enum": [ - "actual", - "calculated", - "estimated", - "unavailable" - ], - "type": "string" -} - changed
Output schema / properties / recentRuns / items / requiredPrevious value: -[ - "loopId", - "title", - "objective", - "status", - "lifecycleState", - "attempts", - "costUsd", - "costProvenance", - "avoidedUsd", - "pressure", - "shouldStop", - "remainingBudgetUsd", - "remainingIterations", - "remainingTokens" -]New value: +[ + "loopId", + "title", + "objective", + "status", + "lifecycleState", + "attempts", + "costUsd", + "avoidedUsd", + "pressure", + "shouldStop", + "remainingBudgetUsd", + "remainingIterations", + "remainingTokens" +]
- Changed
martin_list_runs4 fields changed- removed
Output schema / properties / latestRun / properties / costProvenanceRemoved value: -{ - "enum": [ - "actual", - "calculated", - "estimated", - "unavailable" - ], - "type": "string" -} - changed
Output schema / properties / latestRun / requiredPrevious value: -[ - "loopId", - "title", - "objective", - "status", - "lifecycleState", - "attempts", - "costUsd", - "costProvenance", - "avoidedUsd", - "pressure", - "shouldStop", - "remainingBudgetUsd", - "remainingIterations", - "remainingTokens" -]New value: +[ + "loopId", + "title", + "objective", + "status", + "lifecycleState", + "attempts", + "costUsd", + "avoidedUsd", + "pressure", + "shouldStop", + "remainingBudgetUsd", + "remainingIterations", + "remainingTokens" +] - removed
Output schema / properties / recentRuns / items / properties / costProvenanceRemoved value: -{ - "enum": [ - "actual", - "calculated", - "estimated", - "unavailable" - ], - "type": "string" -} - changed
Output schema / properties / recentRuns / items / requiredPrevious value: -[ - "loopId", - "title", - "objective", - "status", - "lifecycleState", - "attempts", - "costUsd", - "costProvenance", - "avoidedUsd", - "pressure", - "shouldStop", - "remainingBudgetUsd", - "remainingIterations", - "remainingTokens" -]New value: +[ + "loopId", + "title", + "objective", + "status", + "lifecycleState", + "attempts", + "costUsd", + "avoidedUsd", + "pressure", + "shouldStop", + "remainingBudgetUsd", + "remainingIterations", + "remainingTokens" +]
- Changed
martin_run4 fields changed- removed
Output schema / properties / costProvenanceRemoved value: -{ - "enum": [ - "actual", - "calculated", - "estimated", - "unavailable" - ], - "type": "string" -} - removed
Output schema / properties / inspection / properties / loop / properties / costProvenanceRemoved value: -{ - "enum": [ - "actual", - "calculated", - "estimated", - "unavailable" - ], - "type": "string" -} - changed
Output schema / properties / inspection / properties / loop / requiredPrevious value: -[ - "loopId", - "title", - "objective", - "status", - "lifecycleState", - "attempts", - "costUsd", - "costProvenance", - "avoidedUsd", - "pressure", - "shouldStop", - "remainingBudgetUsd", - "remainingIterations", - "remainingTokens" -]New value: +[ + "loopId", + "title", + "objective", + "status", + "lifecycleState", + "attempts", + "costUsd", + "avoidedUsd", + "pressure", + "shouldStop", + "remainingBudgetUsd", + "remainingIterations", + "remainingTokens" +] - changed
Output schema / requiredPrevious value: -[ - "status", - "lifecycleState", - "reason", - "attempts", - "costUsd", - "costProvenance", - "verificationPassed", - "loopId", - "pressure", - "shouldStop", - "remainingBudgetUsd", - "remainingIterations", - "remainingTokens", - "engine", - "workingDirectory", - "budget", - "inspection" -]New value: +[ + "status", + "lifecycleState", + "reason", + "attempts", + "costUsd", + "verificationPassed", + "loopId", + "pressure", + "shouldStop", + "remainingBudgetUsd", + "remainingIterations", + "remainingTokens", + "engine", + "workingDirectory", + "budget", + "inspection" +]
- Changed
martin_run_dossier2 fields changed- removed
Output schema / properties / loop / properties / costProvenanceRemoved value: -{ - "enum": [ - "actual", - "calculated", - "estimated", - "unavailable" - ], - "type": "string" -} - changed
Output schema / properties / loop / requiredPrevious value: -[ - "loopId", - "title", - "objective", - "status", - "lifecycleState", - "attempts", - "costUsd", - "costProvenance", - "avoidedUsd", - "pressure", - "shouldStop", - "remainingBudgetUsd", - "remainingIterations", - "remainingTokens" -]New value: +[ + "loopId", + "title", + "objective", + "status", + "lifecycleState", + "attempts", + "costUsd", + "avoidedUsd", + "pressure", + "shouldStop", + "remainingBudgetUsd", + "remainingIterations", + "remainingTokens" +]
- Changed
martin_status4 fields changed- removed
Output schema / properties / costProvenanceRemoved value: -{ - "enum": [ - "actual", - "calculated", - "estimated", - "unavailable" - ], - "type": "string" -} - removed
Output schema / properties / inspection / properties / loop / properties / costProvenanceRemoved value: -{ - "enum": [ - "actual", - "calculated", - "estimated", - "unavailable" - ], - "type": "string" -} - changed
Output schema / properties / inspection / properties / loop / requiredPrevious value: -[ - "loopId", - "title", - "objective", - "status", - "lifecycleState", - "attempts", - "costUsd", - "costProvenance", - "avoidedUsd", - "pressure", - "shouldStop", - "remainingBudgetUsd", - "remainingIterations", - "remainingTokens" -]New value: +[ + "loopId", + "title", + "objective", + "status", + "lifecycleState", + "attempts", + "costUsd", + "avoidedUsd", + "pressure", + "shouldStop", + "remainingBudgetUsd", + "remainingIterations", + "remainingTokens" +] - changed
Output schema / requiredPrevious value: -[ - "source", - "loopId", - "status", - "lifecycleState", - "attempts", - "costUsd", - "costProvenance", - "avoidedUsd", - "pressure", - "shouldStop", - "remainingBudgetUsd", - "remainingIterations", - "remainingTokens", - "budget", - "inspection" -]New value: +[ + "source", + "loopId", + "status", + "lifecycleState", + "attempts", + "costUsd", + "avoidedUsd", + "pressure", + "shouldStop", + "remainingBudgetUsd", + "remainingIterations", + "remainingTokens", + "budget", + "inspection" +]
- Changed
martin_triage_runs2 fields changed- removed
Output schema / properties / findings / items / properties / loop / properties / costProvenanceRemoved value: -{ - "enum": [ - "actual", - "calculated", - "estimated", - "unavailable" - ], - "type": "string" -} - changed
Output schema / properties / findings / items / properties / loop / requiredPrevious value: -[ - "loopId", - "title", - "objective", - "status", - "lifecycleState", - "attempts", - "costUsd", - "costProvenance", - "avoidedUsd", - "pressure", - "shouldStop", - "remainingBudgetUsd", - "remainingIterations", - "remainingTokens" -]New value: +[ + "loopId", + "title", + "objective", + "status", + "lifecycleState", + "attempts", + "costUsd", + "avoidedUsd", + "pressure", + "shouldStop", + "remainingBudgetUsd", + "remainingIterations", + "remainingTokens" +]
1 tool update
v0.5.4- Changed
martin_run2 fields changed- added
Input schema / properties / providerExecutionTimeoutMsAdded value: +{ + "description": "Hard timeout for each provider coding process in milliseconds.", + "exclusiveMinimum": 0, + "type": "integer" +} - added
Input schema / properties / verifyTimeoutMsAdded value: +{ + "description": "Hard timeout for each verifier command in milliseconds.", + "exclusiveMinimum": 0, + "type": "integer" +}
12 tool updates
v0.5.3- Changed
martin_doctor2 fields changed- added
Output schema / properties / runStore / properties / latestRun / properties / costProvenanceAdded value: +{ + "enum": [ + "actual", + "calculated", + "estimated", + "unavailable" + ], + "type": "string" +} - changed
Output schema / properties / runStore / properties / latestRun / requiredPrevious value: -[ - "loopId", - "title", - "objective", - "status", - "lifecycleState", - "attempts", - "costUsd", - "avoidedUsd", - "pressure", - "shouldStop", - "remainingBudgetUsd", - "remainingIterations", - "remainingTokens" -]New value: +[ + "loopId", + "title", + "objective", + "status", + "lifecycleState", + "attempts", + "costUsd", + "costProvenance", + "avoidedUsd", + "pressure", + "shouldStop", + "remainingBudgetUsd", + "remainingIterations", + "remainingTokens" +]
- Changed
martin_dossier4 fields changed- added
Output schema / properties / cost / properties / provenanceAdded value: +{ + "enum": [ + "actual", + "calculated", + "estimated", + "unavailable" + ], + "type": "string" +} - changed
Output schema / properties / cost / requiredPrevious value: -[ - "actualUsd", - "avoidedUsd", - "tokensIn", - "tokensOut" -]New value: +[ + "actualUsd", + "avoidedUsd", + "tokensIn", + "tokensOut", + "provenance" +] - added
Output schema / properties / loop / properties / costProvenanceAdded value: +{ + "enum": [ + "actual", + "calculated", + "estimated", + "unavailable" + ], + "type": "string" +} - changed
Output schema / properties / loop / requiredPrevious value: -[ - "loopId", - "title", - "objective", - "status", - "lifecycleState", - "attempts", - "costUsd", - "avoidedUsd", - "pressure", - "shouldStop", - "remainingBudgetUsd", - "remainingIterations", - "remainingTokens" -]New value: +[ + "loopId", + "title", + "objective", + "status", + "lifecycleState", + "attempts", + "costUsd", + "costProvenance", + "avoidedUsd", + "pressure", + "shouldStop", + "remainingBudgetUsd", + "remainingIterations", + "remainingTokens" +]
- Changed
martin_estimate1 field changed- added
Input schema / properties / workingDirectoryAdded value: +{ + "description": "Optional workspace path for recording the estimate receipt against the same task root you plan to run.", + "type": "string" +}
- Changed
martin_get_attempt2 fields changed- added
Output schema / properties / loop / properties / costProvenanceAdded value: +{ + "enum": [ + "actual", + "calculated", + "estimated", + "unavailable" + ], + "type": "string" +} - changed
Output schema / properties / loop / requiredPrevious value: -[ - "loopId", - "title", - "objective", - "status", - "lifecycleState", - "attempts", - "costUsd", - "avoidedUsd", - "pressure", - "shouldStop", - "remainingBudgetUsd", - "remainingIterations", - "remainingTokens" -]New value: +[ + "loopId", + "title", + "objective", + "status", + "lifecycleState", + "attempts", + "costUsd", + "costProvenance", + "avoidedUsd", + "pressure", + "shouldStop", + "remainingBudgetUsd", + "remainingIterations", + "remainingTokens" +]
- Changed
martin_get_run4 fields changed- added
Output schema / properties / cost / properties / provenanceAdded value: +{ + "enum": [ + "actual", + "calculated", + "estimated", + "unavailable" + ], + "type": "string" +} - changed
Output schema / properties / cost / requiredPrevious value: -[ - "actualUsd", - "avoidedUsd", - "tokensIn", - "tokensOut" -]New value: +[ + "actualUsd", + "avoidedUsd", + "tokensIn", + "tokensOut", + "provenance" +] - added
Output schema / properties / loop / properties / costProvenanceAdded value: +{ + "enum": [ + "actual", + "calculated", + "estimated", + "unavailable" + ], + "type": "string" +} - changed
Output schema / properties / loop / requiredPrevious value: -[ - "loopId", - "title", - "objective", - "status", - "lifecycleState", - "attempts", - "costUsd", - "avoidedUsd", - "pressure", - "shouldStop", - "remainingBudgetUsd", - "remainingIterations", - "remainingTokens" -]New value: +[ + "loopId", + "title", + "objective", + "status", + "lifecycleState", + "attempts", + "costUsd", + "costProvenance", + "avoidedUsd", + "pressure", + "shouldStop", + "remainingBudgetUsd", + "remainingIterations", + "remainingTokens" +]
- Changed
martin_get_verification_results2 fields changed- added
Output schema / properties / loop / properties / costProvenanceAdded value: +{ + "enum": [ + "actual", + "calculated", + "estimated", + "unavailable" + ], + "type": "string" +} - changed
Output schema / properties / loop / requiredPrevious value: -[ - "loopId", - "title", - "objective", - "status", - "lifecycleState", - "attempts", - "costUsd", - "avoidedUsd", - "pressure", - "shouldStop", - "remainingBudgetUsd", - "remainingIterations", - "remainingTokens" -]New value: +[ + "loopId", + "title", + "objective", + "status", + "lifecycleState", + "attempts", + "costUsd", + "costProvenance", + "avoidedUsd", + "pressure", + "shouldStop", + "remainingBudgetUsd", + "remainingIterations", + "remainingTokens" +]
- Changed
martin_inspect4 fields changed- added
Output schema / properties / latestRun / properties / costProvenanceAdded value: +{ + "enum": [ + "actual", + "calculated", + "estimated", + "unavailable" + ], + "type": "string" +} - changed
Output schema / properties / latestRun / requiredPrevious value: -[ - "loopId", - "title", - "objective", - "status", - "lifecycleState", - "attempts", - "costUsd", - "avoidedUsd", - "pressure", - "shouldStop", - "remainingBudgetUsd", - "remainingIterations", - "remainingTokens" -]New value: +[ + "loopId", + "title", + "objective", + "status", + "lifecycleState", + "attempts", + "costUsd", + "costProvenance", + "avoidedUsd", + "pressure", + "shouldStop", + "remainingBudgetUsd", + "remainingIterations", + "remainingTokens" +] - added
Output schema / properties / recentRuns / items / properties / costProvenanceAdded value: +{ + "enum": [ + "actual", + "calculated", + "estimated", + "unavailable" + ], + "type": "string" +} - changed
Output schema / properties / recentRuns / items / requiredPrevious value: -[ - "loopId", - "title", - "objective", - "status", - "lifecycleState", - "attempts", - "costUsd", - "avoidedUsd", - "pressure", - "shouldStop", - "remainingBudgetUsd", - "remainingIterations", - "remainingTokens" -]New value: +[ + "loopId", + "title", + "objective", + "status", + "lifecycleState", + "attempts", + "costUsd", + "costProvenance", + "avoidedUsd", + "pressure", + "shouldStop", + "remainingBudgetUsd", + "remainingIterations", + "remainingTokens" +]
- Changed
martin_list_runs4 fields changed- added
Output schema / properties / latestRun / properties / costProvenanceAdded value: +{ + "enum": [ + "actual", + "calculated", + "estimated", + "unavailable" + ], + "type": "string" +} - changed
Output schema / properties / latestRun / requiredPrevious value: -[ - "loopId", - "title", - "objective", - "status", - "lifecycleState", - "attempts", - "costUsd", - "avoidedUsd", - "pressure", - "shouldStop", - "remainingBudgetUsd", - "remainingIterations", - "remainingTokens" -]New value: +[ + "loopId", + "title", + "objective", + "status", + "lifecycleState", + "attempts", + "costUsd", + "costProvenance", + "avoidedUsd", + "pressure", + "shouldStop", + "remainingBudgetUsd", + "remainingIterations", + "remainingTokens" +] - added
Output schema / properties / recentRuns / items / properties / costProvenanceAdded value: +{ + "enum": [ + "actual", + "calculated", + "estimated", + "unavailable" + ], + "type": "string" +} - changed
Output schema / properties / recentRuns / items / requiredPrevious value: -[ - "loopId", - "title", - "objective", - "status", - "lifecycleState", - "attempts", - "costUsd", - "avoidedUsd", - "pressure", - "shouldStop", - "remainingBudgetUsd", - "remainingIterations", - "remainingTokens" -]New value: +[ + "loopId", + "title", + "objective", + "status", + "lifecycleState", + "attempts", + "costUsd", + "costProvenance", + "avoidedUsd", + "pressure", + "shouldStop", + "remainingBudgetUsd", + "remainingIterations", + "remainingTokens" +]
- Changed
martin_run4 fields changed- added
Output schema / properties / costProvenanceAdded value: +{ + "enum": [ + "actual", + "calculated", + "estimated", + "unavailable" + ], + "type": "string" +} - added
Output schema / properties / inspection / properties / loop / properties / costProvenanceAdded value: +{ + "enum": [ + "actual", + "calculated", + "estimated", + "unavailable" + ], + "type": "string" +} - changed
Output schema / properties / inspection / properties / loop / requiredPrevious value: -[ - "loopId", - "title", - "objective", - "status", - "lifecycleState", - "attempts", - "costUsd", - "avoidedUsd", - "pressure", - "shouldStop", - "remainingBudgetUsd", - "remainingIterations", - "remainingTokens" -]New value: +[ + "loopId", + "title", + "objective", + "status", + "lifecycleState", + "attempts", + "costUsd", + "costProvenance", + "avoidedUsd", + "pressure", + "shouldStop", + "remainingBudgetUsd", + "remainingIterations", + "remainingTokens" +] - changed
Output schema / requiredPrevious value: -[ - "status", - "lifecycleState", - "reason", - "attempts", - "costUsd", - "verificationPassed", - "loopId", - "pressure", - "shouldStop", - "remainingBudgetUsd", - "remainingIterations", - "remainingTokens", - "engine", - "workingDirectory", - "budget", - "inspection" -]New value: +[ + "status", + "lifecycleState", + "reason", + "attempts", + "costUsd", + "costProvenance", + "verificationPassed", + "loopId", + "pressure", + "shouldStop", + "remainingBudgetUsd", + "remainingIterations", + "remainingTokens", + "engine", + "workingDirectory", + "budget", + "inspection" +]
- Changed
martin_run_dossier4 fields changed- added
Output schema / properties / cost / properties / provenanceAdded value: +{ + "enum": [ + "actual", + "calculated", + "estimated", + "unavailable" + ], + "type": "string" +} - changed
Output schema / properties / cost / requiredPrevious value: -[ - "actualUsd", - "avoidedUsd", - "tokensIn", - "tokensOut" -]New value: +[ + "actualUsd", + "avoidedUsd", + "tokensIn", + "tokensOut", + "provenance" +] - added
Output schema / properties / loop / properties / costProvenanceAdded value: +{ + "enum": [ + "actual", + "calculated", + "estimated", + "unavailable" + ], + "type": "string" +} - changed
Output schema / properties / loop / requiredPrevious value: -[ - "loopId", - "title", - "objective", - "status", - "lifecycleState", - "attempts", - "costUsd", - "avoidedUsd", - "pressure", - "shouldStop", - "remainingBudgetUsd", - "remainingIterations", - "remainingTokens" -]New value: +[ + "loopId", + "title", + "objective", + "status", + "lifecycleState", + "attempts", + "costUsd", + "costProvenance", + "avoidedUsd", + "pressure", + "shouldStop", + "remainingBudgetUsd", + "remainingIterations", + "remainingTokens" +]
- Changed
martin_status4 fields changed- added
Output schema / properties / costProvenanceAdded value: +{ + "enum": [ + "actual", + "calculated", + "estimated", + "unavailable" + ], + "type": "string" +} - added
Output schema / properties / inspection / properties / loop / properties / costProvenanceAdded value: +{ + "enum": [ + "actual", + "calculated", + "estimated", + "unavailable" + ], + "type": "string" +} - changed
Output schema / properties / inspection / properties / loop / requiredPrevious value: -[ - "loopId", - "title", - "objective", - "status", - "lifecycleState", - "attempts", - "costUsd", - "avoidedUsd", - "pressure", - "shouldStop", - "remainingBudgetUsd", - "remainingIterations", - "remainingTokens" -]New value: +[ + "loopId", + "title", + "objective", + "status", + "lifecycleState", + "attempts", + "costUsd", + "costProvenance", + "avoidedUsd", + "pressure", + "shouldStop", + "remainingBudgetUsd", + "remainingIterations", + "remainingTokens" +] - changed
Output schema / requiredPrevious value: -[ - "source", - "loopId", - "status", - "lifecycleState", - "attempts", - "costUsd", - "avoidedUsd", - "pressure", - "shouldStop", - "remainingBudgetUsd", - "remainingIterations", - "remainingTokens", - "budget", - "inspection" -]New value: +[ + "source", + "loopId", + "status", + "lifecycleState", + "attempts", + "costUsd", + "costProvenance", + "avoidedUsd", + "pressure", + "shouldStop", + "remainingBudgetUsd", + "remainingIterations", + "remainingTokens", + "budget", + "inspection" +]
- Changed
martin_triage_runs2 fields changed- added
Output schema / properties / findings / items / properties / loop / properties / costProvenanceAdded value: +{ + "enum": [ + "actual", + "calculated", + "estimated", + "unavailable" + ], + "type": "string" +} - changed
Output schema / properties / findings / items / properties / loop / requiredPrevious value: -[ - "loopId", - "title", - "objective", - "status", - "lifecycleState", - "attempts", - "costUsd", - "avoidedUsd", - "pressure", - "shouldStop", - "remainingBudgetUsd", - "remainingIterations", - "remainingTokens" -]New value: +[ + "loopId", + "title", + "objective", + "status", + "lifecycleState", + "attempts", + "costUsd", + "costProvenance", + "avoidedUsd", + "pressure", + "shouldStop", + "remainingBudgetUsd", + "remainingIterations", + "remainingTokens" +]
22 tool updates
v0.3.9- First observed
martin_cancel - First observed
martin_continue - First observed
martin_create_pr - First observed
martin_doctor - First observed
martin_dossier - First observed
martin_estimate - First observed
martin_eval - First observed
martin_get_attempt - First observed
martin_get_run - First observed
martin_get_verification_results - First observed
martin_inspect - First observed
martin_list_runs - First observed
martin_logs - First observed
martin_pause - First observed
martin_plan - First observed
martin_pr_summary - First observed
martin_preflight - First observed
martin_review_pr - First observed
martin_run - First observed
martin_run_dossier - First observed
martin_status - First observed
martin_triage_runs
TDQS
Scored across 24 tools
Several tools have overlapping purposes: martin_get_run, martin_status, martin_run_dossier, martin_dossier, and martin_inspect all read run data with subtle differences in format and depth. The descriptions try to disambiguate with 'do not use' guidance, but an agent could easily confuse martin_dossier vs martin_run_dossier vs martin_get_run.
Most tools follow a consistent martin_<verb>_<noun> pattern (martin_get_run, martin_create_pr, martin_review_pr). Minor deviations exist: martin_doctor, martin_arcade, and martin_arcade_status use noun-only or different structures, and martin_status vs martin_get_status inconsistency appears in descriptions.
24 tools is at the high end of acceptable for a complex run-management system, but the count feels inflated by near-duplicate read surfaces (dossier, run_dossier, get_run, inspect, status, logs, verification_results). A leaner set of 15-18 tools would cover the same functionality.
The lifecycle is well covered: estimate, plan, preflight, run, pause/cancel/continue, status, verification, eval, PR creation/review. Minor gaps include no explicit tool for listing attempts across runs or deleting/archiving runs, but agents can work around these.
Maintenance
Related MCP Connectors
Token guard and rate limiter preventing runaway API cost spikes for OpenAI and Anthropic.
Deterministic runtime safety for AI agents: scan PII, gate tool actions, verify LLM output.
Budget & cost control for AI agents — per-agent spend caps + rate limits before each call.
Pre-execution governance for AI agents. Deterministic PASS/FAIL/REVIEW verdicts, replayable proof.
Related MCP Servers
- AlicenseAqualityAmaintenanceThis server enables LLMs to retrieve and process content from web pages, converting HTML to markdown for easier consumption.190,569MIT
- AlicenseAqualityNot gradedmaintenanceEnables browser automation through Playwright using accessibility tree snapshots instead of screenshots. Supports web scraping, form interactions, testing, and connecting to existing browser sessions with logged-in accounts.8234,622 npm5-
- AlicenseNot gradedqualityFmaintenanceGovernance kernel for AI agents — policy enforcement, code safety verification, multi-model hallucination detection (CMVK), trust attestation (IATP), and immutable audit trails. Works with Claude Desktop, Cursor, and any MCP client.74MIT
- AlicenseNot gradedqualityDmaintenanceMCP Guard Server - Budget control, approval workflows and audit logging for AI agents (Claude Code, Cursor, ChatGPT)MIT