{
  "markdown": "# siftingio-mcp\n\n[![siftingio-mcp MCP server](https://glama.ai/mcp/servers/SiftingIO/siftingio-mcp/badges/score.svg)](https://glama.ai/mcp/servers/SiftingIO/siftingio-mcp)\n\nThis is a [Model Context Protocol](https://modelcontextprotocol.io) (MCP) server\nthat puts the [SiftingIO market-data SDK](https://github.com/SiftingIO/sdk-typescript)\n(`@siftingio/sdk`) in reach of your AI assistant. Once it's running, the model can\npull live prices, dig through SEC/EDGAR fundamentals, fetch OHLCV bars, look up 13F\nholdings, check market status, and scan the macro economic calendar — all as tools.\n\n## Setup\n\n```bash\nnpm install\nnpm run build\n```\n\nYou'll need an API key, which you can grab at <https://sifting.io>:\n\n```bash\nexport SIFTING_API_KEY=sft_...\n```\n\nIf you need to point at a different backend, `SIFTING_BASE_URL` and `SIFTING_WS_URL`\nare there to override the defaults.\n\nWorking locally? Copy `.env.example` to `.env` instead — `npm run dev` and `npm start`\npick it up automatically (Node does the loading via `--env-file-if-exists`). When you\nwire this into an actual MCP client, though, pass the key through the server's `env`\nblock rather than a file (there's an example further down).\n\n## Run\n\nHere's the toolbox:\n\n- `npm run build` — compile TypeScript into `dist/`.\n- `npm start` — run the compiled server (`node dist/index.js`) over **stdio**.\n- `npm run start:http` — run it over **Streamable HTTP** (`node dist/http.js`).\n- `npm run dev` / `npm run dev:http` — run straight from source with `tsx`, no build step.\n- `npm test` — run the [vitest](https://vitest.dev) suite (add `npm run test:watch` to keep it running).\n- `npm run lint` / `npm run format` — ESLint (typescript-eslint) and Prettier.\n- `npm run typecheck` — `tsc --noEmit`.\n\nOn every push and PR, CI (`.github/workflows/ci.yml`) walks through the same gauntlet:\nformat check → lint → typecheck → build → test.\n\nOne thing worth knowing: the server talks JSON-RPC over **stdio**, so stdout belongs\nentirely to the protocol. Anything diagnostic goes to stderr to stay out of the way.\n\n### Inspect interactively\n\nWant to poke at it by hand? The MCP inspector is the easiest way:\n\n```bash\nSIFTING_API_KEY=sft_... npx @modelcontextprotocol/inspector node dist/index.js\n```\n\n### HTTP (Streamable HTTP) transport\n\nIf you're running this somewhere remote or hosted, use MCP's Streamable HTTP transport\ninstead of stdio:\n\n```bash\nSIFTING_API_KEY=sft_... PORT=3000 npm run start:http\n# → MCP endpoint at http://127.0.0.1:3000/mcp  (POST messages, GET SSE, DELETE session)\n```\n\nIt's **stateful**: every client gets its own session (tracked by the `mcp-session-id`\nheader) and its own `McpServer`, while the upstream SiftingIO connection is shared\nacross the whole process. As a safety measure it only binds to **loopback** and turns\naway non-local browser `Origin`s — that's the DNS-rebinding protection. Set the port\nwith `PORT` (or `MCP_HTTP_PORT`); it defaults to `3000`.\n\nIf you want auth, set **`MCP_AUTH_TOKEN`** and the server will demand\n`Authorization: Bearer <token>` on every request (anything missing or wrong gets a\n401). Pair that with a reverse proxy handling TLS and the token, and you can safely\nexpose the server past localhost:\n\n```bash\nMCP_AUTH_TOKEN=s3cret SIFTING_API_KEY=sft_... npm run start:http\n```\n\nThen just point any HTTP-capable MCP client at `http://127.0.0.1:3000/mcp`:\n\n```bash\nclaude mcp add --transport http siftingio http://127.0.0.1:3000/mcp\n```\n\n## Use with an MCP client\n\nDrop this into your client config — Claude Desktop's `claude_desktop_config.json`,\nsay, or use `claude mcp add` if you're on Claude Code:\n\n```json\n{\n  \"mcpServers\": {\n    \"siftingio\": {\n      \"command\": \"node\",\n      \"args\": [\"/absolute/path/to/siftingio-mcp/dist/index.js\"],\n      \"env\": { \"SIFTING_API_KEY\": \"sft_...\" }\n    }\n  }\n}\n```\n\n## Tools (36)\n\n| Namespace | Tools |\n| --- | --- |\n| Live (snapshot) | `last_trade`, `last_quote`, `last_tvl` |\n| Stocks | `stocks_search`, `stocks_profile`, `stocks_filings`, `stocks_filing`, `stocks_sections`, `stocks_section`, `stocks_risk_factors_diff`, `stocks_ratios`, `stocks_earnings`, `stocks_financials`, `stocks_financial_concept`, `stocks_insiders`, `stocks_ownership`, `stocks_events`, `stocks_compensation`, `stocks_screener`, `stocks_bars` |\n| Crypto / Forex | `crypto_bars`, `forex_bars` |\n| DEX | `dex_wallet` |\n| Markets | `markets_list`, `markets_status_all`, `markets_status`, `markets_hours`, `markets_calendar` |\n| Filers | `filers_holdings` |\n| Macro | `economic_calendar_list` |\n| Live (stream) | `ws_subscribe`, `ws_unsubscribe`, `ws_poll`, `ws_collect`, `ws_status`, `ws_disconnect` |\n\nA few patterns are worth calling out:\n\nPaginated tools take `cursor`/`limit` and hand back a `meta.next_cursor` to fetch the\nnext page. The `stocks_*` list tools — `stocks_filings`, `stocks_earnings`,\n`stocks_insiders`, `stocks_ownership`, `stocks_events`, `stocks_compensation` — also\nunderstand **`max_items`**: set it and they'll auto-paginate, gathering up to that many\nitems across pages in a single call.\n\nThe high-traffic tools (`last_trade`, `last_quote`, `last_tvl`, `stocks_profile`,\n`stocks_search`) come with an **output schema** and return `structuredContent`\nalongside the human-readable text, so clients can read them machine-side too.\n\nEvery tool also carries MCP **annotations**. The data tools are `readOnlyHint: true`\n(and `openWorldHint: true`, since they reach out to the external API), while the\nWebSocket tools that change connection state are `readOnlyHint: false`,\n`destructiveHint: false`.\n\nResults are **size-capped** at roughly 60k characters (see `MAX_RESULT_CHARS` in\n`src/util.ts`). When a heavy endpoint — full XBRL financials, screeners, OHLCV bars —\nreturns more than that, the server trims its largest array and tacks on a `_truncated`\nnote explaining how to narrow the query.\n\n### Live WebSocket streaming\n\nStreaming is the awkward case: it doesn't fit neatly into a single request/response.\nSo the server holds **one persistent WebSocket** open, buffers the frames as they\narrive, and the tools just read from that buffer. Channels (the `product` field) are\n`cex` (crypto), `dex` (DEX trades), `fx` (forex), `us` (US stocks), and `tvl` (DEX\npool TVL).\n\nThere are two ways to work with it:\n\n- **Subscribe + poll**, for ongoing streams: call `ws_subscribe` once, then keep\n  calling `ws_poll`. The first poll gives you a recent tail; feed the returned\n  `next_seq` back in as `after_seq` and you'll only get newer frames from then on.\n  `ws_status` shows you the connection and what's subscribed, and `ws_disconnect`\n  tears the whole thing down.\n- **Collect**, for a quick one-shot: `ws_collect` subscribes, waits up to `duration_ms`\n  (or until it's seen `max` frames), returns what it caught, and cleans up any\n  subscription it had to create. Perfect for \"grab me a few seconds of BTCUSD.\"\n\nThe connection reconnects on its own and replays your subscriptions when it does. The\nbuffer is a rolling window, so the oldest frames eventually fall off — and when they\ndo, you'll hear about it through `dropped`/`gap`.\n\n## Prompts\n\nThese are guided, multi-tool workflows your client can surface as slash-commands:\n\n- **`company_snapshot`** `(ticker)` — pulls `stocks_profile`, `stocks_ratios`, the\n  latest `stocks_filings`, and `last_trade` together into one briefing.\n- **`compare_companies`** `(tickers)` — lines up several tickers side by side across\n  the key ratios.\n- **`market_now`** — what's open and closed right now, plus the high-impact macro\n  events coming up.\n\n## Logging & shutdown\n\nThe server advertises the MCP **logging** capability and pushes structured\n`notifications/message` to the client whenever something happens with the connection\n(WebSocket open/close/reconnect/error) or on shutdown — and it mirrors all of that to\nstderr too.\n\nWhen it catches a **SIGINT or SIGTERM**, it closes the live WebSocket and shuts the\nserver down cleanly before exiting.\n",
  "bytes": 7938,
  "sha": "582ac91bf323a11bee13206429c2788cb48ff9c217e916eab4a785915e70f64e",
  "repo_slug": "siftingio/siftingio-mcp",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_sifting_mcp_19163ef0/readme"
}