@coinrithm/mcp-trading 0.7.1 → 0.7.3
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.
- package/CHANGELOG.md +48 -3
- package/README.md +240 -238
- package/dist/agent/act.d.ts +2 -2
- package/dist/agent/act.js +24 -3
- package/dist/agent/cli.js +59 -18
- package/dist/agent/client.d.ts +33 -0
- package/dist/agent/client.js +34 -7
- package/dist/agent/decision.d.ts +3 -0
- package/dist/agent/decision.js +26 -3
- package/dist/agent/decisionValidator.js +2 -1
- package/dist/agent/deploymentOverlay.js +25 -5
- package/dist/agent/engine.d.ts +2 -1
- package/dist/agent/engine.js +4 -1
- package/dist/agent/extract.js +3 -1
- package/dist/agent/gate.js +25 -5
- package/dist/agent/index.js +0 -1
- package/dist/agent/indicators.js +4 -2
- package/dist/agent/manifest.js +1 -1
- package/dist/agent/mechanical.d.ts +36 -0
- package/dist/agent/mechanical.js +286 -0
- package/dist/agent/observe.js +120 -52
- package/dist/agent/prompt.d.ts +3 -1
- package/dist/agent/prompt.js +17 -6
- package/dist/agent/providers.js +39 -4
- package/dist/agent/resolve.js +23 -6
- package/dist/agent/resolvePm.js +14 -3
- package/dist/agent/runEvidence.js +6 -2
- package/dist/agent/runner.d.ts +8 -2
- package/dist/agent/runner.js +370 -60
- package/dist/agent/scorecard.js +12 -4
- package/dist/agent/setups.js +57 -9
- package/dist/agent/skill.js +1 -1
- package/dist/agent/state.js +9 -4
- package/dist/agent/types.d.ts +17 -2
- package/dist/agent/types.js +2 -1
- package/dist/agent/util.js +11 -4
- package/dist/agent/version.d.ts +1 -1
- package/dist/agent/version.js +1 -1
- package/dist/client.d.ts +33 -0
- package/dist/client.js +12 -3
- package/dist/executionPolicy.d.ts +2 -0
- package/dist/executionPolicy.js +21 -0
- package/dist/http.js +10 -2
- package/dist/tools.d.ts +1 -0
- package/dist/tools.js +220 -32
- package/package.json +9 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,7 +3,52 @@
|
|
|
3
3
|
All notable changes to `@coinrithm/mcp-trading` are documented here. The package
|
|
4
4
|
ships two binaries — `coinrithm-mcp` (the MCP server) and `coinrithm-agent` (the
|
|
5
5
|
self-host agent runner) — versioned together. The CoinRithm **API contract** is
|
|
6
|
-
versioned separately (see `openapi.yaml` `info.version`, currently `1.
|
|
6
|
+
versioned separately (see `openapi.yaml` `info.version`, currently `1.6.0`).
|
|
7
|
+
|
|
8
|
+
## 0.7.3
|
|
9
|
+
|
|
10
|
+
Quality-engine surfaces + independent forecasts. Additive; no breaking change.
|
|
11
|
+
|
|
12
|
+
- **Quality verdicts in tool responses.** `discover_pm_markets`, `pm_quote`, and
|
|
13
|
+
the `pm_data_*` tools now surface the persisted truth-engine `quality` object
|
|
14
|
+
(`decisionEligible`, warning/block reason codes, `policyVersion`, `assessedAt`).
|
|
15
|
+
Markets with critical failures stay visible but cannot drive paper opens or
|
|
16
|
+
alerts.
|
|
17
|
+
- **`openBlocked` preview on `pm_quote`.** Quotes preview the open-time quality
|
|
18
|
+
gate (`openBlocked` + `openBlockReasons`), so an agent can skip a market that
|
|
19
|
+
would 422 before burning the open attempt. The self-host runner
|
|
20
|
+
(`coinrithm-agent`) does this skip automatically.
|
|
21
|
+
- **Independent forecasts in the runner.** The self-host agent runner elicits the
|
|
22
|
+
model's OWN probability (judged from the question/resolution criteria/deadline,
|
|
23
|
+
never anchored to the market price) and submits it as `forecastProbability` on
|
|
24
|
+
PM opens — feeding the public calibration dataset with proper-scoring-rule
|
|
25
|
+
forecasts. Clamped to [1,99]; omitted (never faked) when the model does not
|
|
26
|
+
produce one; `HOUSE_AGENT_FORECAST_ENABLED=false` disables.
|
|
27
|
+
- **`crossPlatform` on event lists** documented in the API contract: sibling
|
|
28
|
+
venues pricing the same question, on list rows.
|
|
29
|
+
- **ForecastEx venue truth.** Public MCP discovery copy and registry metadata
|
|
30
|
+
now describe all 11 live venues, including ForecastEx.
|
|
31
|
+
- **Contract synchronization.** Runner templates and example bundles pin the
|
|
32
|
+
served OpenAPI 1.6.0 contract; canonical scorecard paths are unambiguous.
|
|
33
|
+
|
|
34
|
+
## 0.7.2
|
|
35
|
+
|
|
36
|
+
Docs-truth + privacy release. No tool behavior change, no API-surface change.
|
|
37
|
+
|
|
38
|
+
- **Ten venues in the public listing.** `pm_data_*` tool copy, the README, and
|
|
39
|
+
`server.json` now name all ten venues (adds Futuur and Myriad). npm `0.7.1` was
|
|
40
|
+
published before those landed, so the registry listing still advertised "eight
|
|
41
|
+
venues"; npm versions are immutable, so correcting the public listing required
|
|
42
|
+
a new release.
|
|
43
|
+
- **`source` parameter description** on `pm_data_events` / `pm_data_event_detail`
|
|
44
|
+
now enumerates all ten venue slugs. Accepted values are unchanged — this is
|
|
45
|
+
description text only, which is why it is a patch and not a minor.
|
|
46
|
+
- **Privacy.** Raw model output is no longer persisted, enforcing the package's
|
|
47
|
+
no-chain-of-thought promise.
|
|
48
|
+
- **New tripwire.** `server.json` (the MCP-registry listing) is now guarded
|
|
49
|
+
against version and venue-count drift; it had no guard, which is how it went
|
|
50
|
+
stale in the first place.
|
|
51
|
+
- Refreshed stale Arena-gate example copy.
|
|
7
52
|
|
|
8
53
|
## 0.7.1
|
|
9
54
|
|
|
@@ -11,8 +56,8 @@ Docs + registry-metadata release; no tool behavior changes.
|
|
|
11
56
|
|
|
12
57
|
- **README refresh**: the keyless `pm_data_*` data surface is now front and
|
|
13
58
|
center — 8 venues (Polymarket, Kalshi, Smarkets, Limitless, Manifold,
|
|
14
|
-
Metaculus,
|
|
15
|
-
anonymous hosted-endpoint path, and the `referenceProbability` /
|
|
59
|
+
Metaculus, PredictIt, Rothera — the "seven venues" line predated Rothera),
|
|
60
|
+
the anonymous hosted-endpoint path, and the `referenceProbability` /
|
|
16
61
|
`volumeHistory` fields the data tools return.
|
|
17
62
|
- **`server.json`**: hosted endpoint's `Authorization` header marked optional
|
|
18
63
|
(the `pm_data_*` tools work anonymously — verified live) and the server
|
package/README.md
CHANGED
|
@@ -1,238 +1,240 @@
|
|
|
1
|
-
# @coinrithm/mcp-trading
|
|
2
|
-
|
|
3
|
-
**Deploy an AI trading agent with paper money — for free.** Give any model
|
|
4
|
-
(Claude, GPT, Gemini, Llama…) a 50,000 mUSD virtual account and let it trade
|
|
5
|
-
spot, futures, and prediction markets on
|
|
6
|
-
[CoinRithm](https://coinrithm.com/agentic-trading). No real money, no exchange,
|
|
7
|
-
no risk — a proving ground to show an agent works *before* anything is on the
|
|
8
|
-
line, with a public **Agent Arena** leaderboard ranked by realized paper PnL.
|
|
9
|
-
|
|
10
|
-
**Plus a free prediction-market data surface — no key at all.** The same server
|
|
11
|
-
ships four keyless `pm_data_*` tools serving CoinRithm's public cross-venue
|
|
12
|
-
dataset: live odds across
|
|
13
|
-
Manifold, Metaculus, Futuur,
|
|
14
|
-
liquidity-aware reference probability, a whale-trade tape, and market-wide
|
|
15
|
-
volume stats ($60B+ all-time tracked). Point any MCP client at the hosted
|
|
16
|
-
endpoint `https://mcp.coinrithm.com/mcp` and call them anonymously — the API
|
|
17
|
-
key is only needed for the trading tools.
|
|
18
|
-
|
|
19
|
-
Agents are **OKF bundles** — an open, model-agnostic folder of markdown + YAML
|
|
20
|
-
(strategy, persona, hard caps) that any runtime can read. Two ways to run the
|
|
21
|
-
**same** bundle:
|
|
22
|
-
|
|
23
|
-
- **Managed — nothing to install.** Build and deploy an agent in your browser
|
|
24
|
-
with the **Agent Studio** (CoinRithm → My Agents → Studio): fork a house agent
|
|
25
|
-
or write one from scratch, and CoinRithm runs it **free on Llama 3.1 8B**
|
|
26
|
-
(NVIDIA NIM) on an always-on scheduler. The fastest path to a live agent.
|
|
27
|
-
- **Self-host — this package.** Bring your own model key and run the
|
|
28
|
-
`observe→decide→validate→act` loop on your machine, or wire the MCP server
|
|
29
|
-
into Claude Desktop / Cursor / Codex.
|
|
30
|
-
|
|
31
|
-
This package ships two binaries:
|
|
32
|
-
|
|
33
|
-
- **`coinrithm-mcp`** — an MCP server that lets an AI agent paper-trade on
|
|
34
|
-
CoinRithm (spot, futures, prediction markets) using a personal API key.
|
|
35
|
-
- **`coinrithm-agent`** — a self-host **agent runner**: author an agent as a
|
|
36
|
-
folder and run an `observe→decide→validate→act` loop with your own model key,
|
|
37
|
-
**dry-run by default**. See [Agent runner](#agent-runner-coinrithm-agent) below.
|
|
38
|
-
|
|
39
|
-
> **Paper trading only** — virtual funds (50,000 mUSD). Not financial advice.
|
|
40
|
-
|
|
41
|
-
## Quick start
|
|
42
|
-
|
|
43
|
-
```bash
|
|
44
|
-
# Run the MCP server with your CoinRithm key (no install needed):
|
|
45
|
-
COINRITHM_API_KEY=crk_live_… npx -y @coinrithm/mcp-trading
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
Get a `crk_live_…` key from CoinRithm → Profile → API Keys. To author and run a
|
|
49
|
-
self-host agent instead, see [Agent runner](#agent-runner-coinrithm-agent).
|
|
50
|
-
Building from source? `npm install && npm run build`.
|
|
51
|
-
|
|
52
|
-
## Agent runner (`coinrithm-agent`)
|
|
53
|
-
|
|
54
|
-
This package also ships a **self-host agent runner**. You write an agent as a
|
|
55
|
-
folder (strategy + hard caps in markdown/YAML); the runner compiles it and runs
|
|
56
|
-
an `observe → decide → validate → act` loop, asking *your* model (bring-your-own
|
|
57
|
-
key) for structured decisions and executing only the ones that pass your caps —
|
|
58
|
-
**dry-run by default**, paper-only across spot, futures, and prediction markets.
|
|
59
|
-
|
|
60
|
-
```bash
|
|
61
|
-
coinrithm-agent new my-agent --preset conservative
|
|
62
|
-
coinrithm-agent validate my-agent
|
|
63
|
-
COINRITHM_API_KEY=crk_live_… ANTHROPIC_API_KEY=sk-ant-… \
|
|
64
|
-
coinrithm-agent run my-agent --once --dry-run
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
Full guide (env vars, fail-closed guarantees, folder layout):
|
|
68
|
-
**[docs/agent-runner.md](https://github.com/CoinRithm/coinrithm-agent-trading/blob/main/docs/agent-runner.md)**.
|
|
69
|
-
The CoinRithm hosted scheduler runs this same engine for you — see the
|
|
70
|
-
[scheduler README](../../packages/scheduler/README.md) for the built,
|
|
71
|
-
DB-driven runtime.
|
|
72
|
-
|
|
73
|
-
## Two ways to run
|
|
74
|
-
|
|
75
|
-
| Mode | Entry | Auth | Who it's for |
|
|
76
|
-
| --- | --- | --- | --- |
|
|
77
|
-
| **stdio** (single-user, local) | `dist/index.js` | `COINRITHM_API_KEY` env var | Claude Desktop / Cursor / Codex on your machine |
|
|
78
|
-
| **Streamable HTTP** (multi-user, hosted) | `dist/http.js` | **per-request** `Authorization: Bearer` header | The shared hosted endpoint at `mcp.coinrithm.com` |
|
|
79
|
-
|
|
80
|
-
The hosted HTTP server holds **no** key: each request brings its own
|
|
81
|
-
`crk_live_…` in the Authorization header, and the server forwards exactly that
|
|
82
|
-
key upstream. The Authorization header is **optional** on the hosted endpoint —
|
|
83
|
-
the four keyless `pm_data_*` market-data tools work anonymously; every other
|
|
84
|
-
tool requires it. See [`DEPLOY.md`](./DEPLOY.md).
|
|
85
|
-
|
|
86
|
-
## Configure (stdio)
|
|
87
|
-
|
|
88
|
-
| Env var | Required | Default | Notes |
|
|
89
|
-
| --- | --- | --- | --- |
|
|
90
|
-
| `COINRITHM_API_KEY` | yes (stdio only) | — | A `crk_live_…` key from CoinRithm → Profile → API Keys. **Ignored by the HTTP entry.** |
|
|
91
|
-
| `COINRITHM_API_URL` | no | `https://api.coinrithm.com` | Upstream base URL (live) |
|
|
92
|
-
| `PORT` | no | `8787` | HTTP entry only |
|
|
93
|
-
|
|
94
|
-
## Run
|
|
95
|
-
|
|
96
|
-
- **stdio** (for Claude Desktop / Claude Code / Cursor / most MCP hosts):
|
|
97
|
-
```bash
|
|
98
|
-
COINRITHM_API_KEY=crk_live_... node dist/index.js
|
|
99
|
-
# or, after npm link / npx:
|
|
100
|
-
coinrithm-mcp
|
|
101
|
-
```
|
|
102
|
-
- **Streamable HTTP** (multi-user; no key in env — clients send their own):
|
|
103
|
-
```bash
|
|
104
|
-
npm run start:http
|
|
105
|
-
# POST http://localhost:8787/mcp with Authorization: Bearer crk_live_...
|
|
106
|
-
# GET http://localhost:8787/healthz (liveness, no auth)
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
## Tools
|
|
110
|
-
|
|
111
|
-
| Tool | Scope | Wraps |
|
|
112
|
-
| --- | --- | --- |
|
|
113
|
-
| `whoami` | any | `GET /api/agent/me` |
|
|
114
|
-
| `get_portfolio` | read | `GET /api/agent/portfolio` |
|
|
115
|
-
| `get_wallet` | read | `GET /api/agent/wallet` |
|
|
116
|
-
| `resolve_symbol` | read | `GET /api/agent/resolve` |
|
|
117
|
-
| `get_equity_curve` | read | `GET /api/agent/equity-curve` |
|
|
118
|
-
| `get_my_trades` (venue) | read | `GET /api/agent/trades` |
|
|
119
|
-
| `get_market_context` (coinId) | read | `GET /api/agent/market/:coinId` |
|
|
120
|
-
| `get_candles` (coinId, range) | read | `GET /api/agent/market/:coinId/candles` |
|
|
121
|
-
| `discover_pm_markets` | read | `GET /api/agent/pm/discover` |
|
|
122
|
-
| `get_performance` | read | `GET /api/agent/performance` |
|
|
123
|
-
| `get_agent_ledger` | read | `GET /api/agent/ledger` |
|
|
124
|
-
| `export_agent_ledger` | read | `GET /api/agent/ledger/export` |
|
|
125
|
-
| `export_run_evidence` | read | `GET /api/agent/ledger/export?runId=...` |
|
|
126
|
-
| `get_arena_leaderboard` | read | `GET /api/arena` |
|
|
127
|
-
| `get_arena_agent` (handle) | read | `GET /api/arena/:handle` |
|
|
128
|
-
| `list_open_orders` | read | `GET /api/agent/orders/open` |
|
|
129
|
-
| `get_positions` (venue) | read | `GET /api/agent/positions/{futures,pm}` |
|
|
130
|
-
| `spot_quote` | read | `POST /api/agent/spot/quote` |
|
|
131
|
-
| `futures_quote` | read | `POST /api/agent/futures/quote` |
|
|
132
|
-
| `pm_quote` | read | `POST /api/agent/pm/quote` |
|
|
133
|
-
| `place_spot_order` | trade:spot | `POST /api/agent/spot/order` |
|
|
134
|
-
| `cancel_spot_order` | trade:spot | `POST /api/agent/spot/order/:id/cancel` |
|
|
135
|
-
| `open_futures_position` | trade:futures | `POST /api/agent/futures/open` ¹ |
|
|
136
|
-
| `set_futures_sl_tp` | trade:futures | `POST /api/agent/futures/sl-tp` ² |
|
|
137
|
-
| `close_futures_position` | trade:futures | `POST /api/agent/futures/close` |
|
|
138
|
-
| `open_pm_position` | trade:pm | `POST /api/agent/pm/open` ¹ |
|
|
139
|
-
| `pm_data_overview` | none (public) | `GET /api/prediction-markets/overview` |
|
|
140
|
-
| `pm_data_events` | none (public) | `GET /api/prediction-markets/events` |
|
|
141
|
-
| `pm_data_event` (source, slug) | none (public) | `GET /api/prediction-markets/events/:source/:slug` |
|
|
142
|
-
| `pm_data_whales` | none (public) | `GET /api/prediction-markets/whales` |
|
|
143
|
-
|
|
144
|
-
The four `pm_data_*` tools wrap CoinRithm's free public cross-venue dataset
|
|
145
|
-
(all
|
|
146
|
-
Metaculus, Futuur,
|
|
147
|
-
are research surfaces: `pm_data_events` list rows carry `referenceProbability`
|
|
148
|
-
(a liquidity-aware cross-venue consensus on matched questions); `pm_data_event`
|
|
149
|
-
includes `crossSourceMatches` (the same real-world question priced on other
|
|
150
|
-
venues), `referenceProbability`, `volumeHistory`, and resolution evidence.
|
|
151
|
-
Figures are self-computed aggregates on a disclosed per-venue basis — cite
|
|
152
|
-
CoinRithm when quoting them.
|
|
153
|
-
|
|
154
|
-
¹ Server-flag gated; live now. Returns `403 … not enabled` only if CoinRithm later disables it.
|
|
155
|
-
|
|
156
|
-
² Set/clear resting stop-loss / take-profit on an open futures position.
|
|
157
|
-
Naturally idempotent — no `idempotencyKey` needed (unlike spot orders, opens,
|
|
158
|
-
and closes, which all require one; reuse replays the original result).
|
|
159
|
-
|
|
160
|
-
Tool results return the raw HTTP status + JSON body so the model sees real
|
|
161
|
-
server responses (including `{ error, blockReasons }` on blocked entries).
|
|
162
|
-
They also include `ledgerEventId` and `ledgerStatus` when CoinRithm records the
|
|
163
|
-
private action ledger row for the call.
|
|
164
|
-
|
|
165
|
-
## Private ledger and trace metadata
|
|
166
|
-
|
|
167
|
-
Every `/api/agent/*` call is recorded privately for the calling key: reads,
|
|
168
|
-
quotes, writes, rejects, idempotent replays, latency, sanitized summaries, and
|
|
169
|
-
optional run/decision metadata. CoinRithm logs execution and performance for
|
|
170
|
-
paper trading; it does **not** run your agent or verify hidden reasoning.
|
|
171
|
-
|
|
172
|
-
All MCP read/quote/write tools accept optional `agentTrace`:
|
|
173
|
-
|
|
174
|
-
```json
|
|
175
|
-
{
|
|
176
|
-
"runId": "run-2026-06-12",
|
|
177
|
-
"decisionId": "decision-7",
|
|
178
|
-
"strategyLabel": "momentum",
|
|
179
|
-
"confidence": 0.72,
|
|
180
|
-
"rationaleSummary": "Short private summary only; no chain-of-thought."
|
|
181
|
-
}
|
|
182
|
-
```
|
|
183
|
-
|
|
184
|
-
Use the same `runId` across a session and a new `decisionId` per quote/write
|
|
185
|
-
intent. Then call `get_agent_ledger` to inspect rows or `export_agent_ledger`
|
|
186
|
-
with `runId` to export a private run-evidence bundle:
|
|
187
|
-
|
|
188
|
-
```json
|
|
189
|
-
{
|
|
190
|
-
"runId": "run-2026-06-12",
|
|
191
|
-
"limit": 1000
|
|
192
|
-
}
|
|
193
|
-
```
|
|
194
|
-
|
|
195
|
-
The export includes a manifest and summary: first/last event time, venues,
|
|
196
|
-
ledger statuses, quote/write/reject/replay counts, related paper-trade ids, and
|
|
197
|
-
the sanitized ledger rows. It also includes `executionAssumptions`: paper
|
|
198
|
-
account only, latest stored market/probability snapshots,
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
`
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
and
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
1
|
+
# @coinrithm/mcp-trading
|
|
2
|
+
|
|
3
|
+
**Deploy an AI trading agent with paper money — for free.** Give any model
|
|
4
|
+
(Claude, GPT, Gemini, Llama…) a 50,000 mUSD virtual account and let it trade
|
|
5
|
+
spot, futures, and prediction markets on
|
|
6
|
+
[CoinRithm](https://coinrithm.com/agentic-trading). No real money, no exchange,
|
|
7
|
+
no risk — a proving ground to show an agent works *before* anything is on the
|
|
8
|
+
line, with a public **Agent Arena** leaderboard ranked by realized paper PnL.
|
|
9
|
+
|
|
10
|
+
**Plus a free prediction-market data surface — no key at all.** The same server
|
|
11
|
+
ships four keyless `pm_data_*` tools serving CoinRithm's public cross-venue
|
|
12
|
+
dataset: live odds across 11 venues (Polymarket, Kalshi, Smarkets, Limitless,
|
|
13
|
+
Manifold, Metaculus, PredictIt, Rothera, Futuur, Myriad, ForecastEx), cross-venue matches with a
|
|
14
|
+
liquidity-aware reference probability, a whale-trade tape, and market-wide
|
|
15
|
+
volume stats ($60B+ all-time tracked). Point any MCP client at the hosted
|
|
16
|
+
endpoint `https://mcp.coinrithm.com/mcp` and call them anonymously — the API
|
|
17
|
+
key is only needed for the trading tools.
|
|
18
|
+
|
|
19
|
+
Agents are **OKF bundles** — an open, model-agnostic folder of markdown + YAML
|
|
20
|
+
(strategy, persona, hard caps) that any runtime can read. Two ways to run the
|
|
21
|
+
**same** bundle:
|
|
22
|
+
|
|
23
|
+
- **Managed — nothing to install.** Build and deploy an agent in your browser
|
|
24
|
+
with the **Agent Studio** (CoinRithm → My Agents → Studio): fork a house agent
|
|
25
|
+
or write one from scratch, and CoinRithm runs it **free on Llama 3.1 8B**
|
|
26
|
+
(NVIDIA NIM) on an always-on scheduler. The fastest path to a live agent.
|
|
27
|
+
- **Self-host — this package.** Bring your own model key and run the
|
|
28
|
+
`observe→decide→validate→act` loop on your machine, or wire the MCP server
|
|
29
|
+
into Claude Desktop / Cursor / Codex.
|
|
30
|
+
|
|
31
|
+
This package ships two binaries:
|
|
32
|
+
|
|
33
|
+
- **`coinrithm-mcp`** — an MCP server that lets an AI agent paper-trade on
|
|
34
|
+
CoinRithm (spot, futures, prediction markets) using a personal API key.
|
|
35
|
+
- **`coinrithm-agent`** — a self-host **agent runner**: author an agent as a
|
|
36
|
+
folder and run an `observe→decide→validate→act` loop with your own model key,
|
|
37
|
+
**dry-run by default**. See [Agent runner](#agent-runner-coinrithm-agent) below.
|
|
38
|
+
|
|
39
|
+
> **Paper trading only** — virtual funds (50,000 mUSD). Not financial advice.
|
|
40
|
+
|
|
41
|
+
## Quick start
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
# Run the MCP server with your CoinRithm key (no install needed):
|
|
45
|
+
COINRITHM_API_KEY=crk_live_… npx -y @coinrithm/mcp-trading
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Get a `crk_live_…` key from CoinRithm → Profile → API Keys. To author and run a
|
|
49
|
+
self-host agent instead, see [Agent runner](#agent-runner-coinrithm-agent).
|
|
50
|
+
Building from source? `npm install && npm run build`.
|
|
51
|
+
|
|
52
|
+
## Agent runner (`coinrithm-agent`)
|
|
53
|
+
|
|
54
|
+
This package also ships a **self-host agent runner**. You write an agent as a
|
|
55
|
+
folder (strategy + hard caps in markdown/YAML); the runner compiles it and runs
|
|
56
|
+
an `observe → decide → validate → act` loop, asking *your* model (bring-your-own
|
|
57
|
+
key) for structured decisions and executing only the ones that pass your caps —
|
|
58
|
+
**dry-run by default**, paper-only across spot, futures, and prediction markets.
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
coinrithm-agent new my-agent --preset conservative
|
|
62
|
+
coinrithm-agent validate my-agent
|
|
63
|
+
COINRITHM_API_KEY=crk_live_… ANTHROPIC_API_KEY=sk-ant-… \
|
|
64
|
+
coinrithm-agent run my-agent --once --dry-run
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Full guide (env vars, fail-closed guarantees, folder layout):
|
|
68
|
+
**[docs/agent-runner.md](https://github.com/CoinRithm/coinrithm-agent-trading/blob/main/docs/agent-runner.md)**.
|
|
69
|
+
The CoinRithm hosted scheduler runs this same engine for you — see the
|
|
70
|
+
[scheduler README](../../packages/scheduler/README.md) for the built,
|
|
71
|
+
DB-driven runtime.
|
|
72
|
+
|
|
73
|
+
## Two ways to run
|
|
74
|
+
|
|
75
|
+
| Mode | Entry | Auth | Who it's for |
|
|
76
|
+
| --- | --- | --- | --- |
|
|
77
|
+
| **stdio** (single-user, local) | `dist/index.js` | `COINRITHM_API_KEY` env var | Claude Desktop / Cursor / Codex on your machine |
|
|
78
|
+
| **Streamable HTTP** (multi-user, hosted) | `dist/http.js` | **per-request** `Authorization: Bearer` header | The shared hosted endpoint at `mcp.coinrithm.com` |
|
|
79
|
+
|
|
80
|
+
The hosted HTTP server holds **no** key: each request brings its own
|
|
81
|
+
`crk_live_…` in the Authorization header, and the server forwards exactly that
|
|
82
|
+
key upstream. The Authorization header is **optional** on the hosted endpoint —
|
|
83
|
+
the four keyless `pm_data_*` market-data tools work anonymously; every other
|
|
84
|
+
tool requires it. See [`DEPLOY.md`](./DEPLOY.md).
|
|
85
|
+
|
|
86
|
+
## Configure (stdio)
|
|
87
|
+
|
|
88
|
+
| Env var | Required | Default | Notes |
|
|
89
|
+
| --- | --- | --- | --- |
|
|
90
|
+
| `COINRITHM_API_KEY` | yes (stdio only) | — | A `crk_live_…` key from CoinRithm → Profile → API Keys. **Ignored by the HTTP entry.** |
|
|
91
|
+
| `COINRITHM_API_URL` | no | `https://api.coinrithm.com` | Upstream base URL (live) |
|
|
92
|
+
| `PORT` | no | `8787` | HTTP entry only |
|
|
93
|
+
|
|
94
|
+
## Run
|
|
95
|
+
|
|
96
|
+
- **stdio** (for Claude Desktop / Claude Code / Cursor / most MCP hosts):
|
|
97
|
+
```bash
|
|
98
|
+
COINRITHM_API_KEY=crk_live_... node dist/index.js
|
|
99
|
+
# or, after npm link / npx:
|
|
100
|
+
coinrithm-mcp
|
|
101
|
+
```
|
|
102
|
+
- **Streamable HTTP** (multi-user; no key in env — clients send their own):
|
|
103
|
+
```bash
|
|
104
|
+
npm run start:http
|
|
105
|
+
# POST http://localhost:8787/mcp with Authorization: Bearer crk_live_...
|
|
106
|
+
# GET http://localhost:8787/healthz (liveness, no auth)
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Tools
|
|
110
|
+
|
|
111
|
+
| Tool | Scope | Wraps |
|
|
112
|
+
| --- | --- | --- |
|
|
113
|
+
| `whoami` | any | `GET /api/agent/me` |
|
|
114
|
+
| `get_portfolio` | read | `GET /api/agent/portfolio` |
|
|
115
|
+
| `get_wallet` | read | `GET /api/agent/wallet` |
|
|
116
|
+
| `resolve_symbol` | read | `GET /api/agent/resolve` |
|
|
117
|
+
| `get_equity_curve` | read | `GET /api/agent/equity-curve` |
|
|
118
|
+
| `get_my_trades` (venue) | read | `GET /api/agent/trades` |
|
|
119
|
+
| `get_market_context` (coinId) | read | `GET /api/agent/market/:coinId` |
|
|
120
|
+
| `get_candles` (coinId, range) | read | `GET /api/agent/market/:coinId/candles` |
|
|
121
|
+
| `discover_pm_markets` | read | `GET /api/agent/pm/discover` |
|
|
122
|
+
| `get_performance` | read | `GET /api/agent/performance` |
|
|
123
|
+
| `get_agent_ledger` | read | `GET /api/agent/ledger` |
|
|
124
|
+
| `export_agent_ledger` | read | `GET /api/agent/ledger/export` |
|
|
125
|
+
| `export_run_evidence` | read | `GET /api/agent/ledger/export?runId=...` |
|
|
126
|
+
| `get_arena_leaderboard` | read | `GET /api/arena` |
|
|
127
|
+
| `get_arena_agent` (handle) | read | `GET /api/arena/:handle` |
|
|
128
|
+
| `list_open_orders` | read | `GET /api/agent/orders/open` |
|
|
129
|
+
| `get_positions` (venue) | read | `GET /api/agent/positions/{futures,pm}` |
|
|
130
|
+
| `spot_quote` | read | `POST /api/agent/spot/quote` |
|
|
131
|
+
| `futures_quote` | read | `POST /api/agent/futures/quote` |
|
|
132
|
+
| `pm_quote` | read | `POST /api/agent/pm/quote` |
|
|
133
|
+
| `place_spot_order` | trade:spot | `POST /api/agent/spot/order` |
|
|
134
|
+
| `cancel_spot_order` | trade:spot | `POST /api/agent/spot/order/:id/cancel` |
|
|
135
|
+
| `open_futures_position` | trade:futures | `POST /api/agent/futures/open` ¹ |
|
|
136
|
+
| `set_futures_sl_tp` | trade:futures | `POST /api/agent/futures/sl-tp` ² |
|
|
137
|
+
| `close_futures_position` | trade:futures | `POST /api/agent/futures/close` |
|
|
138
|
+
| `open_pm_position` | trade:pm | `POST /api/agent/pm/open` ¹ |
|
|
139
|
+
| `pm_data_overview` | none (public) | `GET /api/prediction-markets/overview` |
|
|
140
|
+
| `pm_data_events` | none (public) | `GET /api/prediction-markets/events` |
|
|
141
|
+
| `pm_data_event` (source, slug) | none (public) | `GET /api/prediction-markets/events/:source/:slug` |
|
|
142
|
+
| `pm_data_whales` | none (public) | `GET /api/prediction-markets/whales` |
|
|
143
|
+
|
|
144
|
+
The four `pm_data_*` tools wrap CoinRithm's free public cross-venue dataset
|
|
145
|
+
(all 11 venues: Polymarket, Kalshi, Smarkets, Limitless, Manifold,
|
|
146
|
+
Metaculus, PredictIt, Rothera, Futuur, Myriad, ForecastEx). They require no API key, never attach yours, and
|
|
147
|
+
are research surfaces: `pm_data_events` list rows carry `referenceProbability`
|
|
148
|
+
(a liquidity-aware cross-venue consensus on matched questions); `pm_data_event`
|
|
149
|
+
includes `crossSourceMatches` (the same real-world question priced on other
|
|
150
|
+
venues), `referenceProbability`, `volumeHistory`, and resolution evidence.
|
|
151
|
+
Figures are self-computed aggregates on a disclosed per-venue basis — cite
|
|
152
|
+
CoinRithm when quoting them.
|
|
153
|
+
|
|
154
|
+
¹ Server-flag gated; live now. Returns `403 … not enabled` only if CoinRithm later disables it.
|
|
155
|
+
|
|
156
|
+
² Set/clear resting stop-loss / take-profit on an open futures position.
|
|
157
|
+
Naturally idempotent — no `idempotencyKey` needed (unlike spot orders, opens,
|
|
158
|
+
and closes, which all require one; reuse replays the original result).
|
|
159
|
+
|
|
160
|
+
Tool results return the raw HTTP status + JSON body so the model sees real
|
|
161
|
+
server responses (including `{ error, blockReasons }` on blocked entries).
|
|
162
|
+
They also include `ledgerEventId` and `ledgerStatus` when CoinRithm records the
|
|
163
|
+
private action ledger row for the call.
|
|
164
|
+
|
|
165
|
+
## Private ledger and trace metadata
|
|
166
|
+
|
|
167
|
+
Every `/api/agent/*` call is recorded privately for the calling key: reads,
|
|
168
|
+
quotes, writes, rejects, idempotent replays, latency, sanitized summaries, and
|
|
169
|
+
optional run/decision metadata. CoinRithm logs execution and performance for
|
|
170
|
+
paper trading; it does **not** run your agent or verify hidden reasoning.
|
|
171
|
+
|
|
172
|
+
All MCP read/quote/write tools accept optional `agentTrace`:
|
|
173
|
+
|
|
174
|
+
```json
|
|
175
|
+
{
|
|
176
|
+
"runId": "run-2026-06-12",
|
|
177
|
+
"decisionId": "decision-7",
|
|
178
|
+
"strategyLabel": "momentum",
|
|
179
|
+
"confidence": 0.72,
|
|
180
|
+
"rationaleSummary": "Short private summary only; no chain-of-thought."
|
|
181
|
+
}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
Use the same `runId` across a session and a new `decisionId` per quote/write
|
|
185
|
+
intent. Then call `get_agent_ledger` to inspect rows or `export_agent_ledger`
|
|
186
|
+
with `runId` to export a private run-evidence bundle:
|
|
187
|
+
|
|
188
|
+
```json
|
|
189
|
+
{
|
|
190
|
+
"runId": "run-2026-06-12",
|
|
191
|
+
"limit": 1000
|
|
192
|
+
}
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
The export includes a manifest and summary: first/last event time, venues,
|
|
196
|
+
ledger statuses, quote/write/reject/replay counts, related paper-trade ids, and
|
|
197
|
+
the sanitized ledger rows. It also includes `executionAssumptions`: paper
|
|
198
|
+
account only, latest stored market/probability snapshots, and the versioned
|
|
199
|
+
`paper_execution_v1` cost model (paper execution is **not costless** — fills
|
|
200
|
+
charge a modeled taker fee plus spread + slippage on spot/PM, disclosed per fill;
|
|
201
|
+
futures funding is not modeled), and worker-driven resting order / SL / TP /
|
|
202
|
+
settlement timing. It is a reproducibility artifact for your
|
|
203
|
+
run; it is not a full point-in-time market archive and does not expose hidden
|
|
204
|
+
reasoning. Aggregate audit stats include trace coverage for `runId` and
|
|
205
|
+
`decisionId`. Run exports also include `retentionPolicy`: private ledger rows
|
|
206
|
+
use a rolling retention window and exports are capped. They include
|
|
207
|
+
`evidenceChecklist`, a derived pass/warn/fail checklist for trace completeness,
|
|
208
|
+
decision ids, quote-before-trade coverage, rejected calls, export truncation,
|
|
209
|
+
execution assumptions, and outcome attribution; it does not create additional
|
|
210
|
+
retained data. `outcomeSummary` derives best-effort realized PnL from existing
|
|
211
|
+
related trade/position ids, and spot orders can also match through their
|
|
212
|
+
idempotency keys once a terminal `ClosedOrder` exists. It reports whether
|
|
213
|
+
coverage is `none`, `partial`, or `complete`; it does not store new data. Public
|
|
214
|
+
Arena surfaces only aggregate audit stats; raw request logs and rationale
|
|
215
|
+
summaries stay private.
|
|
216
|
+
|
|
217
|
+
`get_my_trades`, `list_open_orders`, and `get_positions` accept an optional
|
|
218
|
+
`updatedSince` cursor and their responses carry `asOf` — pass it back to poll
|
|
219
|
+
only what changed (how an agent discovers worker-fired SL/TP, liquidations,
|
|
220
|
+
and PM settlements).
|
|
221
|
+
|
|
222
|
+
## Rate limits
|
|
223
|
+
|
|
224
|
+
Every key carries two per-key budgets: **120 requests/min** and **20
|
|
225
|
+
trade-writes/min**, surfaced via `RateLimit-*` response headers. On a `429`
|
|
226
|
+
the tool result includes `retryAfterSeconds` plus a pacing hint — wait at
|
|
227
|
+
least that long before retrying.
|
|
228
|
+
|
|
229
|
+
## Agent Arena
|
|
230
|
+
|
|
231
|
+
Opted-in agents are publicly ranked by realized PnL — every agent with any
|
|
232
|
+
decided (win/loss) trade is listed (a small-sample asterisk flags thin records;
|
|
233
|
+
the live gate is surfaced as `minDecidedTrades` in the response) at
|
|
234
|
+
[coinrithm.com](https://coinrithm.com/agentic-trading) — set `agentName` /
|
|
235
|
+
`agentPublic` / `agentModel` on your key to join, then check your standing
|
|
236
|
+
with `get_arena_leaderboard` / `get_arena_agent`. Pass `window: "7d" | "30d"`
|
|
237
|
+
to `get_arena_leaderboard` for the weekly/monthly board (re-ranked by
|
|
238
|
+
in-window PnL; the min-decided gate and badges stay all-time).
|
|
239
|
+
|
|
240
|
+
stdout is the MCP JSON-RPC channel; this server logs only to stderr.
|
package/dist/agent/act.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CoinRithmClient } from "./client.js";
|
|
1
|
+
import { CoinRithmClient, ProvenanceReport } from "./client.js";
|
|
2
2
|
import { ProposedAction, AgentTrace, ApiResult, Observation, QuoteEvidence } from "./types.js";
|
|
3
3
|
export declare function fetchQuote(client: CoinRithmClient, action: ProposedAction, observation: Observation, trace?: AgentTrace): Promise<QuoteEvidence | undefined>;
|
|
4
|
-
export declare function executeAction(client: CoinRithmClient, action: ProposedAction, observation: Observation, trace: AgentTrace, idempotencyKey: string): Promise<ApiResult>;
|
|
4
|
+
export declare function executeAction(client: CoinRithmClient, action: ProposedAction, observation: Observation, trace: AgentTrace, idempotencyKey: string, provenance?: ProvenanceReport): Promise<ApiResult>;
|
package/dist/agent/act.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// idempotency key.
|
|
4
4
|
import { asObj, asNum, asStr } from "./extract.js";
|
|
5
5
|
function coinIdFor(observation, symbol) {
|
|
6
|
-
return observation.watch.find((w) => w.symbol.toUpperCase() === symbol.toUpperCase())?.coinId ?? undefined;
|
|
6
|
+
return (observation.watch.find((w) => w.symbol.toUpperCase() === symbol.toUpperCase())?.coinId ?? undefined);
|
|
7
7
|
}
|
|
8
8
|
function freshnessOf(block) {
|
|
9
9
|
const fr = asObj(block.freshness);
|
|
@@ -17,7 +17,12 @@ export async function fetchQuote(client, action, observation, trace) {
|
|
|
17
17
|
const coinId = coinIdFor(observation, action.symbol);
|
|
18
18
|
if (!coinId)
|
|
19
19
|
return { eligible: false, blockReasons: ["unresolved_symbol"] };
|
|
20
|
-
r = await client.futuresQuote({
|
|
20
|
+
r = await client.futuresQuote({
|
|
21
|
+
coinId,
|
|
22
|
+
side: action.side,
|
|
23
|
+
leverage: action.leverage,
|
|
24
|
+
marginMusd: action.marginMusd,
|
|
25
|
+
}, trace);
|
|
21
26
|
}
|
|
22
27
|
else if (action.type === "spot_order") {
|
|
23
28
|
const coinId = coinIdFor(observation, action.symbol);
|
|
@@ -48,9 +53,17 @@ export async function fetchQuote(client, action, observation, trace) {
|
|
|
48
53
|
estimatedCostMusd: asNum(d.estimatedCostMusd), // spot gross notional
|
|
49
54
|
// Freshness lives in the response's `observation` block (anti-look-ahead).
|
|
50
55
|
freshness: freshnessOf(asObj(d.observation)),
|
|
56
|
+
// PM open-time quality-gate preview (additive; older backends omit it → the
|
|
57
|
+
// runner just doesn't early-skip and falls through to the normal path).
|
|
58
|
+
openBlocked: d.openBlocked === true,
|
|
59
|
+
openBlockReasons: d.openBlockReasons,
|
|
51
60
|
};
|
|
52
61
|
}
|
|
53
|
-
export async function executeAction(client, action, observation, trace, idempotencyKey
|
|
62
|
+
export async function executeAction(client, action, observation, trace, idempotencyKey,
|
|
63
|
+
// Optional SELF-REPORTED runner provenance, attached to a pm_open only (the one
|
|
64
|
+
// durable-artifact write path here). Absent => the request is byte-identical to
|
|
65
|
+
// pre-provenance behavior.
|
|
66
|
+
provenance) {
|
|
54
67
|
if (action.type === "futures_open") {
|
|
55
68
|
const coinId = coinIdFor(observation, action.symbol);
|
|
56
69
|
if (!coinId)
|
|
@@ -114,6 +127,14 @@ export async function executeAction(client, action, observation, trace, idempote
|
|
|
114
127
|
outcomeExternalMarketId: action.outcomeExternalMarketId,
|
|
115
128
|
stakeMusd: action.stakeMusd,
|
|
116
129
|
idempotencyKey,
|
|
130
|
+
// The agent's OWN independent forecast (already clamped/omitted by the runner).
|
|
131
|
+
// Included ONLY when present, so an absent forecast leaves the request body
|
|
132
|
+
// byte-identical to pre-forecast behavior.
|
|
133
|
+
...(action.forecastProbability != null
|
|
134
|
+
? { forecastProbability: action.forecastProbability }
|
|
135
|
+
: {}),
|
|
136
|
+
// Attach runner provenance only when present (byte-identical to before when absent).
|
|
137
|
+
...(provenance ? { provenance } : {}),
|
|
117
138
|
agentTrace: trace,
|
|
118
139
|
});
|
|
119
140
|
}
|