MCP Server¶
AAT exposes a Model Context Protocol (MCP) server that integrates your API project into IDE-based AI tools like Claude Code, Cursor, and VS Code Copilot. The server provides tools, resources, and prompts that let AI assistants browse your API graph, author plans, run tests, and debug failures — over stdio or HTTP.
Quick Start¶
Stdio (local IDE)¶
aat mcp serve
The server auto-discovers your project manifest and loads the graph, templates, domain knowledge, and environment. All output goes to stderr; stdout is reserved for the MCP protocol.
aat mcp serve --manifest path/to/aat-project.yaml
Use --manifest to specify a project explicitly when auto-discovery doesn't apply.
HTTP (remote)¶
aat mcp serve --http
Serves the MCP server over Streamable HTTP on http://localhost:8080. It listens on loopback unless --host (or AAT_HOST) names another interface; to let developers point their IDE's MCP client at a shared server without installing AAT locally, start it with --host 0.0.0.0 on a machine that untrusted networks cannot reach, since HTTP mode has no authentication.
aat mcp serve --http --port 9090 --http-base-path /api/mcp
HTTP mode automatically uses the api persona (read-only Integration tools) and excludes tools that expose raw response bodies. The server shuts down gracefully on SIGINT/SIGTERM.
Personas¶
The MCP server supports personas that tailor the tool set for different workflows. Instead of exposing all tools to every user, personas filter to what's relevant — reducing context window usage and keeping the AI focused.
aat mcp serve # all tools (39 with OAS specs loaded, 32 without)
aat mcp serve --persona api # API knowledge tools (24 with OAS specs loaded, 17 without)
aat mcp serve --persona test # test lifecycle tools (26)
The seven OpenAPI tools register only when an OAS spec is loaded (from the manifest's oas field or the graph's oas references), which is why the api and all-tools counts vary.
| Persona | Target User | Focus |
|---|---|---|
api |
Integration developer | Understanding endpoints, data shapes, schemas, domain rules |
test |
Test developer | Creating plans, running tests, debugging failures |
| (omitted) | Both | All tools registered (backward compatible) |
Choosing a Persona¶
Use api when building client code against the API that AAT describes. The API persona renames tools to match integration vocabulary (e.g., list_api_operations instead of list_nodes) and includes OAS schema tools, domain value pools, and data flow tracing. To give your API's integrators this view without your internal tests, package an integration kit.
Use test when creating, running, or debugging AAT test plans. The test persona includes plan management, execution, archive inspection, and failure analysis tools.
Omit the flag for backward compatibility or when you need both sets of capabilities.
| Flag | Type | Default | Description |
|---|---|---|---|
--manifest |
path | auto-discovered | Explicit path to aat-project.yaml |
--persona |
string | (all) | Server persona: api, test, or all (the same as omitting the flag) |
--env |
string | from manifest | Environment name to load (for multi-environment files) |
--http |
bool | false | Serve over Streamable HTTP instead of stdio |
--host |
string | 127.0.0.1 |
Interface to bind with --http; 0.0.0.0 for all interfaces. AAT_HOST sets it when the flag is absent |
--port |
int | 8080 | HTTP listen port (used with --http) |
--var |
KEY=VALUE |
— | Set a var of a multi-environment file (repeatable) |
--http-base-path |
string | /mcp |
HTTP endpoint path (used with --http) |
--log |
bool | false | Enable structured JSON logging of tool calls to stderr |
IDE Configuration¶
Claude Code¶
Add AAT as an MCP server in your project's .mcp.json. You can configure one or both personas:
{
"mcpServers": {
"aat-api": {
"command": "/path/to/aat",
"args": ["mcp", "serve", "--persona", "api"]
},
"aat-test": {
"command": "/path/to/aat",
"args": ["mcp", "serve", "--persona", "test"]
}
}
}
Or use a single server with all tools:
{
"mcpServers": {
"aat": {
"command": "/path/to/aat",
"args": ["mcp", "serve"]
}
}
}
If the manifest is discoverable from the project directory, omit the --manifest argument.
Cursor / VS Code¶
Add an MCP server entry in your IDE settings. The configuration varies by IDE, but the pattern is the same — point to the AAT binary with mcp serve as the command:
{
"mcp.servers": {
"aat-api": {
"command": "/path/to/aat",
"args": ["mcp", "serve", "--persona", "api"]
}
}
}
Consult your IDE's MCP documentation for the exact settings location.
Remote HTTP Server¶
When AAT is running with --http, configure your IDE to connect via URL instead of spawning a process:
{
"mcpServers": {
"aat-remote": {
"url": "http://your-server:8080/mcp"
}
}
}
This is useful for shared team servers or when AAT is running on a different machine from the IDE.
HTTP Mode¶
HTTP mode serves the MCP protocol over Streamable HTTP, enabling remote access without local AAT installation.
Behavior¶
- Persona: HTTP mode always uses a remote variant of the Integration (
api) persona: the same tools exceptget_sample_response(23 with OAS specs loaded, 16 without).--persona testis ignored with a warning,--persona allis ignored silently, and an unknown value is an error. - Stateless: Each request is independent — no session state is maintained. All Integration tools are pure reads, so no session tracking is needed.
- Excluded tools:
get_sample_responseis excluded from HTTP mode because it exposes raw API response bodies from run archives. - Shutdown: The server shuts down gracefully on SIGINT/SIGTERM, draining in-flight requests with a 5-second timeout.
Authentication¶
HTTP mode does not enforce authentication by default. For production deployments behind a reverse proxy, use the proxy's auth layer.
AAT ships an AuthMiddleware function in the mcp package that validates Authorization: Bearer <token> headers. It's not wired into the CLI by default but is ready for programmatic use:
handler := server.NewStreamableHTTPServer(mcpServer, opts...)
protected := mcp.AuthMiddleware([]string{"your-api-key"})(handler)
http.ListenAndServe(":8080", protected)
Logging¶
Enable structured JSON logging with --log to get visibility into tool usage:
aat mcp serve --http --log
When enabled, one JSON line is written to stderr per tool call at INFO level, and MCP-level errors (tool not found, parse failures) are logged at ERROR level:
{"time":"2026-03-07T14:22:01Z","level":"INFO","msg":"tool_call","tool":"list_nodes","duration_ms":12,"is_error":false}
{"time":"2026-03-07T14:22:02Z","level":"ERROR","msg":"mcp_error","method":"tools/call","error":"tool not found: foo"}
Logging uses Go's log/slog with a JSON handler writing to stderr. In stdio mode, stderr is safe — stdout is reserved for the MCP protocol. In HTTP mode, the logger also captures HTTP transport-level events from mcp-go.
The --log flag is opt-in with zero overhead when disabled (no hooks are registered).
Deployment¶
For production use, run AAT behind a reverse proxy (nginx, Caddy) that handles TLS termination and authentication:
aat mcp serve --http --port 8080
The proxy forwards to http://localhost:8080/mcp. AAT does not handle TLS directly in HTTP mode.
Tools — API Persona¶
The API persona registers 24 tools focused on understanding and integrating with the API — 17 when no OpenAPI spec is loaded, since the OpenAPI group below is registered only when a spec is loaded. Over --http, get_sample_response is also excluded, giving 23 (or 16).
API Operations (7 tools)¶
| Tool | Description |
|---|---|
list_api_operations |
List all API operations with descriptions and input/output counts |
describe_operation |
Show full details for an API operation: inputs, outputs, dependencies, OAS reference, and Lua transform indicator |
trace_dependency_chain |
Trace the dependency chain for a target operation using backward chaining |
search_api |
Search for API operations by keyword across names, descriptions, and input/output names |
get_data_flow |
Show how data flows between two API operations: which outputs map to which inputs |
get_response_shape |
Show the output fields for an API operation with extraction paths, downstream consumers, and transform notes |
explain_field |
Show everything known about a specific field: type, domain concept, value pool, constraints, and which operations produce/consume it |
Request Templates (1 tool)¶
| Tool | Description |
|---|---|
inspect_request_template |
Show the HTTP request template for an API operation: method, path, headers, body, response extraction rules, and Lua transforms |
Domain Knowledge (4 tools)¶
| Tool | Description |
|---|---|
list_concepts |
List all domain concepts with descriptions and applicable fields |
list_types |
List all domain type definitions with format and field info |
list_value_pools |
List all value pools with type, sample values, and total count |
explain_concept |
Show full detail for a concept: description, constraints, examples, and related types/pools |
OpenAPI (7 tools)¶
| Tool | Description |
|---|---|
list_oas_operations |
List operations from loaded OAS specs with optional filters (tag, keyword, HTTP method) |
list_oas_subtypes |
Show polymorphic subtypes for a schema (discriminator mappings, oneOf/anyOf, allOf) |
get_oas_operation |
Show OAS operation details for a graph node: HTTP method, path, parameters, request/response schemas |
get_oas_schema |
Resolve and display a component schema by name, including allOf inheritance and validation constraints |
search_oas_schemas |
Search for component schema names matching a regex pattern across all loaded OAS specs |
validate_oas_request |
Validate a JSON payload against the request body schema for a node's OAS operation |
build_oas_example |
Generate an example JSON request payload for a node's OAS operation (minimal, typical, or full) |
Documentation (2 tools)¶
| Tool | Description |
|---|---|
get_node_documentation |
Show merged documentation for an API operation: graph metadata, user-written docs, and OAS summary |
get_workflow_documentation |
Show merged documentation for every operation in a dependency chain traced backward from goal |
Integration Flows (2 tools)¶
| Tool | Description |
|---|---|
list_integration_flows |
List all integration flows with decision points (slots) and optional extensions (addons) |
get_integration_flow |
Show an enriched step-by-step recipe for an integration flow: HTTP methods, data flow, selections, outputs, and operation name mapping |
Sample Responses (1 tool)¶
| Tool | Description |
|---|---|
get_sample_response |
Get a sample API response for an operation from run archives, showing response body, status code, and extracted outputs; path narrows the body and shape returns its structure |
get_sample_response searches the archives directory, including the runs inside batches, and returns the newest successful (2xx) response for the operation. It returns a failed response, marked as one, only when no run succeeded, so a negative test's error response does not pass for a sample. With run_id (a run ID, a batch ID and run ID joined by a slash, or latest) it searches that run alone. path selects part of the body with a gjson path, such as items.#.sku, and shape returns the body's structure instead of its values: each path with its type, array sizes, and a sample value, for responses too large to read whole. aat run show prints the same from the command line; see Archives: Inspecting a Run from the CLI. When the manifest sets no archives, or no run has called the operation, it describes the expected output shape and extract rules instead.
Tools — Test Persona¶
The test persona registers 26 tools focused on test plan lifecycle, execution, and debugging. It is the only persona that can execute plans (a server started without --persona can too); execute_plan runs a saved plan against the environment loaded at startup (select it with --env).
Graph Exploration (4 tools)¶
| Tool | Description |
|---|---|
list_nodes |
List all nodes in the API graph with descriptions and input/output counts |
describe_node |
Show full details for a node: inputs, outputs, ordering (requires/satisfies), adapter, and OAS reference |
trace_workflow |
Trace the dependency chain for a goal node using backward chaining |
find_workflows |
Search for nodes by keyword across names, descriptions, and input/output names |
Templates (2 tools)¶
| Tool | Description |
|---|---|
list_adapters |
List all registered adapter names |
inspect_template |
Show the HTTP template for an adapter: method, path, headers, body, and response extraction rules |
Domain Knowledge (3 tools)¶
| Tool | Description |
|---|---|
list_concepts |
List all domain concepts with descriptions and applicable fields |
list_types |
List all domain type definitions with format and field info |
explain_concept |
Show full detail for a concept: description, constraints, examples, and related types/pools |
Documentation (3 tools)¶
| Tool | Description |
|---|---|
get_node_documentation |
Show merged documentation for a graph node: graph metadata, user-written docs, and OAS summary |
generate_doc_stub |
Generate a Markdown documentation skeleton for a node with input/output tables and placeholders |
list_undocumented_nodes |
List graph nodes that do not have a corresponding Markdown doc file |
Workflows (3 tools)¶
| Tool | Description |
|---|---|
list_workflows |
List all named workflows in the graph, including addons and composed workflows |
get_workflow_detail |
Show an enriched step-by-step recipe for a workflow: HTTP methods, data flow, selections, outputs |
instantiate_workflow |
Load and compose a workflow template with optional slot choices and addons |
Plans (5 tools)¶
| Tool | Description |
|---|---|
generate_plan |
Generate an execution plan from a natural-language prompt using the LLM pipeline |
validate_plan |
Parse and validate a plan YAML string against the API graph. Lists warnings that don't fail validation, such as a required input that takes from: an optional output |
list_saved_plans |
List saved test plans from the plans directory with name, goal, and step count |
load_plan |
Load a saved plan and return its YAML and narrative |
save_plan |
Validate and save a plan YAML string to the plans directory, with the same warnings as validate_plan |
Execution (1 tool)¶
| Tool | Description |
|---|---|
execute_plan |
Execute a saved test plan by name: authenticate, run the engine, write the archive, and return a summary |
Archives (5 tools)¶
| Tool | Description |
|---|---|
list_archives |
List recent run archives showing run ID, timestamp, outcome, and duration |
inspect_archive |
Show a detailed Markdown view of a run archive including per-step request/response data |
analyze_failure |
Analyze a failed run archive and provide failure-focused diagnostics with suggested next steps |
diff_archives |
Side-by-side comparison of two run archives: outcome, status, duration, and output differences |
list_recent_failures |
List recent failed run archives, skipping passed runs |
Resources¶
Each persona registers a compact overview resource instead of a full graph dump, reducing context window usage from 50-100KB+ to under 10KB.
API Persona Resources¶
Static:
| URI | Name | Description |
|---|---|---|
aat://api/overview |
API Overview | Compact one-liner-per-operation summary with HTTP method and path |
aat://domain |
Domain Knowledge | Domain concepts, types, and value pools |
aat://metadata |
Project Metadata | Project manifest and graph statistics |
aat://readme |
README | Project README.md from the graph directory (when present) |
Dynamic:
| URI Template | Name | Description |
|---|---|---|
aat://operation/{name} |
Operation Detail | Detailed view of a specific API operation |
aat://template/{adapter} |
Request Template | HTTP request template for a specific adapter |
aat://flow/{name} |
Integration Flow | Enriched step-by-step recipe for an integration flow |
Test Persona Resources¶
Static:
| URI | Name | Description |
|---|---|---|
aat://graph/overview |
Graph Overview | Compact one-liner-per-node summary with adapter and I/O counts |
aat://domain |
Domain Knowledge | Domain concepts, types, and value pools |
aat://metadata |
Project Metadata | Project manifest and graph statistics |
aat://readme |
README | Project README.md from the graph directory (when present) |
Dynamic:
| URI Template | Name | Description |
|---|---|---|
aat://node/{name} |
Node Detail | Detailed view of a specific graph node |
aat://template/{adapter} |
Template Detail | HTTP template detail for a specific adapter |
aat://workflow/{name} |
Workflow Detail | Enriched step-by-step recipe for a workflow |
Legacy Resources (no persona)¶
When no persona is specified, the server registers the original resources including the full aat://graph dump:
| URI | Name | Description |
|---|---|---|
aat://graph |
API Graph | Full graph showing all nodes, their ordering tokens, and conditions |
aat://templates |
Templates | HTTP templates for all registered adapters |
aat://domain |
Domain Knowledge | Domain concepts, types, and value pools |
aat://metadata |
Project Metadata | Project manifest and graph statistics |
aat://readme |
README | Project README.md from the graph directory (when present) |
Dynamic resources: aat://node/{name}, aat://template/{adapter}, aat://workflow/{name}.
Prompts¶
API Persona Prompts¶
| Prompt | Arguments | Description |
|---|---|---|
explain_integration_flow |
goal (required) |
Explain how an API integration flow achieves a goal, with full chain trace and domain context |
generate_client_code |
node (required), language (optional, default: go) |
Generate client code for calling a specific API endpoint |
integration_guide |
goal (required) |
Comprehensive guide for integrating with a workflow: chain trace, templates, OAS, domain |
Test Persona Prompts¶
| Prompt | Arguments | Description |
|---|---|---|
test_workflow |
description (required) |
Guide the full test lifecycle: understand goal, generate plan, validate, execute, inspect |
debug_failing_test |
run_id (required) |
Load a failed run archive and diagnose root causes with comprehensive failure context |
enrich_documentation |
node (required) |
Create or enrich documentation for a node using graph metadata, existing docs, OAS, and domain |
Legacy Prompts (no persona)¶
All 6 prompts are registered: explain_workflow, generate_client_code, integration_guide, test_workflow, debug_failing_test, enrich_documentation.
Per-Node Documentation¶
AAT supports per-node Markdown documentation files that enrich the AI's understanding of individual API operations. Set the docs field in aat-project.yaml to a directory (resolved relative to the manifest; there is no default) and name each file <NodeName>.md. Files that match no node are ignored, and the server reads the directory when it starts, so restart it to pick up new files.
# aat-project.yaml
docs: docs/
my-ecommerce-api/
aat-project.yaml
graph.yaml
docs/
listProducts.md
createOrder.md
cancelOrder.md
Each doc file can contain whatever context is useful: business rules, edge cases, error codes, example payloads, or integration notes.
The generate_doc_stub tool (test persona) returns starter documentation with input/output tables and placeholders pre-filled from the graph metadata; it does not write a file, so the assistant saves it into the docs directory.
The list_undocumented_nodes tool (test persona) shows which nodes don't have doc files yet — useful for tracking documentation coverage.
When the AI uses get_node_documentation, AAT merges three sources:
- Graph metadata — inputs, outputs, types, descriptions from the graph YAML
- Per-node docs — the Markdown file for that node
- OAS details — operation description, parameters, and schemas from the OpenAPI spec
This merged view gives the AI rich context for authoring plans, generating client code, or explaining API behavior.
UX Features¶
The MCP tools include several features designed to reduce friction when AI assistants use them.
Step IDs vs Operation Names¶
Workflow templates assign step IDs that may differ from the underlying graph node (operation) name. For example, the shop's Checkout workflow uses the step ID checkout for the graph node checkoutCart.
get_integration_flow/get_workflow_detailshows the operation name under each step when the step ID differs:**Operation:** checkoutCart. This makes the mapping visible so you know which name to use in other tools.- Error messages across
describe_operation,get_data_flow,get_response_shape,explain_field,inspect_request_template, andget_sample_responsesuggest checking the workflow detail if the name looks like a step ID.
Lua Transform Indicators¶
Only some templates have Lua transforms, but they contain critical post-processing logic. Rather than requiring a separate inspect_request_template call to discover this:
describe_operation/describe_nodeshows a**Transform:** Lua (summary)line when the node's template has a Lua transform script. The summary is extracted from the leading comment block.get_response_shapeadds a note when outputs are post-processed by a transform, since extract paths alone don't tell the full story.inspect_request_templateshows the full Lua script with syntax highlighting and a comment summary.
Data Flow Guidance¶
When get_data_flow finds no direct graph connection between two operations, it suggests using get_integration_flow or get_workflow_detail to see step-level data flow within workflows — since many connections are established through workflow composition rather than a direct output-to-input match in the graph.
Server Context¶
When the MCP server starts, it loads and caches the project context:
| Artifact | Required | Source |
|---|---|---|
| Graph | yes | graph field in manifest |
| Templates | yes | templates field in manifest |
| Domain knowledge | no | domain field in manifest |
| OAS specs | no | oas field in the manifest, the graph's oas, and per-node oas.spec references |
| Environment | no | environment field in manifest (--env, AAT_ENV_NAME, or defaultEnvironment picks the environment) |
| Node docs | no | docs field in manifest |
| Workflows | no | workflows field in manifest |
| Layers | no | layers field in manifest (recipes that name layers need it) |
| Saved plans | no | plans field in manifest |
| Archives | no | archives field in manifest (also where get_sample_response looks) |
| README | no | README.md in the graph file's directory |
The graph and templates are required. Everything else is optional and adds capabilities — domain knowledge improves plan generation, OAS specs enable schema validation tools, node docs enrich documentation queries.
See Project Setup for how to configure the manifest.
Source: cmd/aat/mcp_cmd.go, mcp/server.go, mcp/middleware.go, mcp/context.go, mcp/resources.go, mcp/prompts.go, mcp/prompts_workflow.go, mcp/tools_*.go.