@coinrithm/mcp-trading 0.7.14 → 0.7.16
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 +811 -613
- package/README.md +415 -366
- package/dist/agent/bench/bench.d.ts +59 -0
- package/dist/agent/bench/bench.js +319 -0
- package/dist/agent/bench/cassette.d.ts +97 -0
- package/dist/agent/bench/cassette.js +181 -0
- package/dist/agent/bench/costs.d.ts +28 -0
- package/dist/agent/bench/costs.js +60 -0
- package/dist/agent/bench/labelBuilder.d.ts +123 -0
- package/dist/agent/bench/labelBuilder.js +282 -0
- package/dist/agent/bench/labels.d.ts +75 -0
- package/dist/agent/bench/labels.js +259 -0
- package/dist/agent/bench/recordingClient.d.ts +51 -0
- package/dist/agent/bench/recordingClient.js +193 -0
- package/dist/agent/bench/replayClient.d.ts +41 -0
- package/dist/agent/bench/replayClient.js +262 -0
- package/dist/agent/bench/report.d.ts +115 -0
- package/dist/agent/bench/report.js +435 -0
- package/dist/agent/cli.d.ts +25 -0
- package/dist/agent/cli.js +300 -2
- package/dist/agent/client.d.ts +14 -0
- package/dist/agent/client.js +113 -4
- package/dist/agent/configurationWarnings.js +11 -0
- package/dist/agent/decision.d.ts +3 -0
- package/dist/agent/decision.js +85 -3
- package/dist/agent/decisionReceipt.d.ts +5 -1
- package/dist/agent/decisionReceipt.js +52 -3
- package/dist/agent/decisionValidator.d.ts +30 -0
- package/dist/agent/decisionValidator.js +147 -2
- package/dist/agent/engine.d.ts +3 -3
- package/dist/agent/engine.js +3 -3
- package/dist/agent/futuresEligibility.d.ts +36 -0
- package/dist/agent/futuresEligibility.js +90 -0
- package/dist/agent/observe.d.ts +35 -2
- package/dist/agent/observe.js +969 -128
- package/dist/agent/pmContext.d.ts +10 -1
- package/dist/agent/pmContext.js +163 -1
- package/dist/agent/prompt.d.ts +18 -1
- package/dist/agent/prompt.js +229 -33
- package/dist/agent/promptTables.d.ts +1 -0
- package/dist/agent/promptTables.js +33 -0
- package/dist/agent/providerCapabilities.d.ts +9 -0
- package/dist/agent/providerCapabilities.js +57 -4
- package/dist/agent/providers.d.ts +28 -7
- package/dist/agent/providers.js +200 -50
- package/dist/agent/resolve.js +3 -0
- package/dist/agent/runner.d.ts +8 -0
- package/dist/agent/runner.js +159 -26
- package/dist/agent/setups.d.ts +2 -1
- package/dist/agent/setups.js +17 -16
- package/dist/agent/signals.d.ts +33 -0
- package/dist/agent/signals.js +89 -0
- package/dist/agent/skill.js +37 -0
- package/dist/agent/skillValidator.js +33 -0
- package/dist/agent/strictLint.js +29 -0
- package/dist/agent/templates.js +30 -30
- package/dist/agent/types.d.ts +266 -13
- package/dist/agent/types.js +4 -0
- package/dist/agent/universe.d.ts +78 -0
- package/dist/agent/universe.js +215 -0
- package/dist/client.d.ts +9 -2
- package/dist/client.js +22 -10
- package/dist/http.d.ts +1 -0
- package/dist/http.js +17 -2
- package/dist/httpCompletion.d.ts +1 -1
- package/dist/httpCompletion.js +1 -0
- package/dist/index.js +2 -1
- package/dist/instructions.d.ts +1 -0
- package/dist/instructions.js +16 -0
- package/dist/tools.d.ts +1 -0
- package/dist/tools.js +150 -66
- package/package.json +98 -97
package/dist/tools.js
CHANGED
|
@@ -7,8 +7,9 @@
|
|
|
7
7
|
import { z } from "zod";
|
|
8
8
|
import { bearerFromHeader } from "./client.js";
|
|
9
9
|
import { PAPER_EXECUTION_VERSION } from "./executionPolicy.js";
|
|
10
|
-
// Served
|
|
11
|
-
// claims costless execution
|
|
10
|
+
// Served once in the MCP server instructions (instructions.ts). Names the
|
|
11
|
+
// versioned execution policy and never claims costless execution
|
|
12
|
+
// (drift-tested in executionPolicy.test.ts).
|
|
12
13
|
export const PAPER_NOTE = "Paper trading only — virtual funds (50,000 mUSD). Not financial advice. " +
|
|
13
14
|
`Paper fills run under the versioned ${PAPER_EXECUTION_VERSION} policy and ` +
|
|
14
15
|
"apply a disclosed execution cost folded into realized PnL: " +
|
|
@@ -17,27 +18,22 @@ export const PAPER_NOTE = "Paper trading only — virtual funds (50,000 mUSD). N
|
|
|
17
18
|
"shaped taker fee, with entryProbability kept at the mid for calibration. " +
|
|
18
19
|
"See the executionModel in quote/trade results — a rehearsal cost, not an " +
|
|
19
20
|
"exchange fill guarantee.";
|
|
21
|
+
// Per-tool form of PAPER_NOTE. The full note is sent once in the server
|
|
22
|
+
// instructions (instructions.ts); every tool still names the versioned
|
|
23
|
+
// execution policy and its disclosed cost (drift-tested with PAPER_NOTE).
|
|
24
|
+
export const PAPER_NOTE_SHORT = `Paper trading only (virtual mUSD). Fills follow ${PAPER_EXECUTION_VERSION} ` +
|
|
25
|
+
"with a disclosed execution cost; see executionModel in quote/trade results.";
|
|
26
|
+
// The same result envelope on every tool: { httpStatus, ok, ledgerEventId,
|
|
27
|
+
// ledgerStatus, body }. It is sent 40 times in tools/list, so its field
|
|
28
|
+
// descriptions live in the server instructions' wording, not here: httpStatus
|
|
29
|
+
// is CoinRithm's HTTP status (0 = network error), ok is a 2xx, the ledger
|
|
30
|
+
// fields come from /api/agent/* writes, and body is the parsed response.
|
|
20
31
|
const API_RESULT_OUTPUT_SCHEMA = {
|
|
21
|
-
httpStatus: z
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
.boolean()
|
|
27
|
-
.describe("True when CoinRithm returned a successful 2xx response."),
|
|
28
|
-
ledgerEventId: z
|
|
29
|
-
.string()
|
|
30
|
-
.nullable()
|
|
31
|
-
.optional()
|
|
32
|
-
.describe("Private AgentActionEvent id returned by /api/agent/*, when present."),
|
|
33
|
-
ledgerStatus: z
|
|
34
|
-
.string()
|
|
35
|
-
.nullable()
|
|
36
|
-
.optional()
|
|
37
|
-
.describe("Ledger write status header returned by CoinRithm, when present."),
|
|
38
|
-
body: z
|
|
39
|
-
.unknown()
|
|
40
|
-
.describe("Parsed CoinRithm response body, or raw text when the response is not JSON."),
|
|
32
|
+
httpStatus: z.number().int(),
|
|
33
|
+
ok: z.boolean(),
|
|
34
|
+
ledgerEventId: z.string().nullable().optional(),
|
|
35
|
+
ledgerStatus: z.string().nullable().optional(),
|
|
36
|
+
body: z.unknown(),
|
|
41
37
|
};
|
|
42
38
|
const AGENT_TRACE_SCHEMA = z
|
|
43
39
|
.object({
|
|
@@ -165,9 +161,7 @@ function present(result) {
|
|
|
165
161
|
body: result.data,
|
|
166
162
|
};
|
|
167
163
|
return {
|
|
168
|
-
content: [
|
|
169
|
-
{ type: "text", text: JSON.stringify(payload, null, 2) },
|
|
170
|
-
],
|
|
164
|
+
content: [{ type: "text", text: JSON.stringify(payload) }],
|
|
171
165
|
structuredContent: payload,
|
|
172
166
|
isError: !result.ok,
|
|
173
167
|
};
|
|
@@ -226,6 +220,9 @@ const OUTCOME_SUMMARY_FIELDS = [
|
|
|
226
220
|
"lifecycle",
|
|
227
221
|
"priorProbability",
|
|
228
222
|
"venueTerms",
|
|
223
|
+
"hasObservedPrice",
|
|
224
|
+
"priceBasis",
|
|
225
|
+
"sourceObservation",
|
|
229
226
|
];
|
|
230
227
|
const WHALE_TRADE_FIELDS = [
|
|
231
228
|
"source",
|
|
@@ -233,6 +230,7 @@ const WHALE_TRADE_FIELDS = [
|
|
|
233
230
|
"eventSlug",
|
|
234
231
|
"eventTitle",
|
|
235
232
|
"wallet",
|
|
233
|
+
"walletAddress",
|
|
236
234
|
"traderName",
|
|
237
235
|
"side",
|
|
238
236
|
"outcome",
|
|
@@ -256,6 +254,32 @@ function boundedText(value, maxLength) {
|
|
|
256
254
|
return value;
|
|
257
255
|
return `${value.slice(0, maxLength - 1)}…`;
|
|
258
256
|
}
|
|
257
|
+
function compactSourceObservation(value) {
|
|
258
|
+
if (value === null)
|
|
259
|
+
return null;
|
|
260
|
+
if (!isJsonRecord(value))
|
|
261
|
+
return undefined;
|
|
262
|
+
return pick(value, [
|
|
263
|
+
"version",
|
|
264
|
+
"basis",
|
|
265
|
+
"provider",
|
|
266
|
+
"observedAt",
|
|
267
|
+
"tradeDate",
|
|
268
|
+
]);
|
|
269
|
+
}
|
|
270
|
+
function compactOutcomeSummary(value) {
|
|
271
|
+
if (!isJsonRecord(value))
|
|
272
|
+
return value;
|
|
273
|
+
const outcome = pick(value, OUTCOME_SUMMARY_FIELDS);
|
|
274
|
+
if ("sourceObservation" in outcome) {
|
|
275
|
+
const sourceObservation = compactSourceObservation(value.sourceObservation);
|
|
276
|
+
if (sourceObservation === undefined)
|
|
277
|
+
delete outcome.sourceObservation;
|
|
278
|
+
else
|
|
279
|
+
outcome.sourceObservation = sourceObservation;
|
|
280
|
+
}
|
|
281
|
+
return outcome;
|
|
282
|
+
}
|
|
259
283
|
function compactWhaleTrade(value) {
|
|
260
284
|
return isJsonRecord(value) ? pick(value, WHALE_TRADE_FIELDS) : value;
|
|
261
285
|
}
|
|
@@ -308,9 +332,7 @@ function eventSummary(value) {
|
|
|
308
332
|
: left.index - right.index;
|
|
309
333
|
})
|
|
310
334
|
.slice(0, 5)
|
|
311
|
-
.map(({ outcome }) => isJsonRecord(outcome)
|
|
312
|
-
? pick(outcome, OUTCOME_SUMMARY_FIELDS)
|
|
313
|
-
: outcome)
|
|
335
|
+
.map(({ outcome }) => isJsonRecord(outcome) ? compactOutcomeSummary(outcome) : outcome)
|
|
314
336
|
: [];
|
|
315
337
|
return {
|
|
316
338
|
...pick(value, EVENT_SUMMARY_FIELDS),
|
|
@@ -392,9 +414,7 @@ function compactSnapshot(value) {
|
|
|
392
414
|
outcomeCount: value.outcomes.length,
|
|
393
415
|
outcomes: value.outcomes
|
|
394
416
|
.slice(0, 10)
|
|
395
|
-
.map((outcome) => isJsonRecord(outcome)
|
|
396
|
-
? pick(outcome, OUTCOME_SUMMARY_FIELDS)
|
|
397
|
-
: outcome),
|
|
417
|
+
.map((outcome) => isJsonRecord(outcome) ? compactOutcomeSummary(outcome) : outcome),
|
|
398
418
|
}
|
|
399
419
|
: {}),
|
|
400
420
|
};
|
|
@@ -425,6 +445,8 @@ function compactComparison(value) {
|
|
|
425
445
|
"label",
|
|
426
446
|
"eventAProbability",
|
|
427
447
|
"eventBProbability",
|
|
448
|
+
"eventAHasObservedPrice",
|
|
449
|
+
"eventBHasObservedPrice",
|
|
428
450
|
"deltaPoints",
|
|
429
451
|
"presentInA",
|
|
430
452
|
"presentInB",
|
|
@@ -727,7 +749,7 @@ export function registerTools(server, client) {
|
|
|
727
749
|
"(equity.totalUsd plus available/frozen/frozenPm/frozenFutures/" +
|
|
728
750
|
"cashTotal cash partitions), period PnL (pnl.24hUsd … allTimePct), " +
|
|
729
751
|
"open spot orders, and a progression block (league/XP). " +
|
|
730
|
-
|
|
752
|
+
PAPER_NOTE_SHORT,
|
|
731
753
|
inputSchema: {
|
|
732
754
|
fiat: z
|
|
733
755
|
.string()
|
|
@@ -744,7 +766,7 @@ export function registerTools(server, client) {
|
|
|
744
766
|
description: "Get raw cash balances: USDT available plus the three frozen partitions " +
|
|
745
767
|
"(frozen = spot orders, frozenPm = PM, frozenFutures = futures margin). " +
|
|
746
768
|
"Optionally include one coin asset. " +
|
|
747
|
-
|
|
769
|
+
PAPER_NOTE_SHORT,
|
|
748
770
|
inputSchema: {
|
|
749
771
|
coinId: z
|
|
750
772
|
.string()
|
|
@@ -761,7 +783,7 @@ export function registerTools(server, client) {
|
|
|
761
783
|
"across coins, or pass one to filter. Response includes asOf — pass it " +
|
|
762
784
|
"back as updatedSince on the next call to poll only rows that changed " +
|
|
763
785
|
"(delta polling). " +
|
|
764
|
-
|
|
786
|
+
PAPER_NOTE_SHORT,
|
|
765
787
|
inputSchema: {
|
|
766
788
|
coinId: z
|
|
767
789
|
.string()
|
|
@@ -793,7 +815,7 @@ export function registerTools(server, client) {
|
|
|
793
815
|
"unrealized mark on open ones). Response includes asOf — pass it back " +
|
|
794
816
|
"as updatedSince on the next call to poll only positions that changed " +
|
|
795
817
|
"(catches worker-fired SL/TP, liquidations, and settlements). " +
|
|
796
|
-
|
|
818
|
+
PAPER_NOTE_SHORT,
|
|
797
819
|
inputSchema: {
|
|
798
820
|
venue: z
|
|
799
821
|
.enum(["futures", "pm"])
|
|
@@ -817,7 +839,7 @@ export function registerTools(server, client) {
|
|
|
817
839
|
"CoinGecko category tags. Use this FIRST to get the coinId that the " +
|
|
818
840
|
"wallet / quote / order tools need — don't guess UCIDs (symbols are not " +
|
|
819
841
|
"unique). " +
|
|
820
|
-
|
|
842
|
+
PAPER_NOTE_SHORT,
|
|
821
843
|
inputSchema: {
|
|
822
844
|
q: z
|
|
823
845
|
.string()
|
|
@@ -837,7 +859,7 @@ export function registerTools(server, client) {
|
|
|
837
859
|
"PnL event (spot sells, futures closes/liquidations, PM settlements) " +
|
|
838
860
|
"with a cumulative running total — use it for active intraday agents. " +
|
|
839
861
|
"days = look-back window (1-365, default 30). " +
|
|
840
|
-
|
|
862
|
+
PAPER_NOTE_SHORT,
|
|
841
863
|
inputSchema: {
|
|
842
864
|
days: z
|
|
843
865
|
.number()
|
|
@@ -865,7 +887,7 @@ export function registerTools(server, client) {
|
|
|
865
887
|
"asOf — pass it back as updatedSince on the next call to fetch only " +
|
|
866
888
|
"NEW closes since your last poll (how you discover worker-fired " +
|
|
867
889
|
"stop-loss/take-profit, liquidations, and PM settlements). " +
|
|
868
|
-
|
|
890
|
+
PAPER_NOTE_SHORT,
|
|
869
891
|
inputSchema: {
|
|
870
892
|
venue: z
|
|
871
893
|
.enum(["all", "spot", "futures", "pm"])
|
|
@@ -899,7 +921,7 @@ export function registerTools(server, client) {
|
|
|
899
921
|
"market's depth/tradability — and up to 6 similar coins (shared category " +
|
|
900
922
|
"/ market-cap peers). Facts only — no generated thesis. Call " +
|
|
901
923
|
"resolve_symbol first to get the coinId. " +
|
|
902
|
-
|
|
924
|
+
PAPER_NOTE_SHORT,
|
|
903
925
|
inputSchema: {
|
|
904
926
|
coinId: z
|
|
905
927
|
.string()
|
|
@@ -921,7 +943,7 @@ export function registerTools(server, client) {
|
|
|
921
943
|
"These are sampled composite-price bars, not venue trade candles. " +
|
|
922
944
|
"v is the mean rolling 24-hour quote-volume observation in the bar, " +
|
|
923
945
|
"NOT volume traded during that candle; do not sum v across bars. " +
|
|
924
|
-
|
|
946
|
+
PAPER_NOTE_SHORT,
|
|
925
947
|
inputSchema: {
|
|
926
948
|
coinId: z
|
|
927
949
|
.string()
|
|
@@ -940,6 +962,47 @@ export function registerTools(server, client) {
|
|
|
940
962
|
outputSchema: API_RESULT_OUTPUT_SCHEMA,
|
|
941
963
|
annotations: readOnlyAnnotations("Get OHLCV candles"),
|
|
942
964
|
}, async ({ coinId, range, fiat, agentTrace }, extra) => present(await client.getCandles(coinId, { range, fiat }, requestKey(extra), agentTrace)));
|
|
965
|
+
server.registerTool("get_news", {
|
|
966
|
+
title: "Get scored crypto news",
|
|
967
|
+
description: "Recent crypto news for up to 25 coins, linked to each coin by " +
|
|
968
|
+
"CoinRithm's curated coin-news graph. Only AI-scored stories are " +
|
|
969
|
+
"returned: sentiment (bullish, bearish or neutral) with its " +
|
|
970
|
+
"confidence and importance 0-10 (8+ = market-moving), ranked by " +
|
|
971
|
+
"importance then recency. ageMinutes is each story's age. Scoring can " +
|
|
972
|
+
"lag publication by hours, so an empty or older list does not prove " +
|
|
973
|
+
"there is no news. Needs an API key with read scope.",
|
|
974
|
+
inputSchema: {
|
|
975
|
+
coins: z
|
|
976
|
+
.string()
|
|
977
|
+
.min(1)
|
|
978
|
+
.max(400)
|
|
979
|
+
.describe('Comma-separated symbols or slugs, e.g. "BTC,ETH" (max 25).'),
|
|
980
|
+
limit: z
|
|
981
|
+
.number()
|
|
982
|
+
.int()
|
|
983
|
+
.min(1)
|
|
984
|
+
.max(25)
|
|
985
|
+
.optional()
|
|
986
|
+
.describe("Stories to return, 1-25 (default 8)."),
|
|
987
|
+
hours: z
|
|
988
|
+
.number()
|
|
989
|
+
.int()
|
|
990
|
+
.min(1)
|
|
991
|
+
.max(168)
|
|
992
|
+
.optional()
|
|
993
|
+
.describe("Look-back window in hours, 1-168 (default 48)."),
|
|
994
|
+
minImportance: z
|
|
995
|
+
.number()
|
|
996
|
+
.int()
|
|
997
|
+
.min(0)
|
|
998
|
+
.max(10)
|
|
999
|
+
.optional()
|
|
1000
|
+
.describe("Only stories at or above this importance (default 0)."),
|
|
1001
|
+
agentTrace: AGENT_TRACE_SCHEMA,
|
|
1002
|
+
},
|
|
1003
|
+
outputSchema: API_RESULT_OUTPUT_SCHEMA,
|
|
1004
|
+
annotations: readOnlyAnnotations("Get scored crypto news"),
|
|
1005
|
+
}, async ({ coins, limit, hours, minImportance, agentTrace }, extra) => present(await client.getNews({ coins, limit, hours, minImportance }, requestKey(extra), agentTrace)));
|
|
943
1006
|
server.registerTool("discover_pm_markets", {
|
|
944
1007
|
title: "Discover prediction markets",
|
|
945
1008
|
description: "Find active-open, quote-ready-first prediction markets on the mock-PM " +
|
|
@@ -951,7 +1014,7 @@ export function registerTools(server, client) {
|
|
|
951
1014
|
"while the market stays visible). This is discovery only — call pm_quote " +
|
|
952
1015
|
"with one returned outcomeExternalMarketId before open_pm_position " +
|
|
953
1016
|
"because pm_quote is the final eligibility source. " +
|
|
954
|
-
|
|
1017
|
+
PAPER_NOTE_SHORT,
|
|
955
1018
|
inputSchema: {
|
|
956
1019
|
q: z
|
|
957
1020
|
.string()
|
|
@@ -996,7 +1059,7 @@ export function registerTools(server, client) {
|
|
|
996
1059
|
"PnL (mUSD), trade count, win/loss/neutral counts, and win rate (null " +
|
|
997
1060
|
"until there are decided trades). Closed trades only — the scorecard for " +
|
|
998
1061
|
"this agent. " +
|
|
999
|
-
|
|
1062
|
+
PAPER_NOTE_SHORT,
|
|
1000
1063
|
inputSchema: {
|
|
1001
1064
|
agentTrace: AGENT_TRACE_SCHEMA,
|
|
1002
1065
|
},
|
|
@@ -1009,7 +1072,7 @@ export function registerTools(server, client) {
|
|
|
1009
1072
|
"rejects, idempotent replays, latency, sanitized summaries, and optional " +
|
|
1010
1073
|
"run/decision trace metadata. Only rows for the calling key are returned. " +
|
|
1011
1074
|
"Use this to audit a reproducible paper-trading run. " +
|
|
1012
|
-
|
|
1075
|
+
PAPER_NOTE_SHORT,
|
|
1013
1076
|
inputSchema: {
|
|
1014
1077
|
venue: z.string().optional().describe("Optional venue filter."),
|
|
1015
1078
|
eventType: z
|
|
@@ -1057,7 +1120,7 @@ export function registerTools(server, client) {
|
|
|
1057
1120
|
description: "Export up to 1,000 private ledger rows for the calling API key as JSON. " +
|
|
1058
1121
|
"Use filters to export a specific runId or decisionId for reproducible " +
|
|
1059
1122
|
"evaluation. No public Arena user can see this data. " +
|
|
1060
|
-
|
|
1123
|
+
PAPER_NOTE_SHORT,
|
|
1061
1124
|
inputSchema: {
|
|
1062
1125
|
venue: z.string().optional().describe("Optional venue filter."),
|
|
1063
1126
|
eventType: z
|
|
@@ -1083,7 +1146,7 @@ export function registerTools(server, client) {
|
|
|
1083
1146
|
"The bundle includes sanitized ledger rows, execution assumptions, " +
|
|
1084
1147
|
"retention policy, outcome attribution, and the evidence checklist. " +
|
|
1085
1148
|
"No public Arena user can see this data. " +
|
|
1086
|
-
|
|
1149
|
+
PAPER_NOTE_SHORT,
|
|
1087
1150
|
inputSchema: {
|
|
1088
1151
|
runId: z.string().min(1).describe("Required run id to export."),
|
|
1089
1152
|
agentTrace: AGENT_TRACE_SCHEMA,
|
|
@@ -1105,7 +1168,7 @@ export function registerTools(server, client) {
|
|
|
1105
1168
|
"and where you stand — pair " +
|
|
1106
1169
|
"with get_performance (your own scorecard) and get_arena_agent (drill " +
|
|
1107
1170
|
"into one handle). Public data: agent names + performance only. " +
|
|
1108
|
-
|
|
1171
|
+
PAPER_NOTE_SHORT,
|
|
1109
1172
|
inputSchema: {
|
|
1110
1173
|
page: z
|
|
1111
1174
|
.number()
|
|
@@ -1130,14 +1193,14 @@ export function registerTools(server, client) {
|
|
|
1130
1193
|
},
|
|
1131
1194
|
outputSchema: API_RESULT_OUTPUT_SCHEMA,
|
|
1132
1195
|
annotations: readOnlyAnnotations("Get Agent Arena leaderboard"),
|
|
1133
|
-
}, async ({ page, pageSize, window }
|
|
1196
|
+
}, async ({ page, pageSize, window }) => present(await client.getArenaLeaderboard({ page, pageSize, window })));
|
|
1134
1197
|
server.registerTool("get_arena_agent", {
|
|
1135
1198
|
title: "Get Agent Arena profile",
|
|
1136
1199
|
description: "One agent's public Arena profile by handle (the `handle` field from " +
|
|
1137
1200
|
"get_arena_leaderboard, e.g. 'a42-momentum-scout'): rank, total + " +
|
|
1138
1201
|
"per-venue realized PnL, decided/total trade counts, and win rate. " +
|
|
1139
1202
|
"Public data only — no account or key identity. " +
|
|
1140
|
-
|
|
1203
|
+
PAPER_NOTE_SHORT,
|
|
1141
1204
|
inputSchema: {
|
|
1142
1205
|
handle: z
|
|
1143
1206
|
.string()
|
|
@@ -1146,14 +1209,14 @@ export function registerTools(server, client) {
|
|
|
1146
1209
|
},
|
|
1147
1210
|
outputSchema: API_RESULT_OUTPUT_SCHEMA,
|
|
1148
1211
|
annotations: readOnlyAnnotations("Get Agent Arena profile"),
|
|
1149
|
-
}, async ({ handle }
|
|
1212
|
+
}, async ({ handle }) => present(await client.getArenaAgent(handle)));
|
|
1150
1213
|
// ---------------- quotes (read scope, read-only) ----------------
|
|
1151
1214
|
server.registerTool("futures_quote", {
|
|
1152
1215
|
title: "Futures quote",
|
|
1153
1216
|
description: "Read-only futures quote: entry price, notional, size, liquidation price, " +
|
|
1154
1217
|
"and eligibility. Never mutates state — always quote before opening. " +
|
|
1155
1218
|
"leverage 1-20, marginMusd >= 10. " +
|
|
1156
|
-
|
|
1219
|
+
PAPER_NOTE_SHORT,
|
|
1157
1220
|
inputSchema: {
|
|
1158
1221
|
coinId: z.string().describe("Coin UCID."),
|
|
1159
1222
|
side: z
|
|
@@ -1182,7 +1245,7 @@ export function registerTools(server, client) {
|
|
|
1182
1245
|
"stakeMusd must be > 0 (min to open is 10). Pass side: 'no' to quote " +
|
|
1183
1246
|
"backing the NO side (omitted = yes); a NO entry fills at 100 minus the " +
|
|
1184
1247
|
"outcome probability and pays out if the outcome resolves false. " +
|
|
1185
|
-
|
|
1248
|
+
PAPER_NOTE_SHORT,
|
|
1186
1249
|
inputSchema: {
|
|
1187
1250
|
source: z.string().describe("Source slug (e.g. kalshi, polymarket)."),
|
|
1188
1251
|
slug: z.string().describe("Event slug."),
|
|
@@ -1231,7 +1294,7 @@ export function registerTools(server, client) {
|
|
|
1231
1294
|
"before place_spot_order instead of buying/selling blind. Price age is " +
|
|
1232
1295
|
"informational only (a market order fills regardless). coinId is a UCID, " +
|
|
1233
1296
|
"NOT a ticker — use resolve_symbol first. " +
|
|
1234
|
-
|
|
1297
|
+
PAPER_NOTE_SHORT,
|
|
1235
1298
|
inputSchema: {
|
|
1236
1299
|
coinId: z.string().describe("Coin UCID (e.g. '1' = BTC)."),
|
|
1237
1300
|
side: z
|
|
@@ -1255,7 +1318,7 @@ export function registerTools(server, client) {
|
|
|
1255
1318
|
"per intent (reuse replays the original result — retry a timed-out " +
|
|
1256
1319
|
"call with the SAME key; it will never double-execute). Requires the " +
|
|
1257
1320
|
"trade:spot scope. CONFIRM with the user before calling. " +
|
|
1258
|
-
|
|
1321
|
+
PAPER_NOTE_SHORT,
|
|
1259
1322
|
inputSchema: {
|
|
1260
1323
|
coinId: z.string().describe('Coin UCID (e.g. "1" = BTC).'),
|
|
1261
1324
|
side: z
|
|
@@ -1326,7 +1389,7 @@ export function registerTools(server, client) {
|
|
|
1326
1389
|
"stopLossPrice/takeProfitPrice atomically at open (side-aware corridor: " +
|
|
1327
1390
|
"long needs liq < SL < mark < TP; short inverted) — protecting every " +
|
|
1328
1391
|
"position is good practice. Quote first and CONFIRM with the user. " +
|
|
1329
|
-
|
|
1392
|
+
PAPER_NOTE_SHORT,
|
|
1330
1393
|
inputSchema: {
|
|
1331
1394
|
coinId: z
|
|
1332
1395
|
.string()
|
|
@@ -1384,7 +1447,7 @@ export function registerTools(server, client) {
|
|
|
1384
1447
|
"live mark (liquidation always takes precedence); a fire closes the " +
|
|
1385
1448
|
"FULL position at mark with realized PnL. Discover fills between polls " +
|
|
1386
1449
|
"via my_trades with updatedSince. Requires the trade:futures scope. " +
|
|
1387
|
-
|
|
1450
|
+
PAPER_NOTE_SHORT,
|
|
1388
1451
|
inputSchema: {
|
|
1389
1452
|
positionId: z
|
|
1390
1453
|
.number()
|
|
@@ -1420,7 +1483,7 @@ export function registerTools(server, client) {
|
|
|
1420
1483
|
description: "Close or partially reduce a mock futures position. fraction in (0,1] " +
|
|
1421
1484
|
"reduces partially; omit (or 1) for a full close. idempotencyKey is " +
|
|
1422
1485
|
"REQUIRED. Requires the trade:futures scope. " +
|
|
1423
|
-
|
|
1486
|
+
PAPER_NOTE_SHORT,
|
|
1424
1487
|
inputSchema: {
|
|
1425
1488
|
positionId: z
|
|
1426
1489
|
.number()
|
|
@@ -1453,7 +1516,7 @@ export function registerTools(server, client) {
|
|
|
1453
1516
|
"REQUIRED. stakeMusd >= 10. Pass side: 'no' to back the NO side (omitted " +
|
|
1454
1517
|
"= yes); a NO entry fills at 100 minus the outcome probability and pays " +
|
|
1455
1518
|
"out if the outcome resolves false. Quote first and CONFIRM with the user. " +
|
|
1456
|
-
|
|
1519
|
+
PAPER_NOTE_SHORT,
|
|
1457
1520
|
inputSchema: {
|
|
1458
1521
|
source: z
|
|
1459
1522
|
.string()
|
|
@@ -1683,7 +1746,8 @@ export function registerTools(server, client) {
|
|
|
1683
1746
|
status: z
|
|
1684
1747
|
.string()
|
|
1685
1748
|
.optional()
|
|
1686
|
-
.describe("
|
|
1749
|
+
.describe("Status filter: open (default), closed, or all. Without it " +
|
|
1750
|
+
"the API's newest-first list starts with long-closed markets."),
|
|
1687
1751
|
sort: z.string().optional().describe("Optional sort key."),
|
|
1688
1752
|
limit: z
|
|
1689
1753
|
.number()
|
|
@@ -1708,7 +1772,9 @@ export function registerTools(server, client) {
|
|
|
1708
1772
|
}, async ({ q, source, status, sort, limit, offset, fiat }) => present(mapSuccessfulBody(await client.listPublicPmEvents({
|
|
1709
1773
|
q,
|
|
1710
1774
|
source,
|
|
1711
|
-
status
|
|
1775
|
+
// Open by default: with no status the API's first page was 20
|
|
1776
|
+
// closed markets, 70+ days stale (audit 2026-09-29).
|
|
1777
|
+
status: status ?? "open",
|
|
1712
1778
|
sort,
|
|
1713
1779
|
limit,
|
|
1714
1780
|
offset,
|
|
@@ -1729,6 +1795,14 @@ export function registerTools(server, client) {
|
|
|
1729
1795
|
"2026-07-02 — read the event's volume trend directly from it). " +
|
|
1730
1796
|
"The default summary bounds outcomes, related events, matches and tape " +
|
|
1731
1797
|
"for agent context windows while preserving counts and core evidence. " +
|
|
1798
|
+
"Outcome summaries may include hasObservedPrice and bounded " +
|
|
1799
|
+
"sourceObservation: hasObservedPrice:false means the provider supplied " +
|
|
1800
|
+
"no usable observed price input, while an omitted hasObservedPrice field " +
|
|
1801
|
+
"is unknown; sourceObservation:null means unavailable provenance, not " +
|
|
1802
|
+
"proof that the outcome has no price. Neither field is a live, " +
|
|
1803
|
+
"liquidity, or trading guarantee. " +
|
|
1804
|
+
"priceBasis:'unquoted' (Polymarket/Kalshi) means never traded with no " +
|
|
1805
|
+
"usable book: that probability is not a price. " +
|
|
1732
1806
|
"Set detail=full only when the untouched provider-rich record is needed. " +
|
|
1733
1807
|
"This is the cross-venue research view; for tradability use pm_quote. " +
|
|
1734
1808
|
"No API key required.",
|
|
@@ -1837,7 +1911,7 @@ export function registerTools(server, client) {
|
|
|
1837
1911
|
.string()
|
|
1838
1912
|
.trim()
|
|
1839
1913
|
.regex(/^0x[0-9a-fA-F]{40}$/, "expected a 20-byte EVM wallet address")
|
|
1840
|
-
.describe("
|
|
1914
|
+
.describe("Full walletAddress from pm_data_whales or pm_data_event, or address from pm_data_whale_wallets. The shortened wallet display is not an address."),
|
|
1841
1915
|
},
|
|
1842
1916
|
outputSchema: API_RESULT_OUTPUT_SCHEMA,
|
|
1843
1917
|
annotations: readOnlyAnnotations("Inspect one prediction-market whale wallet"),
|
|
@@ -1870,7 +1944,7 @@ export function registerTools(server, client) {
|
|
|
1870
1944
|
.min(1)
|
|
1871
1945
|
.max(25)
|
|
1872
1946
|
.optional()
|
|
1873
|
-
.describe("Max clusters (1-25, default
|
|
1947
|
+
.describe("Max clusters (1-25, default 3)."),
|
|
1874
1948
|
offset: z
|
|
1875
1949
|
.number()
|
|
1876
1950
|
.int()
|
|
@@ -1923,7 +1997,9 @@ export function registerTools(server, client) {
|
|
|
1923
1997
|
outputSchema: API_RESULT_OUTPUT_SCHEMA,
|
|
1924
1998
|
annotations: readOnlyAnnotations("Cross-venue disagreement clusters"),
|
|
1925
1999
|
}, async ({ limit, offset, sort, minDivergence, sourceKind, status, maxSnapshotAgeMinutes, requirePriced, fiat, }) => present(mapSuccessfulBody(await client.getPublicPmMatches({
|
|
1926
|
-
|
|
2000
|
+
// 3 by default: the API's default of 10 returned about 239k
|
|
2001
|
+
// characters, more than an assistant's context should take at once.
|
|
2002
|
+
limit: limit ?? 3,
|
|
1927
2003
|
offset,
|
|
1928
2004
|
sort,
|
|
1929
2005
|
minDivergence,
|
|
@@ -1958,9 +2034,16 @@ export function registerTools(server, client) {
|
|
|
1958
2034
|
"venue's slug. Omit `key` to page the directory of active canonicals " +
|
|
1959
2035
|
"(uuid, slug, title, memberCount). Pass `key` (a canonical's uuid OR " +
|
|
1960
2036
|
"slug) for one canonical's full record: its venue members (each with " +
|
|
1961
|
-
"orientation — same/
|
|
2037
|
+
"orientation — same/flipped/unknown, NEVER price-inferred — plus " +
|
|
1962
2038
|
"confidence and provenance basis) and an append-only judgment lineage " +
|
|
1963
|
-
"(created/member_added/member_removed/merged, newest first).
|
|
2039
|
+
"(created/member_added/member_removed/merged, newest first). It also " +
|
|
2040
|
+
"carries `consensus`: the current cross-venue reference probability " +
|
|
2041
|
+
"(kind, outcomeName, probability, venueCount, spreadPoints, " +
|
|
2042
|
+
"computedAt, methodologyVersion, listings), or null when the open " +
|
|
2043
|
+
"members do not agree on one current reference; and " +
|
|
2044
|
+
"`consensusHistory`, a daily tape whose points each carry their own " +
|
|
2045
|
+
"outcome label. `listings` may be a subset of the contributing venues. " +
|
|
2046
|
+
"A MERGED " +
|
|
1964
2047
|
"canonical still resolves (status='merged' + a mergedInto pointer) so " +
|
|
1965
2048
|
"a stable key never 404s. Use this to track one question across " +
|
|
1966
2049
|
"venues by a durable identity instead of re-matching venue slugs " +
|
|
@@ -2012,8 +2095,9 @@ export function registerTools(server, client) {
|
|
|
2012
2095
|
"biggest 24h price moves — top gainers or top losers, ordered by " +
|
|
2013
2096
|
"24h change percent. Use this to DISCOVER candidates beyond your " +
|
|
2014
2097
|
"watchlist (abnormal rapid moves), then deep-analyze each candidate " +
|
|
2015
|
-
"with get_candles (OHLC + indicators)
|
|
2016
|
-
"(sentiment,
|
|
2098
|
+
"with get_candles (OHLC + indicators), get_market_context " +
|
|
2099
|
+
"(sentiment, related markets) and get_news before any trade " +
|
|
2100
|
+
"decision. Rows carry coinId, " +
|
|
2017
2101
|
"symbol, name, slug, change24hPct and priceUsd; data refreshes on the " +
|
|
2018
2102
|
"~60s core price tick. Pass the row's coinId straight to get_candles " +
|
|
2019
2103
|
"/ get_market_context — do NOT re-resolve it from the symbol, since " +
|