@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/CHANGELOG.md +573 -531
- package/README.md +364 -345
- package/dist/agent/act.js +37 -1
- package/dist/agent/client.d.ts +4 -0
- package/dist/agent/decision.d.ts +12 -12
- package/dist/agent/engine.d.ts +1 -1
- package/dist/agent/engine.js +1 -1
- package/dist/agent/observe.js +34 -4
- package/dist/agent/prompt.js +4 -0
- package/dist/agent/providers.d.ts +4 -0
- package/dist/agent/providers.js +16 -10
- package/dist/agent/runner.js +2 -1
- package/dist/agent/templates.js +30 -30
- package/dist/agent/types.d.ts +14 -0
- package/dist/client.d.ts +7 -0
- package/dist/client.js +43 -0
- package/dist/httpCompletion.d.ts +1 -1
- package/dist/httpCompletion.js +2 -0
- package/dist/tools.d.ts +2 -0
- package/dist/tools.js +251 -48
- package/package.json +97 -97
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: "
|
|
608
|
-
"
|
|
609
|
-
"
|
|
610
|
-
"
|
|
611
|
-
"
|
|
612
|
-
|
|
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
|
|
1180
|
-
"trade:spot scope
|
|
1181
|
-
|
|
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
|
|
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: "
|
|
1379
|
-
"
|
|
1380
|
-
"
|
|
1381
|
-
"
|
|
1382
|
-
"
|
|
1383
|
-
"
|
|
1384
|
-
"
|
|
1385
|
-
"
|
|
1386
|
-
"
|
|
1387
|
-
"
|
|
1388
|
-
"
|
|
1389
|
-
"
|
|
1390
|
-
"
|
|
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)
|
|
1414
|
-
"
|
|
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("
|
|
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
|
-
|
|
1452
|
-
|
|
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
|
-
"
|
|
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
|
|
1735
|
-
description: "Free public per-venue
|
|
1736
|
-
"
|
|
1737
|
-
"
|
|
1738
|
-
"
|
|
1739
|
-
"
|
|
1740
|
-
"
|
|
1741
|
-
"
|
|
1742
|
-
"minSample (currently 30 scored events) appear in
|
|
1743
|
-
"
|
|
1744
|
-
"
|
|
1745
|
-
"
|
|
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
|
|
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.
|
|
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
|
+
}
|