Skip to main content
Glama
sF1nX

x402station-mcp

7-day forensics report

forensics

Analyze an x402 endpoint with 7-day hourly uptime, latency percentiles, status-code distribution, namespace concentration, and decoy probability score. Fee: $0.001 USDC.

Instructions

Deep history for one x402 endpoint: hourly uptime over 7 days, latency p50/p90/p99, status-code distribution, concentration-group stats (how crowded this provider's namespace is), and a decoy probability score [0, 1]. Costs $0.001 USDC. Superset of preflight — if you're running forensics you don't need preflight too.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
urlYesThe full URL of the x402 endpoint to analyse.

Implementation Reference

  • src/index.ts:366-387 (registration)
    MCP server registration of the 'forensics' tool. Registered via server.registerTool with zod schema for url input, calls callPaid('/api/v1/forensics', {url}) and returns text content or error.
    server.registerTool(
      "forensics",
      {
        title: "7-day forensics report",
        description:
          "Deep history for one x402 endpoint: hourly uptime over 7 days, latency p50/p90/p99, status-code distribution, concentration-group stats (how crowded this provider's namespace is), and a decoy probability score [0, 1]. Costs $0.001 USDC. Superset of preflight — if you're running forensics you don't need preflight too.",
        inputSchema: {
          url: z.string().url().describe("The full URL of the x402 endpoint to analyse."),
        },
      },
      async ({ url }) => {
        try {
          const text = await callPaid("/api/v1/forensics", { url });
          return { content: [{ type: "text" as const, text }] };
        } catch (err) {
          return {
            isError: true,
            content: [{ type: "text" as const, text: (err as Error).message }],
          };
        }
      },
    );
  • AgentKit ActionProvider implementation of the 'forensics' tool (handler). Decorated with @CreateAction, takes a URL via ForensicsSchema, delegates to callPaid(walletProvider, '/api/v1/forensics', {url}).
    @CreateAction({
      name: "forensics",
      description:
        "Deep history report for one x402 endpoint: hourly uptime over 7 days, latency p50/p90/p99, status-code distribution, concentration-group stats (how crowded this provider's namespace is), and a decoy probability score [0, 1]. Costs $0.001 USDC. Superset of preflight — if you're running forensics you don't need preflight too.",
      schema: ForensicsSchema,
    })
    async forensics(
      walletProvider: EvmWalletProvider,
      args: z.infer<typeof ForensicsSchema>,
    ): Promise<string> {
      return this.callPaid(walletProvider, "/api/v1/forensics", { url: args.url });
    }
  • Input schema for the forensics tool. ForensicsSchema is defined as an alias for PreflightSchema — requires a single 'url' field validated as a URL string.
    /**
     * Input schema for the `preflight` and `forensics` actions.
     */
    export const PreflightSchema = z.object({
      url: z
        .string()
        .url()
        .describe(
          "Full URL of the x402 endpoint the agent is about to pay (must be http(s)://, max 2048 chars).",
        ),
    });
    
    export const ForensicsSchema = PreflightSchema;
  • Inline input schema for the forensics tool in the MCP server registration. Requires a single 'url' field validated as a URL string.
    inputSchema: {
      url: z.string().url().describe("The full URL of the x402 endpoint to analyse."),
    },
  • Helper function callPaid used by the forensics tool handler. Sends a POST request with x402 payment to the given path, parses JSON response, and provides clear error messages (including for nginx 502 case referenced in comment).
    async function callPaid(path: string, body: unknown): Promise<string> {
      const f = payingFetch();
      let res: Response;
      try {
        res = await f(`${BASE_URL}${path}`, {
          method: "POST",
          headers: { "content-type": "application/json" },
          body: JSON.stringify(body ?? {}),
          signal: AbortSignal.timeout(DEFAULT_TIMEOUT_MS),
        });
      } catch (err) {
        const e = err as { name?: string };
        if (e.name === "AbortError" || e.name === "TimeoutError") {
          throw new Error(
            `x402station ${path} timed out after ${DEFAULT_TIMEOUT_MS}ms`,
          );
        }
        throw err;
      }
      const receipt = res.headers.get("x-payment-response");
    
      // Read body as text first, then parse JSON ONLY when the response is
      // actually OK. Otherwise nginx 502/504 (Next.js down) would arrive as
      // an HTML body, res.json() would throw a SyntaxError, and the agent
      // would see "Unexpected token '<', '<!DOCTYPE'..." instead of a clear
      // "x402station /api/v1/forensics returned 502" message. Audit M-1.
      const raw = await res.text();
      if (!res.ok) {
        const snippet = raw.length > 200 ? raw.slice(0, 200) + "…" : raw;
        // If the receipt header is set, settlement happened upstream — surface
        // that so the agent doesn't retry quickly and double-charge. The body
        // (if JSON-parseable) likely already carries `payment_settled: true`
        // for routes that adopted the audit-2026-04-28 pattern; we mention
        // the receipt presence on the error message itself for the older 503
        // shapes too. Audit 2026-04-28 (Sonnet HIGH-2 on mcp-adapter).
        const settled = receipt ? " (PAYMENT SETTLED — do NOT retry quickly)" : "";
        throw new Error(`x402station ${path} returned ${res.status}${settled}: ${snippet}`);
      }
      let data: unknown;
Behavior4/5

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

No annotations provided, but description discloses cost ($0.001 USDC) and the scope of data (7-day history). It does not mention potential failure cases or permissions, but overall transparent.

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?

Two concise sentences front-load all critical information: data provided, cost, and relationship to sibling tool. No wasted words.

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 adequately explains the return data (list of metrics). Could mention pagination or error handling, but the depth is sufficient for a paid tool.

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 already covers the single parameter with a clear description. The description adds that the URL must be for an x402 endpoint, but this is minor beyond schema.

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

Purpose5/5

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

Description clearly states 'deep history for one x402 endpoint' and lists specific metrics (uptime, latency, status-code distribution, etc.), differentiating from siblings like preflight by explicitly stating it's a superset.

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

Usage Guidelines5/5

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

Provides explicit guidance: 'superset of preflight — if you're running forensics you don't need preflight too.' Also mentions cost, helping agents decide when to invoke.

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

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/sF1nX/x402station-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server