Files
Claude e3536df3c9 refactor: address review feedback on the Server Card API surface
- Replace build_server_card() with the ServerCard.from_server() classmethod,
  matching the SDK's from_* alternate-constructor idiom; the _ServerIdentity
  protocol moves to mcp.shared.experimental.server_card alongside it.
- Make DiscoveryResult iterable over its listings (__iter__/__len__), so
  'for listing in result:' works without the .listings attribute hop.
- Remove the client-side server_card_url() helper: card URLs must come from
  an AI Catalog entry per the discovery spec, never be constructed by the
  client. fetch_server_card's docstring now says so.
- Explain the RFC 6598 shared address space constant in the SSRF guard and
  rename it _CGNAT_NETWORK -> _SHARED_ADDRESS_SPACE; ipaddress reports these
  addresses as neither private nor global, so the guard names them explicitly.

All symbols are experimental (no deprecation cycle), so the removals are clean.
2026-08-02 18:15:56 +00:00

23 lines
1.2 KiB
Python

import httpx2
from mcp import Client
from mcp.client.experimental.server_card import discover_server_cards, reconcile_server_card
from mcp.client.streamable_http import streamable_http_client
from mcp.shared.experimental.server_card import resolve_remote
async def main() -> None:
result = await discover_server_cards("https://example.com/docs")
for listing in result:
print(listing.entry.identifier, "listed on", listing.listing_domain, "hosted at", listing.hosting_domain)
chosen = result.listings[0] # your host app: consent UI, dedup on chosen.card.endpoint_urls()
assert chosen.card.remotes is not None
resolved = resolve_remote(chosen.card.remotes[0], {"token": "..."}) # ValueError names missing inputs
async with httpx2.AsyncClient(headers=resolved.headers, follow_redirects=True) as http_client:
transport = streamable_http_client(resolved.url, http_client=http_client)
async with Client(transport) as client:
for mismatch in reconcile_server_card(chosen.card, client.server_info): # advisory: runtime wins
print("card mismatch:", mismatch.field, mismatch.card_value, mismatch.runtime_value)