MarkApiDown implements the Model Context Protocol (MCP) to give AI agents a structured, token-efficient interface to your API workspace. Instead of shelling out toDocumentation Index
Fetch the complete documentation index at: https://docs.markapidown.net/llms.txt
Use this file to discover all available pages before exploring further.
mad exec and parsing console output, an MCP-enabled agent calls a tool and receives a clean JSON object — status code, body, headers, assertion results, and error details, all in one response. That means fewer tokens spent on parsing, fewer hallucinated shell commands, and faster, more reliable automation.
Register the MCP server
The MCP server integrates with Claude Code via theclaude CLI. Run the following command from your project root:
claude mcp add mad -- mad mcp under the hood and prints a confirmation. Verify the registration at any time:
mad install mcp currently registers the server with Claude Code only. Other agents can connect to the server using their own MCP configuration — point them at mad mcp as the command with stdio transport.Start the MCP server manually
If you need to start the server outside of Claude Code — for example, to test it or connect a custom client — run:2024-11-05. It stays running until you terminate it.
Available tools
MarkApiDown exposes the following MCP tools. Each tool accepts a JSON object as input and returns a structured JSON result — no shell parsing required.mad_exec — execute one endpoint spec
mad_exec — execute one endpoint spec
Run a single endpoint spec and receive a structured result containing the HTTP status, response body, headers, assertion outcomes, and any diff against the expected response.Input:
Example:Returns:
| Field | Type | Required | Description |
|---|---|---|---|
spec_path | string | ✓ | Path to the endpoint .md spec file |
env | string | — | Environment name (default: "dev") |
vars | object | — | Variable overrides as key/value pairs |
dry_run | boolean | — | Resolve variables and return the request without sending it |
verbose | boolean | — | Include full request and response objects in the result |
infer_expected | boolean | — | Return actual response formatted as an ## Expected response block |
{ "passed": true, "status": 201, "duration_ms": 142, "diff": null, "assertion_results": [ { "rule": "status: 201", "passed": true } ] }mad_flow — run a pipeline
mad_flow — run a pipeline
Execute a multi-step pipeline and receive per-step results, including each step’s status, captured values, and assertion outcomes. If a step fails, execution stops and the result includes the failure reason and which step caused it.Input:
Example:Returns: An object with
| Field | Type | Required | Description |
|---|---|---|---|
pipeline_path | string | ✓ | Path to the pipeline .md file |
env | string | — | Environment name (default: "dev") |
vars | object | — | Variable overrides injected at pipeline start |
verbose | boolean | — | Include full execution objects per step |
passed, captures, and a steps array. Each step has name, endpoint, passed, status, and error_type if the step failed. Secrets in captured values are masked as ****.mad_author — create or update a spec
mad_author — create or update a spec
mad_search — find specs by method, path, or tag
mad_search — find specs by method, path, or tag
Search the spec collection by HTTP method, URL path substring, tag, or free-text query. Returns a list of matching specs with their frontmatter metadata, so your agent can locate the right file before executing or updating it.Input:
All fields are optional — pass any combination to narrow results.Example:Returns:
| Field | Type | Required | Description |
|---|---|---|---|
q | string | — | Free-text search in title or description |
method | string | — | HTTP method filter, e.g. "POST" |
path | string | — | URL path substring, e.g. "/orders" |
tag | string | — | Tag to filter on |
{ "count": 1, "results": [ { "file": "api-docs/apis/orders/post-create-order.md", "method": "POST", "path": "/orders", "title": "Create order", "tags": ["orders"] } ] }mad_vars — show variable resolution for a spec
mad_vars — show variable resolution for a spec
Show which variables a spec requires and which are resolved in the current environment. Useful for diagnosing
Example:Returns:
VAR_MISSING errors before executing a spec.Input:| Field | Type | Required | Description |
|---|---|---|---|
spec_path | string | ✓ | Path to the endpoint .md spec file |
env | string | — | Environment name (default: "dev") |
{ "spec": "...", "env": "dev", "ready": false, "variables": [ { "name": "baseUrl", "kind": "template", "resolved": true, "source": "env.md" }, { "name": "authToken", "kind": "template", "resolved": false, "hint": "Set in _shared/env.md [dev] or pass as vars: {\"authToken\": \"...\"}" } ] }mad_exec_batch — run multiple specs in one call
mad_exec_batch — run multiple specs in one call
Execute a list of endpoint specs sequentially and receive a summary with per-spec results. Use this when you want to verify a group of related endpoints in one tool call.Input:
Example:Returns:
| Field | Type | Required | Description |
|---|---|---|---|
specs | string[] | ✓ | Array of spec file paths to execute |
env | string | — | Environment name (default: "dev") |
vars | object | — | Variable overrides applied to all specs |
{ "summary": { "total": 2, "passed": 2, "failed": 0, "duration_ms": 310 }, "results": [ { "spec": "...", "passed": true, "status": 201, "duration_ms": 145 }, ... ] }mad_history — view recent execution history for a spec
mad_history — view recent execution history for a spec
Return recent execution history for a spec, including timestamps, pass/fail status, HTTP status codes, duration, and error types. Also returns a trend summary (
Example:Returns:
improving, degrading, or stable) based on the last several runs.Input:| Field | Type | Required | Description |
|---|---|---|---|
spec_path | string | ✓ | Path to the endpoint .md spec file |
last | integer | — | Number of recent entries to return (default: 10) |
{ "spec": "...", "entries": [ { "timestamp": "2024-11-05T12:00:00Z", "passed": true, "status": 201, "duration_ms": 142, "error_type": null } ], "trend": "stable" }mad_session — get or set session-level defaults
mad_session — get or set session-level defaults
Get or set the session context — a persistent default
Example — set defaults for a session:Example — read current session:Returns (get):
env and vars map stored in a temp file. When set, mad_exec and mad_flow use session values as low-priority defaults, so you don’t need to pass the same env and variables on every call.Input:| Field | Type | Required | Description |
|---|---|---|---|
action | string | ✓ | "get" to read the current session, or "set" to update it |
env | string | — | Default environment name to store in the session |
vars | object | — | Default variable values to store in the session |
{ "env": "dev", "vars": { "authToken": "test-token-123" } }Token efficiency
Using MCP tools instead of shell commands significantly reduces the tokens your agent spends on a typical “execute and check” task. The table below shows a rough comparison for running a single endpoint spec.| Approach | What the agent must do | Approximate token cost |
|---|---|---|
Shell: mad exec <file> | Parse colored console output, extract status/body, handle ANSI codes | High — output parsing is noisy |
MCP: mad_exec | Read one JSON object with named fields | Low — structured, no parsing needed |
| Shell: construct curl | Read source, build headers, body, flags from scratch | Very high — requires source analysis |
mad_flow returns all step results in one call, while a shell-based approach requires one round-trip per step plus output parsing for each.
Error codes
When a tool call fails, the MCP server returns a structured error object with a code and a hint message.| Error type | Code | Hint |
|---|---|---|
VAR_MISSING | -32000 | Define the variable in _shared/env.md or pass via vars: {...} |
NETWORK_ERROR | -32000 | Check baseUrl in env.md and ensure the server is running |
CONTRACT_MISMATCH | -32000 | Update ## Expected response or fix the API |
SPEC_PARSE_ERROR | -32000 | Fix YAML frontmatter or section structure |
| Tool not found | -32601 | Check the tool name — available tools are listed above |
| Missing required field | -32602 | Include the required input field in your call |