mastra-x402station
v0.1.0
Published
x402station pre-flight oracle tools for Mastra agents — preflight, forensics, decoy catalog, alternatives, watch alerts, and prepaid credits for x402 endpoints
Maintainers
Readme
mastra-x402station
Pre-flight oracle tools for x402 endpoints in Mastra agents.
Backed by x402station.io — an independent prober that scans every endpoint
on agentic.market (≈ 35 000 active URLs across ≈ 593 services) every 10 minutes and exposes safety
signals priced in USDC via x402 itself.
Why agents need this
Agents that pay arbitrary x402 endpoints fall into three traps:
- Decoys. ≈ 161 endpoints in the network are listed at ≥ $1 000 USDC; an agent paying one loses its wallet. Most are anti-scraper "swarm" routes.
- Zombies. Services 100% erroring in the last hour but still listed in the catalog. Invisible to facilitator-based competitors because nobody calls them.
- Catalog concentration. A single provider can be > 40% of the catalog under one billing namespace — agents need this context before treating the network as diverse.
x402station's prober sees these because it runs naked HTTP probes — no payment required to register a probe. This package wraps the public oracle as Mastra tools so an agent can preflight a URL before paying.
Installation
npm install mastra-x402station
# or
pnpm add mastra-x402station
# or
bun add mastra-x402stationYou'll also need a viem-compatible account holding USDC on Base mainnet (eip155:8453) or Base
Sepolia (eip155:84532). USDC on Base mainnet:
0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913.
Quick start
import { Agent } from '@mastra/core/agent';
import { createX402StationTools } from 'mastra-x402station';
const privateKey = process.env.AGENT_PRIVATE_KEY;
if (!privateKey) throw new Error('Set AGENT_PRIVATE_KEY for the x402station tools');
const tools = createX402StationTools({
// 0x-prefixed 64-hex private key. Or pass `account: viemAccount` instead,
// or rely on X402STATION_PRIVATE_KEY in the environment (read by the client).
privateKey,
});
const agent = new Agent({
id: 'shielded-x402-agent',
name: 'Shielded x402 agent',
instructions:
'Before paying any unfamiliar x402 URL, call x402StationPreflight. ' +
'Refuse to pay when ok=false; warnings explain why.',
model: 'anthropic/claude-sonnet-4-6',
tools,
});createX402StationTools returns ten tools:
| Tool | Cost | Purpose |
|---|---|---|
| x402StationPreflight | $0.001 USDC | {ok, warnings[], metadata} for one URL. The fast path. |
| x402StationForensics | $0.001 USDC | 7-day uptime, latency p50/p90/p99, status codes, decoy probability. |
| x402StationCatalogDecoys | $0.005 USDC | Full known-bad list as one JSON. Cache as a blacklist. |
| x402StationAlternatives | $0.005 USDC | Routing fallback — alternative endpoints when one is flagged. |
| x402StationWhatsNew | $0.001 USDC | Catalog diff — endpoints added/removed in a time window. |
| x402StationBuyCredits | $0.50 USDC | Buy 1000 prepaid /preflight calls (60-day expiry). |
| x402StationCreditsStatus | free | Read balance + expiry on a creditId. |
| x402StationWatchSubscribe | $0.01 USDC | 30-day watch + 100 prepaid HMAC-signed alerts on state changes. |
| x402StationWatchStatus | free | Status + recent alert deliveries (secret-gated). |
| x402StationWatchUnsubscribe | free | Deactivate a watch (secret-gated). |
Payments are auto-signed via @x402/fetch — every paid response includes a settled-payment receipt
that decodes the on-chain transaction hash so the agent can audit spend.
Individual tools
import {
createX402StationPreflightTool,
createX402StationForensicsTool,
createX402StationAlternativesTool,
createX402StationBuyCreditsTool,
} from 'mastra-x402station';
const preflight = createX402StationPreflightTool({ privateKey: process.env.AGENT_PK });
const forensics = createX402StationForensicsTool({ privateKey: process.env.AGENT_PK });Preflight
Posts the URL to /api/v1/preflight and returns { ok, warnings[], metadata }.
ok is true only when no critical signal fires. Critical set:
dead— endpoint failing in the last hourzombie— listed but 100% erroring for the full hourdecoy_price_extreme— price ≥ $1 000 USDC
Other signals (slow, new_provider, unknown_endpoint, …) appear in warnings but do not flip
ok to false. See signals.md
for the full vocabulary.
Forensics
Superset of preflight. Returns hourly uptime over 7 days, latency p50/p90/p99, status-code
distribution, concentration-group stats (how crowded the provider's namespace is), and a
decoy_probability score in [0, 1].
Catalog decoys
{ generated_at, counts: { total, by_reason }, truncated, entries[] }. Refreshed every ~10 min
server-side. Pull periodically and cache locally; cheaper than preflighting every URL.
Alternatives
When a target URL is flagged, x402StationAlternatives returns up to 10 substitute endpoints from
the same category. Match keys: provider, domain, category, price band. Useful for routing
fallback so the agent can complete the task on a healthy peer.
What's new
x402StationWhatsNew returns the catalog diff over a window (since ISO 8601 + limit), default
last 24h. Useful for an agent that polls periodically and wants to know which endpoints appeared
or disappeared since the last poll.
Bulk credits
x402StationBuyCredits settles $0.50 USDC and returns a creditId good for 1000 prepaid
/preflight calls (60-day expiry, $0.0005 effective per call vs. $0.001 pay-as-you-go).
x402StationCreditsStatus reads the remaining balance. Pass the creditId server-side via the
X-Credit-Id header on subsequent preflights to skip the x402 challenge entirely.
Watch subscribe / status / unsubscribe
x402StationWatchSubscribe pays $0.01 for a 30-day watch + 100 HMAC-SHA256-signed alerts. The
response includes a 64-char hex secret — store it; it's the HMAC seed and is not retrievable
later.
webhookUrl is HTTPS-only at the schema level — HMAC-signed payloads must travel encrypted. The
client also performs an SSRF-style guard locally: localhost, 127.0.0.0/8, RFC 1918 private
ranges, link-local, cloud-metadata, IPv6 ULA / NAT64 / 6to4 / loopback are all rejected before the
call reaches the server.
x402StationWatchStatus and x402StationWatchUnsubscribe are free, secret-gated. Wrong secret
returns 404 (constant-time compare; an attacker scraping IDs cannot distinguish "exists with wrong
secret" from "does not exist").
Configuration
| Option | Type | Default | Description |
|---|---|---|---|
| account | viem.Account | — | Pre-built viem account for signing. |
| privateKey | string | process.env.X402STATION_PRIVATE_KEY | 0x-prefixed 64-hex key. Mutually exclusive with account. |
| baseUrl | string | https://x402station.io | Override base URL. Only canonical or localhost dev URLs accepted. |
| fetchImpl | typeof fetch | globalThis.fetch | Custom fetch. Mostly for tests. |
| timeoutMs | number | 30000 | Per-call timeout. Aborts the underlying fetch on hang. |
The baseUrl allow-list refuses anything other than https://x402station.io or
http(s)://localhost / 127.0.0.1 / [::1] — a misconfigured agent cannot be tricked into
signing x402 payments against an attacker-controlled host.
Networks
Base mainnet (eip155:8453) and Base Sepolia (eip155:84532). The CDP facilitator
(https://x402.org/facilitator) settles payments. Mainnet requires the receiver wallet to be
funded — testnet is anonymous.
Discovery
x402station also publishes its own discovery surfaces (/.well-known/x402, agent-card, OpenAPI,
MCP server-card, llms.txt). It scores 5/5 ("Agent-Native") on Cloudflare's
isitagentready.com scanner, with
isCommerce=true.
Companion packages
| Package | Audience | Surface |
|---|---|---|
| x402station-mcp | Claude Code / Cursor / Windsurf / Continue | MCP server (stdio) |
| x402station-middleware | any TypeScript agent | Drop-in wrapWithPreflight around @x402/fetch |
| mastra-x402station (this) | Mastra agents | Tools registered into a mastra.Agent instance |
License
MIT
