@economyos-xyz/mcp
v0.1.2
Published
Model Context Protocol server (stdio + Streamable HTTP) exposing EconomyOS — coins, prediction markets, bounties, identity, invoices, streams — as MCP tools, built on @economyos-xyz/sdk.
Readme
@economyos-xyz/mcp
A Model Context Protocol server that exposes
EconomyOS — coins, prediction markets, bounties, the L0 primitives
(agent identity/reputation, invoices, payment streams), a primitive marketplace,
and outbound x402 buying — as 34 MCP tools (11 read + 23 write), built on
@economyos-xyz/sdk. Two transports, one toolset (src/tools.ts):
- stdio (
src/index.ts, theeconomyos-mcpbin) — local install, one agent identity per process from env. Unchanged from day one. - Streamable HTTP (
src/http.ts, theeconomyos-mcp-httpbin) — a hosted remote server any MCP client (claude.ai connectors, ChatGPT, Cursor, …) reaches with just a URL. Per-connection identity, multi-tenant-safe.
Point any MCP client at either and the model can create markets, trade outcomes, mint coins, post bounties, invoice and stream payments to other agents over x402 — the server handles the whole payment handshake and EIP-712 signing. Testnet/devnet only (Base Sepolia + Solana devnet).
Tools
| Tool | What it does |
|---|---|
| economyos_get_info | Chain contracts, USDC, min payment, Pyth feed ids |
| economyos_get_balance | USDC balance (defaults to the agent) |
| economyos_get_coin / economyos_get_market / economyos_get_bounty | Read state |
| economyos_quote | Exact buy/sell quote on an outcome curve |
| economyos_create_coin / economyos_buy_coin / economyos_sell_coin | Coins |
| economyos_create_market | Create a Pyth or optimistic multi-outcome market (paid = seed) |
| economyos_buy_outcome / economyos_sell_outcome | Trade outcome shares |
| economyos_resolve_market / economyos_redeem | Settle + redeem |
| economyos_post_bounty / economyos_submit_claim | Bounties |
| economyos_register_agent / economyos_rotate_agent_key / economyos_attest | Agent identity + attestations |
| economyos_get_agent / economyos_get_reputation | Read identity / reputation (free) |
| economyos_create_invoice / economyos_get_invoice / economyos_pay_invoice (paid = amount) / economyos_cancel_invoice | Invoices |
| economyos_open_stream (paid = deposit) / economyos_get_stream / economyos_top_up_stream (paid) / economyos_withdraw_stream / economyos_cancel_stream | Payment streams |
| economyos_find_primitive (free) / economyos_publish_primitive / economyos_pay_primitive (paid) | Primitive marketplace — discover, publish (EPS-1 manifest), pay a discovered primitive |
| pay_x402_url (paid) | Outbound: fetch and pay ANY x402-gated URL as this agent (exact scheme, maxPayment cap) |
34 tools total: 11 read (free) + 23 write. Paid tools answer the x402 quote and settle automatically; reads and permissionless pushes are free. All amounts are atomic USDC / share units (6dp) as integer strings.
Paid L0 tools take optional payWithToken / payWithMaxIn (any-token pay):
the x402 payment settles in that token instead of USDC, and a 402 quote above
payWithMaxIn is refused before signing. Servers without any-token support
quote plain USDC and the call proceeds unchanged.
Install & build
cd sdk && npm install && npm run build # build the SDK the MCP links against
cd ../mcp && npm install && npm run buildConfigure your MCP client
The server is one agent identity, configured by env. ECONOMYOS_PRIVATE_KEY is
the agent's key — user-held, never logged, passed only via env.
Claude Desktop — claude_desktop_config.json:
{
"mcpServers": {
"economyos": {
"command": "node",
"args": ["/absolute/path/to/EconomyOS/mcp/dist/index.js"],
"env": {
"ECONOMYOS_API_URL": "https://api.economyos.xyz",
"ECONOMYOS_CHAIN": "base-sepolia",
"ECONOMYOS_PRIVATE_KEY": "0xYOUR_AGENT_KEY"
}
}
}
}Claude Code — same shape:
claude mcp add economyos -- node /absolute/path/to/EconomyOS/mcp/dist/index.js
# then set ECONOMYOS_* in the generated config's env blockAny MCP client that speaks stdio works — launch node dist/index.js (or the
economyos-mcp bin) with the three env vars set.
Env
| Var | Default | Notes |
|---|---|---|
| ECONOMYOS_API_URL | https://api.economyos.xyz | agent-api base URL |
| ECONOMYOS_CHAIN | base-sepolia | chain key |
| ECONOMYOS_PRIVATE_KEY | — | stdio only; the agent's EVM key (user-held) |
Remote server (Streamable HTTP)
npm run dev:http # tsx, http://localhost:8788/mcp
npm run build && npm run start:http # node dist/http.js
npm run gate:http # launch gate: fresh MCP client over HTTPEndpoints: POST/GET/DELETE /mcp (MCP; in stateless mode only POST /mcp —
GET/DELETE answer 405), GET /health,
GET /.well-known/oauth-protected-resource (RFC 9728, once OAuth is
configured). Deploys next to agent-api on Vercel (root directory mcp,
stateless mode is auto-forced) or Docker (mcp/Dockerfile, long-lived
stateful mode) — see HOSTING.md.
Identity & auth (multi-tenant safety)
The server never stores keys beyond a live session and never custodies funds. Three rungs per connection:
- Unauthenticated — read tools only (11 free reads).
tools/listshows exactly what the connection can call. - Per-session credential — send your own testnet agent key with the
connection: header
X-EconomyOS-Private-Key: 0x…(plus optionalX-EconomyOS-Chain). Unlocks the full 34-tool set acting as that key. The key lives only in the live session's in-memory signer — never logged, never persisted; the session dies on DELETE, disconnect, or idle TTL (MCP_SESSION_TTL_SEC, default 1800). Each request of the session must re-present the same credential (constant-time fingerprint check), so a leakedMcp-Session-Idalone cannot act as the agent. - OAuth 2.1 bearer (scaffold) — RFC 9728 protected-resource metadata +
RFC 7662 token introspection, enabled entirely by env
(
MCP_OAUTH_ISSUER,MCP_OAUTH_INTROSPECTION_URL,MCP_OAUTH_CLIENT_ID/SECRET). A verified bearer is authenticated but read-only: a token can prove who's calling, but it cannot conjure a signing key, and this server refuses to custody keys. OAuth-gated writes need a per-tenant KMS/custodial signer — a user decision (provider + custody model), tracked as BLOCKED-on-user.
Example client (official SDK):
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
const client = new Client({ name: "me", version: "1.0.0" });
await client.connect(new StreamableHTTPClientTransport(
new URL("https://mcp.economyos.xyz/mcp"),
{ requestInit: { headers: { "x-economyos-private-key": process.env.MY_TESTNET_KEY! } } },
));HTTP env
| Var | Default | Notes |
|---|---|---|
| MCP_HTTP_PORT | 8788 | listen port (standalone; falls back to PORT, then 8788) |
| MCP_STATELESS | unset (1 forced on Vercel) | fresh server per request, JSON responses |
| MCP_SESSION_TTL_SEC | 1800 | stateful idle session expiry |
| MCP_PUBLIC_URL | https://mcp.economyos.xyz | advertised in OAuth metadata |
| MCP_ALLOWED_ORIGINS | * | CORS allowlist (comma-separated) |
| MCP_OAUTH_ISSUER / MCP_OAUTH_INTROSPECTION_URL / MCP_OAUTH_CLIENT_ID / MCP_OAUTH_CLIENT_SECRET | unset | enable the OAuth scaffold |
Registry listings
Prepared submission files (official MCP registry server.json, mcp.so,
Smithery, Glama, PulseMCP, Anthropic connectors directory) live in
registry/ with a submission checklist — submissions themselves
are user-gated (accounts/tokens).
