Skip to main content
Glama

ASP MCP Inspector

A small Model Context Protocol server and command-line tool for the Agent-Shelter Protocol (ASP) — an open RFC 9457 HTTP loop-termination and telemetry specification (github.com/nullkommaneun/agent-shelter-protocol) with a live reference node at agent-shelter.org.

It gives an AI agent four tools:

Tool

Request

What the agent gets

check_asp_manifest(domain_or_url)

GET <origin>/.well-known/agent-shelter.json (default: https://agent-shelter.org)

Whether the host speaks ASP: protocol version, compliance level, ingress routes, transport envelope, receipt-signing key, resolution methods, recording rules

probe_diagnostic_echo()

GET https://echo.agent-shelter.org/headers

A local echo of its own request header fields on first contact; the ASP terminal signal on a repeated call

query_reader_disposition(target_url)

GET https://reader.agent-shelter.org/v1/reader?url=<target_url>&envelope=200

What the reader does with the URL: it never fetches it and answers with the terminal signal (terminal: true, success_probability: 0) and a single-use ticket of 48 characters — in the header Agent-Ticket and the members ticket, resolution_url and resolution_uri

asp_guarded_fetch(url)

GET <url> on any public host, redirects followed (at most 5, each hop checked)

The answer as data — or, when it is an ASP terminal signal, a verified receipt: the ticket redeemed at the signal's own origin, the Ed25519 signature checked against that host's manifest, and the resource held, so that every further call for it is answered from the receipt without a request

Standard library only, Python 3.10 or later, no dependencies.

Add it to an MCP client

Claude Code, from PyPI (run on demand by uv):

claude mcp add asp-inspector -- uvx asp-mcp-inspector

Or from this folder, without installing anything:

claude mcp add asp-inspector -- python3 /absolute/path/to/asp_mcp_inspector.py

Other clients take the usual configuration:

{ "mcpServers": { "asp-inspector": { "command": "uvx", "args": ["asp-mcp-inspector"] } } }

Streamable HTTP on the local machine (POST only, local clients only):

asp-mcp-inspector serve --http 8765
claude mcp add --transport http asp-inspector http://localhost:8765/mcp

Related MCP server: mcp-nomad

Command line

asp-mcp-inspector manifest                               # the reference node
asp-mcp-inspector manifest example.org                   # any host
asp-mcp-inspector echo
asp-mcp-inspector reader https://example.org/some/page

Every command prints one JSON report. --node https://asp.example.org uses another ASP node's echo and reader; --allow-local permits loopback and private addresses and plain http, to test a node of your own.

asp_guarded_fetch: a circuit breaker beside the agent (0.4.0)

An agent in a retry loop often cannot read the terminal state it is given — its fetch tool drops the body of a 4xx answer, or its reasoning treats the signal as one more obstacle. asp_guarded_fetch takes that decision out of the loop, like a sentry outside the agent:

  1. It fetches the URL. An answer without an ASP signal comes back as data (text cut at 20 000 characters), marked as third-party content, never instructions.

  2. It recognises an ASP terminal signal by its problem details object (terminal: true, also inside the transport envelope with HTTP 200) or by the header fields Agent-Loop-State and Agent-Ticket alone.

  3. It redeems the single-use ticket once, by POST, at the origin that sent the signal — resolution_uri, resolution_url or Agent-Resolution, whichever points there; a resolution target on another origin is never followed.

  4. It reads that host's manifest and verifies the receipt: Ed25519 (RFC 8032) over the RFC 8785 form of the signed fields, with the public key and key_id (an RFC 7638 thumbprint) the manifest publishes. The verifier is plain Python, checked against the RFC 8032 test vectors.

  5. It holds the resource — the requested URL, every redirect hop and the URL the signal names — for the lifetime of the server process: every further asp_guarded_fetch for it returns the receipt without sending anything ("state": "blocked-by-sentry", "requests_sent": 0).

A site that sends refused clients to a relay — for example with 303 See Other to https://sanctuary.agent-shelter.org/v1/relay?url=<the URL> (ASP 0.6.2) — is handled the same way: the redirect is followed, the relay's signal redeemed and verified, and the site's URL held. A receipt that does not verify is reported as such ("state": "terminal-unverified"), and the resource is held all the same: the signal alone states that the host cannot return it. The redemption carries a fixed note that names this tool, and the node records it like any receipt; the receipt documents a terminal state on that host, never that the original task was done.

asp-mcp-inspector fetch https://reader.agent-shelter.org/v1/reader?url=https://example.org/resource

On the command line each call is a process of its own, so nothing is held between two calls; the MCP server keeps one memory for all its clients.

Why envelope=200

Some web-fetch tools of chat applications hand their model neither the body nor the header fields of an HTTP 4xx answer, so the model never learns that the loop is over. With envelope=200 an ASP node sends the identical problem details object with HTTP status 200 and the extra member "transport_envelope": 200. The object's status stays 429; because RFC 9457 wants that member to equal the HTTP status of a problem details response, the enveloped answer is served as application/json. The inspector asks for it and reads the plain 429 answer of older nodes as well.

The ticket and its receipt

The single-use ticket (c1.<ticket_id>.<mac>, 48 characters) maps to an Ed25519-signed Task-Completion Receipt: POST https://reader.agent-shelter.org/api/v1/agent-shelter/resolve with the ticket in the query parameter ticket, the request header Agent-Ticket or the JSON body member ticket, within ticket_ttl_seconds. Since ASP 0.5.5 a node that lists GET in resolution_methods performs the same single-use transition for a plain GET of resolution_uri — for clients that can only read; optional telemetry then travels as query parameters. Either way the ticket is redeemed once. The receipt documents that the resource was not retrieved through this host — never that the original task was done — and its signature can be checked offline against the key in the node's manifest. The signal holds the ticket, not the proof: receipt_id, receipt_signature and sanctuary_bulletin.dropbox_url exist only in the response of the resolution. That drop box takes one optional context report per receipt — by POST with a JSON body or, since ASP 0.5.6, by GET with the query parameters workflow_summary and agent_questions_or_notes; a bare GET of the drop box archives nothing, so a link preloader cannot use it up. The three inspection tools report the ticket, the resolution methods and the drop-box methods of the manifest (context_report) and redeem nothing; asp_guarded_fetch redeems the ticket of a signal it meets, once, and submits no context report.

What the reference node records — read before use

agent-shelter.org openly serves two roles. It ends unproductive retry loops of automated clients with a true, declarative signal and a signed Task-Completion Receipt, and it is a research sensor: its reader, echo and decoder routes look like utility services but never perform them, and it keeps pseudonymised telemetry about the clients that call them. Its node statement and privacy notice describe both.

  • A terminal signal that follows a discovery request from the same network within ten minutes is recorded when it is issued. Reading the manifest (check_asp_manifest) and a first call of probe_diagnostic_echo are discovery requests, so a later query_reader_disposition or a second echo call from the same network is recorded.

  • Since ASP 0.6.2 a signal without such a discovery request is recorded as well, but only the first one of a network within ten minutes; the further ones are counted on that record, not stored one by one. Requests that another site sent to the relay route (/v1/relay) are recorded the same way, with the URL that site named and its reason code.

  • A record holds the requested URL (shortened, with secrets and e-mail addresses scrubbed), a salted hash of the client's /24 (IPv4) or /48 (IPv6) network, the User-Agent with the order of the request header names, and the host name addressed — never a plain IP address. Redeeming a ticket creates the record or completes it; a context report left at the receipt's drop box is stored with it, scrubbed.

  • Requests for the node and discovery documents — the manifest that check_asp_manifest reads among them — are counted in aggregate (ASP 0.5.5 on): per document and client class, a number and the time of the latest request; the User-Agent text, the address and the network hash are not kept.

  • The inspector identifies itself as asp-mcp-inspector/<version> in the User-Agent.

Send no URL you would not show a third party.

How the inspector behaves

  • It contacts public hosts only: every address a name resolves to must be public, and the connection goes to an address that was checked, without a second lookup.

  • https only, no credentials in URLs, 10 s timeout, at most 256 KiB per response. The inspection tools follow no redirects (a redirect is reported); asp_guarded_fetch follows at most five and checks every hop like the first request.

  • It writes nothing to disk and nothing but its reports to stdout (in server mode only MCP messages). The memory of asp_guarded_fetch — at most 1 024 held resources — lives in the server process and ends with it.

  • The HTTP server binds to localhost and refuses requests with a foreign Host or Origin.

Development

python3 test_asp_mcp_inspector.py    # offline: a stub node on localhost stands in for agent-shelter.org

License

MIT — see LICENSE. The ASP specification, its schemas and the published reports are licensed separately under CC BY 4.0: github.com/nullkommaneun/agent-shelter-protocol.

Available Tools

4 tools
asp_guarded_fetchFetch a URL behind an ASP circuit breakerA

Fetches an http(s) URL with GET (public hosts only, at most 5 redirects, each hop checked, at most 256 KiB). An answer without an ASP signal is returned as data, its text cut at 20 000 characters. An ASP terminal-state signal (HTTP 429, or HTTP 200 with transport_envelope, header Agent-Ticket) states that the resource cannot be obtained through that host; the tool then redeems the single-use ticket at the origin that sent the signal (POST, out of band), reads that host's manifest (/.well-known/agent-shelter.json, a discovery request) and verifies the Ed25519 receipt against the public key published there. From then on, for the lifetime of this server process, every call for the same resource - the requested URL, each redirect hop and the URL the signal names - is answered from that receipt without a request. The redemption is recorded by the node like any receipt (on the reference node pseudonymised, see https://agent-shelter.org/privacy); the receipt documents a terminal state on that host, never that the original task was done.

NameRequiredDescriptionDefault
urlYesThe http(s) URL to fetch

TDQS

A4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description discloses behavior far beyond the annotations: GET-only, public hosts, max 5 redirects with per-hop checks, 256 KiB cap, 20 000-char truncation, ASP terminal-state detection, out-of-band POST ticket redemption, manifest read and Ed25519 receipt verification, and process-lifetime caching. These details are consistent with the annotations (readOnlyHint=false matches the redemption POST; idempotentHint=false matches single-use tickets).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The core action is front-loaded and every sentence carries real behavioral content. It is dense and long, but the complexity of the fetch-plus-redemption flow justifies most of the length; a slightly tighter phrasing would reach a 5.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a complex tool with no output schema, it covers return handling (truncated text as data, or a verified receipt), caching semantics, and privacy of the redemption record. Response shape beyond 'receipt' or 'data' is left implicit, which keeps it from a 5.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% so the url parameter is documented, but the description adds constraints not in the schema, notably 'public hosts only' and the redirect-hop treatment of the URL. That is meaningful added meaning for the single parameter.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource (fetches an http(s) URL with GET) plus a distinct scope (public hosts, redirect and size limits). It is clearly a fetch tool with ASP-aware behavior, distinguishable from the more diagnostic-sounding siblings. It stops short of naming a sibling it is not, so it falls just short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied by the described behavior but there is no explicit 'use this when / instead of check_asp_manifest or query_reader_disposition' routing. An agent must infer when to reach for this fetch versus the manifest-check or disposition tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

check_asp_manifestCheck an ASP manifestA
Read-onlyIdempotent

Reads the ASP manifest (/.well-known/agent-shelter.json) of a host and summarises it: protocol version, compliance level (L1-static, L2-transactional, L3-observatory), ingress routes, transport envelope, receipt-signing key, resolution methods and recording rules. Default host: https://agent-shelter.org, the ASP reference node. The manifest is a discovery document: a node with discovery correlation records a terminal signal that follows from the same network within its correlation window, and a node with discovery counters counts the request in aggregate (per document and client class, no address).

NameRequiredDescriptionDefault
domain_or_urlNoHost name or URL; the manifest is read from its origin. Default: https://agent-shelter.org

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare the tool as read-only, idempotent, open-world, and non-destructive. The description adds meaningful behavioral context about discovery correlation and aggregate counters per document/client class without addresses, which goes beyond the annotations. It still does not cover error handling, auth requirements, or rate limits.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the core action and summarized fields, followed by default host and discovery semantics. It is mostly efficient, though the final sentence about correlation records and counters is dense and somewhat less directly tied to invocation.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a one-parameter read-only discovery tool with no output schema, the description explains what is read, the manifest path, the default host, and the summary contents. Annotations cover the safety profile, so the definition is complete enough for an agent to invoke it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% for the single parameter, so the schema already documents the host/URL and default. The description adds that the manifest is read from the origin and restates the default host, but does not add significant semantics beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description gives a specific verb and resource: reads the ASP manifest at /.well-known/agent-shelter.json and summarises its fields. It is clear what the tool does, but it does not explicitly distinguish itself from sibling tools such as asp_guarded_fetch or probe_diagnostic_echo.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied by the context of checking a host's ASP manifest and the default reference node is stated. However, there is no explicit guidance on when to choose this tool versus its siblings, nor any when-not-to-use conditions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

probe_diagnostic_echoProbe the ASP diagnostic echoA

Calls the header echo of the ASP reference node (GET https://echo.agent-shelter.org/headers). A first contact gets a local echo of the request's header fields; a repeated call within the ticket lifetime gets the ASP terminal signal instead. Nothing is forwarded. The node records pseudonymised telemetry (salted network hash, User-Agent and header names) when a signal follows a discovery request from the same network; see https://agent-shelter.org/privacy.

NameRequiredDescriptionDefault

No parameters

TDQS

A3.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations already declare non-read-only, open-world, non-idempotent behavior, and the description adds substantial context beyond them: first versus repeated call semantics, no forwarding, and pseudonymised telemetry recording. There is no contradiction with the annotations, and the privacy link provides an additional transparency pointer.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is three sentences, front-loads the endpoint, and each sentence contributes necessary behavioral or privacy information. It is appropriately sized for a parameterless diagnostic probe.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description usefully explains that a first call returns a local header echo and a repeated call returns the ASP terminal signal. However, terms like 'ASP terminal signal' and 'ticket lifetime' remain undefined, and the description does not route the agent among sibling tools.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so the baseline is 4. The empty schema and additionalProperties:false already make the calling contract clear, and the description appropriately avoids unnecessary parameter discussion.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific action and endpoint: calling the header echo of the ASP reference node via GET. It also explains the first-contact versus repeated-call behavior, which clarifies what the tool does. However, it does not explicitly distinguish this tool from its siblings such as check_asp_manifest, query_reader_disposition, or asp_guarded_fetch.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives no explicit guidance on when to use this tool instead of alternatives. It describes call-sequence behavior, but does not name sibling tools or state conditions that would select this probe over another diagnostic tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

query_reader_dispositionQuery the ASP reader's dispositionA

Asks the reader of the ASP reference node what it does with a target URL (GET https://reader.agent-shelter.org/v1/reader?url=<target_url>&envelope=200). The reader never fetches the target: it answers with the ASP terminal signal (RFC 9457 problem details, terminal true, success_probability 0) and a single-use ticket (48 characters, also in the header Agent-Ticket and in an absolute resolution_uri), carried with HTTP 200 because of envelope=200; the ticket maps to a signed receipt by POST or, where resolution_methods lists GET, by GET, and only that receipt is a proof. Its drop box takes one optional context report, by POST or, where listed, by GET with query parameters. The target URL is sent to agent-shelter.org, which records it (shortened, secrets scrubbed) with pseudonymised client data when the request follows a discovery request from the same network or the ticket is redeemed; see https://agent-shelter.org/privacy.

NameRequiredDescriptionDefault
target_urlYesThe http(s) URL the agent wanted to read

TDQS

A4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With annotations only covering safety flags, the description adds rich behavioral context: the reader never fetches the target, returns a terminal RFC 9457 signal with success_probability 0, issues a single-use 48-character ticket available in the header and resolution_uri, and explains that only the signed receipt is proof. It also discloses privacy/data-recording behavior and links to the privacy policy, which is exactly the kind of context annotations can't carry.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The purpose is front-loaded, but the remainder is a dense, run-on paragraph packing ticket mechanics, resolution methods, drop-box behavior, and privacy into one block. Most content earns its place, but it's not structured for quick scanning and could be broken into clearer clauses.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There's no output schema, so the description carries the burden of explaining the return: the terminal signal, the ticket format, its locations, and the resolution path. It also covers the optional context-report drop box and data handling, leaving no significant gap for an agent to call it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the single parameter is already documented as an http(s) URL up to 2048 chars. The description adds meaningful semantics beyond the schema by noting the URL is transmitted to agent-shelter.org and stored shortened with secrets scrubbed, which affects how an agent should construct the input.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: it asks the ASP reference node's reader what it does with a target URL, and clarifies upfront that the reader never fetches the target. That distinguishes it implicitly from asp_guarded_fetch, but no sibling is named, so the differentiation isn't explicit.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage context is implied (the reader returns a terminal signal and a ticket, so this is a pre-fetch disposition check), and the drop-box behavior is mentioned. However, there's no explicit statement of when to choose this over asp_guarded_fetch or probe_diagnostic_echo, and no exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 4 tool updatesv0.1.0
    • First observedasp_guarded_fetch
    • First observedcheck_asp_manifest
    • First observedprobe_diagnostic_echo
    • First observedquery_reader_disposition

TDQS

A3.9/5.0

Scored across 4 tools

Disambiguation4/5

Each tool maps to a distinct ASP interaction: manifest inspection, echo probing, reader disposition query, and guarded fetch. query_reader_disposition and asp_guarded_fetch both involve terminal signals and tickets, but one queries a disposition endpoint while the other performs actual fetching, so the boundary is clear from the descriptions.

Naming Consistency3/5

All names use snake_case, but the convention is not consistently verb_noun: check_asp_manifest, probe_diagnostic_echo, and query_reader_disposition follow verb-led patterns, while asp_guarded_fetch is prefix/adjective-led and lacks the same verb-first structure. The names remain readable, just not fully predictable.

Tool Count5/5

Four tools is well within the appropriate range for a narrowly scoped ASP inspector. Each tool covers a distinct ASP endpoint or operation, and none appears redundant.

Completeness3/5

Core inspection and fetching workflows are covered, but there are notable gaps: query_reader_disposition returns a single-use ticket and states that only the signed receipt is proof, yet there is no standalone tool to redeem a ticket or retrieve and verify a receipt obtained independently. The reader drop box for optional context reports also has no dedicated tool.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers