mcpField
A
agent-protocols

agent-protocols

github.com/bartwaardenburgDevelopment0182 installsUpdated 1w ago
Repository

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

  1. 01Configure WebMCP forms and tool annotations
  2. 02Publish an A2A Agent Card
  3. 03Provide MCP discovery data and server cards
  4. 04Publish and improve OpenAPI documentation
  5. 05Verify protocol endpoints and API responses

Use cases

  1. 01Resolve Agent Protocols scan failures
  2. 02Document a website API with OpenAPI
  3. 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-protocols

After installing, type/agent-protocolsin Claude Code to confirm it loaded.

Bundled files

References and scripts installed along with SKILL.md.

references/
a2a-mcp-guide.md
checkpoints.md
gotchas.md
webmcp-guide.md

Details

From the project README

Agent 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.

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

  1. Get the failing checkpoints from the scan. Each result has a legacy id (4.3) and a stable id (ia.a2a-agent-card).
  2. Go to the fix workflow with the anchor that is equal to the stable id.
  3. Adapt the example to the site. Replace example.com with the domain of the site.
  4. Serve each /.well-known/* document as application/json. Make sure that the WAF and CDN do not block it.
  5. 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.

LegacyStable IDNameAR IDsStrength
4.1ia.webmcp-declarativeWebMCP declarative APIAR-ACT-07SHOULD
4.3ia.a2a-agent-cardA2A Agent CardAR-READ-06MAY
4.4ia.mcp-discoveryMCP discoveryAR-ACT-03, AR-ACT-10MAY
4.5ia.openapiOpenAPI / API docsAR-ACT-02SHOULD
4.6ia.agents-jsonagents.jsonnoneMAY
4.7ia.webmcp-form-qualityDeclarative form qualityAR-ACT-07SHOULD
4.9ia.interactive-surface-coverageInteractive surface coverageAR-ACT-07SHOULD
4.10ia.api-catalogAPI Catalog (RFC 9727)AR-READ-06, AR-ACT-02SHOULD
4.11ia.agent-skills-indexAgent Skills indexAR-ACT-06MAY
4.12ia.x402x402 paymentsAR-ACT-08MAY
4.13ia.mppMPP (x-payment-info)AR-ACT-08MAY
4.14ia.ucpUCPAR-ACT-08, AR-READ-06MAY
4.15ia.acp-manifestACP manifestAR-ACT-08, AR-READ-06MAY
4.16ia.ap2AP2AR-ACT-08MAY
4.17ia.openapi-qualityOpenAPI actionability qualityAR-ACT-02SHOULD
4.18ia.mcp-server-cardMCP server card qualityAR-ACT-04MAY
4.19ia.openapi-liveLive OpenAPI verificationAR-ACT-02SHOULD
4.20ia.mcp-liveLive MCP verificationAR-ACT-03SHOULD
4.21ia.ai-catalogAI CatalogAR-FIND-04MAY
4.22ia.api-errorsAPI error responsesAR-ACT-02SHOULD
4.23ia.api-rate-limitsAPI rate-limit headersAR-ACT-02MAY
4.24ia.developer-docs-linkDeveloper docs discoverabilityAR-FIND-02, AR-READ-04MAY
4.25ia.mcp-appsMCP Apps UI resourcesAR-ACT-05MAY
4.26ia.nlweb-askNLWeb ask endpointAR-ACT-09MAY
4.27ia.agent-checkoutAgent checkoutAR-ACT-08MAY
4.28ia.sdk-cliSDKs and CLIAR-ACT-06SHOULD
4.29ia.agent-task-accessAgent task accessAR-ACT-10MUST
4.30ia.docs-answerDocs pages that answerAR-READ-04, AR-FIND-02, AR-READ-05SHOULD

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.

  1. 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>
    
  2. 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.

  1. Use the form in 4.1 as the pattern. Give each field name, id, a <label for> and toolparamdescription.

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.

  1. 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.

  1. 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.

  1. 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.

  1. Extend the card from 4.4 with capabilities (for example { "tools": {} }) and the auth headers in remotes[].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.

  1. Serve the MCP endpoint on the same origin as the card, for example https://example.com/mcp.
  2. Support server/discover (MCP 2026-07-28) or initialize. 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.

  1. Link the tool to a UI resource:
    { "name": "show_order", "description": "Show an order", "_meta": { "ui": { "resourceUri": "ui://orders/detail" } } }
    
  2. Serve ui://orders/detail from resources/read with the MIME type text/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.

  1. 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.

  1. 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.

  1. Document one public GET such as GET /api/status that 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.

  1. 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.

  1. Send the standard headers on API responses: RateLimit-Policy: "default";q=60;w=60 and RateLimit: "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.

  1. 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.

  1. 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.

  1. 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.

  1. 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".

  1. 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.

  1. 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.

  1. 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.

  1. 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.

  1. 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).

  1. On paid endpoints, return 402 and Base64-encode this JSON into the Payment-Required header:
    { "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.

  1. 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.

  1. 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.

  1. 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.

  1. 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.

  1. Turn on Stripe Link in the Payment Element, or accept Shared Payment Tokens.
  2. Declare the ACP checkout_sessions endpoint in /.well-known/acp.json.

Verify: curl -sf https://example.com/.well-known/acp.json | jq -e '.. | strings | select(test("checkout_sessions"))'

Key Gotchas

  1. Only tool-name (hyphenated) gives partial credit. Use toolname.
  2. An A2A 0.3 card with a top-level url and no supportedInterfaces gives partial credit.
  3. Swagger UI HTML at /api-docs does not count as OpenAPI.
  4. An empty {} document fails each discovery check.
  5. 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

Comments

Markdown supported