# What a Real MCP and A2A Conformance Scan Actually Checks

> Source: <https://contextiq.trango-compute.com/blog/mcp-a2a-protocol-conformance-scan-explained>
> Published: 2026-09-18 00:00:00+00:00

# What a Real MCP and A2A Conformance Scan Actually Checks

Inside the MCP and A2A conformance checks that go beyond detection: server/discover vs the legacy initialize handshake, RFC 9728 auth metadata, CIMD vs DCR, and agent-card spec-lint rules.

"Does this URL support MCP?" is the easy question. A `200` response from a Streamable HTTP endpoint answers it in one request. The harder, more useful question is whether that endpoint actually implements the spec correctly enough to be worth depending on — and that requires checking a lot more than whether it answers at all.

Agent Protocol Inspector reports a three-state result for every protocol it checks: **`not_detected`**, **` indicated`** (some signal, not fully validated), or **` confirmed`** (found and validated). Getting to `confirmed` means passing a specific set of checks per protocol, each producing its own evidence — not a single boolean.

## MCP: Two Eras, One Scanner

The Model Context Protocol's **2026-07-28** revision replaced the original stateful design with a fully stateless core, and a real conformance scan has to speak both.

**Legacy (pre-2026-07-28).** A client sends a JSON-RPC `initialize` request with its `protocolVersion` and `clientInfo`; the server responds with its own `serverInfo`, negotiated `protocolVersion`, and a `Mcp-Session-Id` header that scopes every subsequent call.

**Modern (2026-07-28+).** The stateful handshake is gone. Every request carries its protocol version via `_meta`, and a new mandatory `server/discover` call advertises supported versions and capabilities up front, with no session to establish first. This revision also put **Roots**, **Sampling**, and **Logging** on a deprecation track (removal no earlier than 2027-07-28) and shortened the runway for the dedicated HTTP+SSE transport (protocol version 2024-11-05), which has been deprecated since March 2025.

A scanner that only speaks one era silently misreports every server on the other one as broken. Agent Protocol Inspector probes `server/discover` first and falls back to the legacy `initialize` handshake — both paths produce a real `confirmed` result with the era recorded, not just a pass/fail.

Beyond the handshake itself, the scan checks things that only show up on a second look:

- **Tool list stability** — calling`tools/list` twice and comparing ordering. A tool list that reorders between identical calls is a real integration hazard for any client that indexes tools positionally.
- **Cache metadata presence** — whether the server declares a TTL and scope for its tool list, missing on servers that never considered client-side caching.
- **Extensions** — non-core capability extensions the server advertises beyond the baseline spec.

## MCP Authentication: Beyond "Requires OAuth"

An MCP server behind auth answers with a `401` or `403` and a `WWW-Authenticate` header. From there, the scan follows the actual discovery chain a real client would have to implement:

1. Parse `resource_metadata` out of the challenge, or check`/.well-known/oauth-protected-resource` directly (RFC 9728).
2. Read the declared `authorization_servers[0]` as the issuer.
3. Check the issuer's `/.well-known/openid-configuration` and`/.well-known/oauth-authorization-server` (RFC 8414) independently — not one as a fallback for the other, since an issuer can genuinely serve both.
4. Classify the client-registration mechanism: **Client ID Metadata Documents** (`client_id_metadata_document_supported: true` ) versus**Dynamic Client Registration** (a bare`registration_endpoint` , RFC 7591). DCR-only gets flagged with a specific deprecation note, since CIMD is the current mechanism.

That step-3 independence turned out to matter in practice — we cover exactly how, and what it looks like on real MCP servers, in a [dedicated post on detecting OpenID Connect vs. bare OAuth 2.0](https://contextiq.trango-compute.com/blog/mcp-server-openid-connect-oauth2-detection).

## A2A: Spec-Lint, Not Just Card-Parsing

Fetching an Agent Card successfully only means the JSON parsed. A `confirmed` A2A result also runs the card through a set of spec-hygiene checks:

- **Required fields** —`protocolVersion` ,`version` ,`url` ,`description` all present.
- **Skill quality** — at least one skill declared, and every skill has a description. A routing agent selects which agent to delegate to based on skill descriptions; a skill with no description is invisible to that routing logic even though it technically exists.
- **Input/output modes declared** —`defaultInputModes` and`defaultOutputModes` present, since a client can't negotiate content types with an agent that never states what it accepts.
- **Security scheme declared** — flagged when a production-shaped agent has no`securitySchemes` at all.
- **Legacy path warning** — a card served only from`/.well-known/agent.json` (the pre-0.3.0 path) rather than the current`agent-card.json` .
- **Embedded secrets** — the card's raw JSON is checked against a credential-pattern regex. An agent card is a public document by definition; a stray API key or bearer token baked into one is a real, surprisingly common leak class.
- **OIDC URL resolution** — if the card declares an`openIdConnectUrl` in its security schemes, the scan actually fetches it and confirms it resolves to a document with an`issuer` or`authorization_endpoint` — a declared-but-dead discovery URL is worse than not declaring one, since a client will trust it until it tries to use it.

Two of these rules exist specifically because of false positives caught during validation against real targets, not theoretical ones: an early "agent-card" keyword and later a "schema" keyword were both dropped from unrelated matching logic after they fired on ordinary API-documentation language that had nothing to do with the capability being checked. Every rule that ships has been checked against a real card, not just written from the spec text.

## Why the Distinction Matters

A `confirmed` badge that only means "an endpoint returned 200" isn't something you can build a decision on. The warnings and lint layer is what turns "this looks like MCP" into "this is a spec-conformant MCP server with declared, resolvable authentication metadata" — the difference between a detection and something you can actually route production traffic to.

Run [Agent Protocol Inspector](https://contextiq.trango-compute.com/agent-readiness-detector) against your own MCP server or A2A agent before you tell anyone else it's ready — the warnings it surfaces are the same gaps a real integrating client would hit first.

Follow Trango Compute on LinkedIn

We post updates on new tools, context engineering patterns, and LLM cost research.

[Follow on LinkedIn](https://www.linkedin.com/company/trango-compute)
