Thin x402 payment gateway + MCP server: charge agents USDC per HTTP route or tool call
Four tools with mixed quality. All have descriptions and basic schemas, but several lack proper input validation, parameter type definitions are inconsistent, and error handling is generic. The proxy_request and fetch_md tools accept complex inputs but lack comprehensive parameter guidance. Output schemas are undocumented. Tool naming is acceptable but could be more action-specific. Overall fair but with significant gaps in parameter validation and output documentation.
Fetch a public http(s) URL and convert HTML to Markdown. Requires payment of {price} USDC. Same capability as HTTP GET /v1/fetch-md.
Fetch a sample quote from the upstream API (mock when UPSTREAM_URL is unset). Requires payment of {price} USDC.
Forward method/path/query/headers/body to UPSTREAM_URL (or mock). Requires payment of {price} USDC.
Gateway status: mode, network, price, gatedPrefix, upstream. No payment required.
proxy_request lacks validation guidance for HTTP methods and path constraints. Description mentions '(GET, POST, PUT, PATCH, DELETE, …)' but does not constrain to enum or state which are allowed. LLMs may pass invalid methods.
No output schemas documented for any tool. LLMs cannot plan downstream actions or extract required fields. The textResult() helper returns generic { content: [{ type: 'text', text: JSON.stringify(...) }], isError? } but this structure is not declared in tool registration.
proxy_request 'query' and 'headers' parameters use z.record(z.string()) but do not enforce type safety on values. 'query' schema allows union of string|number|boolean|null but description does not explain serialization rules. LLMs may pass nested objects.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 63 | 2026-07-28+ | v2 |
fetch_md error handling is minimal. Catches generic errors and returns { error: code, message } but does not distinguish between network failures, invalid URLs, parsing errors, or SSRF blocks. No recovery guidance provided.
get_quote and proxy_request descriptions mention payment requirement ('{price} USDC') but do not explain what triggers payment, whether the call fails if payment is insufficient, or how to check balance beforehand. Payment flow is opaque to the LLM.
proxy_request 'body' parameter typed as z.unknown() with description 'Optional JSON body for non-GET requests'. No validation that GET/HEAD/DELETE omit body, no enforcement of JSON structure for methods that require it. LLMs may pass invalid combinations.
fetch_md description does not specify supported URL schemes, rate limits, content size limits, or SSRF-blocked domains. HTTPS URL requirement is not stated. LLMs may attempt to fetch file://, data://, or localhost URLs.