@coinrithm/mcp-trading 0.7.11 → 0.7.13

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/dist/tools.js CHANGED
@@ -197,6 +197,8 @@ const EVENT_SUMMARY_FIELDS = [
197
197
  "endDate",
198
198
  "resolvedAt",
199
199
  "resolvedAtBasis",
200
+ "resolvedOutcomeExternalMarketId",
201
+ "resolutionOutcomeBasis",
200
202
  "settlementWindowClosedAt",
201
203
  "freshness",
202
204
  "volume",
@@ -221,6 +223,9 @@ const OUTCOME_SUMMARY_FIELDS = [
221
223
  "probability",
222
224
  "normalizedProbability",
223
225
  "priceChange24h",
226
+ "lifecycle",
227
+ "priorProbability",
228
+ "venueTerms",
224
229
  ];
225
230
  const WHALE_TRADE_FIELDS = [
226
231
  "source",
@@ -274,6 +279,20 @@ function eventSummary(value) {
274
279
  ? value.outcomes
275
280
  .map((outcome, index) => ({ outcome, index }))
276
281
  .sort((left, right) => {
282
+ if (value.status === "open") {
283
+ const leftTerminal = isJsonRecord(left.outcome) && isTerminalOutcome(left.outcome);
284
+ const rightTerminal = isJsonRecord(right.outcome) && isTerminalOutcome(right.outcome);
285
+ if (leftTerminal !== rightTerminal)
286
+ return leftTerminal ? 1 : -1;
287
+ }
288
+ else {
289
+ const leftWinner = isJsonRecord(left.outcome) &&
290
+ isProviderConfirmedWinner(left.outcome, value);
291
+ const rightWinner = isJsonRecord(right.outcome) &&
292
+ isProviderConfirmedWinner(right.outcome, value);
293
+ if (leftWinner !== rightWinner)
294
+ return leftWinner ? -1 : 1;
295
+ }
277
296
  const a = isJsonRecord(left.outcome)
278
297
  ? probability(left.outcome.probability)
279
298
  : null;
@@ -300,6 +319,22 @@ function eventSummary(value) {
300
319
  outcomes,
301
320
  };
302
321
  }
322
+ function isTerminalOutcome(outcome) {
323
+ const lifecycle = isJsonRecord(outcome.lifecycle) ? outcome.lifecycle : null;
324
+ return Boolean(lifecycle?.isResult === true ||
325
+ (typeof lifecycle?.state === "string" &&
326
+ ["closed", "resolved", "voided"].includes(lifecycle.state)));
327
+ }
328
+ function isProviderConfirmedWinner(outcome, event) {
329
+ const lifecycle = isJsonRecord(outcome.lifecycle) ? outcome.lifecycle : null;
330
+ const lifecycleWinner = lifecycle?.isResult === true &&
331
+ lifecycle.result === "won" &&
332
+ lifecycle.basis === "provider";
333
+ const eventWinner = event.resolutionOutcomeBasis === "provider" &&
334
+ typeof event.resolvedOutcomeExternalMarketId === "string" &&
335
+ outcome.externalMarketId === event.resolvedOutcomeExternalMarketId;
336
+ return lifecycleWinner || eventWinner;
337
+ }
303
338
  /**
304
339
  * Keep keyless discovery calls small enough for an agent context window.
305
340
  * Full event evidence remains available from pm_data_event.
@@ -507,6 +542,73 @@ export function compactPublicPmWhales(data, limit) {
507
542
  : data.trades;
508
543
  return { ...data, trades };
509
544
  }
545
+ const WHALE_WALLET_FIELDS = [
546
+ "wallet",
547
+ "address",
548
+ "traderName",
549
+ "venues",
550
+ "tradeCount",
551
+ "totalUsd",
552
+ "maxUsd",
553
+ "firstSeen",
554
+ "lastSeen",
555
+ ];
556
+ export function compactPublicPmWhaleWallets(data, limit, requestedSource) {
557
+ if (!isJsonRecord(data))
558
+ return data;
559
+ if (requestedSource &&
560
+ (!Array.isArray(data.venues) ||
561
+ data.venues.length !== 1 ||
562
+ data.venues[0] !== requestedSource)) {
563
+ return {
564
+ unavailable: "filtered_wallet_scope_unconfirmed",
565
+ requestedSource,
566
+ };
567
+ }
568
+ const wallets = Array.isArray(data.wallets)
569
+ ? data.wallets
570
+ .slice(0, limit)
571
+ .map((wallet) => isJsonRecord(wallet) ? pick(wallet, WHALE_WALLET_FIELDS) : wallet)
572
+ : data.wallets;
573
+ return { ...data, wallets };
574
+ }
575
+ const WHALE_WALLET_FILL_FIELDS = [
576
+ "side",
577
+ "outcome",
578
+ "marketQuestion",
579
+ "usdValue",
580
+ "price",
581
+ "evidenceType",
582
+ "evidenceUrl",
583
+ "availability",
584
+ "tradedAt",
585
+ "event",
586
+ ];
587
+ export function compactPublicPmWhaleWalletDetail(data) {
588
+ if (!isJsonRecord(data))
589
+ return data;
590
+ const compactEvent = (value) => isJsonRecord(value)
591
+ ? pick(value, ["source", "slug", "title", "status"])
592
+ : value;
593
+ const compactFill = (value) => {
594
+ if (!isJsonRecord(value))
595
+ return value;
596
+ const fill = pick(value, WHALE_WALLET_FILL_FIELDS);
597
+ if (isJsonRecord(fill) && "event" in fill) {
598
+ return { ...fill, event: compactEvent(fill.event) };
599
+ }
600
+ return fill;
601
+ };
602
+ return {
603
+ ...data,
604
+ topEvents30d: Array.isArray(data.topEvents30d)
605
+ ? data.topEvents30d.slice(0, 20)
606
+ : data.topEvents30d,
607
+ recentFills: Array.isArray(data.recentFills)
608
+ ? data.recentFills.slice(0, 20).map(compactFill)
609
+ : data.recentFills,
610
+ };
611
+ }
510
612
  // Crypto movers rows arrive as {ucid, symbol, name, slug, change24h,
511
613
  // currentPrice} with the numerics as STRINGS (backend SQL fn passthrough).
512
614
  // Coerce so a brain never string-compares "9.5" > "12"; drop the internal
@@ -604,12 +706,14 @@ export function registerTools(server, client) {
604
706
  // ---------------- identity ----------------
605
707
  server.registerTool("whoami", {
606
708
  title: "Who am I (CoinRithm)",
607
- description: "Return the identity behind the configured API key: userId, keyId, " +
608
- "granted scopes, plus the key's agentName and agentModel (both null " +
609
- "until set in Profile -> API Keys; agentModel is the self-reported " +
610
- "model/runtime label shown on the public Agent Arena when opted in). " +
611
- "Use this first to confirm what the key is allowed to do. " +
612
- PAPER_NOTE,
709
+ description: "Check the caller's CoinRithm API-key identity and permissions before " +
710
+ "using account or trading tools. Returns userId, keyId, scopes, usage, " +
711
+ "and nullable agentName/agentModel labels; agentModel is self-reported, " +
712
+ "not verified runtime identity. Any valid configured or per-request key " +
713
+ "works; no additional scope is required. Missing or invalid keys return " +
714
+ "401. Omit agentTrace for a simple check. Does not change permissions " +
715
+ "or paper balances; requests update usage/last-used metadata and may " +
716
+ "be privately logged.",
613
717
  inputSchema: {
614
718
  agentTrace: AGENT_TRACE_SCHEMA,
615
719
  },
@@ -1092,16 +1196,31 @@ export function registerTools(server, client) {
1092
1196
  "resolves false; fills at 100 minus the outcome probability. " +
1093
1197
  "Omitted = yes."),
1094
1198
  stakeMusd: z.number().positive().describe("mUSD to stake (> 0)."),
1199
+ forecastProbability: z
1200
+ .number()
1201
+ .finite()
1202
+ .gt(0)
1203
+ .lt(100)
1204
+ .optional()
1205
+ .describe("Optional own probability that the selected side wins (0-100 exclusive) for advisory edge sizing."),
1206
+ bankrollMusd: z
1207
+ .number()
1208
+ .finite()
1209
+ .positive()
1210
+ .optional()
1211
+ .describe("Optional bankroll in mUSD for the advisory suggested stake."),
1095
1212
  agentTrace: AGENT_TRACE_SCHEMA,
1096
1213
  },
1097
1214
  outputSchema: API_RESULT_OUTPUT_SCHEMA,
1098
1215
  annotations: readOnlyAnnotations("Prediction-market quote"),
1099
- }, async ({ source, slug, outcomeExternalMarketId, side, stakeMusd, agentTrace }, extra) => present(await client.pmQuote({
1216
+ }, async ({ source, slug, outcomeExternalMarketId, side, stakeMusd, forecastProbability, bankrollMusd, agentTrace, }, extra) => present(await client.pmQuote({
1100
1217
  source,
1101
1218
  slug,
1102
1219
  outcomeExternalMarketId,
1103
1220
  side,
1104
1221
  stakeMusd,
1222
+ forecastProbability,
1223
+ bankrollMusd,
1105
1224
  agentTrace,
1106
1225
  }, requestKey(extra))));
1107
1226
  server.registerTool("spot_quote", {
@@ -1176,16 +1295,26 @@ export function registerTools(server, client) {
1176
1295
  }, requestKey(extra))));
1177
1296
  server.registerTool("cancel_spot_order", {
1178
1297
  title: "Cancel spot order",
1179
- description: "Cancel an open spot order by id (releases frozen funds). Requires the " +
1180
- "trade:spot scope. " +
1181
- PAPER_NOTE,
1298
+ description: "Cancel the unfilled remainder of your paper spot order and release " +
1299
+ "its reserved funds. Requires trade:spot scope; get orderId from " +
1300
+ "list_open_orders. Does not reverse filled trades. Safe to repeat with " +
1301
+ "the same orderId: an order not open under your key returns " +
1302
+ "body.alreadyClosed=true, which does not distinguish a fill from an " +
1303
+ "earlier cancellation or an unknown order. Use get_my_trades to check " +
1304
+ "fills. API failures return ok=false and httpStatus; on 429, respect " +
1305
+ "retryAfterSeconds when provided.",
1182
1306
  inputSchema: {
1183
- orderId: z.number().int().positive().describe("Open order id."),
1307
+ orderId: z
1308
+ .number()
1309
+ .int()
1310
+ .positive()
1311
+ .describe("Your paper spot order id from list_open_orders."),
1184
1312
  agentTrace: AGENT_TRACE_SCHEMA,
1185
1313
  },
1186
1314
  outputSchema: API_RESULT_OUTPUT_SCHEMA,
1187
1315
  annotations: mutatingAnnotations("Cancel spot order", {
1188
1316
  destructive: true,
1317
+ idempotent: true,
1189
1318
  }),
1190
1319
  }, async ({ orderId, agentTrace }, extra) => present(await client.cancelSpotOrder(orderId, requestKey(extra), agentTrace)));
1191
1320
  server.registerTool("open_futures_position", {
@@ -1355,6 +1484,11 @@ export function registerTools(server, client) {
1355
1484
  "PUBLIC calibration record (agentBrier), which scores your forecast " +
1356
1485
  "SKILL — not the market's. Omit it if you are not forecasting; never " +
1357
1486
  "echo the market probability back."),
1487
+ thesis: z
1488
+ .string()
1489
+ .max(280)
1490
+ .optional()
1491
+ .describe("Optional one-line thesis for this decision (max 280 characters)."),
1358
1492
  provenance: PROVENANCE_REPORT_SCHEMA,
1359
1493
  agentTrace: AGENT_TRACE_SCHEMA,
1360
1494
  },
@@ -1362,7 +1496,7 @@ export function registerTools(server, client) {
1362
1496
  annotations: mutatingAnnotations("Open prediction-market position", {
1363
1497
  idempotent: true,
1364
1498
  }),
1365
- }, async ({ source, slug, outcomeExternalMarketId, side, stakeMusd, idempotencyKey, forecastProbability, provenance, agentTrace, }, extra) => present(await client.openPmPosition({
1499
+ }, async ({ source, slug, outcomeExternalMarketId, side, stakeMusd, idempotencyKey, forecastProbability, thesis, provenance, agentTrace, }, extra) => present(await client.openPmPosition({
1366
1500
  source,
1367
1501
  slug,
1368
1502
  outcomeExternalMarketId,
@@ -1370,26 +1504,25 @@ export function registerTools(server, client) {
1370
1504
  stakeMusd,
1371
1505
  idempotencyKey,
1372
1506
  forecastProbability,
1507
+ thesis,
1373
1508
  provenance,
1374
1509
  agentTrace,
1375
1510
  }, requestKey(extra))));
1376
1511
  server.registerTool("report_pm_opportunity", {
1377
1512
  title: "Report a non-opened PM opportunity",
1378
- description: "Report a prediction-market opportunity you evaluated but did NOT open, so " +
1379
- "your PUBLIC evaluation reflects the FULL opportunity universe — not only " +
1380
- "the trades you took (otherwise an agent can look skilled by exposure " +
1381
- "choice alone). kind is one of: 'abstained' (you looked at markets and " +
1382
- "chose not to bet), 'forecast_only' (you formed your OWN probability but " +
1383
- "did not trade — forecastProbability is REQUIRED, 1-99), or 'quote_expired' " +
1384
- "(a bet you validated was rejected at open because the market moved). This " +
1385
- "is EVIDENCE, not a trade: it needs only the read scope, never moves funds, " +
1386
- "and is recorded as a durable, hashed decision artifact. It is a " +
1387
- "SELF-REPORT — CoinRithm records what you assert about your own reasoning; " +
1388
- "it does not independently verify that you truly evaluated the market. Put " +
1389
- "the breadth of what you weighed in cohort.universeSize (how many markets) " +
1390
- "and report ONCE per decision cycle, not once per market. Reuse decisionId " +
1391
- "to make a retry idempotent. " +
1392
- PAPER_NOTE,
1513
+ description: "Save a durable SELF-REPORT of a prediction-market evaluation for a " +
1514
+ "decision that did not open a position. This WRITES an evidence record " +
1515
+ "but never moves paper funds; authorization requires the read scope. " +
1516
+ "It does not independently verify your evaluation. Choose abstained, " +
1517
+ "forecast_only (requires your own forecastProbability, 1-99), or " +
1518
+ "quote_expired. Report once per decision cycle; cohort.universeSize " +
1519
+ "records its breadth. Supply a non-empty decisionId and reuse it with " +
1520
+ "the same API key on retries: the first stored record wins. " +
1521
+ "agentTrace.decisionId is a fallback; omitting both creates separate " +
1522
+ "records. Success returns " +
1523
+ "body.decisionUuid and, on replay, body.idempotentReplay=true. Check " +
1524
+ "ok/httpStatus before treating delivery as confirmed; a network error " +
1525
+ "does not prove rejection. Use open_pm_position to place a paper trade.",
1393
1526
  inputSchema: {
1394
1527
  kind: z
1395
1528
  .enum(["abstained", "forecast_only", "quote_expired"])
@@ -1410,8 +1543,8 @@ export function registerTools(server, client) {
1410
1543
  .min(1)
1411
1544
  .max(99)
1412
1545
  .optional()
1413
- .describe("Your OWN probability (1-99) the chosen side wins. REQUIRED for " +
1414
- "forecast_only; omit for the other kinds. Never echo the market price."),
1546
+ .describe("Your OWN forecast probability (1-99). REQUIRED for forecast_only; " +
1547
+ "optional for other kinds. Never echo the market price."),
1415
1548
  marketProbability: z
1416
1549
  .number()
1417
1550
  .min(0)
@@ -1442,15 +1575,17 @@ export function registerTools(server, client) {
1442
1575
  decisionId: z
1443
1576
  .string()
1444
1577
  .optional()
1445
- .describe("Your own id for this decision — idempotency key within your API key."),
1578
+ .describe("Non-empty id for this decision, unique within your API key. " +
1579
+ "Reuse for retries. Falls back to agentTrace.decisionId; " +
1580
+ "omitting both creates a new record on each call."),
1446
1581
  runId: z.string().optional().describe("Your own run id for grouping."),
1447
1582
  provenance: PROVENANCE_REPORT_SCHEMA,
1448
1583
  agentTrace: AGENT_TRACE_SCHEMA,
1449
1584
  },
1450
1585
  outputSchema: API_RESULT_OUTPUT_SCHEMA,
1451
- annotations: mutatingAnnotations("Report a non-opened PM opportunity", {
1452
- idempotent: true,
1453
- }),
1586
+ // Idempotency is conditional on decisionId; it is not a safe default
1587
+ // for the entire tool because the field remains optional.
1588
+ annotations: mutatingAnnotations("Report a non-opened PM opportunity"),
1454
1589
  }, async ({ kind, source, slug, outcomeExternalMarketId, forecastProbability, marketProbability, reasonCode, cohort, decisionId, runId, provenance, agentTrace, }, extra) => present(await client.reportPmOpportunity({
1455
1590
  kind,
1456
1591
  source,
@@ -1527,7 +1662,8 @@ export function registerTools(server, client) {
1527
1662
  "Manifold, Metaculus, PredictIt, Futuur, Myriad, ForecastEx, Gemini) — broader than discover_pm_markets, which is " +
1528
1663
  "scoped to the paper-tradeable venues. Returns titles, probabilities, " +
1529
1664
  "volume/liquidity, status, and source per event, plus " +
1530
- "the five highest-probability outcomes and the full outcome count. " +
1665
+ "up to five outcomes, with current outcomes ahead of terminal result " +
1666
+ "rows when an event still has live quotes, plus the full outcome count. " +
1531
1667
  "Use pm_data_event for all outcomes and full evidence. Also returns " +
1532
1668
  "referenceProbability when present (CoinRithm's canonical cross-venue " +
1533
1669
  "number for open events matched across venues — probability, " +
@@ -1615,6 +1751,20 @@ export function registerTools(server, client) {
1615
1751
  annotations: readOnlyAnnotations("Get prediction-market event detail"),
1616
1752
  }, async ({ source, slug, fiat, detail }) => {
1617
1753
  const result = await client.getPublicPmEvent(source, slug, { fiat });
1754
+ const body = result.data;
1755
+ const event = body && typeof body === "object" && !Array.isArray(body)
1756
+ ? body.event
1757
+ : null;
1758
+ const status = event && typeof event === "object" && !Array.isArray(event)
1759
+ ? event.status
1760
+ : body && typeof body === "object" && !Array.isArray(body)
1761
+ ? body.status
1762
+ : null;
1763
+ if (result.ok && status === "open") {
1764
+ void client
1765
+ .markPublicPmEventViewed(source, slug)
1766
+ .catch(() => undefined);
1767
+ }
1618
1768
  return present(detail === "full"
1619
1769
  ? result
1620
1770
  : mapSuccessfulBody(result, compactPublicPmEvent));
@@ -1639,6 +1789,59 @@ export function registerTools(server, client) {
1639
1789
  outputSchema: API_RESULT_OUTPUT_SCHEMA,
1640
1790
  annotations: readOnlyAnnotations("Get latest prediction-market whale trades"),
1641
1791
  }, async ({ limit }) => present(mapSuccessfulBody(await client.getPublicPmWhales(), (data) => compactPublicPmWhales(data, limit ?? 10))));
1792
+ server.registerTool("pm_data_whale_wallets", {
1793
+ title: "Explore prediction-market whale wallets",
1794
+ description: "Free public 7-day (default) or 30-day aggregation of identifiable " +
1795
+ "large-trader " +
1796
+ "wallet activity for the on-chain venues that expose wallet addresses. " +
1797
+ "Returns trade count, total and " +
1798
+ "maximum notional, venue attribution, and first/last observed times. " +
1799
+ "An absent wallet does not prove absent trading: anonymized venues and " +
1800
+ "unavailable feeds are excluded. This is market context, not a wallet " +
1801
+ "identity guarantee or recommendation. No API key required.",
1802
+ inputSchema: {
1803
+ limit: z
1804
+ .number()
1805
+ .int()
1806
+ .min(1)
1807
+ .max(50)
1808
+ .optional()
1809
+ .describe("Max wallets (1-50, default 10)."),
1810
+ window: z
1811
+ .enum(["7d", "30d"])
1812
+ .optional()
1813
+ .describe("Observed aggregation window (default 7d)."),
1814
+ source: z
1815
+ .enum(["polymarket", "limitless", "myriad"])
1816
+ .optional()
1817
+ .describe("Restrict results to one wallet-address venue."),
1818
+ },
1819
+ outputSchema: API_RESULT_OUTPUT_SCHEMA,
1820
+ annotations: readOnlyAnnotations("Explore prediction-market whale wallets"),
1821
+ }, async ({ limit, window, source }) => present(mapSuccessfulBody(await client.getPublicPmWhaleWallets(window, source), (data) => compactPublicPmWhaleWallets(data, limit ?? 10, source))));
1822
+ server.registerTool("pm_data_whale_wallet", {
1823
+ title: "Inspect one prediction-market whale wallet",
1824
+ description: "Free public wallet movement detail for one supported on-chain " +
1825
+ "prediction-market venue and address. Returns observed trade-notional " +
1826
+ "summaries, daily activity, top events, and recent BUY/SELL fills with " +
1827
+ "event provenance. CoinRithm flow fields are matched-trade observations; " +
1828
+ "optional provider-reported positions/PnL context is separate and may " +
1829
+ "carry its own availability and as-of markers. Absence of a row is not " +
1830
+ "proof of inactivity. No API " +
1831
+ "key required.",
1832
+ inputSchema: {
1833
+ source: z
1834
+ .enum(["polymarket", "limitless", "myriad"])
1835
+ .describe("Supported wallet-address venue."),
1836
+ wallet: z
1837
+ .string()
1838
+ .trim()
1839
+ .regex(/^0x[0-9a-fA-F]{40}$/, "expected a 20-byte EVM wallet address")
1840
+ .describe("Wallet address returned by pm_data_whale_wallets."),
1841
+ },
1842
+ outputSchema: API_RESULT_OUTPUT_SCHEMA,
1843
+ annotations: readOnlyAnnotations("Inspect one prediction-market whale wallet"),
1844
+ }, async ({ source, wallet }) => present(mapSuccessfulBody(await client.getPublicPmWhaleWallet(source, wallet), compactPublicPmWhaleWalletDetail)));
1642
1845
  server.registerTool("pm_data_disagreements", {
1643
1846
  title: "Cross-venue disagreement clusters",
1644
1847
  description: "Free public cross-venue disagreement clusters: prediction-market " +
@@ -1731,22 +1934,22 @@ export function registerTools(server, client) {
1731
1934
  fiat,
1732
1935
  }), compactPublicPmDisagreements)));
1733
1936
  server.registerTool("pm_data_calibration", {
1734
- title: "Per-venue forecast-accuracy calibration",
1735
- description: "Free public per-venue forecast-accuracy scorecard: for each venue, " +
1736
- "calibrationError (Expected Calibration Error, 0-1, lower is better — " +
1737
- "the fair cross-venue headline), sampleSize, meanWinnerConfidence, and " +
1738
- "a 10-bucket reliability curve (predictedMean vs realizedRate per " +
1739
- "probability bucket) computed from that venue's OWN probability ~24h " +
1740
- "before resolution against the outcome that actually happened, over " +
1741
- "resolved markets with >=24h of pre-resolution history. Venues below " +
1742
- "minSample (currently 30 scored events) appear in `pending` instead of " +
1743
- "a curve — too few resolutions to publish a reliable number yet. Use " +
1744
- "this to answer 'which venue forecasts best' with evidence, not vibes; " +
1745
- "cite CoinRithm's methodology field when quoting a number. No API key " +
1746
- "required.",
1937
+ title: "Per-venue market-price calibration",
1938
+ description: "Free public per-venue market-price calibration scorecard. The primary " +
1939
+ "scored lane compares the venue price for each outcome at one complete-book " +
1940
+ "snapshot selected nearest 24h before resolution within the inclusive 20-28h " +
1941
+ "window against the realised result. calibrationError is event-weighted " +
1942
+ "Expected Calibration Error (0-1, lower is better) within comparable samples; " +
1943
+ "sampleSize counts scored events. This measures market-price calibration, " +
1944
+ "not provider or agent forecast skill, profitability, or a continuous 24h " +
1945
+ "history. Venues below minSample (currently 30 scored events) appear in " +
1946
+ "`pending`. The additive `finalPrice` and `ownCapture` lanes use different " +
1947
+ "timing bases and are not interchangeable with the primary scored lane. " +
1948
+ "Cite CoinRithm's methodology and excluded counts when comparing venues. " +
1949
+ "No API key required.",
1747
1950
  inputSchema: {},
1748
1951
  outputSchema: API_RESULT_OUTPUT_SCHEMA,
1749
- annotations: readOnlyAnnotations("Per-venue forecast-accuracy calibration"),
1952
+ annotations: readOnlyAnnotations("Per-venue market-price calibration"),
1750
1953
  }, async () => present(await client.getPublicPmCalibration()));
1751
1954
  server.registerTool("pm_data_canonical", {
1752
1955
  title: "Canonical cross-venue event identity",
package/package.json CHANGED
@@ -1,97 +1,97 @@
1
- {
2
- "name": "@coinrithm/mcp-trading",
3
- "version": "0.7.11",
4
- "mcpName": "io.github.CoinRithm/mcp-trading",
5
- "description": "CoinRithm paper-trading toolkit: an MCP server (coinrithm-mcp) AND a self-host agent runner (coinrithm-agent) for spot, futures, and prediction markets with a user-minted API key.",
6
- "type": "module",
7
- "author": "CoinRithm",
8
- "homepage": "https://coinrithm.com/agentic-trading",
9
- "repository": {
10
- "type": "git",
11
- "url": "git+https://github.com/CoinRithm/coinrithm-agent-trading.git",
12
- "directory": "packages/mcp-trading"
13
- },
14
- "bugs": {
15
- "url": "https://github.com/CoinRithm/coinrithm-agent-trading/issues"
16
- },
17
- "publishConfig": {
18
- "access": "public"
19
- },
20
- "bin": {
21
- "coinrithm-mcp": "dist/index.js",
22
- "coinrithm-agent": "dist/agent/index.js"
23
- },
24
- "main": "dist/index.js",
25
- "files": [
26
- "dist",
27
- "README.md",
28
- "CHANGELOG.md"
29
- ],
30
- "scripts": {
31
- "build": "tsc -p tsconfig.json",
32
- "typecheck": "tsc -p tsconfig.json --noEmit",
33
- "test": "vitest run",
34
- "test:coverage": "vitest run --coverage",
35
- "lint": "eslint src",
36
- "lint:fix": "eslint src --fix",
37
- "format": "prettier --write \"src/**/*.ts\"",
38
- "format:check": "prettier --check \"src/**/*.ts\"",
39
- "start": "node dist/index.js",
40
- "start:http": "node dist/http.js",
41
- "smoke:agent": "npm run build && node scripts/agent-smoke.mjs",
42
- "prepare": "npm run build"
43
- },
44
- "engines": {
45
- "node": ">=18"
46
- },
47
- "keywords": [
48
- "mcp",
49
- "mcp-server",
50
- "model-context-protocol",
51
- "ai-agent",
52
- "agent-trading",
53
- "trading",
54
- "paper-trading",
55
- "crypto",
56
- "futures",
57
- "prediction-markets",
58
- "polymarket",
59
- "kalshi",
60
- "claude",
61
- "chatgpt",
62
- "gemini",
63
- "cursor",
64
- "open-knowledge-format",
65
- "okf",
66
- "model-agnostic",
67
- "leaderboard",
68
- "coinrithm"
69
- ],
70
- "license": "MIT",
71
- "dependencies": {
72
- "@modelcontextprotocol/sdk": "^1.0.0",
73
- "express": "^4.21.0",
74
- "yaml": "^2.5.0",
75
- "zod": "^3.23.8"
76
- },
77
- "devDependencies": {
78
- "@eslint/js": "^9.13.0",
79
- "@types/express": "^4.17.21",
80
- "@types/node": "^20.14.0",
81
- "@vitest/coverage-v8": "4.1.11",
82
- "eslint": "^9.13.0",
83
- "prettier": "^3.3.3",
84
- "typescript": "^5.5.0",
85
- "typescript-eslint": "^8.11.0",
86
- "vitest": "4.1.11"
87
- },
88
- "exports": {
89
- ".": "./dist/index.js",
90
- "./engine": {
91
- "types": "./dist/agent/engine.d.ts",
92
- "import": "./dist/agent/engine.js"
93
- },
94
- "./package.json": "./package.json",
95
- "./dist/*": "./dist/*"
96
- }
97
- }
1
+ {
2
+ "name": "@coinrithm/mcp-trading",
3
+ "version": "0.7.13",
4
+ "mcpName": "io.github.CoinRithm/mcp-trading",
5
+ "description": "CoinRithm paper-trading toolkit: an MCP server (coinrithm-mcp) AND a self-host agent runner (coinrithm-agent) for spot, futures, and prediction markets with a user-minted API key.",
6
+ "type": "module",
7
+ "author": "CoinRithm",
8
+ "homepage": "https://coinrithm.com/agentic-trading",
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://github.com/CoinRithm/coinrithm-agent-trading.git",
12
+ "directory": "packages/mcp-trading"
13
+ },
14
+ "bugs": {
15
+ "url": "https://github.com/CoinRithm/coinrithm-agent-trading/issues"
16
+ },
17
+ "publishConfig": {
18
+ "access": "public"
19
+ },
20
+ "bin": {
21
+ "coinrithm-mcp": "dist/index.js",
22
+ "coinrithm-agent": "dist/agent/index.js"
23
+ },
24
+ "main": "dist/index.js",
25
+ "files": [
26
+ "dist",
27
+ "README.md",
28
+ "CHANGELOG.md"
29
+ ],
30
+ "scripts": {
31
+ "build": "tsc -p tsconfig.json",
32
+ "typecheck": "tsc -p tsconfig.json --noEmit",
33
+ "test": "vitest run",
34
+ "test:coverage": "vitest run --coverage",
35
+ "lint": "eslint src",
36
+ "lint:fix": "eslint src --fix",
37
+ "format": "prettier --write \"src/**/*.ts\"",
38
+ "format:check": "prettier --check \"src/**/*.ts\"",
39
+ "start": "node dist/index.js",
40
+ "start:http": "node dist/http.js",
41
+ "smoke:agent": "npm run build && node scripts/agent-smoke.mjs",
42
+ "prepare": "npm run build"
43
+ },
44
+ "engines": {
45
+ "node": ">=18"
46
+ },
47
+ "keywords": [
48
+ "mcp",
49
+ "mcp-server",
50
+ "model-context-protocol",
51
+ "ai-agent",
52
+ "agent-trading",
53
+ "trading",
54
+ "paper-trading",
55
+ "crypto",
56
+ "futures",
57
+ "prediction-markets",
58
+ "polymarket",
59
+ "kalshi",
60
+ "claude",
61
+ "chatgpt",
62
+ "gemini",
63
+ "cursor",
64
+ "open-knowledge-format",
65
+ "okf",
66
+ "model-agnostic",
67
+ "leaderboard",
68
+ "coinrithm"
69
+ ],
70
+ "license": "MIT",
71
+ "dependencies": {
72
+ "@modelcontextprotocol/sdk": "^1.0.0",
73
+ "express": "^4.21.0",
74
+ "yaml": "^2.5.0",
75
+ "zod": "^3.23.8"
76
+ },
77
+ "devDependencies": {
78
+ "@eslint/js": "^9.13.0",
79
+ "@types/express": "^4.17.21",
80
+ "@types/node": "^20.14.0",
81
+ "@vitest/coverage-v8": "4.1.11",
82
+ "eslint": "^9.13.0",
83
+ "prettier": "^3.3.3",
84
+ "typescript": "^5.5.0",
85
+ "typescript-eslint": "^8.11.0",
86
+ "vitest": "4.1.11"
87
+ },
88
+ "exports": {
89
+ ".": "./dist/index.js",
90
+ "./engine": {
91
+ "types": "./dist/agent/engine.d.ts",
92
+ "import": "./dist/agent/engine.js"
93
+ },
94
+ "./package.json": "./package.json",
95
+ "./dist/*": "./dist/*"
96
+ }
97
+ }