MCP server for Worm prediction markets on Solana
Project description
Worm MCP
Browse, trade, and manage prediction markets from any AI agent.
Installation
worm-mcp runs over stdio; your MCP client launches it on demand. Set WALLET_PRIVATE_KEY to enable authenticated and trading tools, or omit it to use only the public, read-only tools.
Pick the flow that fits you:
- For users: you just want to use the tool in your MCP client. Your client launches it with
uvx; no manual install. - For developers: you want to modify the code. Clone the repo and run it from a local editable install.
For users
Your client launches worm-mcp on demand; uvx fetches and runs it for you.
Claude Code: register it once from the CLI; --scope user makes it available in every project:
claude mcp add --scope user worm \
-e WALLET_PRIVATE_KEY=<base58-solana-private-key> \
-- uvx worm-mcp
Confirm with claude mcp list (shows worm … ✓ Connected).
Cursor: add to ~/.cursor/mcp.json (global) or .cursor/mcp.json (per project), then enable it under Settings → MCP:
{
"mcpServers": {
"worm": {
"command": "uvx",
"args": ["worm-mcp"],
"env": { "WALLET_PRIVATE_KEY": "<base58-solana-private-key>" }
}
}
}
Claude Desktop: Settings → Developer → Edit Config opens claude_desktop_config.json; add the same mcpServers block and restart the app.
Smithery: Smithery installs it into a supported client with one command (it runs locally over stdio, so your key stays on your machine):
npx -y @smithery/cli install worm-mcp --client claude
Other clients (Windsurf, Cline, Zed, VS Code, …): same launch: command uvx, args ["worm-mcp"], plus the WALLET_PRIVATE_KEY env. Only the config file location differs.
No
uv?pipx run worm-mcporpip install worm-mcpwork too.
For developers
Run worm-mcp from a local clone, for hacking on the code or running an unpublished build. Clone and set up an editable environment:
git clone https://github.com/wormwtf/worm-mcp.git
cd worm-mcp
uv venv
uv pip install -e ".[dev]"
uv run ruff check src
WALLET_PRIVATE_KEY=... worm-mcp # run the stdio server directly
Point your client at the editable checkout so code changes take effect on the next client restart. Either add --with-editable to the uvx launch:
claude mcp add --scope user worm \
-e WALLET_PRIVATE_KEY=<base58-solana-private-key> \
-- uvx --from /path/to/worm-mcp --with-editable /path/to/worm-mcp worm-mcp
…or point the client's command straight at the venv binary the editable install creates (args can be omitted):
{
"mcpServers": {
"worm": {
"command": "/path/to/worm-mcp/.venv/bin/worm-mcp",
"env": { "WALLET_PRIVATE_KEY": "<base58-solana-private-key>" }
}
}
}
Verify
Ask your client "List trending markets on Worm" (public) or "What's my Worm account summary?" (confirms auth): a sensible answer means it's wired up.
Requirements
- An MCP client (Claude Code, Cursor, Claude Desktop, …)
uv(orpipx/pip)- A funded Solana wallet (only for trading and other authenticated tools)
Environment variables
| Variable | Required | Purpose |
|---|---|---|
WALLET_PRIVATE_KEY |
for writes | Base58 Solana private key (the export from Phantom/Solflare; a 64-byte hex keypair also works). Signs transactions locally and bootstraps HMAC credentials on first run, cached in ~/.worm/config.json. |
WORM_API_KEY / WORM_API_SECRET |
no | Use existing HMAC credentials instead of bootstrapping |
WORM_API_BASE |
no | API base URL (default https://api.worm.wtf) |
Tools
Public (no credentials)
| Tool | Description |
|---|---|
search |
Search markets and events by text and filters |
list_markets |
Browse markets by category, state, or sort |
get_market |
Full market detail (outcomes, fees, config, state) |
get_market_stats |
Volume, market cap, and trade count |
get_market_price |
Mid-price snapshot for an outcome |
get_orderbook |
Spot orderbook bids and asks |
get_market_candles |
OHLCV candles (5m / 30m) |
get_market_trades |
Recent public trades |
get_market_margin_activity |
Public margin activity feed |
list_events |
Browse events (groups of related markets) |
get_event |
Full event detail with all markets |
list_sports |
Sports and leagues catalog |
estimate_margin_position |
Preview a leveraged position |
read_worm_docs |
Fetch Worm documentation pages |
Authenticated read (HMAC)
| Tool | Description |
|---|---|
get_account_summary |
Your profile |
get_account_assets |
Portfolio share balances |
get_account_pnl |
PnL breakdown |
list_orders / get_order |
Your spot orders |
list_trades |
Your trade fills |
list_margin_positions / get_margin_position |
Your margin positions |
list_margin_requests / get_margin_request |
Your margin position requests |
list_margin_settlements |
Margin settlements |
list_redeems / get_redeem |
Your redeem records |
list_api_keys |
Your API keys |
Authenticated write (HMAC)
| Tool | Description |
|---|---|
cancel_margin_request |
Cancel a pending margin request |
close_margin_position |
Close a margin position |
set_tp_sl / remove_tp_sl |
Set / clear take-profit and stop-loss |
claim_margin_settlement |
Claim a resolved settlement |
revoke_api_key |
Revoke an API key |
Authenticated write: local signing (needs WALLET_PRIVATE_KEY)
| Tool | Description |
|---|---|
place_order / cancel_order |
Place / cancel a spot order |
open_margin_position |
Open a leveraged position |
redeem |
Redeem winnings from a resolved market |
Notes for agents
- Spot vs margin:
place_orderis for non-margin (orderbook) markets; useopen_margin_positionwhenmargin_enabled=true. Margin markets quote against an AMM, soget_orderbookmay be empty; size withestimate_margin_position. - Margin lifecycle:
open_margin_positionreturns a position-request pubkey; the actual position appears vialist_margin_positions(matchposition_request_pubkey) once funding completes. TP/SL is unsupported on Hyperliquid-backed markets. - Leverage: always call
estimate_margin_positionand confirm with the user before opening; leverage carries liquidation risk. - Docs on demand: call
read_worm_docswith no arguments for the index, then pass a path for exact API schemas and examples.
Features
- 38 tools across markets, events, search, sports, account, orders, trades, margin, redeems, key management, and docs
- Local Solana keypair signing, so your private key never leaves the MCP process
- Auto-bootstrapped HMAC credentials: set one env var and the rest is automatic
- Public market data works with no credentials at all
- Built on the official
worm-sdk, with full type hints
Architecture
┌──────────────┐ stdio ┌────────────┐ HTTPS + HMAC ┌──────────────┐
│ MCP client │ ◀──────▶ │ worm-mcp │ ◀────────────▶ │ Worm API │
│ (Claude etc.)│ │ (Python) │ │ api.worm.wtf │
└──────────────┘ └─────┬──────┘ └──────────────┘
│ ed25519 signing (orders, margin, redeems)
▼
worm-sdk + solders (local keypair)
See rate limits in the docs. Markets are viewable at https://worm.wtf/market/{condition_id}.
Security
- Your private key is used only to sign transactions locally; it is never sent to the Worm API or any third party.
- Bootstrapped HMAC credentials are cached at
~/.worm/config.jsonwith0600permissions, keyed by API base URL and wallet, so multiple wallets or environments (e.g.WORM_API_BASEoverrides) each keep their own credentials instead of clobbering one another. Writes are atomic and locked, so concurrent clients can't corrupt or lose cached credentials. - Use a dedicated wallet funded with only what you intend to trade, and keep the key out of version control and shared configs.
Troubleshooting
uvx: command not found: installuv, or usepipx run worm-mcp/pip install worm-mcp.- Tools don't appear: fully restart the client; it spawns the server once at startup. In Claude Code, check
claude mcp list. - Authentication errors: confirm
WALLET_PRIVATE_KEYis a valid base58 Solana key; delete~/.worm/config.jsonto force a fresh credential bootstrap.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file worm_mcp-0.1.0.tar.gz.
File metadata
- Download URL: worm_mcp-0.1.0.tar.gz
- Upload date:
- Size: 17.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0fb6570e6e77c2c713a25cde2fd8379cbfa3e68eeef2c67b7cc49370a70acfe0
|
|
| MD5 |
38c3b1d3301225c5265cce657710ae67
|
|
| BLAKE2b-256 |
bc521f2762940f03c2d84dc72e809d7a13bbd9df95e4e454dbf654e86400989b
|
Provenance
The following attestation bundles were made for worm_mcp-0.1.0.tar.gz:
Publisher:
release.yml on wormwtf/worm-mcp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
worm_mcp-0.1.0.tar.gz -
Subject digest:
0fb6570e6e77c2c713a25cde2fd8379cbfa3e68eeef2c67b7cc49370a70acfe0 - Sigstore transparency entry: 1766515413
- Sigstore integration time:
-
Permalink:
wormwtf/worm-mcp@d0fc3436d66d27bcbde311d3af325239c7b148a2 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/wormwtf
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@d0fc3436d66d27bcbde311d3af325239c7b148a2 -
Trigger Event:
release
-
Statement type:
File details
Details for the file worm_mcp-0.1.0-py3-none-any.whl.
File metadata
- Download URL: worm_mcp-0.1.0-py3-none-any.whl
- Upload date:
- Size: 20.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
baac6ccda2f76811ab645dcb7fe4a6f4745cef2429a49ac39b61e25e74825fdf
|
|
| MD5 |
3414e13d1de886845a831463a1e7a52b
|
|
| BLAKE2b-256 |
b125b93def54ab71e5d52dab23c8b28965cdb3ced9fcb242a4cc71ef339f9bc8
|
Provenance
The following attestation bundles were made for worm_mcp-0.1.0-py3-none-any.whl:
Publisher:
release.yml on wormwtf/worm-mcp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
worm_mcp-0.1.0-py3-none-any.whl -
Subject digest:
baac6ccda2f76811ab645dcb7fe4a6f4745cef2429a49ac39b61e25e74825fdf - Sigstore transparency entry: 1766515607
- Sigstore integration time:
-
Permalink:
wormwtf/worm-mcp@d0fc3436d66d27bcbde311d3af325239c7b148a2 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/wormwtf
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@d0fc3436d66d27bcbde311d3af325239c7b148a2 -
Trigger Event:
release
-
Statement type: