About agent-protocols
agent-protocols is a skill for fixing IsAgentReady.com Agent Protocols checks. It helps site maintainers make website functions discoverable and usable through standard protocols, with setup and verification workflows for protocols such as WebMCP, MCP, A2A, and OpenAPI.
Key features
- 01Configure WebMCP forms and tool annotations
- 02Publish an A2A Agent Card
- 03Provide MCP discovery data and server cards
- 04Publish and improve OpenAPI documentation
- 05Verify protocol endpoints and API responses
Use cases
- 01Resolve Agent Protocols scan failures
- 02Document a website API with OpenAPI
- 03Help Agents discover a site's MCP server
MCP support
The skill guides sites in publishing MCP discovery files and server cards, then verifying MCP endpoints. The scanner connects to a same-origin Streamable HTTP endpoint for discovery and listing requests; it does not call tools.
Install
Copy the command and run it in a terminal.
npx skills add https:/ / github.com/ bartwaardenburg/ isagentready-skills --skill agent-protocolsAfter installing, type/agent-protocolsin Claude Code to confirm it loaded.
Bundled files
References and scripts installed along with SKILL.md.
references/a2a-mcp-guide.mdcheckpoints.mdgotchas.mdwebmcp-guide.mdDetails
From the project READMEAgent Protocols
Fixes the Agent Protocols category of IsAgentReady.com. These checkpoints test if agents can discover and use the functions of the site through standard protocols.
- Methodology version:
2026-10-22. Methodology: https://isagentready.com/en/methodology - Scoring (weights and points): https://isagentready.com/api/v2/methodology/2026-10-22/scoring
- Full checkpoint data (stage, evidence type, verify command, rescan command): references/checkpoints.md
Many checkpoints apply only to a detected surface (API, MCP, commerce). A content site without an API skips them. WebMCP results are experimental evidence and do not change the headline score.
When to Use
- The scan shows failures in Agent Protocols (legacy ids 4.x).
- The site has forms, an API, an MCP server, an agent or a shop that agents must use.
- The user asks for WebMCP, A2A, MCP, OpenAPI, API catalog, NLWeb or agent payments.
When NOT to Use
- A static content site without interactive functions or an API.
- Security headers or OAuth metadata: use
security-trust. - JSON-LD: use
structured-data. - robots.txt, llms.txt or AGENTS.md: use
ai-content-discovery.
Instructions
- Get the failing checkpoints from the scan. Each result has a legacy id (
4.3) and a stable id (ia.a2a-agent-card). - Go to the fix workflow with the anchor that is equal to the stable id.
- Adapt the example to the site. Replace
example.comwith the domain of the site. - Serve each
/.well-known/*document asapplication/json. Make sure that the WAF and CDN do not block it. - Run the verify command. All verify commands are read-only. Then rescan with
isagentready results <domain> --checkpoint <stable-id>.
If $ARGUMENTS is provided, use it as the URL to fix or as the checkpoint to fix.
Checkpoints
Strength is the agentready.org spec level (MUST, SHOULD, MAY). Strength does not change the score.
| Legacy | Stable ID | Name | AR IDs | Strength |
|---|---|---|---|---|
| 4.1 | ia.webmcp-declarative | WebMCP declarative API | AR-ACT-07 | SHOULD |
| 4.3 | ia.a2a-agent-card | A2A Agent Card | AR-READ-06 | MAY |
| 4.4 | ia.mcp-discovery | MCP discovery | AR-ACT-03, AR-ACT-10 | MAY |
| 4.5 | ia.openapi | OpenAPI / API docs | AR-ACT-02 | SHOULD |
| 4.6 | ia.agents-json | agents.json | none | MAY |
| 4.7 | ia.webmcp-form-quality | Declarative form quality | AR-ACT-07 | SHOULD |
| 4.9 | ia.interactive-surface-coverage | Interactive surface coverage | AR-ACT-07 | SHOULD |
| 4.10 | ia.api-catalog | API Catalog (RFC 9727) | AR-READ-06, AR-ACT-02 | SHOULD |
| 4.11 | ia.agent-skills-index | Agent Skills index | AR-ACT-06 | MAY |
| 4.12 | ia.x402 | x402 payments | AR-ACT-08 | MAY |
| 4.13 | ia.mpp | MPP (x-payment-info) | AR-ACT-08 | MAY |
| 4.14 | ia.ucp | UCP | AR-ACT-08, AR-READ-06 | MAY |
| 4.15 | ia.acp-manifest | ACP manifest | AR-ACT-08, AR-READ-06 | MAY |
| 4.16 | ia.ap2 | AP2 | AR-ACT-08 | MAY |
| 4.17 | ia.openapi-quality | OpenAPI actionability quality | AR-ACT-02 | SHOULD |
| 4.18 | ia.mcp-server-card | MCP server card quality | AR-ACT-04 | MAY |
| 4.19 | ia.openapi-live | Live OpenAPI verification | AR-ACT-02 | SHOULD |
| 4.20 | ia.mcp-live | Live MCP verification | AR-ACT-03 | SHOULD |
| 4.21 | ia.ai-catalog | AI Catalog | AR-FIND-04 | MAY |
| 4.22 | ia.api-errors | API error responses | AR-ACT-02 | SHOULD |
| 4.23 | ia.api-rate-limits | API rate-limit headers | AR-ACT-02 | MAY |
| 4.24 | ia.developer-docs-link | Developer docs discoverability | AR-FIND-02, AR-READ-04 | MAY |
| 4.25 | ia.mcp-apps | MCP Apps UI resources | AR-ACT-05 | MAY |
| 4.26 | ia.nlweb-ask | NLWeb ask endpoint | AR-ACT-09 | MAY |
| 4.27 | ia.agent-checkout | Agent checkout | AR-ACT-08 | MAY |
| 4.28 | ia.sdk-cli | SDKs and CLI | AR-ACT-06 | SHOULD |
| 4.29 | ia.agent-task-access | Agent task access | AR-ACT-10 | MUST |
| 4.30 | ia.docs-answer | Docs pages that answer | AR-READ-04, AR-FIND-02, AR-READ-05 | SHOULD |
Fix Workflows: WebMCP
4.1 WebMCP declarative API
Passes with toolname and tooldescription on a form or field, or with document.modelContext.registerTool(). Only hyphenated attributes (tool-name) or navigator.modelContext give partial credit.
- Annotate the forms that agents need:
<form action="/search" method="get" toolname="search_products" tooldescription="Search the product catalog by keyword and category"> <label for="q">Search</label> <input id="q" name="q" toolparamdescription="Search keywords"> </form> - Or register a tool in script. See references/webmcp-guide.md.
Verify: curl -sf https://example.com/ | grep -oE '<form[^>]*toolname="[^"]*"'
4.7 Declarative form quality
Applies to forms with toolname and tooldescription. The check wants a snake_case toolname, a tooldescription of 10 or more characters, a name and a <label> on each field, and toolparamdescription on the inputs.
- Use the form in 4.1 as the pattern. Give each field
name,id, a<label for>andtoolparamdescription.
Verify: curl -sf https://example.com/ | grep -oE 'tool(name|description|paramdescription)="[^"]*"'
4.9 Interactive surface coverage
Counts the visible forms, search inputs, action buttons and filter controls. Passes when tool annotations cover them. Hidden, inert and template content does not count.
- Annotate each search, filter and main action form as in 4.1. Aim for 50% or more coverage.
Verify: curl -sf https://example.com/ | grep -c '<form' (compare with the tool forms from 4.1)
Fix Workflows: Agent and API Discovery
4.3 A2A Agent Card
Passes with an A2A 1.0 card at /.well-known/agent-card.json (or /.well-known/agent.json) with name, description, version, capabilities and a complete supportedInterfaces entry. A legacy 0.3 card gives partial credit.
- Publish the card:
{ "name": "Example Support Agent", "description": "Answers order and product questions", "version": "1.0.0", "capabilities": { "streaming": false, "pushNotifications": false }, "supportedInterfaces": [ { "url": "https://example.com/a2a/v1", "protocolBinding": "JSONRPC", "protocolVersion": "1.0" } ], "skills": [{ "id": "order_status", "name": "Order status", "description": "Get the status of an order" }] }
Verify: curl -sf https://example.com/.well-known/agent-card.json | jq -e '.name and .description and .version and .capabilities and (.supportedInterfaces | length > 0)'
4.4 MCP discovery
Passes when /.well-known/mcp.json, /.well-known/mcp/server-card.json or /.well-known/mcp/server-cards.json has name or serverInfo.name. A legacy mcpServers map also passes.
- Publish a server card (SEP-1649):
{ "name": "com.example/catalog", "title": "Example catalog", "version": "1.0.0", "description": "Search products and read order status", "remotes": [{ "type": "streamable-http", "url": "https://example.com/mcp" }] }
Verify: curl -sf https://example.com/.well-known/mcp/server-card.json | jq -e '.name // .serverInfo.name'
4.18 MCP server card quality
Applies when 4.4 finds a card. The check wants identity and version, a transport type and endpoint, the capabilities, auth metadata, and a description or instructions.
- Extend the card from 4.4 with
capabilities(for example{ "tools": {} }) and the auth headers inremotes[].headers. See references/a2a-mcp-guide.md.
Verify: curl -sf https://example.com/.well-known/mcp/server-card.json | jq -e '.version and .description and (.remotes | length > 0)'
4.20 Live MCP verification
The scanner connects to a same-origin Streamable HTTP endpoint. It sends discovery and list requests only. It never calls a tool.
- Serve the MCP endpoint on the same origin as the card, for example
https://example.com/mcp. - Support
server/discover(MCP 2026-07-28) orinitialize. Return method-not-found (HTTP 404, JSON-RPC error) for unknown methods.
Verify: MCP needs a POST request, so no read-only shell check exists. Use the rescan command.
4.25 MCP Apps UI resources
Applies when 4.20 verifies the MCP endpoint. Passes when a tool in tools/list has _meta.ui.resourceUri, or resources/list has ui:// resources that return text/html;profile=mcp-app.
- Link the tool to a UI resource:
{ "name": "show_order", "description": "Show an order", "_meta": { "ui": { "resourceUri": "ui://orders/detail" } } } - Serve
ui://orders/detailfromresources/readwith the MIME typetext/html;profile=mcp-app.
Verify: MCP needs a POST request, so no read-only shell check exists. Use the rescan command.
4.5 OpenAPI / API docs
Passes with OpenAPI 3.x at /openapi.json, /openapi.yaml, /swagger.json, /api-docs or /.well-known/openapi. Swagger 2.x gives partial credit. HTML (for example Swagger UI) does not count.
- Serve the spec as JSON. A complete example is in references/a2a-mcp-guide.md.
{ "openapi": "3.1.0", "info": { "title": "Example API", "version": "1.0.0" }, "servers": [{ "url": "https://example.com/api" }], "paths": {} }
Verify: curl -sf https://example.com/openapi.json | jq -e '.openapi | startswith("3.")'
4.17 OpenAPI actionability quality
Applies to a valid OpenAPI JSON. Each operation needs an operationId, a summary or description, typed parameters, a 2xx response schema and an error model.
- Complete each operation:
"/products": { "get": { "operationId": "listProducts", "summary": "List products", "parameters": [{ "name": "q", "in": "query", "schema": { "type": "string" } }], "responses": { "200": { "description": "Products", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ProductList" } } } }, "default": { "description": "Error", "content": { "application/problem+json": { "schema": { "$ref": "#/components/schemas/Problem" } } } } } } }
Verify: curl -sf https://example.com/openapi.json | jq '[.paths[][] | objects | select(.operationId == null)] | length' (expect 0)
4.19 Live OpenAPI verification
The scanner selects one same-origin GET without auth, path parameters, required inputs or a body. It checks the documented 2xx status and media type.
- Document one public GET such as
GET /api/statusthat returns the documented 2xx response and content type.
Verify: curl -sf https://example.com/openapi.json | jq -r '.paths | to_entries[] | select(.value.get) | .key' | head -5
4.22 API error responses
Applies when 4.5 finds OpenAPI. The scanner requests a missing path under the API base. Passes with 404 or 410 and a JSON body with title, detail, error, message, code, type or status.
- Return problem details for unknown API paths:
{ "type": "about:blank", "title": "Not Found", "status": 404, "detail": "No route for /api/unknown" }
Verify: curl -s -H 'Accept: application/json' https://example.com/api/isagentready-missing-check
4.23 API rate-limit headers
Inspects the responses of 4.19 and 4.22. Passes with RateLimit, RateLimit-Policy or RateLimit-Limit. Only X-RateLimit-* or Retry-After gives partial credit.
- Send the standard headers on API responses:
RateLimit-Policy: "default";q=60;w=60andRateLimit: "default";r=59;t=60.
Verify: curl -sfI https://example.com/api | grep -iE '^(ratelimit|ratelimit-policy|ratelimit-limit):'
4.10 API Catalog (RFC 9727)
Passes when /.well-known/api-catalog returns a linkset array. Each entry needs an anchor and one or more of item, service-desc, service-doc or status.
- Publish the linkset as
application/linkset+json:{ "linkset": [{ "anchor": "https://example.com/api", "service-desc": [{ "href": "https://example.com/openapi.json", "type": "application/openapi+json" }], "service-doc": [{ "href": "https://example.com/docs", "type": "text/html" }] }] }
Verify: curl -sf -H 'Accept: application/linkset+json' https://example.com/.well-known/api-catalog | jq -e '.linkset | length > 0'
4.21 AI Catalog
Found through a same-origin Link relation or at /.well-known/ai-catalog.json. The check wants specVersion, a bounded list of entries with a media type and one url or inline data, and same-origin URLs.
- Publish the catalog:
{ "specVersion": "1.0", "entries": [ { "identifier": "urn:air:example.com:mcp:catalog", "displayName": "Example MCP server", "type": "application/mcp-server-card+json", "url": "https://example.com/.well-known/mcp/server-card.json" } ] }
Verify: curl -sf https://example.com/.well-known/ai-catalog.json | jq -e '.specVersion and (.entries | length > 0)'
4.11 Agent Skills index
Passes when /.well-known/agent-skills/index.json (or /.well-known/skills/index.json) has a skills array. Each entry needs name, type, description, url and digest.
- Publish the index (v0.2.0):
{ "$schema": "https://schemas.agentskills.io/discovery/0.2.0/schema.json", "skills": [{ "name": "place-order", "type": "skill-md", "description": "Place an order", "url": "https://example.com/.well-known/agent-skills/place-order/SKILL.md", "digest": "sha256:<64 hex>" }] }
Verify: curl -sf https://example.com/.well-known/agent-skills/index.json | jq -e '.skills | all(.name and .type and .description and .url and .digest)'
4.6 agents.json
Passes with a valid, non-empty JSON document at /.well-known/agents.json or /agents.json.
- Publish the agent list:
{ "agents": [{ "name": "Support agent", "url": "https://example.com/a2a/v1", "protocol": "a2a" }] }
Verify: curl -sf https://example.com/.well-known/agents.json | jq -e 'length > 0'
4.24 Developer docs discoverability
Applies when the site has an API, MCP or A2A surface. Passes when the homepage links to /docs, /developers, /api, /api-docs, /documentation or /reference, or sends a Link header with rel="service-doc".
- Add a docs link to the main navigation:
<a href="/docs">Developer docs</a>.
Verify: curl -sf https://example.com/ | grep -oE 'href="/(docs|developers|api|api-docs|documentation|reference)[/"]'
4.30 Docs pages that answer
Applies when 4.24 finds a docs link. The scanner reads one to three docs pages. It wants status 200, server-rendered text, headings, enough text and fenced code with a language class.
- Render docs as server HTML. Mark each code block with its language:
<h2>Create a project</h2> <pre><code class="language-bash">curl https://example.com/api/projects</code></pre>
Verify: curl -sf https://example.com/docs | grep -cE '<code[^>]*class="[^"]*language-'
4.28 SDKs and CLI
Passes when the docs link to npm, PyPI, crates.io or Homebrew, the docs show install commands, or llms.txt or the AI Catalog lists a CLI.
- Publish the SDK or CLI. Add the install command to the docs and to llms.txt:
## Tools - [CLI](https://www.npmjs.com/package/@example/cli): `npm install -g @example/cli`
Verify: curl -sf https://example.com/llms.txt | grep -iE 'npm|pypi|crates.io|brew|cli'
4.29 MCP server or CLI for task sites
Applies to transactional and task sites. Passes when 4.20 verifies an MCP server or 4.28 finds a CLI.
- Give agents one direct path to the tasks of the site: a verified MCP server (4.4 and 4.20) or a CLI (4.28).
Verify: this check uses the results of 4.20 and 4.28. Use the rescan command.
4.26 NLWeb ask endpoint
Experimental. The scanner sends a fixed, harmless GET to /ask?query= and looks for an NLWeb ask tool on /mcp. It wants JSON with schema.org results.
- Serve the NLWeb ask endpoint:
{ "query": "help", "results": [{ "@type": "Article", "name": "Getting started", "url": "https://example.com/docs/start" }] }
Verify: curl -sf 'https://example.com/ask?query=help' | jq -e '.results | type == "array"'
Fix Workflows: Agent Commerce
These checkpoints apply only when the site shows commerce signals (Offer or Product JSON-LD). The probes are read-only. The scanner never sends a POST to a commerce endpoint.
4.12 x402 payments
Passes when /api, /api/v1 or / returns HTTP 402 with a valid x402 v2 challenge in the Payment-Required header (Base64 JSON).
- On paid endpoints, return 402 and Base64-encode this JSON into the
Payment-Requiredheader:{ "x402Version": 2, "resource": { "url": "https://example.com/api/report" }, "accepts": [{ "scheme": "exact", "network": "eip155:8453", "amount": "10000", "asset": "0xUSDCAddress", "payTo": "0xYourAddress", "maxTimeoutSeconds": 60 }] }
Verify: curl -s -D - -o /dev/null https://example.com/api | grep -iE '^(HTTP/|payment-required:)'
4.13 MPP (x-payment-info)
Passes when an operation in /openapi.json has a valid x-payment-info extension.
- Add the extension to the paid operation:
"x-payment-info": { "price": "0.01", "currency": "USD", "protocols": ["x402"] }.
Verify: curl -sf https://example.com/openapi.json | jq -e '[.paths[][] | objects | has("x-payment-info")] | any'
4.14 UCP
Passes when /.well-known/ucp returns a profile with version and a non-empty capabilities list.
- Publish the profile:
{ "version": "2026-01-11", "capabilities": [{ "name": "dev.ucp.shopping.checkout" }] }.
Verify: curl -sf https://example.com/.well-known/ucp | jq -e '.version and (.capabilities | length > 0)'
4.15 ACP manifest
Passes when /.well-known/acp.json has a non-empty flows list and a capabilities object.
- Publish the document:
{ "flows": ["checkout"], "capabilities": { "checkout_sessions": "https://example.com/acp/checkout_sessions" } }.
Verify: curl -sf https://example.com/.well-known/acp.json | jq -e '(.flows | length > 0) and (.capabilities | type == "object")'
4.16 AP2
Passes when the A2A Agent Card from 4.3 declares the AP2 extension.
- Add to the card:
"extensions": [{ "uri": "https://google.github.io/A2A/extensions/ap2", "required": false }].
Verify: curl -sf https://example.com/.well-known/agent-card.json | jq -e '[.extensions[]?.uri] | any(test("ap2"))'
4.27 Agent checkout (Link, ACP checkout)
Experimental. Passes with Stripe Link or Shared Payment Token markers on the checkout pages, or with a checkout_sessions endpoint in the ACP document from 4.15.
- Turn on Stripe Link in the Payment Element, or accept Shared Payment Tokens.
- Declare the ACP
checkout_sessionsendpoint in/.well-known/acp.json.
Verify: curl -sf https://example.com/.well-known/acp.json | jq -e '.. | strings | select(test("checkout_sessions"))'
Key Gotchas
- Only
tool-name(hyphenated) gives partial credit. Usetoolname. - An A2A 0.3 card with a top-level
urland nosupportedInterfacesgives partial credit. - Swagger UI HTML at
/api-docsdoes not count as OpenAPI. - An empty
{}document fails each discovery check. - A WebMCP manifest file does not count. No spec defines one and no agent reads one.
See references/gotchas.md for correct and incorrect examples.
References
- references/checkpoints.md: generated checkpoint data for each checkpoint
- references/webmcp-guide.md: declarative and imperative WebMCP
- references/a2a-mcp-guide.md: A2A, MCP, OpenAPI and agents.json
- references/gotchas.md: common errors with correct and incorrect examples