pr-legislative-x402
This server lets an AI agent search and read structured Puerto Rico legislative measures (bills and resolutions), paying per call in USDC on Base via x402 — no accounts or API keys.
Search legislation (
search_pr_legislation): free-text search across bill titles/identifiers (e.g.cannabis,PC 456), filtered by chamber (upper= Senado,lower= Cámara de Representantes) and/or status slug (e.g.ley,aprobada,radicada).Bounded results: returns summary rows only, max 25 per call (limit 1–25) — no abstracts.
Get full bill detail (
get_pr_bill): fetch one measure by identifier (e.g.PC 456,ps-123) including abstract, sponsors, and action history — a separate, pricier single-record call.Autonomous payment: paid routes ($0.01 search, $0.03 detail) are auto-paid in USDC on Base by the MCP client when a low-balance wallet key is configured; unset means plain fetch against an open dev server.
Read-only, structured data: ~4,900 cleaned, topic-tagged, bilingual measures sourced from OpenStates/SUTRA, queryable with zod-validated inputs (400 on bad query/identifier).
Uses the Coinbase CDP facilitator for x402 agent payments, verifying and settling per-call USDC charges on Base so agents can pay the Puerto Rico legislative API without accounts or API keys.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@pr-legislative-x402 search for bills about solar energy"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
pr-legislative-x402
Pay-per-call access to structured Puerto Rico legislative data, over the x402 agent-payment standard.
▶ API: legislative.r21digital.com — try /health, /v1/preview, /v1/bills/search?q=solar. (Sample data, payments off.)
An HTTP API + MCP server that lets AI agents search and read measures of the Puerto Rico Legislative Assembly (Asamblea Legislativa) — and pay per call in USDC on Base, autonomously, no accounts or API keys.
Data originates from OpenStates / SUTRA (public source); the value sold here is
the cleaned, structured, topic-tagged, bilingual layer that CivicaPR built
on top of it — the same corpus behind civicapr.com/legislacion (~4,900 measures).
Status: scaffold. Runs end-to-end on built-in sample data with zero secrets. Wire it to the live Neon DB + a wallet to go paid.
Why this exists (and why it protects the data, not exposes it)
The public site already serves this data free to any scraper. This project adds a separate, controlled, paid channel for machines — which is strictly more control than a public HTML page:
Read-only.
DATABASE_URLshould point at a role withSELECTonly. The code issues no writes.Bounded responses. Search returns summary rows capped at 25 (no abstract); full detail is a separate, pricier single-record call. Extracting the whole corpus therefore costs per bill — bulk scraping isn't cheap.
Neutral naming. Given the live
CIVICAtrademark conflict, this package is deliberately not branded "Civica."Free tier stays free. The human site is untouched; this is an additive paid API tier for agents.
Related MCP server: x402farm-mcp
Architecture
Agent (Claude Code / OpenClaw)
│ calls MCP tools: search_pr_legislation, get_pr_bill
▼
MCP server (src/mcp) ── wraps fetch with wallet auto-pay (x402) ──┐
│ │ 402 → pay USDC on Base → retry
▼ ▼
HTTP API (src/server) ── x402 payment gate ──▶ priced routes ──▶ Neon `bills` (read-only)
free: /health, /v1/preview └─ falls back to sample dataPayment layer is isolated in src/server/x402.ts (seller) and
src/mcp/pay-fetch.ts (buyer) so the young x402 SDK can churn without touching
the rest of the app.
Quickstart (dev — no wallet, no DB)
npm install
npm test # bounds + paywall-config tests, on sample data
npm run dev:server # API on http://localhost:4021, payments OFF
# in another shell:
curl localhost:4021/v1/preview
curl 'localhost:4021/v1/bills/search?q=solar'
curl localhost:4021/v1/bills/PC%20456Point an agent at the MCP server (payments off):
PR_X402_API_BASE=http://localhost:4021 npm run dev:mcpEndpoints
Method | Path | Tier | Price* |
GET |
| free | — |
GET |
| free | — (corpus counts only) |
GET |
| paid |
|
GET |
| paid |
|
*Prices live in one place: src/server/routes.ts.
Going paid (production)
Point at real data — create the read-only role with
scripts/neon-readonly-role.sql, then setDATABASE_URLto that role's pooled Neon connection string.Set your receiving wallet —
RECEIVING_WALLET_ADDRESS= a Base address you control. (This project never handles a seller private key; USDC settles on-chain to that address.)Enable + configure the facilitator —
PAYMENTS_ENABLED=true, plus the Coinbase CDP keys the facilitator needs (CDP_API_KEY_ID/CDP_API_KEY_SECRET).Deploy — see "Deploy" below.
✅ The seller wiring (
src/server/x402.ts) is verified against the real@x402/express@2.xAPI — anx402ResourceServer+ExactEvmScheme, CAIP-2 networks,accepts-shaped routes — and the unpaid → 402 challenge is certified on Base Sepolia (npm run test:testnet). The remaining unproven leg is a live paid settlement (402 → pay → 200), which needs a funded testnet key — seeTESTNET.mdto run it, then flip to mainnet.
Deploy
Vercel (recommended for a data API). All routes rewrite to one serverless
function (api/index.ts) that runs the same Express app. vercel.json is
included.
vercel # link + preview deploy
vercel --prod # production
# set env in the dashboard (or `vercel env add`):
# DATABASE_URL, PAYMENTS_ENABLED, RECEIVING_WALLET_ADDRESS,
# X402_NETWORK, CDP_API_KEY_ID, CDP_API_KEY_SECRETContainer / VPS / your own box. A multi-stage Dockerfile is
included:
docker build -t pr-legislative-x402 .
docker run -p 4021:4021 --env-file .env pr-legislative-x402Option | Good for | Notes |
Vercel (serverless) | data API like this | Near-zero compute; reuses your existing stack. Recommended. |
Cheap VPS ($5/mo) / Docker | always-on control | Fine; more ops than Vercel for no real gain here. |
Closet box | selling compute (GPU/inference/transcription) | Only worth it when your marginal cost beats cloud. For a data API the box adds downtime/ISP risk with no upside — skip it here. |
Use it from an agent (MCP)
Copy examples/claude-mcp-config.json into a
project .mcp.json, point PR_X402_API_BASE at your deployment, and (for a
paid server) set a dedicated low-balance WALLET_PRIVATE_KEY. Tools exposed:
search_pr_legislation, get_pr_bill.
Quality gates
npm run lint(Oxlint) ·npm run typecheck(TypeScript 7) ·npm test(21 tests) ·npm run build— all run in CI (.github/workflows/ci.yml) on push/PR.npm run hooks:installonce per clone runs lint and typecheck before everygit push.HTTP layer: zod-validated inputs (400 on bad query/identifier), JSON 404 + error handlers, CORS, security headers, and a best-effort rate limit on the free routes. API described in
openapi.yaml.
Buyer side (agents that pay)
The MCP auto-pays only if WALLET_PRIVATE_KEY is set — use a dedicated,
low-balance Base key, never a treasury wallet. Unset = plain fetch, which
works against an open dev server.
Layout
src/
data/ schema.ts (types + zod inputs + limit clamp) · queries.ts (Neon, read-only) · mock.ts (sample corpus)
server/ routes.ts (price config) · x402.ts (seller gate) · middleware.ts (cors/ratelimit/errors) · app.ts · index.ts
mcp/ index.ts (tools) · pay-fetch.ts (buyer auto-pay)
api/ index.ts (Vercel serverless entry)
scripts/ neon-readonly-role.sql
examples/ claude-mcp-config.json
test/ bounds.test.ts · paywall.test.ts · validation.test.ts
openapi.yaml · vercel.json · Dockerfile · .github/workflows/ci.ymlMIT. Built by R21 Digital.
Hosting
The API runs on a Cloudflare Worker at https://legislative.r21digital.com, a custom domain on the existing zone (routes in wrangler.jsonc). The workers.dev address stays enabled as a secondary address. Every push to main runs npm ci && npm run cf:test && npm run cf:build && npm run cf:verify in Workers Builds and then deploys with npx wrangler deploy; branch pushes do not build or deploy. npm run cf:preview uploads a version without promoting it. Database and payment bindings must remain absent on this deployment (sample data, payments off); the existing static landing page is retained.
Available Tools
2 toolsget_pr_billA
Get full detail for one Puerto Rico legislative measure by identifier: abstract, sponsors, and action history.
Inputs: identifier (required).
search_pr_legislationA
Search measures (proyectos y resoluciones) of the Puerto Rico Legislative Assembly by text, chamber, or status. Returns summary rows.
Inputs: limit, query, status, chamber.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 2 tools
The two tools have clearly distinct purposes: one searches for legislation with filters, the other retrieves full details for a specific measure. There is no overlap or ambiguity.
Both tools follow a verb_noun pattern, but one uses 'pr_bill' and the other 'pr_legislation,' which is a minor inconsistency in resource naming. Overall style is consistent and readable.
With only two tools, the set feels thin for a legislative domain, though it may be sufficient for a minimal read-only API. The count is borderline but not unreasonable.
The tool surface covers search and detail retrieval, which are the core operations for accessing legislative measures. No significant gaps are apparent, though more specialized endpoints (e.g., by chamber or session) could be added.
Maintenance
Related MCP Connectors
15 paid AI agent primitives via x402 (USDC on Base). Pay-per-call MCP server.
Agent-commerce MCP server for x402/USDC payments and affiliate splits on Base.
x402 pay-per-call APIs over MCP, settled in USDC on Base for autonomous agents and developers.
Canadian public-sector data and legal information for AI agents, paid per call in USDC over x402
Related MCP Servers
- FlicenseAqualityCmaintenanceMCP server for a live x402 payment gateway on Base (USDC). Lets AI agents discover, preview for free, then pay per call — with prepaid gasless payments, signed receipts, and delta delivery.7-
- AlicenseNot gradedqualityDmaintenanceMCP server that provides AI agents with pay-per-call access to a suite of tools (honeypot check, token market, DeFi yields, etc.) via USDC on Base using the x402 protocol.11 npmMIT
- AlicenseNot gradedqualityDmaintenanceA small, autonomous, pay-per-call MCP server that AI agents discover and pay for per call, with revenue landing directly in a USDC wallet on Base via the x402 payment protocol.MIT
- AlicenseNot gradedqualityDmaintenanceMCP server providing 11 pay-per-call web intelligence tools (page reading, PDF extraction, RSS parsing, screenshots, summarization, structured data extraction) for AI agents, paid automatically in USDC via the x402 protocol on Base mainnet with no API keys required.38 npmMIT