coil-mcp 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +91 -0
  2. package/bin/coil-mcp.mjs +108 -0
  3. package/package.json +55 -0
package/README.md ADDED
@@ -0,0 +1,91 @@
1
+ # coil-mcp
2
+
3
+ **Live US stock market data and trading signals, as an MCP server.** Market regime, ranked buy
4
+ lists, 0-100 opportunity / entry-timing / hold-strength scores across ~575 S&P 500, Nasdaq-100
5
+ and macro names, sector rotation, and a 24/7 crypto board covering 81 pairs.
6
+
7
+ The free tier needs **no key, no wallet, no signup**.
8
+
9
+ ## Install
10
+
11
+ Claude Code speaks remote MCP directly — you do not need this package:
12
+
13
+ ```
14
+ claude mcp add --transport http coil https://coil.trade/mcp
15
+ ```
16
+
17
+ For clients that launch servers by command (Claude Desktop, Cursor, Windsurf), use this bridge:
18
+
19
+ ```json
20
+ {
21
+ "mcpServers": {
22
+ "coil": { "command": "npx", "args": ["-y", "coil-mcp"] }
23
+ }
24
+ }
25
+ ```
26
+
27
+ Or run it directly:
28
+
29
+ ```
30
+ npx -y coil-mcp
31
+ ```
32
+
33
+ ## What you get for free
34
+
35
+ The full board, delayed one market day, with no account of any kind:
36
+ `get_market_regime`, `get_buy_list`, `get_stock_read`, `get_market_leaders`, `get_sector_read`,
37
+ `get_crypto_trend`, `get_morning_brief`, `get_day_board`, `get_rotation`, `get_crypto_day`,
38
+ `get_crypto_night`, `get_hold_state`.
39
+
40
+ ## Live data
41
+
42
+ Every free tool has a `*_live` twin. Two ways to open them:
43
+
44
+ **Pay per call** — x402, USDC on Base, Solana or Algorand. $0.001 to $0.25 per read, no
45
+ account and no card. A wallet-equipped client pays inline via `params._meta["x402/payment"]`
46
+ (@x402/mcp compatible). Cheapest read is `/api/crypto/gate` at $0.001.
47
+
48
+ **Subscribe** — [Coil Live](https://coil.trade/live-feed) is $29/mo and unlocks every `*_live`
49
+ tool plus two sold nowhere else: `get_engine_feed` and `get_live_rules`.
50
+
51
+ ```
52
+ COIL_LICENSE_KEY=your_key npx -y coil-mcp # subscription
53
+ COIL_KEY=your_free_key npx -y coil-mcp # free key: 25 live calls/day on the cheap slices
54
+ ```
55
+
56
+ Mint a free key with no signup flow:
57
+
58
+ ```
59
+ curl -X POST https://coil.trade/api/key -H 'Content-Type: application/json' \
60
+ -d '{"email":"you@example.com"}'
61
+ ```
62
+
63
+ Or sign in with a wallet instead of an email — SIWX / CAIP-122 on Base, Solana or Algorand.
64
+ The signature moves no funds. See [coil.trade/auth.md](https://coil.trade/auth.md).
65
+
66
+ ## What this package is
67
+
68
+ A dependency-free stdio bridge. It forwards JSON-RPC verbatim to `https://coil.trade/mcp` and
69
+ never inspects, rewrites or caches a payload — whatever the server supports, this supports,
70
+ including tools added after you installed it. Point it elsewhere with `COIL_MCP_URL`.
71
+
72
+ Zero dependencies is deliberate: a market-data bridge should not ask you to trust a package
73
+ tree. Node 18+.
74
+
75
+ ## Honest limits
76
+
77
+ Coil is an **impersonal research publication** — identical for every reader, never
78
+ individualized advice. Scores describe historical and technical structure, not future returns.
79
+ Where a study failed, the read says so: the overnight crypto continuation product ships its own
80
+ refutation, because the ranking beat its random null but the studied trade lost money at real
81
+ Robinhood taker fees.
82
+
83
+ The engine's live record, next to SPY and QQQ, win or lose: [coil.trade/results](https://coil.trade/results)
84
+
85
+ ## Links
86
+
87
+ - Agent docs and the full endpoint catalogue: [coil.trade/agents](https://coil.trade/agents)
88
+ - OpenAPI: [coil.trade/openapi.json](https://coil.trade/openapi.json)
89
+ - Free proof chain: [coil.trade/api/board/proof](https://coil.trade/api/board/proof)
90
+
91
+ MIT © Coil Technologies LLC
@@ -0,0 +1,108 @@
1
+ #!/usr/bin/env node
2
+ // coil-mcp — stdio bridge to Coil's remote MCP server (https://coil.trade/mcp).
3
+ //
4
+ // WHY THIS EXISTS: Claude Code speaks remote MCP natively, so for that client this package is
5
+ // redundant. It exists for the clients that only speak stdio (Claude Desktop configs, Cursor,
6
+ // Windsurf, and anything driving an MCP server by command+args) and for the operators who
7
+ // reach for `npx` before reading docs. Measured channel ranking says ~99% of MCP distribution
8
+ // routes around the directories and through npm/PyPI — this is the npm half of that.
9
+ //
10
+ // ZERO DEPENDENCIES on purpose: an install that pulls a tree is an install a cautious operator
11
+ // abandons, and a market-data bridge asking for transitive trust is a bad trade. Node 18+ has
12
+ // fetch and that is all this needs.
13
+ //
14
+ // npx -y coil-mcp # free tier: delayed board, no key, no wallet
15
+ // COIL_KEY=... npx -y coil-mcp # free key -> higher daily limit on the cheap slices
16
+ // COIL_LICENSE_KEY=... npx -y coil-mcp # Coil Live subscription -> every *_live tool
17
+ //
18
+ // It is a PROXY, not a client: it forwards JSON-RPC verbatim and never inspects, rewrites or
19
+ // caches a payload. Whatever the server supports, this supports, including tools added later.
20
+ const ENDPOINT = process.env.COIL_MCP_URL || "https://coil.trade/mcp";
21
+ const VERSION = "1.0.0";
22
+
23
+ function headers() {
24
+ const h = {
25
+ "content-type": "application/json",
26
+ // Our worker can answer either way; accept both so a server-side switch to SSE framing
27
+ // does not break installed clients.
28
+ accept: "application/json, text/event-stream",
29
+ "user-agent": `coil-mcp/${VERSION} (+https://coil.trade/agents)`,
30
+ };
31
+ if (process.env.COIL_KEY) h["X-Coil-Key"] = process.env.COIL_KEY;
32
+ if (process.env.COIL_LICENSE_KEY) h["X-License-Key"] = process.env.COIL_LICENSE_KEY;
33
+ return h;
34
+ }
35
+
36
+ // The server may reply as plain JSON or as SSE (`data: {...}`). Take the LAST data frame:
37
+ // that is the terminal message of the response stream.
38
+ function parseBody(text, contentType = "") {
39
+ const t = text.trim();
40
+ if (contentType.includes("text/event-stream") || t.startsWith("event:") || t.startsWith("data:")) {
41
+ const frames = t.split("\n").filter((l) => l.startsWith("data: ")).map((l) => l.slice(6));
42
+ if (!frames.length) throw new Error("empty SSE response");
43
+ return JSON.parse(frames[frames.length - 1]);
44
+ }
45
+ return JSON.parse(t);
46
+ }
47
+
48
+ async function forward(msg) {
49
+ const r = await fetch(ENDPOINT, { method: "POST", headers: headers(), body: JSON.stringify(msg) });
50
+ const text = await r.text();
51
+ if (!r.ok && !text.trim()) throw new Error(`HTTP ${r.status} from ${ENDPOINT}`);
52
+ return parseBody(text, r.headers.get("content-type") || "");
53
+ }
54
+
55
+ const out = (obj) => process.stdout.write(JSON.stringify(obj) + "\n");
56
+
57
+ // MCP stdio framing is newline-delimited JSON. Buffer across chunk boundaries — a large
58
+ // tools/list reply arrives split, and parsing per-chunk drops messages non-deterministically.
59
+ let buf = "";
60
+ let stdinEnded = false;
61
+ const inflight = new Set();
62
+
63
+ // Requests are dispatched CONCURRENTLY and each reply is written when it lands. JSON-RPC ids
64
+ // exist precisely so responses need not be ordered, and awaiting inside the read loop would
65
+ // serialise a client's whole batch behind its slowest call.
66
+ function dispatch(msg) {
67
+ // Notifications carry no id and expect no reply. Forward and stay silent — emitting a
68
+ // response to a notification is a protocol violation some clients treat as fatal.
69
+ const isNotification = msg.id === undefined || msg.id === null;
70
+ const p = forward(msg)
71
+ .then((res) => { if (!isNotification) out(res); })
72
+ .catch((e) => {
73
+ if (!isNotification) {
74
+ out({ jsonrpc: "2.0", id: msg.id,
75
+ error: { code: -32603, message: `coil-mcp bridge: ${String(e && e.message || e)}` } });
76
+ }
77
+ })
78
+ .finally(() => { inflight.delete(p); maybeExit(); });
79
+ inflight.add(p);
80
+ }
81
+
82
+ // Exit ONLY when stdin is closed AND nothing is in flight. Exiting on "end" alone kills every
83
+ // pending request — the first version did exactly that and emitted zero responses for a piped
84
+ // session, which is how a bridge ships looking fine and works for nobody.
85
+ function maybeExit() {
86
+ if (stdinEnded && inflight.size === 0) process.exit(0);
87
+ }
88
+
89
+ process.stdin.setEncoding("utf8");
90
+ process.stdin.on("data", (chunk) => {
91
+ buf += chunk;
92
+ let i;
93
+ while ((i = buf.indexOf("\n")) >= 0) {
94
+ const line = buf.slice(0, i).trim();
95
+ buf = buf.slice(i + 1);
96
+ if (!line) continue;
97
+ let msg;
98
+ try { msg = JSON.parse(line); } catch { continue; } // not our frame; drop it, never crash
99
+ dispatch(msg);
100
+ }
101
+ });
102
+ process.stdin.on("end", () => {
103
+ const tail = buf.trim(); // a final line with no trailing newline is still a message
104
+ buf = "";
105
+ if (tail) { try { dispatch(JSON.parse(tail)); } catch { /* not our frame */ } }
106
+ stdinEnded = true;
107
+ maybeExit();
108
+ });
package/package.json ADDED
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "coil-mcp",
3
+ "version": "1.7.0",
4
+ "description": "MCP server for live US stock market data and trading signals \u2014 market regime (risk-on/risk-off), ranked buy lists, 0-100 opportunity and hold scores across ~575 S&P 500 and Nasdaq-100 names, sector rotation, and a 24/7 crypto board for 81 pairs. Free tier needs no key, no wallet, no signup; pay-per-call over x402 in USDC for live data.",
5
+ "keywords": [
6
+ "mcp",
7
+ "modelcontextprotocol",
8
+ "mcp-server",
9
+ "claude",
10
+ "claude-code",
11
+ "claude-desktop",
12
+ "cursor",
13
+ "windsurf",
14
+ "ai-agent",
15
+ "llm-tools",
16
+ "stock-market",
17
+ "stocks",
18
+ "market-data",
19
+ "trading",
20
+ "trading-signals",
21
+ "stock-scanner",
22
+ "finance",
23
+ "financial-data",
24
+ "sp500",
25
+ "nasdaq",
26
+ "market-regime",
27
+ "sector-rotation",
28
+ "crypto",
29
+ "bitcoin",
30
+ "x402",
31
+ "agentic-payments",
32
+ "usdc"
33
+ ],
34
+ "homepage": "https://coil.trade/agents",
35
+ "bugs": {
36
+ "url": "https://coil.trade/agents"
37
+ },
38
+ "license": "MIT",
39
+ "author": "Coil Technologies LLC",
40
+ "type": "module",
41
+ "bin": {
42
+ "coil-mcp": "bin/coil-mcp.mjs"
43
+ },
44
+ "files": [
45
+ "bin/",
46
+ "README.md"
47
+ ],
48
+ "engines": {
49
+ "node": ">=18"
50
+ },
51
+ "dependencies": {},
52
+ "publishConfig": {
53
+ "access": "public"
54
+ }
55
+ }