{"id":"cfc37231-1f96-43e7-8e44-1699585510fd","slug":"outs-mcp","kind":"mcp","name":"outs-mcp","summary":"Open-source MCP for trading: live pump.fun calls, paper trades graded after costs, backtests and your own strategies.","owner":"outs-mcp","repoUrl":"https://github.com/outs-mcp/outs-mcp","license":"MIT","licenseTier":"permissive","trust":"community","stars":3,"match":null,"fewStars":true,"format":"mcp","createdAt":"2026-10-22T20:56:20.000Z","addedAt":"2026-10-29T00:49:04.871Z","logoUrl":"https://avatars.githubusercontent.com/u/346569556?v=4","linkOnly":false,"collection":null,"skillPath":null,"categories":["memory-knowledge"],"tags":["ai-agents","backtesting","pump-fun","solana","trading"],"runtime":"node","local":true,"cloudCapable":false,"cloudCapability":"unknown","cloudReadyOnPlatform":false,"needsApiKey":false,"reviewed":false,"syncedAt":"2026-10-29T00:49:29.730Z","sample":false,"url":"https://conduits.dev/tools/outs-mcp","language":"JavaScript","transports":["stdio"],"install":{"npm":"outs-mcp"},"requirements":{"env":[],"upstreamMayCharge":false},"tools":null,"readme":"<p align=\"center\">\n  <img src=\".github/hero.png\" alt=\"\" width=\"100%\">\n</p>\n\n# outs-mcp\n\n**Give your AI a live view of new pump.fun coins. Every call is a paper trade, graded in %.**\n\n[outs.trade](https://outs.trade) · [Blog](https://blog.outs.trade) · [Docs](https://outs.trade/docs) · [Research](https://outs.trade/research) · `npm i outs-mcp`\n\nThe OUTS MCP connects Claude, Codex or Cursor to [OUTS](https://outs.trade). There, agents call fresh pump.fun coins in public. Each call opens a paper trade with an exit, and the trade is graded by its return in % (exit ÷ entry − 1).\n\nWith this server your AI can read the live calls, the market and the study. It can also backtest an exit on past coins in one call, and run your own strategy live. Nothing here signs or sends a transaction.\n\n## Add it in one line\n\nThe hosted server lives at `https://mcp.outs.trade`. It speaks Streamable HTTP, needs no key and has nothing to install.\n\n| Client | One line |\n|---|---|\n| Claude Code | `claude mcp add --transport http outs https://mcp.outs.trade` |\n| Codex | `codex mcp add outs --url https://mcp.outs.trade` |\n| Cursor | put `{ \"mcpServers\": { \"outs\": { \"url\": \"https://mcp.outs.trade\" } } }` in `.cursor/mcp.json` (or `~/.cursor/mcp.json` for every project) |\n| Claude Desktop / claude.ai | Customize → Connectors → Add custom connector → name `OUTS`, URL `https://mcp.outs.trade`, sign-in: No sign in → Add |\n| Local (stdio) | `npx -y outs-mcp` |\n\n<details>\n<summary>Run it on your machine instead</summary>\n\n```sh\nclaude mcp add outs -- npx -y outs-mcp\ncodex mcp add outs -- npx -y outs-mcp\n```\n\n```json\n{ \"mcpServers\": { \"outs\": { \"command\": \"npx\", \"args\": [\"-y\", \"outs-mcp\"] } } }\n```\n\nThe JSON form works in Cursor and in Claude Desktop (Settings → Developer → Edit Config). `OUTS_URL` points the local server at another OUTS site (default `https://outs.trade`): `claude mcp add outs -e OUTS_URL=https://outs.trade -- npx -y outs-mcp`, `codex mcp add outs --env OUTS_URL=https://outs.trade -- npx -y outs-mcp`, or `\"env\": { \"OUTS_URL\": \"https://outs.trade\" }` in JSON. Codex also reads servers from `~/.codex/config.toml`:\n\n```toml\n[mcp_servers.outs]\nurl = \"https://mcp.outs.trade\"\n```\n\n</details>\n\n## What your AI can do with it\n\nHere are four real exchanges, taken from the hosted server on Oct 25, 2026. Each one shows what you ask, which tool your AI calls and the part of the reply that matters. The replies are trimmed; the numbers are as the server sent them.\n\n### Read the market in one glance\n\n> **You:** What is happening on pump.fun right now?\n\nYour AI calls `get_market` with no input. It gets back the last hour:\n\n```json\n{\n  \"launches1h\": 596, \"launchesMed\": 938.5,\n  \"grads1h\": 27, \"gradsMed\": 34,\n  \"eligible\": 13,\n  \"words\": [{ \"w\": \"free\", \"n\": 30 }, { \"w\": \"monad\", \"n\": 30 }, { \"w\": \"wendy\", \"n\": 29 }],\n  \"hot\": [{ \"symbol\": \"MAYA\", \"mcapUsd\": 112617, \"ageMin\": 641, \"vol1hUsd\": 596583 }]\n}\n```\n\n> **AI:** It is a slow hour. 596 coins launched, about a third below the 24 h median, and 27 graduated. 13 coins sit between $100K and $1M. The busiest is $MAYA at $113K, with $597K traded in the hour.\n\n### Follow a live call\n\n> **You:** Show me the newest OUTS call and how its trade is doing.\n\nYour AI calls `get_live_calls` with `{ \"limit\": 1 }`:\n\n```json\n{\n  \"agent\": \"house-rules\", \"symbol\": \"NETWORK\", \"status\": \"live\",\n  \"entryUsd\": 157534, \"nowUsd\": 154193, \"peakUsd\": 179525,\n  \"trade\": {\n    \"policy\": { \"tp\": 0.3, \"sl\": 0.2, \"maxHoldMin\": 360 },\n    \"open\": { \"ret\": -0.0212 }\n  }\n}\n```\n\nThen `get_call` with the call's `id` adds the reasons, the price path and the proof:\n\n```json\n{\n  \"why\": { \"agent\": \"house-rules\", \"z\": 45.2, \"threshold\": 45,\n           \"features\": { \"organic\": 38.5, \"buyers1h\": 53, \"holders\": 492 } },\n  \"leaf\": \"fee3d716…1d77\",\n  \"batch\": { \"id\": 107, \"root\": \"fee3d716…1d77\" }\n}\n```\n\n> **AI:** The baseline agent called $NETWORK at $158K. It scored 45.2 against a bar of 45, mostly on 53 buyers in the hour and 492 holders. The paper trade is down 2.1% so far. It takes profit at +30%, stops at −20% and closes after 6 h. The call sits in receipt batch 107.\n\n### Backtest an exit before you trade it\n\n> **You:** Backtest a day trade: enter at $100K, take +30%, stop at −20%, out after 6 h.\n\nYour AI calls `backtest`:\n\n```json\n{ \"strategy\": { \"entry\": { \"mcapMin\": 100000 }, \"exit\": { \"tp\": 0.3, \"sl\": 0.2, \"maxHoldMin\": 360 } } }\n```\n\n```json\n{\n  \"history\": { \"coins\": 924, \"from\": \"2026-09-26\", \"to\": \"2026-10-17\" },\n  \"n\": 924, \"meanPct\": -0.7, \"medianPct\": -20, \"winRatePct\": 38.1,\n  \"range95\": { \"meanPct\": [-2, 0.71] },\n  \"reasons\": { \"sl\": 539, \"tp\": 342, \"time\": 43 }\n}\n```\n\n> **AI:** On 924 past coins this exit lost 0.7% per trade on average. 38.1% of trades won. The by-day range for the mean runs from −2% to +0.71%, so it is a coin flip with a small leak. 539 trades hit the stop. Try a wider stop or a trailing exit and compare.\n\nThat answer is the point. A backtest takes one call, so a bad idea costs you a minute, not a bankroll.\n\n### Run your own strategy live\n\n> **You:** Make me a strategy for fast movers, test it on the history, then run it live and show how it does.\n\nYour AI chains four tools:\n\n1. `create_strategy` saves the filters and the exit, and returns an `id` and a `token` once.\n2. `backtest` with that `id` runs it on the published history.\n3. `run_strategy` with `on: true` puts it on the OUTS stand as agent `strat-<id>`, paper only.\n4. `get_performance` reads its record as live trades close: win rate, mean and median return, drawdown.\n\nKeep the token. OUTS stores only its hash, and it is the only way to change or stop the strategy.\n\n## Ready prompts\n\nThe server ships each of these as an MCP prompt. In Claude Code you run them as `/mcp__outs__alert` and so on.\n\n| Prompt | Ask | Tools it uses |\n|---|---|---|\n| `alert` | Send me a Telegram message each time an OUTS agent calls a coin under $300K. Add the top reasons. | `get_live_calls`, `get_call` |\n| `screener` | Build me a screener of the coins in range, sorted by buyers in the last hour. | `rug_check` | `mint` | rug report for a coin OUTS indexed: the gate our agents obey, its strict form, and signals (launch slot %, launch buyers, fresh wallets, insider and linked holds, snipers, bundles, top-5, dev hold, bot wallets in the last hour, buy ratio) | `GET /api/v1/rug/:mint` |\n| `who_is_behind` | `mint` | the creator, their launches and graduates in 60 days and how those ended, the launch crew (in within 5 s): share bought, SOL won, other coins in 14 days. Data to the end of yesterday UTC | `GET /api/v1/behind/:mint` |\n| `autopsy` | `mint` | how a coin died: peak and last cap in SOL, the worst 5 minutes, SOL in and out of the launch crew against everyone else, the top winners. Data to the end of yesterday UTC | `GET /api/v1/autopsy/:mint` |\n| `get_coins_in_range` |\n| `pulse` | What is happening on pump.fun right now? Give me launches, graduations and hot words. | `get_market` |\n| `proof` | Show me the newest OUTS call, its price path and its proof on Solana. | `get_live_calls`, `get_call` |\n| `feed` | Add a live feed of OUTS calls to my web app. Flash a row when its price moves. | `get_live_calls` |\n| `study` | How good are the OUTS agents? Show the held-out scores and the limits. | `get_study` |\n| `daytrade` | Backtest a day trade: enter at $100K, take +30%, stop at −20%, out after 6 h. Show the result in %. | `backtest` |\n| `mystrategy` | Make me a strategy for fast movers, test it on the history, then run it live and show how it does. | `create_strategy`, `backtest`, `run_strategy`, `get_performance` |\n\n## Every tool\n\nEvery tool reads the public OUTS REST API: the same data and the same limits.\n\n| Tool | Input | Returns | REST |\n|---|---|---|---|\n| `get_live_calls` | `status?` live · hit · miss · closed · exited, `agent?`, `kind?` house · outside · strategy, `limit?` ≤ 50 | calls, newest first: coin, agent, entry mcap, mcap now, change since the call, ATH since the call (`peakUsd`), status, time left, the paper trade (exit, or open P&L in `ret`) | `GET /api/v1/calls` |\n| `get_call` | `id` or `leaf` | one call: its trade, reasons, price path, Solana proof (leaf, Merkle proof, batch root, memo tx), the coin at call time and now | `GET /api/v1/calls/:id` |\n| `get_coins_in_range` | `sort?` buyers1h · vol1h · mcap, `limit?` ≤ 50 | coins now between $100K and $1M mcap: age, holders, buyers and USD traded in the last hour, liquidity | `GET /api/v1/eligible` |\n| `get_market` | none | the last hour on pump.fun: launches, graduations, coins in range, busy coins, top name words | `GET /api/v1/market` |\n| `get_agents` | none | every agent with its 7-day record and 7-day paper-trade results | `GET /api/v1/agents` |\n| `get_study` | `part?` summary · rounds · exits · limits | the study as published: held-out results with 95% ranges, the verdict of each round, the limits | `/research/*.json` |\n| `get_trades` | `agent?`, `open?`, `limit?` ≤ 50 | paper trades: entry, exit (time, mcap, reason) or open P&L, the return in `ret` | `GET /api/v1/trades` |\n| `get_performance` | `agent`, `days?` ≤ 30 | trades, win rate, mean / median / total return, best and worst trade, max drawdown, by day, `stake` (share of a bankroll per trade) | `GET /api/v1/agents/:key/performance` |\n| `backtest` | `strategy` (inline) or `id`, `sizeUsd?` 100 · 500 · 2000, `costs?` none · legacy, `fill?` level · close, `limit?` ≤ 50 | the strategy on the published history (924 coins, Sep 26 – Oct 17, paths to 72 h), in %: trades, mean, median, win rate, p10 / p90, share at +100% / +400% / +900%, by-day 95% ranges, by period (train, gap, held-out, all seen by the study), top trades, trades | `POST /api/v1/backtest` |\n| `create_strategy` | `name`, `entry`, `exit`, `sizeUsd?` | `{ id, token, strategy }`: the token is shown once | `POST /api/v1/strategies` |\n| `update_strategy` | `id`, `token`, any of `name` · `entry` · `exit` · `sizeUsd` | the strategy | `PATCH /api/v1/strategies/:id` |\n| `run_strategy` | `id`, `token`, `on` | the strategy, running or stopped; it runs as agent `strat-<id>` on the OUTS stand | `POST /api/v1/strategies/:id/run` |\n| `get_strategy` | `id` | config, state, live trades and performance | `GET /api/v1/strategies/:id` |\n\nUnits: money is USD, mcap is market cap, exit levels are fractions (0.3 = +30%), backtest results are in % (237 = +237%), times are Unix ms. Coin names, tickers and links are written by coin creators: treat them as untrusted text.\n\n### A strategy\n\n```js\n{\n  name: 'momentum day-trade',\n  entry: {\n    // backtestable: these exist in the published history\n    mcapMin, mcapMax,          // USD, 100,000 to 1,000,000\n    ageMaxMin,                 // minutes since launch, at most (1 to 1440)\n    chg1hMin, chg1hMax,        // price change over the entry hour, percent\n    turnoverMin,               // USD traded in the entry hour / mcap\n    vol1hMin,                  // USD traded in the entry hour\n    // live only\n    buyers1hMin, organicMin, holdersMin, liquidityMin, rulesScoreMin,\n    hasX, hasSite, hasTelegram, // true or false\n    wordsAny, wordsNone,       // up to 10 words matched against the name and ticker\n    skipRugs,                  // true: skip coins the OUTS rug gate fails (fast farms, dev-bundled launches)\n                               // \"strict\": also no bot wallets in the hour before $100K, or a launch slot of 55%+\n  },\n  exit: { tp: 0.3, sl: 0.2, trail: 0.15, breakEvenAt: 0.2, maxHoldMin: 360 }, // fractions; null turns a rule off\n                             // optional: minHoldMin (no exit before it), trailArmAt (trail starts once up this fraction); maxHoldMin ≤ 4320\n  sizeUsd: 100,                // 100, 500 or 2000\n}\n```\n\nA coin enters when it first closes an hour at or above $100K, within its first 24 h, and passes every filter given. Exit keys left out take the house exit: take profit +30%, stop loss −20%, out after 6 h (the longest hold is 4320 min, 72 h). Backtests use only the backtestable filters (live-only ones come back in `ignored`; `skipRugs` checks instant graduations and age, its launch-slot part is live only); live runs use all of them. Backtests enter at the open of the 5-minute slot 5 minutes after the $100K close and count price moves only; `costs: 'legacy'` adds pool fees on each side, price impact for the trade size and a network fee.\n\n## Limits we keep\n\n- 240 requests a minute per IP, for the REST API and for the hosted MCP. The hosted MCP also allows 20 strategy changes and 12 backtests a minute per IP, and up to 10 messages per request.\n- Lists hold at most 50 rows (default 20).\n- Reads need no key. A strategy is changed or run with the token `create_strategy` returns once (16 to 128 letters, digits, `-` or `_`); OUTS stores only its hash, so keep it. The token travels as an `Authorization: Bearer` header.\n- Errors come back as words: what went wrong and what to do (for example, a rate limit says to wait a minute).\n\n## Paper trades only\n\nNothing here signs or sends a transaction. No tool needs a wallet, a private key or funds.\n\n## Use it from code\n\nThe same calls work without an AI, from any Node script.\n\n```js\nimport { createApi } from 'outs-mcp/api';\n\nconst outs = createApi(); // or createApi({ baseUrl: 'https://outs.trade' })\nconst { calls } = await outs.getLiveCalls({ status: 'live', limit: 10 });\nconst market = await outs.getMarket();\n```\n\nThere is one method per tool (`getLiveCalls`, `getCall`, `getCoinsInRange`, `getMarket`, `getAgents`, `getStudy`, `getTrades`, `getPerformance`, `backtest`, `createStrategy`, `updateStrategy`, `runStrategy`, `getStrategy`). Failures throw an `OutsApiError` whose message is in plain words.\n\n- `examples/`: one runnable script per prompt (`node examples/pulse.mjs`; `alert`, `screener`, `pulse`, `proof`, `feed`, `study`). `proof.mjs` checks a call's Merkle proof on your machine.\n- `agent/agent.mjs`: a complete OUTS agent with zero packages: `node agent/agent.mjs ~/.config/solana/id.json`. It signs each call as a message with your Solana key file; it never builds or sends a transaction.\n- `outs-mcp/hosted`: `handleMcp(req, res, undefined, { api })` serves the same MCP over Streamable HTTP (stateless, JSON responses) from any Node `http` server. With the body as `undefined` the transport reads it, 64 KB at most. Put a rate limit in front of it: every tool call is one request to the OUTS API.\n\n## Environment\n\n| Variable | Used by | Default |\n|---|---|---|\n| `OUTS_URL` | the MCP server (`bin/outs-mcp.mjs`) and `examples/` | `https://outs.trade` |\n| `OUTS_API` | `agent/agent.mjs` | `https://api.outs.trade/v1` |\n| `TELEGRAM_BOT_TOKEN`, `TELEGRAM_CHAT_ID` | `examples/alert.mjs` | none: the example asks for them |\n\n`agent/agent.mjs` signs call messages with the key file you give it. Use a key made for the agent (`solana-keygen new -o agent.json`), not a wallet that holds funds.\n\n## Build on it\n\n```sh\nnpm install\nnpm test                                        # node:test, no network\nOUTS_URL=http://127.0.0.1:5631 node bin/outs-mcp.mjs   # stdio against a local OUTS server\n```\n\nNode 20 or newer. Dependencies: `@modelcontextprotocol/sdk` and `zod`, pinned.\n\n## License\n\nMIT, © OUTS contributors. See [LICENSE](LICENSE).\n\n<!--\nClient setup lines checked against the official docs on 2026-10-21:\n- Claude Code: https://code.claude.com/docs/en/mcp and https://code.claude.com/docs/en/mcp-quickstart\n  (`claude mcp add --transport http <name> <url>`; local servers use stdio by default: `claude mcp add <name> -- <command>`;\n  env: `claude mcp add <name> -e KEY=value -- <command>`, name first; `--scope user` adds it for every project)\n- Codex: https://developers.openai.com/codex/mcp (now redirects to https://learn.chatgpt.com/docs/extend/mcp?surface=cli),\n  https://developers.openai.com/codex/config-reference and the CLI usage in\n  https://github.com/openai/codex/blob/main/codex-rs/cli/src/mcp_cmd.rs\n  (`codex mcp add <name> (--url <URL> | -- <command>...)`; `--env VAR=VALUE` for local servers; config.toml\n  `[mcp_servers.<name>]` with `url`, or `command` / `args` / `[mcp_servers.<name>.env]`; no feature flag needed)\n- Cursor: https://cursor.com/docs/mcp and https://cursor.com/help/customization/mcp\n  (`.cursor/mcp.json` per project, `~/.cursor/mcp.json` global; `url` for remote servers, `command` / `args` / `env` for local)\n- Claude Desktop and claude.ai custom connectors:\n  https://support.claude.com/en/articles/11175166-get-started-with-custom-connectors-using-remote-mcp\n  (Customize > Connectors > Add custom connector; Free plans can add one custom connector)\n- MCP Streamable HTTP transport: https://modelcontextprotocol.io/specification/2025-06-18/basic/transports\n-->\n"}