@0xinsider/mcp 3.4.0 → 3.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/README.md +26 -5
  2. package/dist/catalog.generated.d.ts +40 -1
  3. package/dist/catalog.generated.d.ts.map +1 -1
  4. package/dist/catalog.generated.js +50 -1
  5. package/dist/catalog.generated.js.map +1 -1
  6. package/dist/cli-lib.d.ts +0 -1
  7. package/dist/cli-lib.d.ts.map +1 -1
  8. package/dist/cli-lib.js +0 -3
  9. package/dist/cli-lib.js.map +1 -1
  10. package/dist/client.d.ts +35 -12
  11. package/dist/client.d.ts.map +1 -1
  12. package/dist/client.js +37 -133
  13. package/dist/client.js.map +1 -1
  14. package/dist/constants.d.ts +1 -2
  15. package/dist/constants.d.ts.map +1 -1
  16. package/dist/constants.js +1 -2
  17. package/dist/constants.js.map +1 -1
  18. package/dist/resources/index.d.ts.map +1 -1
  19. package/dist/resources/index.js +2 -1
  20. package/dist/resources/index.js.map +1 -1
  21. package/dist/sdk/client.d.ts +7 -0
  22. package/dist/sdk/client.d.ts.map +1 -1
  23. package/dist/sdk/client.js +7 -1
  24. package/dist/sdk/client.js.map +1 -1
  25. package/dist/sdk/index.d.ts +5 -5
  26. package/dist/sdk/index.d.ts.map +1 -1
  27. package/dist/sdk/index.js +4 -3
  28. package/dist/sdk/index.js.map +1 -1
  29. package/dist/sdk/retry.d.ts +19 -0
  30. package/dist/sdk/retry.d.ts.map +1 -1
  31. package/dist/sdk/retry.js +111 -0
  32. package/dist/sdk/retry.js.map +1 -1
  33. package/dist/sdk/schema.d.ts +299 -40
  34. package/dist/sdk/schema.d.ts.map +1 -1
  35. package/dist/sdk/webhooks.d.ts +93 -174
  36. package/dist/sdk/webhooks.d.ts.map +1 -1
  37. package/dist/sdk/webhooks.js +22 -6
  38. package/dist/sdk/webhooks.js.map +1 -1
  39. package/dist/server.d.ts.map +1 -1
  40. package/dist/server.js +14 -0
  41. package/dist/server.js.map +1 -1
  42. package/dist/tools/combos.d.ts +6 -0
  43. package/dist/tools/combos.d.ts.map +1 -0
  44. package/dist/tools/combos.js +133 -0
  45. package/dist/tools/combos.js.map +1 -0
  46. package/dist/tools/get-trader.d.ts.map +1 -1
  47. package/dist/tools/get-trader.js +7 -2
  48. package/dist/tools/get-trader.js.map +1 -1
  49. package/dist/tools/large-trade-counterparties.d.ts +5 -0
  50. package/dist/tools/large-trade-counterparties.d.ts.map +1 -0
  51. package/dist/tools/large-trade-counterparties.js +91 -0
  52. package/dist/tools/large-trade-counterparties.js.map +1 -0
  53. package/dist/tools/market-reads.d.ts +5 -0
  54. package/dist/tools/market-reads.d.ts.map +1 -0
  55. package/dist/tools/market-reads.js +100 -0
  56. package/dist/tools/market-reads.js.map +1 -0
  57. package/dist/tools/pick-of-the-day.js +1 -1
  58. package/dist/tools/read-parity.d.ts.map +1 -1
  59. package/dist/tools/read-parity.js +8 -4
  60. package/dist/tools/read-parity.js.map +1 -1
  61. package/dist/tools/trader-reads.d.ts +6 -0
  62. package/dist/tools/trader-reads.d.ts.map +1 -0
  63. package/dist/tools/trader-reads.js +99 -0
  64. package/dist/tools/trader-reads.js.map +1 -0
  65. package/package.json +1 -1
@@ -0,0 +1,133 @@
1
+ // The combo (multi-leg) reads, REST-only until #24738. Each needs a Pro or
2
+ // Max API key, and the route answers a lower plan with its own error.
3
+ //
4
+ // Descriptions and schemas mirror `backend/src/mcp/tools/contract.rs` and
5
+ // `backend/src/mcp/tools/schema.rs`; `scripts/check-mcp-stdio-contract-parity.mjs`
6
+ // fails a drift between the two transports.
7
+ import { z } from "zod";
8
+ import { fail, ok, withMeta } from "./result.js";
9
+ const readAnnotations = {
10
+ readOnlyHint: true,
11
+ destructiveHint: false,
12
+ idempotentHint: true,
13
+ openWorldHint: false,
14
+ };
15
+ export function registerGetComboFills(server, client) {
16
+ server.registerTool("get_combo_fills", {
17
+ title: "Get combo fills",
18
+ description: `Live Polymarket combo (multi-leg) taker fills with exact decimal-string economics, wallet identity and grade, legs, conjunction result and ingest coverage. Requires a Pro or Max API key. The listing holds executions priced at most 0.95; get_combo has a combo's complete history. sort recent pages with next_cursor; largest and payout page with next_offset. A continuation can end on an empty page.
19
+
20
+ Args:
21
+ - result (string, optional): CSV of pending, won, lost; all clears the filter
22
+ - legs (string, optional): CSV of 2, 3, 4, 5+; all clears the filter
23
+ - min_stake (integer, optional, default 0): Minimum collateral in whole USDC
24
+ - min_multiplier (integer, optional, default 0): 0 disables the filter; otherwise 2 to 1000000 shares per dollar at execution
25
+ - grades (string, optional): CSV of S, A, B, C, D, F; all clears the filter; ungraded wallets never match
26
+ - sports (string, optional): CSV of sport slugs such as nfl, nba, soccer, esports; all clears the filter; a combo matches when any leg is in a selected sport
27
+ - sort (string, optional): recent (default, newest first), largest (collateral), or payout (buy-fill shares, sells excluded)
28
+ - window (string, optional): 24h, 7d or all; defaults to all for recent and 24h for largest and payout
29
+ - limit (number, 1-200, default 50): Fills per page
30
+ - cursor (string, optional): next_cursor from the previous recent page
31
+ - offset (number, 0-5000, optional): next_offset from the previous largest or payout page
32
+
33
+ Returns: data (fills), has_more, next_cursor, next_offset, limit, sort, window, coverage and meta.`,
34
+ inputSchema: {
35
+ // The CSV filters stay strings: the route reads comma-separated lists,
36
+ // with `all` clearing the filter.
37
+ result: z.string().optional()
38
+ .describe("CSV of pending, won, lost; all clears the filter"),
39
+ legs: z.string().optional()
40
+ .describe("CSV of 2, 3, 4, 5+; all clears the filter. A combo matches any named pick count"),
41
+ min_stake: z.number().int().min(0).max(1_000_000_000).optional()
42
+ .describe("Minimum collateral in whole USDC (default 0)"),
43
+ // The route refuses 1 (it would admit every fill). `.meta()` copies
44
+ // `not: {const: 1}` into the advertised JSON Schema, as the remote
45
+ // schema states it (scripts/check-mcp-stdio-contract-parity.mjs
46
+ // compares the two); zod does not enforce metadata, so a 1 still
47
+ // reaches the route, whose bad_request names the parameter.
48
+ min_multiplier: z.number().int().min(0).max(1_000_000).optional()
49
+ .describe("Minimum shares per dollar at execution: 0 (the default) disables the filter, otherwise 2 to 1000000")
50
+ .meta({ not: { const: 1 } }),
51
+ grades: z.string().optional()
52
+ .describe("CSV of S, A, B, C, D, F; all clears the filter. Ungraded wallets never match"),
53
+ sports: z.string().optional()
54
+ .describe("CSV of sport slugs such as nfl, nba, soccer, esports; all clears the filter. A combo matches when any leg is in a selected sport"),
55
+ sort: z.enum(["recent", "largest", "payout"]).optional()
56
+ .describe("recent (the default) is newest first; largest ranks collateral; payout ranks buy-fill shares and excludes sells"),
57
+ window: z.enum(["24h", "7d", "all"]).optional()
58
+ .describe("Defaults to all for recent and 24h for largest and payout"),
59
+ limit: z.number().int().min(1).max(200).default(50)
60
+ .describe("Max fills per page (1-200, default 50)"),
61
+ cursor: z.string().optional()
62
+ .describe("next_cursor from the previous page; recent ordering only"),
63
+ offset: z.number().int().min(0).max(5000).optional()
64
+ .describe("next_offset from the previous page; largest and payout ordering only"),
65
+ },
66
+ annotations: readAnnotations,
67
+ }, async (args, extra) => {
68
+ try {
69
+ const response = await client.request("/api/v1/combos/fills", args, undefined, { signal: extra.signal });
70
+ // `ListMetadata::ComboFills` in `response.rs`: the page and its cursor
71
+ // pair, with the offset continuation and the page's limit, sort,
72
+ // window and coverage beside it. An absent field stays absent.
73
+ return ok({
74
+ data: response.data,
75
+ has_more: response.has_more ?? false,
76
+ next_cursor: response.next_cursor ?? null,
77
+ ...(response.total === undefined ? {} : { total: response.total }),
78
+ ...(response.next_offset === undefined ? {} : { next_offset: response.next_offset }),
79
+ ...(response.limit === undefined ? {} : { limit: response.limit }),
80
+ ...(response.sort === undefined ? {} : { sort: response.sort }),
81
+ ...(response.window === undefined ? {} : { window: response.window }),
82
+ ...(response.coverage === undefined ? {} : { coverage: response.coverage }),
83
+ ...(response.meta === undefined ? {} : { meta: response.meta }),
84
+ });
85
+ }
86
+ catch (error) {
87
+ return fail(error);
88
+ }
89
+ });
90
+ }
91
+ export function registerGetCombosSummary(server, client) {
92
+ server.registerTool("get_combos_summary", {
93
+ title: "Get live combo count",
94
+ description: `The stored count of traded Polymarket combos whose YES conjunction is still pending, and when it was computed. Requires a Pro or Max API key. The count refreshes at most every five minutes and is cached for 60 seconds. A null live value is unknown, never zero.
95
+
96
+ Returns: live (count and computed_at, or null) and meta.`,
97
+ inputSchema: {},
98
+ annotations: readAnnotations,
99
+ }, async (_args, extra) => {
100
+ try {
101
+ const response = await client.request("/api/v1/combos/summary", undefined, undefined, { signal: extra.signal });
102
+ return ok(withMeta(response.data, response.meta));
103
+ }
104
+ catch (error) {
105
+ return fail(error);
106
+ }
107
+ });
108
+ }
109
+ export function registerGetCombo(server, client) {
110
+ server.registerTool("get_combo", {
111
+ title: "Get combo",
112
+ description: `One Polymarket combo: legs, conjunction result, all-time trade totals, the newest 100 taker fills, lifecycle totals and ingest coverage. Requires a Pro or Max API key. Unlike get_combo_fills it keeps executions priced above 0.95. Null lifecycle or missing leg facts are unknown, never zero.
113
+
114
+ Args:
115
+ - condition_id (string, required): Combo ID, 0x and 62 lowercase hex characters; not a binary market's condition_id
116
+
117
+ Returns: combo, fills, lifecycle, coverage, access and meta. A malformed ID is a bad_request error and an unknown one not_found.`,
118
+ inputSchema: {
119
+ condition_id: z.string().regex(/^0x[0-9a-f]{62}$/)
120
+ .describe("Combo ID: 0x and 62 lowercase hex characters, not a binary market's condition_id"),
121
+ },
122
+ annotations: readAnnotations,
123
+ }, async ({ condition_id }, extra) => {
124
+ try {
125
+ const response = await client.request(`/api/v1/combos/${encodeURIComponent(condition_id)}`, undefined, undefined, { signal: extra.signal });
126
+ return ok(withMeta(response.data, response.meta));
127
+ }
128
+ catch (error) {
129
+ return fail(error);
130
+ }
131
+ });
132
+ }
133
+ //# sourceMappingURL=combos.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"combos.js","sourceRoot":"","sources":["../../src/tools/combos.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"get-trader.d.ts","sourceRoot":"","sources":["../../src/tools/get-trader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAGzC,eAAO,MAAM,kBAAkB,aAAoC,CAAC;AAEpE,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CAuD5E"}
1
+ {"version":3,"file":"get-trader.d.ts","sourceRoot":"","sources":["../../src/tools/get-trader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAGzC,eAAO,MAAM,kBAAkB,aAAoC,CAAC;AAEpE,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CA4D5E"}
@@ -17,6 +17,7 @@ A wallet address with no trader yet returns sync_status "unknown" (not an error)
17
17
  Args:
18
18
  - address (string, required): Ethereum wallet address (0x...) or trader username
19
19
  - expand (string[], optional): Heavy fields to include: "strategy", "categories", "quant_metrics", "trust"
20
+ - max_age_s (integer, optional, 0 or more): Freshness ceiling in seconds. The call answers only when data_quality.status is fresh and data_quality.as_of is no older than this; otherwise it fails with reason freshness_ceiling_unsatisfied (HTTP 409). Nothing is refreshed to meet it
20
21
 
21
22
  Returns: Trader profile with grade, P&L, stats, and optional expanded fields. The trader carries data_quality: status, as_of (the oldest clock the body rests on) and field_groups. fresh means tracked and clocked, not current: compare as_of with your own tolerance. unknown means this read cannot date that group, never that it is recent.`,
22
23
  inputSchema: {
@@ -25,6 +26,10 @@ Returns: Trader profile with grade, P&L, stats, and optional expanded fields. Th
25
26
  expand: z.array(z.enum(["strategy", "categories", "quant_metrics", "trust"]))
26
27
  .optional()
27
28
  .describe("Optional heavy fields to include"),
29
+ // The route's whole-response freshness ceiling (#24738): REST took it
30
+ // and neither transport's tool could send it.
31
+ max_age_s: z.number().int().min(0).optional()
32
+ .describe("Freshness ceiling in seconds: answer only when data_quality.status is fresh and data_quality.as_of is no older than this, otherwise fail with freshness_ceiling_unsatisfied"),
28
33
  },
29
34
  annotations: {
30
35
  readOnlyHint: true,
@@ -32,13 +37,13 @@ Returns: Trader profile with grade, P&L, stats, and optional expanded fields. Th
32
37
  idempotentHint: true,
33
38
  openWorldHint: false,
34
39
  },
35
- }, async ({ address, expand }, extra) => {
40
+ }, async ({ address, expand, max_age_s }, extra) => {
36
41
  try {
37
42
  const traderLookup = address.trim();
38
43
  const repeatedParams = expand && expand.length > 0
39
44
  ? { expand }
40
45
  : undefined;
41
- const response = await client.request(`/api/v1/trader/${encodeURIComponent(traderLookup)}`, undefined, repeatedParams, { signal: extra.signal });
46
+ const response = await client.request(`/api/v1/trader/${encodeURIComponent(traderLookup)}`, { max_age_s }, repeatedParams, { signal: extra.signal });
42
47
  return {
43
48
  content: [{ type: "text", text: JSON.stringify(withMeta(response.data, response.meta), null, 2) }],
44
49
  };
@@ -1 +1 @@
1
- {"version":3,"file":"get-trader.js","sourceRoot":"","sources":["../../src/tools/get-trader.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE7C,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAEpE,MAAM,UAAU,iBAAiB,CAAC,MAAiB,EAAE,MAAiB;IACpE,MAAM,CAAC,YAAY,CACjB,YAAY,EACZ;QACE,KAAK,EAAE,YAAY;QACnB,WAAW,EAAE;;;;;;;;;;;;;;kVAc+T;QAC5U,WAAW,EAAE;YACX,OAAO,EAAE,kBAAkB;iBACxB,QAAQ,CAAC,oDAAoD,CAAC;YACjE,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,YAAY,EAAE,eAAe,EAAE,OAAO,CAAC,CAAC,CAAC;iBAC1E,QAAQ,EAAE;iBACV,QAAQ,CAAC,kCAAkC,CAAC;SAChD;QACD,WAAW,EAAE;YACX,YAAY,EAAE,IAAI;YAClB,eAAe,EAAE,KAAK;YACtB,cAAc,EAAE,IAAI;YACpB,aAAa,EAAE,KAAK;SACrB;KACF,EACD,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,EAAE;QACnC,IAAI,CAAC;YACH,MAAM,YAAY,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;YACpC,MAAM,cAAc,GAAG,MAAM,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC;gBAChD,CAAC,CAAC,EAAE,MAAM,EAAE;gBACZ,CAAC,CAAC,SAAS,CAAC;YAEd,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,OAAO,CACnC,kBAAkB,kBAAkB,CAAC,YAAY,CAAC,EAAE,EACpD,SAAS,EACT,cAAc,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CACzC,CAAC;YAEF,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;aAC5G,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC;QACrB,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"get-trader.js","sourceRoot":"","sources":["../../src/tools/get-trader.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE7C,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAEpE,MAAM,UAAU,iBAAiB,CAAC,MAAiB,EAAE,MAAiB;IACpE,MAAM,CAAC,YAAY,CACjB,YAAY,EACZ;QACE,KAAK,EAAE,YAAY;QACnB,WAAW,EAAE;;;;;;;;;;;;;;;kVAe+T;QAC5U,WAAW,EAAE;YACX,OAAO,EAAE,kBAAkB;iBACxB,QAAQ,CAAC,oDAAoD,CAAC;YACjE,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,YAAY,EAAE,eAAe,EAAE,OAAO,CAAC,CAAC,CAAC;iBAC1E,QAAQ,EAAE;iBACV,QAAQ,CAAC,kCAAkC,CAAC;YAC/C,sEAAsE;YACtE,8CAA8C;YAC9C,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;iBAC1C,QAAQ,CAAC,6KAA6K,CAAC;SAC3L;QACD,WAAW,EAAE;YACX,YAAY,EAAE,IAAI;YAClB,eAAe,EAAE,KAAK;YACtB,cAAc,EAAE,IAAI;YACpB,aAAa,EAAE,KAAK;SACrB;KACF,EACD,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE,EAAE;QAC9C,IAAI,CAAC;YACH,MAAM,YAAY,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;YACpC,MAAM,cAAc,GAAG,MAAM,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC;gBAChD,CAAC,CAAC,EAAE,MAAM,EAAE;gBACZ,CAAC,CAAC,SAAS,CAAC;YAEd,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,OAAO,CACnC,kBAAkB,kBAAkB,CAAC,YAAY,CAAC,EAAE,EACpD,EAAE,SAAS,EAAE,EACb,cAAc,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CACzC,CAAC;YAEF,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;aAC5G,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC;QACrB,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,5 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { ApiClient } from "../client.js";
3
+ export declare function registerGetLargeTradeCounterpartyExecutions(server: McpServer, client: ApiClient): void;
4
+ export declare function registerGetLargeTradeCounterpartyMakers(server: McpServer, client: ApiClient): void;
5
+ //# sourceMappingURL=large-trade-counterparties.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"large-trade-counterparties.d.ts","sourceRoot":"","sources":["../../src/tools/large-trade-counterparties.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAyBzC,wBAAgB,2CAA2C,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CAgCtG;AAED,wBAAgB,uCAAuC,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CAwClG"}
@@ -0,0 +1,91 @@
1
+ // The counterparty pages of one large trade (#24738). get_large_trade embeds
2
+ // the first executions page, and each execution its first makers page; these
3
+ // two tools page past them on the same immutable snapshot.
4
+ //
5
+ // Descriptions and schemas mirror `backend/src/mcp/tools/contract.rs` and
6
+ // `backend/src/mcp/tools/schema.rs`; `scripts/check-mcp-stdio-contract-parity.mjs`
7
+ // fails a drift between the two transports.
8
+ import { z } from "zod";
9
+ import { fail, ok, withMeta } from "./result.js";
10
+ const readAnnotations = {
11
+ readOnlyHint: true,
12
+ destructiveHint: false,
13
+ idempotentHint: true,
14
+ openWorldHint: false,
15
+ };
16
+ /** `counterparty_page_properties` in `schema.rs`: the arguments both pages share. */
17
+ const largeTradeId = z.string().trim().min(1)
18
+ .describe("Large trade ID such as wt_123 or 123");
19
+ const snapshotId = z.string().min(1)
20
+ .describe("counterparty_analysis.snapshot_id from get_large_trade");
21
+ function pageLimit(rows) {
22
+ return z.number().int().min(1).max(100).default(100)
23
+ .describe(`Max ${rows} per page (1-100, default 100)`);
24
+ }
25
+ function executionsPath(id) {
26
+ return `/api/v1/large-trades/${encodeURIComponent(id)}/counterparties/executions`;
27
+ }
28
+ export function registerGetLargeTradeCounterpartyExecutions(server, client) {
29
+ server.registerTool("get_large_trade_counterparty_executions", {
30
+ title: "Get large trade counterparty executions",
31
+ description: `Page the counterparty executions of one large trade past the first page get_large_trade embeds in counterparty_analysis. Reads the immutable snapshot that response names; a stale or changed snapshot fails with reason cursor_expired, so read get_large_trade again and restart.
32
+
33
+ Args:
34
+ - id (string, required): Large trade ID such as wt_123 or 123
35
+ - snapshot_id (string, required): counterparty_analysis.snapshot_id from get_large_trade
36
+ - cursor (string, optional): executions_next_cursor from get_large_trade or from the previous page
37
+ - limit (number, 1-100, default 100): Executions per page
38
+
39
+ Returns: executions (each with its first makers page and makers_next_cursor), executions_next_cursor, execution counts, status and meta.`,
40
+ inputSchema: {
41
+ id: largeTradeId,
42
+ snapshot_id: snapshotId,
43
+ cursor: z.string().optional()
44
+ .describe("executions_next_cursor from get_large_trade or from the previous page"),
45
+ limit: pageLimit("executions"),
46
+ },
47
+ annotations: readAnnotations,
48
+ }, async ({ id, ...query }, extra) => {
49
+ try {
50
+ const response = await client.request(executionsPath(id), query, undefined, { signal: extra.signal });
51
+ return ok(withMeta(response.data, response.meta));
52
+ }
53
+ catch (error) {
54
+ return fail(error);
55
+ }
56
+ });
57
+ }
58
+ export function registerGetLargeTradeCounterpartyMakers(server, client) {
59
+ server.registerTool("get_large_trade_counterparty_makers", {
60
+ title: "Get large trade counterparty makers",
61
+ description: `Page the maker wallets of one counterparty execution past the first page its execution embeds. Percentages keep the whole execution as their denominator across pages.
62
+
63
+ Args:
64
+ - id (string, required): Large trade ID such as wt_123 or 123
65
+ - execution_id (string, required): execution_id of the execution
66
+ - snapshot_id (string, required): counterparty_analysis.snapshot_id from get_large_trade
67
+ - cursor (string, optional): makers_next_cursor from the execution or next_cursor from the previous page
68
+ - limit (number, 1-100, default 100): Makers per page
69
+
70
+ Returns: items (makers), next_cursor, execution_id, snapshot_id and meta.`,
71
+ inputSchema: {
72
+ id: largeTradeId,
73
+ execution_id: z.string().trim().min(1)
74
+ .describe("execution_id of one counterparty execution"),
75
+ snapshot_id: snapshotId,
76
+ cursor: z.string().optional()
77
+ .describe("makers_next_cursor from the execution, or next_cursor from the previous page"),
78
+ limit: pageLimit("makers"),
79
+ },
80
+ annotations: readAnnotations,
81
+ }, async ({ id, execution_id, ...query }, extra) => {
82
+ try {
83
+ const response = await client.request(`${executionsPath(id)}/${encodeURIComponent(execution_id)}/makers`, query, undefined, { signal: extra.signal });
84
+ return ok(withMeta(response.data, response.meta));
85
+ }
86
+ catch (error) {
87
+ return fail(error);
88
+ }
89
+ });
90
+ }
91
+ //# sourceMappingURL=large-trade-counterparties.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"large-trade-counterparties.js","sourceRoot":"","sources":["../../src/tools/large-trade-counterparties.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { ApiClient } from "../client.js";
3
+ export declare function registerGetMarketHolders(server: McpServer, client: ApiClient): void;
4
+ export declare function registerGetMarketCandles(server: McpServer, client: ApiClient): void;
5
+ //# sourceMappingURL=market-reads.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"market-reads.d.ts","sourceRoot":"","sources":["../../src/tools/market-reads.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAkBzC,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CAmDnF;AAED,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CAoCnF"}
@@ -0,0 +1,100 @@
1
+ // Market reads that were REST-only until #24738: the graded holder roster and
2
+ // the stored price candles.
3
+ //
4
+ // Descriptions and schemas mirror `backend/src/mcp/tools/contract.rs` and
5
+ // `backend/src/mcp/tools/schema.rs`; `scripts/check-mcp-stdio-contract-parity.mjs`
6
+ // fails a drift between the two transports.
7
+ import { z } from "zod";
8
+ import { fail, ok, withMeta } from "./result.js";
9
+ const readAnnotations = {
10
+ readOnlyHint: true,
11
+ destructiveHint: false,
12
+ idempotentHint: true,
13
+ openWorldHint: false,
14
+ };
15
+ /** `market_condition_id_property` in `schema.rs`. */
16
+ const marketConditionId = z.string().trim().min(1)
17
+ .describe("Raw provider condition_id or the mkt_-prefixed market id");
18
+ function marketPath(conditionId, suffix) {
19
+ return `/api/v1/market/${encodeURIComponent(conditionId)}/${suffix}`;
20
+ }
21
+ export function registerGetMarketHolders(server, client) {
22
+ server.registerTool("get_market_holders", {
23
+ title: "Get market holders",
24
+ description: `The S, A and B graded wallets holding one Polymarket market, from a complete provider holder scan: shares, Polymarket's currentValue for the leg, grade, win record in the market's category, and badges. A wallet holding both outcomes is listed once on its net side. Ordered by current value. The roster is at most 60 seconds old over a provider walk at most 180 seconds old; scan.fetched_at is its only timestamp. An incomplete scan is an error with a retry time, never a shorter list. C, D, F and ungraded wallets are never listed and are counted only in scan.wallet_count. Counts differ from get_positions by design: a live scan, the graded cohort, and no 100 USD size floor.
25
+
26
+ Args:
27
+ - condition_id (string, required): Raw provider condition_id or the mkt_-prefixed market id
28
+ - outcome (string, optional): yes, no, or all (default)
29
+ - min_grade (string, optional): S keeps S, A keeps S and A, B (default) keeps S, A and B
30
+ - limit (number, 1-100, default 20): Holders per page
31
+ - cursor (string, optional): next_cursor from the previous page, bound to the same market and filters
32
+
33
+ Returns: data (holders), has_more, next_cursor, total, market, scan, totals and meta.`,
34
+ inputSchema: {
35
+ condition_id: marketConditionId,
36
+ outcome: z.enum(["yes", "no", "all"]).optional()
37
+ .describe("Keep holders netting one side; all (the default) lists both"),
38
+ min_grade: z.enum(["S", "A", "B"]).optional()
39
+ .describe("Narrow the graded cohort: S keeps S, A keeps S and A, B (the default) keeps S, A and B"),
40
+ limit: z.number().int().min(1).max(100).default(20)
41
+ .describe("Max holders per page (1-100, default 20)"),
42
+ cursor: z.string().optional()
43
+ .describe("next_cursor from the previous page; it is bound to the same market and filters"),
44
+ },
45
+ annotations: readAnnotations,
46
+ }, async ({ condition_id, ...query }, extra) => {
47
+ try {
48
+ const response = await client.request(marketPath(condition_id, "holders"), query, undefined, { signal: extra.signal });
49
+ // `ListMetadata::MarketHolders` in `response.rs`: the page and its
50
+ // cursor pair, with the market, the scan and the roster totals beside
51
+ // it. An absent field stays absent; none is invented.
52
+ return ok({
53
+ data: response.data,
54
+ has_more: response.has_more ?? false,
55
+ next_cursor: response.next_cursor ?? null,
56
+ ...(response.total === undefined ? {} : { total: response.total }),
57
+ ...(response.market === undefined ? {} : { market: response.market }),
58
+ ...(response.scan === undefined ? {} : { scan: response.scan }),
59
+ ...(response.totals === undefined ? {} : { totals: response.totals }),
60
+ ...(response.meta === undefined ? {} : { meta: response.meta }),
61
+ });
62
+ }
63
+ catch (error) {
64
+ return fail(error);
65
+ }
66
+ });
67
+ }
68
+ export function registerGetMarketCandles(server, client) {
69
+ server.registerTool("get_market_candles", {
70
+ title: "Get market price candles",
71
+ description: `OHLC price candles for a market's outcome tokens from the stored Polymarket CLOB price history, the series the market chart draws, for open and resolved markets. The stored series is daily: a 1d candle usually holds one point, so its open, high, low and close are that day's close, and 1w aggregates the daily closes. No intraday detail is invented.
72
+
73
+ Args:
74
+ - condition_id (string, required): Raw provider condition_id or the mkt_-prefixed market id
75
+ - resolution (string, optional): 1d (default, UTC day) or 1w (ISO week from Monday 00:00 UTC)
76
+ - from (integer, optional): Exclusive lower bound, unix seconds
77
+ - to (integer, optional): Inclusive upper bound, unix seconds; from must not be after to
78
+
79
+ Returns: condition_id, resolution, and outcomes, each with its token_id and candles, plus meta.`,
80
+ inputSchema: {
81
+ condition_id: marketConditionId,
82
+ resolution: z.enum(["1d", "1w"]).optional()
83
+ .describe("1d (the default) buckets by UTC day, 1w by ISO week from Monday 00:00 UTC"),
84
+ from: z.number().int().optional()
85
+ .describe("Exclusive lower bound in unix seconds"),
86
+ to: z.number().int().optional()
87
+ .describe("Inclusive upper bound in unix seconds; from must not be after to"),
88
+ },
89
+ annotations: readAnnotations,
90
+ }, async ({ condition_id, ...query }, extra) => {
91
+ try {
92
+ const response = await client.request(marketPath(condition_id, "candles"), query, undefined, { signal: extra.signal });
93
+ return ok(withMeta(response.data, response.meta));
94
+ }
95
+ catch (error) {
96
+ return fail(error);
97
+ }
98
+ });
99
+ }
100
+ //# sourceMappingURL=market-reads.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"market-reads.js","sourceRoot":"","sources":["../../src/tools/market-reads.ts"],"names":[],"mappings":"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"}
@@ -17,7 +17,7 @@ const readAnnotations = {
17
17
  export function registerGetPickOfTheDay(server, client) {
18
18
  server.registerTool("get_pick_of_the_day", {
19
19
  title: "Get Pick of the Day",
20
- description: `Get today's published Pick of the Day: the sports markets where graded (S/A/B) sharp money is positioned, frozen at publish time. Pro opens the explicitly designated free selection plus the first four non-free selections in publication order; Max opens every available daily selection, up to fifteen. Read entitled \`picks\` in \`publication_order\` order; use stable decimal-string \`pick_id\` for identity, not deprecated \`pick_rank\`. \`is_free_selection\` designates account access and \`supersedes_pick_id\` records replacement lineage. \`locked_picks\` lists extra unresolved ranks with only pick_rank and required_tier=max; no game, participants, league, time, links, market identifiers or backed facts are exposed. Each pick carries the matchup, the backed side (pick_outcome_label), the frozen pre-game price and the return on the flat $1,000 stake (\`stake_usd\`, \`return_usd\`; \`return_per_100\` keeps the literal $100 basis), the sharp-money holders on that side, the top grade, CLV capture status, and the thesis. \`scheduled_picks\` contains only entitled selected-but-unreleased slots and preserves required release_at; unauthorized future ranks join the identity-free locked_picks descriptors instead. No market identity is revealed before publication. Withdrawn picks are omitted from current and dated recommendations, the archive, and its statistics, even after market settlement. The public ledger retains every published commitment under its original identity and proof bytes.
20
+ description: `Get today's published Pick of the Day: the sports markets where graded (S/A/B) sharp money is positioned, frozen at publish time. Pro opens the explicitly designated free selection plus the first four non-free selections in publication order; Max opens every available daily selection, up to fifteen. Read entitled \`picks\` in \`publication_order\` order; use stable decimal-string \`pick_id\` for identity, not deprecated \`pick_rank\`. \`is_free_selection\` designates account access; \`supersedes_pick_id\` is deprecated and always null. \`locked_picks\` lists extra unresolved ranks with only pick_rank and required_tier=max; no game, participants, league, time, links, market identifiers or backed facts are exposed. Each pick carries the matchup, the backed side (pick_outcome_label), the frozen pre-game price and the return on the flat $1,000 stake (\`stake_usd\`, \`return_usd\`; \`return_per_100\` keeps the literal $100 basis), the sharp-money holders on that side, the top grade, CLV capture status, and the thesis. \`scheduled_picks\` contains only entitled selected-but-unreleased slots and preserves required release_at; unauthorized future ranks join the identity-free locked_picks descriptors instead. No market identity is revealed before publication. Withdrawn picks are omitted from current and dated recommendations, the archive, and its statistics, even after market settlement. The public ledger retains every published commitment under its original identity and proof bytes.
21
21
 
22
22
  When no active pick is available, including after cancelled pending recommendations are withdrawn, the tool returns an error carrying reason pick_not_released and a retry_at instant: schedule the next read from retry_at (or the earliest scheduled_picks.release_at) instead of polling. A current-day pick whose holder proof is not readable yet is listed in \`proof_pending_picks\` (pick_rank, release_at, kickoff, retry_at) while \`picks\` carries the proof-readable picks; the tool returns read_model_warming only when no entitled published pick has readable proof. If only Max-locked ranks have published, a successful state=none response carries picks=[], pick_count=0, locked_picks, and an upgrade action. This is not a proof-warming state.
23
23
 
@@ -1 +1 @@
1
- {"version":3,"file":"read-parity.d.ts","sourceRoot":"","sources":["../../src/tools/read-parity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAezC,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CA6BlF;AAqDD,wBAAgB,6BAA6B,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CAuBxF;AAED,gEAAgE;AAChE,wBAAgB,6BAA6B,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CAuBxF;AAgCD,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CAYhF;AAED,uDAAuD;AACvD,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CAYhF;AA8BD,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CAarF;AAED,6DAA6D;AAC7D,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CAatF;AAMD,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CA4CrF;AAID,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CA4CrF;AAED,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CA2BpF;AAED,wBAAgB,+BAA+B,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CAoC1F;AAED,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CAsBtF;AAED,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CAoDtF;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CAsB/E;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CAyB7E;AAED,wBAAgB,8BAA8B,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CAyBzF;AAED,wBAAgB,+BAA+B,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CAkC1F;AAED,wBAAgB,gCAAgC,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CAyB3F;AAED,wBAAgB,+BAA+B,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CA2B1F;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CAsB9E;AAGD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CAsB/E;AAMD,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CA4BhF;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CA4B5E;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CAsDhF"}
1
+ {"version":3,"file":"read-parity.d.ts","sourceRoot":"","sources":["../../src/tools/read-parity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAezC,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CA6BlF;AAqDD,wBAAgB,6BAA6B,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CAuBxF;AAED,gEAAgE;AAChE,wBAAgB,6BAA6B,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CAuBxF;AAgCD,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CAYhF;AAED,uDAAuD;AACvD,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CAYhF;AA8BD,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CAarF;AAED,6DAA6D;AAC7D,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CAatF;AAMD,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CA4CrF;AAID,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CA4CrF;AAED,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CAkCpF;AAED,wBAAgB,+BAA+B,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CAoC1F;AAED,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CAsBtF;AAED,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CAoDtF;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CAsB/E;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CAyB7E;AAED,wBAAgB,8BAA8B,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CAyBzF;AAED,wBAAgB,+BAA+B,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CAkC1F;AAED,wBAAgB,gCAAgC,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CAyB3F;AAED,wBAAgB,+BAA+B,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CA2B1F;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CAsB9E;AAGD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CAsB/E;AAMD,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CA4BhF;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CA4B5E;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CAsDhF"}
@@ -320,15 +320,19 @@ export function registerGetMarketSnapshot(server, client) {
320
320
 
321
321
  Args:
322
322
  - condition_id (string, required): Raw provider condition_id returned by search or explore
323
+ - expand (string[], optional): "trust" adds per-field provenance (source, freshness, reconciliation, completeness) for current_price and spread_bps
323
324
 
324
- Returns: Market identity, outcomes, liquidity, sports context, and freshness states.`,
325
+ Returns: Market identity, outcomes, liquidity, sports context, and freshness states, plus trust when expanded.`,
325
326
  inputSchema: {
326
327
  condition_id: z.string().trim().min(1).describe("Raw provider condition_id"),
328
+ // `expand=trust` on the route (#24738); `trust` is the only value it accepts.
329
+ expand: z.array(z.enum(["trust"])).optional()
330
+ .describe("Optional heavy fields to include: trust adds provenance for current_price and spread_bps"),
327
331
  },
328
332
  annotations: readAnnotations,
329
- }, async ({ condition_id }, extra) => {
333
+ }, async ({ condition_id, expand }, extra) => {
330
334
  try {
331
- const response = await client.request(`/api/v1/market/${encodeURIComponent(condition_id)}/snapshot`, undefined, undefined, { signal: extra.signal });
335
+ const response = await client.request(`/api/v1/market/${encodeURIComponent(condition_id)}/snapshot`, undefined, expand && expand.length > 0 ? { expand: [...expand] } : undefined, { signal: extra.signal });
332
336
  return ok(withMeta(response.data, response.meta));
333
337
  }
334
338
  catch (error) {
@@ -679,7 +683,7 @@ Returns: Report snapshot metadata and entries (source_range, snapshot.status, co
679
683
  export function registerGetEdgeHunter(server, client) {
680
684
  server.registerTool("get_edge_hunter", {
681
685
  title: "Get Edge Hunter",
682
- description: "Read the Max-only Edge Hunter API at https://0xinsider.com/sports/edge. Pro receives 403 forbidden with reason max_plan_required. One view selector offers board (default), full signals and cohort observations. All views accept kind sports|esports (omission covers both), sports, leagues, market_types, condition_ids, event_slugs, series_slugs and legacy category. Array selections accept 1..100 supplied values before deduplication, including comma-separated values inside a value; repeat REST query keys or supply MCP arrays. Lists match OR; axes match AND. Canonical sports and machine league identities normalize case-insensitively; market types and event/series slugs are exact case-sensitive provider strings. category=NFL selects the Football bucket; leagues=[nfl] selects NFL. Selection precedes the cap or pagination and appears as normalized selection beside the result fields; changed selections cannot share cursors or ETags. Every row carries nullable market_context with nullable league, series_slug, market_type and metadata_updated_at for authoritative filter discovery; metadata_updated_at is the local canonical writer clock, not provider observation time. Selected reads fail closed with 503 read_model_warming if frozen sidecar readiness is absent. Board defaults stay B grade floor, 30 rows and 48-hour horizon; min_grade S/A/B and limit clamp 1..30 are configurable, total is before the cap, with both current outcome quotes. Signals use min_grade default B, horizon default 12/clamp 1..48, limit default 20/clamp 1..100 and cursor, retaining token_id, all ranked/holder/directional/category-skill fields and clocks. Grade floor requires a holder at that grade or better without removing other holders. Observations require cohort wider_holder|in_play|emerging_pile, accept limit/cursor, and retain full observation rows, snapshot_as_of, degraded, source-generation/category funnel diagnostics and REST meta. Required degradation_reasons names each cause with its canonical sport or null for a generation-wide cause. Degradation and coverage input_markets/capacity_limited_markets/emitted_observations/incomplete_holder_markets describe the whole all-sports generation and remain unchanged by selectors. coverage.selected_observations counts matching selected cohort rows before pagination; returned_observations counts this page. Intentional capacity_limited admission does not itself degrade a snapshot, and pagination cannot recover excluded markets. not_configured upcoming supply is not a provider failure. A selected funnel with no failure terminals does not prove the shared generation healthy. A legacy category value that cannot resolve to a sport retains its zero-work empty result: all six counts are zero and reasons are empty without reading the all-sports snapshot, so those values do not establish its health. Observation horizon stays 48h with 12h in-play kickoff lookback and 30s live snapshot ceiling; funnel accounting is not a league/type/ID selection census. All public views read warmed generations only; missing or stale readiness returns 503 read_model_warming with Retry-After 5. Advanced views use private,no-cache with REST/SDK ETag/304 helpers; board uses private,no-store and has no ETag/pagination. Invalid mode-specific parameters return 400. Price marks are market midpoints, not wallet entry prices; volume is shares. Null/db_only/degraded identify unavailable or weaker evidence. Analytics is not an order instruction.",
686
+ description: "Read the Max-only Edge Hunter API at https://0xinsider.com/sports/edge. Pro receives 403 forbidden with reason max_plan_required. One view selector offers board (default), full signals and cohort observations. All views accept kind sports|esports (omission covers both), sports, leagues, market_types, condition_ids, event_slugs, series_slugs and legacy category. Array selections accept 1..100 supplied values before deduplication, including comma-separated values inside a value; repeat REST query keys or supply MCP arrays. Lists match OR; axes match AND. Canonical sports and machine league identities normalize case-insensitively; market types and event/series slugs are exact case-sensitive provider strings. category=NFL selects the Football bucket; leagues=[nfl] selects NFL. Selection precedes the cap or pagination and appears as normalized selection beside the result fields; changed selections cannot share cursors or ETags. Every row carries nullable market_context with nullable league, series_slug, market_type and metadata_updated_at for authoritative filter discovery; metadata_updated_at is the local canonical writer clock, not provider observation time. Selected reads fail closed with 503 read_model_warming if frozen sidecar readiness is absent. Board defaults stay B grade floor, 30 rows and 48-hour horizon; min_grade S/A/B and limit clamp 1..30 are configurable, total is before the cap, with both current outcome quotes. Signals use min_grade default B, horizon default 12/clamp 1..48, limit default 20/clamp 1..100 and cursor, retaining token_id, all ranked/holder/directional/category-skill fields and clocks. Grade floor requires a holder at that grade or better without removing other holders. Observations require cohort wider_holder|in_play|emerging_pile, accept limit/cursor, and retain full observation rows, snapshot_as_of, degraded, source-generation/category funnel diagnostics and REST meta. Required degradation_reasons names each cause with its canonical sport or null for a generation-wide cause. Degradation and coverage input_markets/capacity_limited_markets/emitted_observations/incomplete_holder_markets describe the whole all-sports generation and remain unchanged by selectors. coverage.selected_observations counts matching selected cohort rows before pagination; returned_observations counts this page. Intentional capacity_limited admission does not itself degrade a snapshot, and pagination cannot recover excluded markets. not_configured upcoming supply is not a provider failure. A selected funnel with no failure terminals does not prove the shared generation healthy. A legacy category value that cannot resolve to a sport retains its zero-work empty result: all six counts are zero and reasons are empty without reading the all-sports snapshot, so those values do not establish its health. Observation horizon stays 48h with 12h in-play kickoff lookback and 30s live snapshot ceiling; after one missed refresh, observations serve the last snapshot up to 45s longer with its age in meta.cache_age_s, and a second miss in a row returns 503; funnel accounting is not a league/type/ID selection census. All public views read warmed generations only; missing or stale readiness returns 503 read_model_warming with Retry-After 5. Advanced views use private,no-cache with REST/SDK ETag/304 helpers; board uses private,no-store and has no ETag/pagination. Invalid mode-specific parameters return 400. Price marks are market midpoints, not wallet entry prices; volume is shares. Null/db_only/degraded identify unavailable or weaker evidence. Analytics is not an order instruction.",
683
687
  inputSchema: {
684
688
  view: z.enum(["board", "signals", "observations"]).default("board").describe("Response mode; defaults to board"),
685
689
  kind: z.enum(["sports", "esports"]).optional().describe("All views: sports excludes the Esports bucket; esports selects only Esports. Omit for both. Combines with other selections using AND. Selected reads echo normalized selection and require frozen metadata readiness."),