@shroud-fi/mcp-server 0.1.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 (183) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +130 -0
  3. package/dist/cjs/auth.d.ts +41 -0
  4. package/dist/cjs/auth.d.ts.map +1 -0
  5. package/dist/cjs/auth.js +103 -0
  6. package/dist/cjs/auth.js.map +1 -0
  7. package/dist/cjs/bin/http.d.ts +7 -0
  8. package/dist/cjs/bin/http.d.ts.map +1 -0
  9. package/dist/cjs/bin/http.js +24 -0
  10. package/dist/cjs/bin/http.js.map +1 -0
  11. package/dist/cjs/bin/stdio.d.ts +9 -0
  12. package/dist/cjs/bin/stdio.d.ts.map +1 -0
  13. package/dist/cjs/bin/stdio.js +15 -0
  14. package/dist/cjs/bin/stdio.js.map +1 -0
  15. package/dist/cjs/config.d.ts +22 -0
  16. package/dist/cjs/config.d.ts.map +1 -0
  17. package/dist/cjs/config.js +180 -0
  18. package/dist/cjs/config.js.map +1 -0
  19. package/dist/cjs/constants.d.ts +29 -0
  20. package/dist/cjs/constants.d.ts.map +1 -0
  21. package/dist/cjs/constants.js +35 -0
  22. package/dist/cjs/constants.js.map +1 -0
  23. package/dist/cjs/errors.d.ts +43 -0
  24. package/dist/cjs/errors.d.ts.map +1 -0
  25. package/dist/cjs/errors.js +72 -0
  26. package/dist/cjs/errors.js.map +1 -0
  27. package/dist/cjs/http.d.ts +32 -0
  28. package/dist/cjs/http.d.ts.map +1 -0
  29. package/dist/cjs/http.js +180 -0
  30. package/dist/cjs/http.js.map +1 -0
  31. package/dist/cjs/index.d.ts +19 -0
  32. package/dist/cjs/index.d.ts.map +1 -0
  33. package/dist/cjs/index.js +40 -0
  34. package/dist/cjs/index.js.map +1 -0
  35. package/dist/cjs/package.json +1 -0
  36. package/dist/cjs/server.d.ts +14 -0
  37. package/dist/cjs/server.d.ts.map +1 -0
  38. package/dist/cjs/server.js +92 -0
  39. package/dist/cjs/server.js.map +1 -0
  40. package/dist/cjs/stdio.d.ts +9 -0
  41. package/dist/cjs/stdio.d.ts.map +1 -0
  42. package/dist/cjs/stdio.js +21 -0
  43. package/dist/cjs/stdio.js.map +1 -0
  44. package/dist/cjs/tools/balance.d.ts +9 -0
  45. package/dist/cjs/tools/balance.d.ts.map +1 -0
  46. package/dist/cjs/tools/balance.js +61 -0
  47. package/dist/cjs/tools/balance.js.map +1 -0
  48. package/dist/cjs/tools/index.d.ts +17 -0
  49. package/dist/cjs/tools/index.d.ts.map +1 -0
  50. package/dist/cjs/tools/index.js +40 -0
  51. package/dist/cjs/tools/index.js.map +1 -0
  52. package/dist/cjs/tools/receive.d.ts +13 -0
  53. package/dist/cjs/tools/receive.d.ts.map +1 -0
  54. package/dist/cjs/tools/receive.js +100 -0
  55. package/dist/cjs/tools/receive.js.map +1 -0
  56. package/dist/cjs/tools/register.d.ts +9 -0
  57. package/dist/cjs/tools/register.d.ts.map +1 -0
  58. package/dist/cjs/tools/register.js +36 -0
  59. package/dist/cjs/tools/register.js.map +1 -0
  60. package/dist/cjs/tools/schema.d.ts +18 -0
  61. package/dist/cjs/tools/schema.d.ts.map +1 -0
  62. package/dist/cjs/tools/schema.js +25 -0
  63. package/dist/cjs/tools/schema.js.map +1 -0
  64. package/dist/cjs/tools/send-to-wallet.d.ts +9 -0
  65. package/dist/cjs/tools/send-to-wallet.d.ts.map +1 -0
  66. package/dist/cjs/tools/send-to-wallet.js +60 -0
  67. package/dist/cjs/tools/send-to-wallet.js.map +1 -0
  68. package/dist/cjs/tools/send.d.ts +9 -0
  69. package/dist/cjs/tools/send.d.ts.map +1 -0
  70. package/dist/cjs/tools/send.js +68 -0
  71. package/dist/cjs/tools/send.js.map +1 -0
  72. package/dist/cjs/tools/status.d.ts +6 -0
  73. package/dist/cjs/tools/status.d.ts.map +1 -0
  74. package/dist/cjs/tools/status.js +39 -0
  75. package/dist/cjs/tools/status.js.map +1 -0
  76. package/dist/cjs/tools/sweep.d.ts +14 -0
  77. package/dist/cjs/tools/sweep.d.ts.map +1 -0
  78. package/dist/cjs/tools/sweep.js +119 -0
  79. package/dist/cjs/tools/sweep.js.map +1 -0
  80. package/dist/cjs/tools/x402-pay.d.ts +14 -0
  81. package/dist/cjs/tools/x402-pay.d.ts.map +1 -0
  82. package/dist/cjs/tools/x402-pay.js +78 -0
  83. package/dist/cjs/tools/x402-pay.js.map +1 -0
  84. package/dist/cjs/tools/x402-serve.d.ts +17 -0
  85. package/dist/cjs/tools/x402-serve.d.ts.map +1 -0
  86. package/dist/cjs/tools/x402-serve.js +133 -0
  87. package/dist/cjs/tools/x402-serve.js.map +1 -0
  88. package/dist/cjs/types.d.ts +66 -0
  89. package/dist/cjs/types.d.ts.map +1 -0
  90. package/dist/cjs/types.js +6 -0
  91. package/dist/cjs/types.js.map +1 -0
  92. package/dist/esm/auth.d.ts +41 -0
  93. package/dist/esm/auth.d.ts.map +1 -0
  94. package/dist/esm/auth.js +99 -0
  95. package/dist/esm/auth.js.map +1 -0
  96. package/dist/esm/bin/http.d.ts +7 -0
  97. package/dist/esm/bin/http.d.ts.map +1 -0
  98. package/dist/esm/bin/http.js +22 -0
  99. package/dist/esm/bin/http.js.map +1 -0
  100. package/dist/esm/bin/stdio.d.ts +9 -0
  101. package/dist/esm/bin/stdio.d.ts.map +1 -0
  102. package/dist/esm/bin/stdio.js +13 -0
  103. package/dist/esm/bin/stdio.js.map +1 -0
  104. package/dist/esm/config.d.ts +22 -0
  105. package/dist/esm/config.d.ts.map +1 -0
  106. package/dist/esm/config.js +175 -0
  107. package/dist/esm/config.js.map +1 -0
  108. package/dist/esm/constants.d.ts +29 -0
  109. package/dist/esm/constants.d.ts.map +1 -0
  110. package/dist/esm/constants.js +32 -0
  111. package/dist/esm/constants.js.map +1 -0
  112. package/dist/esm/errors.d.ts +43 -0
  113. package/dist/esm/errors.d.ts.map +1 -0
  114. package/dist/esm/errors.js +61 -0
  115. package/dist/esm/errors.js.map +1 -0
  116. package/dist/esm/http.d.ts +32 -0
  117. package/dist/esm/http.d.ts.map +1 -0
  118. package/dist/esm/http.js +177 -0
  119. package/dist/esm/http.js.map +1 -0
  120. package/dist/esm/index.d.ts +19 -0
  121. package/dist/esm/index.d.ts.map +1 -0
  122. package/dist/esm/index.js +18 -0
  123. package/dist/esm/index.js.map +1 -0
  124. package/dist/esm/server.d.ts +14 -0
  125. package/dist/esm/server.d.ts.map +1 -0
  126. package/dist/esm/server.js +89 -0
  127. package/dist/esm/server.js.map +1 -0
  128. package/dist/esm/stdio.d.ts +9 -0
  129. package/dist/esm/stdio.d.ts.map +1 -0
  130. package/dist/esm/stdio.js +18 -0
  131. package/dist/esm/stdio.js.map +1 -0
  132. package/dist/esm/tools/balance.d.ts +9 -0
  133. package/dist/esm/tools/balance.d.ts.map +1 -0
  134. package/dist/esm/tools/balance.js +58 -0
  135. package/dist/esm/tools/balance.js.map +1 -0
  136. package/dist/esm/tools/index.d.ts +17 -0
  137. package/dist/esm/tools/index.d.ts.map +1 -0
  138. package/dist/esm/tools/index.js +28 -0
  139. package/dist/esm/tools/index.js.map +1 -0
  140. package/dist/esm/tools/receive.d.ts +13 -0
  141. package/dist/esm/tools/receive.d.ts.map +1 -0
  142. package/dist/esm/tools/receive.js +97 -0
  143. package/dist/esm/tools/receive.js.map +1 -0
  144. package/dist/esm/tools/register.d.ts +9 -0
  145. package/dist/esm/tools/register.d.ts.map +1 -0
  146. package/dist/esm/tools/register.js +33 -0
  147. package/dist/esm/tools/register.js.map +1 -0
  148. package/dist/esm/tools/schema.d.ts +18 -0
  149. package/dist/esm/tools/schema.d.ts.map +1 -0
  150. package/dist/esm/tools/schema.js +21 -0
  151. package/dist/esm/tools/schema.js.map +1 -0
  152. package/dist/esm/tools/send-to-wallet.d.ts +9 -0
  153. package/dist/esm/tools/send-to-wallet.d.ts.map +1 -0
  154. package/dist/esm/tools/send-to-wallet.js +57 -0
  155. package/dist/esm/tools/send-to-wallet.js.map +1 -0
  156. package/dist/esm/tools/send.d.ts +9 -0
  157. package/dist/esm/tools/send.d.ts.map +1 -0
  158. package/dist/esm/tools/send.js +65 -0
  159. package/dist/esm/tools/send.js.map +1 -0
  160. package/dist/esm/tools/status.d.ts +6 -0
  161. package/dist/esm/tools/status.d.ts.map +1 -0
  162. package/dist/esm/tools/status.js +36 -0
  163. package/dist/esm/tools/status.js.map +1 -0
  164. package/dist/esm/tools/sweep.d.ts +14 -0
  165. package/dist/esm/tools/sweep.d.ts.map +1 -0
  166. package/dist/esm/tools/sweep.js +116 -0
  167. package/dist/esm/tools/sweep.js.map +1 -0
  168. package/dist/esm/tools/x402-pay.d.ts +14 -0
  169. package/dist/esm/tools/x402-pay.d.ts.map +1 -0
  170. package/dist/esm/tools/x402-pay.js +75 -0
  171. package/dist/esm/tools/x402-pay.js.map +1 -0
  172. package/dist/esm/tools/x402-serve.d.ts +17 -0
  173. package/dist/esm/tools/x402-serve.d.ts.map +1 -0
  174. package/dist/esm/tools/x402-serve.js +130 -0
  175. package/dist/esm/tools/x402-serve.js.map +1 -0
  176. package/dist/esm/types.d.ts +66 -0
  177. package/dist/esm/types.d.ts.map +1 -0
  178. package/dist/esm/types.js +5 -0
  179. package/dist/esm/types.js.map +1 -0
  180. package/dist/tsconfig.cjs.tsbuildinfo +1 -0
  181. package/dist/tsconfig.esm.tsbuildinfo +1 -0
  182. package/dist/tsconfig.tsbuildinfo +1 -0
  183. package/package.json +81 -0
@@ -0,0 +1,177 @@
1
+ /**
2
+ * HTTP transport for the MCP server.
3
+ *
4
+ * Uses node:http to stay zero-dep. Exposes three endpoints:
5
+ * POST /auth/challenge → mint EIP-191 challenge
6
+ * POST /mcp → JSON-RPC framed MCP body (auth-gated)
7
+ * GET /healthz → public liveness ping
8
+ *
9
+ * Auth rules:
10
+ * - /auth/challenge public (clients need a way to get a challenge)
11
+ * - /mcp requires X-Shroudfi-Wallet + X-Shroudfi-Nonce +
12
+ * X-Shroudfi-Signature headers. Signature is verified,
13
+ * consumed (single-use), allow-list checked.
14
+ * - /healthz public
15
+ *
16
+ * Privacy invariants:
17
+ * - Signatures never logged or echoed.
18
+ * - Errors are short tag strings; no body bytes, no key bytes.
19
+ * - Allow-list is enforced when SHROUDFI_MCP_HTTP_ALLOWED_WALLETS is set;
20
+ * when empty, ANY EIP-191 wallet may authenticate. Operators MUST set
21
+ * the allow-list in production.
22
+ */
23
+ import { createServer } from 'node:http';
24
+ import { isHex } from 'viem';
25
+ import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
26
+ import { ALL_TOOLS, findTool } from './tools/index.js';
27
+ import { createAuthCache } from './auth.js';
28
+ import { buildContextFromConfig, loadBootstrapConfigFromEnv } from './config.js';
29
+ import { McpInvalidArgsError, McpServerError, McpUnauthorizedError } from './errors.js';
30
+ const HEADER_WALLET = 'x-shroudfi-wallet';
31
+ const HEADER_NONCE = 'x-shroudfi-nonce';
32
+ const HEADER_SIGNATURE = 'x-shroudfi-signature';
33
+ const JSON_HEADERS = { 'content-type': 'application/json' };
34
+ async function readJsonBody(req) {
35
+ const chunks = [];
36
+ for await (const chunk of req) {
37
+ chunks.push(chunk);
38
+ if (Buffer.concat(chunks).length > 1_048_576) {
39
+ throw new McpInvalidArgsError();
40
+ }
41
+ }
42
+ const raw = Buffer.concat(chunks).toString('utf-8');
43
+ if (raw.length === 0)
44
+ return {};
45
+ try {
46
+ return JSON.parse(raw);
47
+ }
48
+ catch {
49
+ throw new McpInvalidArgsError();
50
+ }
51
+ }
52
+ function send(res, status, body) {
53
+ res.writeHead(status, JSON_HEADERS);
54
+ res.end(JSON.stringify(body));
55
+ }
56
+ async function authenticate(req, authCache, allowList) {
57
+ const wallet = req.headers[HEADER_WALLET];
58
+ const nonce = req.headers[HEADER_NONCE];
59
+ const sig = req.headers[HEADER_SIGNATURE];
60
+ if (typeof wallet !== 'string' ||
61
+ typeof nonce !== 'string' ||
62
+ typeof sig !== 'string') {
63
+ throw new McpUnauthorizedError();
64
+ }
65
+ if (!isHex(wallet) || wallet.length !== 42)
66
+ throw new McpUnauthorizedError();
67
+ if (!isHex(nonce))
68
+ throw new McpUnauthorizedError();
69
+ if (!isHex(sig))
70
+ throw new McpUnauthorizedError();
71
+ const walletLc = wallet.toLowerCase();
72
+ if (allowList.size > 0 && !allowList.has(walletLc)) {
73
+ throw new McpUnauthorizedError();
74
+ }
75
+ await authCache.verifyAndConsume({
76
+ wallet: walletLc,
77
+ nonce: nonce,
78
+ signature: sig,
79
+ });
80
+ return walletLc;
81
+ }
82
+ /**
83
+ * Direct JSON-RPC-ish dispatch — we expose the same RPC envelope MCP uses but
84
+ * over a synchronous request/response cycle (no SSE in v1). Clients send:
85
+ * { method: 'tools/list', params: {} }
86
+ * { method: 'tools/call', params: { name, arguments } }
87
+ */
88
+ async function dispatch(ctx, body) {
89
+ if (typeof body !== 'object' ||
90
+ body === null ||
91
+ !('method' in body) ||
92
+ typeof body.method !== 'string') {
93
+ throw new McpInvalidArgsError();
94
+ }
95
+ const method = body.method;
96
+ const params = (body.params ?? {});
97
+ if (method === 'tools/list') {
98
+ ListToolsRequestSchema.parse({ method, params });
99
+ return {
100
+ tools: ALL_TOOLS.map((t) => ({
101
+ name: t.name,
102
+ description: t.description,
103
+ inputSchema: t.inputSchema,
104
+ })),
105
+ };
106
+ }
107
+ if (method === 'tools/call') {
108
+ const parsed = CallToolRequestSchema.parse({ method, params });
109
+ const tool = findTool(parsed.params.name);
110
+ if (tool === undefined) {
111
+ throw new McpInvalidArgsError();
112
+ }
113
+ const args = parsed.params.arguments ?? {};
114
+ const result = await tool.handler(ctx, args);
115
+ return {
116
+ content: [{ type: 'text', text: JSON.stringify(result) }],
117
+ };
118
+ }
119
+ throw new McpInvalidArgsError();
120
+ }
121
+ export async function runHttpServer(opts) {
122
+ const bootstrap = opts.bootstrap ?? loadBootstrapConfigFromEnv();
123
+ const ctx = buildContextFromConfig(bootstrap);
124
+ const authCache = createAuthCache();
125
+ const allowList = bootstrap.httpAllowedWallets;
126
+ const server = createServer((req, res) => {
127
+ void handleRequest(req, res, ctx, authCache, allowList).catch((err) => {
128
+ if (err instanceof McpServerError) {
129
+ send(res, 400, { ok: false, code: err.code });
130
+ return;
131
+ }
132
+ send(res, 500, { ok: false, code: 'internal_error' });
133
+ });
134
+ });
135
+ await new Promise((resolve) => {
136
+ server.listen(opts.port, () => resolve());
137
+ });
138
+ return {
139
+ close: () => new Promise((resolve, reject) => {
140
+ server.close((err) => (err ? reject(err) : resolve()));
141
+ }),
142
+ };
143
+ }
144
+ async function handleRequest(req, res, ctx, authCache, allowList) {
145
+ const url = req.url ?? '/';
146
+ const method = req.method ?? 'GET';
147
+ if (url === '/healthz' && method === 'GET') {
148
+ send(res, 200, { ok: true });
149
+ return;
150
+ }
151
+ if (url === '/auth/challenge' && method === 'POST') {
152
+ const body = (await readJsonBody(req));
153
+ if (typeof body.wallet !== 'string' ||
154
+ !isHex(body.wallet) ||
155
+ body.wallet.length !== 42) {
156
+ throw new McpInvalidArgsError();
157
+ }
158
+ const challenge = authCache.issue(body.wallet.toLowerCase());
159
+ send(res, 200, {
160
+ ok: true,
161
+ wallet: challenge.wallet,
162
+ nonce: challenge.nonce,
163
+ message: challenge.message,
164
+ expiresAtMs: challenge.expiresAtMs,
165
+ });
166
+ return;
167
+ }
168
+ if (url === '/mcp' && method === 'POST') {
169
+ await authenticate(req, authCache, allowList);
170
+ const body = await readJsonBody(req);
171
+ const result = await dispatch(ctx, body);
172
+ send(res, 200, { ok: true, result });
173
+ return;
174
+ }
175
+ send(res, 404, { ok: false, code: 'not_found' });
176
+ }
177
+ //# sourceMappingURL=http.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.js","sourceRoot":"","sources":["../../src/http.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Public barrel — @shroud-fi/mcp-server.
3
+ *
4
+ * Two consumption paths:
5
+ * - `import { runStdioServer } from '@shroud-fi/mcp-server'` for stdio bin.
6
+ * - `import { runHttpServer } from '@shroud-fi/mcp-server/http'` for HTTP.
7
+ * - `import { ALL_TOOLS } from '@shroud-fi/mcp-server/tools'` to embed the
8
+ * tool registry into a host MCP server you already own.
9
+ */
10
+ export { runStdioServer } from './stdio.js';
11
+ export { runHttpServer } from './http.js';
12
+ export { buildMcpServer } from './server.js';
13
+ export { buildContextFromConfig, loadBootstrapConfigFromEnv, readHttpPortFromEnv, } from './config.js';
14
+ export { createAuthCache } from './auth.js';
15
+ export { ALL_TOOLS, findTool } from './tools/index.js';
16
+ export type { McpTool, McpToolResult, McpServerContext, McpServerBootstrapConfig, Eip191Challenge, } from './types.js';
17
+ export { McpServerError, McpConfigError, McpUnauthorizedError, McpToolNotFoundError, McpInvalidArgsError, McpExecutionError, McpEip191ChallengeExpiredError, McpEip191SignatureInvalidError, } from './errors.js';
18
+ export { SHROUDFI_MCP_SERVER_NAME, SHROUDFI_MCP_SERVER_VERSION, } from './constants.js';
19
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EACL,sBAAsB,EACtB,0BAA0B,EAC1B,mBAAmB,GACpB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACvD,YAAY,EACV,OAAO,EACP,aAAa,EACb,gBAAgB,EAChB,wBAAwB,EACxB,eAAe,GAChB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,cAAc,EACd,cAAc,EACd,oBAAoB,EACpB,oBAAoB,EACpB,mBAAmB,EACnB,iBAAiB,EACjB,8BAA8B,EAC9B,8BAA8B,GAC/B,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,wBAAwB,EACxB,2BAA2B,GAC5B,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Public barrel — @shroud-fi/mcp-server.
3
+ *
4
+ * Two consumption paths:
5
+ * - `import { runStdioServer } from '@shroud-fi/mcp-server'` for stdio bin.
6
+ * - `import { runHttpServer } from '@shroud-fi/mcp-server/http'` for HTTP.
7
+ * - `import { ALL_TOOLS } from '@shroud-fi/mcp-server/tools'` to embed the
8
+ * tool registry into a host MCP server you already own.
9
+ */
10
+ export { runStdioServer } from './stdio.js';
11
+ export { runHttpServer } from './http.js';
12
+ export { buildMcpServer } from './server.js';
13
+ export { buildContextFromConfig, loadBootstrapConfigFromEnv, readHttpPortFromEnv, } from './config.js';
14
+ export { createAuthCache } from './auth.js';
15
+ export { ALL_TOOLS, findTool } from './tools/index.js';
16
+ export { McpServerError, McpConfigError, McpUnauthorizedError, McpToolNotFoundError, McpInvalidArgsError, McpExecutionError, McpEip191ChallengeExpiredError, McpEip191SignatureInvalidError, } from './errors.js';
17
+ export { SHROUDFI_MCP_SERVER_NAME, SHROUDFI_MCP_SERVER_VERSION, } from './constants.js';
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EACL,sBAAsB,EACtB,0BAA0B,EAC1B,mBAAmB,GACpB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAQvD,OAAO,EACL,cAAc,EACd,cAAc,EACd,oBAAoB,EACpB,oBAAoB,EACpB,mBAAmB,EACnB,iBAAiB,EACjB,8BAA8B,EAC9B,8BAA8B,GAC/B,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,wBAAwB,EACxB,2BAA2B,GAC5B,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * MCP server core — wires our tool registry into the official MCP SDK.
3
+ *
4
+ * Transport-agnostic: this function builds the configured Server instance.
5
+ * stdio.ts and http.ts each connect it to their respective transport.
6
+ */
7
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
8
+ import type { McpServerContext } from './types.js';
9
+ /**
10
+ * Build a configured MCP Server. The caller plugs in a transport via
11
+ * `server.connect(transport)` once this returns.
12
+ */
13
+ export declare function buildMcpServer(ctx: McpServerContext): Server;
14
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/server.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAYnE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEnD;;;GAGG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,gBAAgB,GAAG,MAAM,CA6E5D"}
@@ -0,0 +1,89 @@
1
+ /**
2
+ * MCP server core — wires our tool registry into the official MCP SDK.
3
+ *
4
+ * Transport-agnostic: this function builds the configured Server instance.
5
+ * stdio.ts and http.ts each connect it to their respective transport.
6
+ */
7
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
8
+ import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
9
+ import { ALL_TOOLS, findTool } from './tools/index.js';
10
+ import { SHROUDFI_MCP_SERVER_NAME, SHROUDFI_MCP_SERVER_VERSION, } from './constants.js';
11
+ import { McpInvalidArgsError, McpToolNotFoundError, McpServerError } from './errors.js';
12
+ /**
13
+ * Build a configured MCP Server. The caller plugs in a transport via
14
+ * `server.connect(transport)` once this returns.
15
+ */
16
+ export function buildMcpServer(ctx) {
17
+ const server = new Server({
18
+ name: SHROUDFI_MCP_SERVER_NAME,
19
+ version: SHROUDFI_MCP_SERVER_VERSION,
20
+ }, {
21
+ capabilities: {
22
+ tools: {},
23
+ },
24
+ });
25
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
26
+ const tools = ALL_TOOLS.map((t) => ({
27
+ name: t.name,
28
+ description: t.description,
29
+ inputSchema: t.inputSchema,
30
+ }));
31
+ return { tools };
32
+ });
33
+ server.setRequestHandler(CallToolRequestSchema, async (req) => {
34
+ const name = req.params.name;
35
+ const tool = findTool(name);
36
+ if (tool === undefined) {
37
+ throw new McpToolNotFoundError();
38
+ }
39
+ try {
40
+ const args = (req.params.arguments ?? {});
41
+ const result = await tool.handler(ctx, args);
42
+ return {
43
+ content: [
44
+ {
45
+ type: 'text',
46
+ text: JSON.stringify(result),
47
+ },
48
+ ],
49
+ };
50
+ }
51
+ catch (err) {
52
+ if (err instanceof McpInvalidArgsError || err instanceof McpToolNotFoundError) {
53
+ return {
54
+ isError: true,
55
+ content: [
56
+ {
57
+ type: 'text',
58
+ text: JSON.stringify({ ok: false, code: err.code, message: err.message }),
59
+ },
60
+ ],
61
+ };
62
+ }
63
+ if (err instanceof McpServerError) {
64
+ return {
65
+ isError: true,
66
+ content: [
67
+ {
68
+ type: 'text',
69
+ text: JSON.stringify({ ok: false, code: err.code, message: err.message }),
70
+ },
71
+ ],
72
+ };
73
+ }
74
+ // Wrap unexpected error — short tag only, never the raw .message.
75
+ const code = err?.name ?? 'execution_failed';
76
+ return {
77
+ isError: true,
78
+ content: [
79
+ {
80
+ type: 'text',
81
+ text: JSON.stringify({ ok: false, code, message: 'Tool execution failed' }),
82
+ },
83
+ ],
84
+ };
85
+ }
86
+ });
87
+ return server;
88
+ }
89
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Stdio transport entry point.
3
+ *
4
+ * Reads operator config from env, builds the agent context, attaches the
5
+ * MCP server to stdin/stdout. Used by `.mcp.json` config in Claude Code,
6
+ * Cursor, Windsurf, Zed AI, etc.
7
+ */
8
+ export declare function runStdioServer(): Promise<void>;
9
+ //# sourceMappingURL=stdio.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stdio.d.ts","sourceRoot":"","sources":["../../src/stdio.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,wBAAsB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CAMpD"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Stdio transport entry point.
3
+ *
4
+ * Reads operator config from env, builds the agent context, attaches the
5
+ * MCP server to stdin/stdout. Used by `.mcp.json` config in Claude Code,
6
+ * Cursor, Windsurf, Zed AI, etc.
7
+ */
8
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
9
+ import { buildContextFromConfig, loadBootstrapConfigFromEnv } from './config.js';
10
+ import { buildMcpServer } from './server.js';
11
+ export async function runStdioServer() {
12
+ const bootstrap = loadBootstrapConfigFromEnv();
13
+ const ctx = buildContextFromConfig(bootstrap);
14
+ const server = buildMcpServer(ctx);
15
+ const transport = new StdioServerTransport();
16
+ await server.connect(transport);
17
+ }
18
+ //# sourceMappingURL=stdio.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stdio.js","sourceRoot":"","sources":["../../src/stdio.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,sBAAsB,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAC;AACjF,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C,MAAM,CAAC,KAAK,UAAU,cAAc;IAClC,MAAM,SAAS,GAAG,0BAA0B,EAAE,CAAC;IAC/C,MAAM,GAAG,GAAG,sBAAsB,CAAC,SAAS,CAAC,CAAC;IAC9C,MAAM,MAAM,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;IACnC,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AAClC,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * shroud_balance — read ETH and (optionally) ERC-20 balance for a wallet.
3
+ *
4
+ * Defaults to the agent's operator wallet. Pass `address` to query a different
5
+ * one (e.g. a stealth address whose private key was just recovered).
6
+ */
7
+ import type { McpTool } from '../types.js';
8
+ export declare const shroudBalanceTool: McpTool;
9
+ //# sourceMappingURL=balance.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"balance.d.ts","sourceRoot":"","sources":["../../../src/tools/balance.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,OAAO,EAAiB,MAAM,aAAa,CAAC;AAW1D,eAAO,MAAM,iBAAiB,EAAE,OA6C/B,CAAC"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * shroud_balance — read ETH and (optionally) ERC-20 balance for a wallet.
3
+ *
4
+ * Defaults to the agent's operator wallet. Pass `address` to query a different
5
+ * one (e.g. a stealth address whose private key was just recovered).
6
+ */
7
+ import { z } from 'zod';
8
+ import { ERC20Abi } from '@shroud-fi/transport';
9
+ import { McpInvalidArgsError } from '../errors.js';
10
+ import { AddressSchema } from './schema.js';
11
+ const ArgsSchema = z
12
+ .object({
13
+ address: AddressSchema.optional(),
14
+ token: AddressSchema.optional(),
15
+ })
16
+ .strict();
17
+ export const shroudBalanceTool = {
18
+ name: 'shroud_balance',
19
+ description: 'Read the ETH balance and (optionally) a single ERC-20 balance for a wallet. Defaults to the operator wallet. Returns wei-denominated strings.',
20
+ inputSchema: {
21
+ type: 'object',
22
+ additionalProperties: false,
23
+ properties: {
24
+ address: { type: 'string', pattern: '^0x[0-9a-fA-F]{40}$' },
25
+ token: { type: 'string', pattern: '^0x[0-9a-fA-F]{40}$' },
26
+ },
27
+ },
28
+ async handler(ctx, raw) {
29
+ const parsed = ArgsSchema.safeParse(raw ?? {});
30
+ if (!parsed.success) {
31
+ throw new McpInvalidArgsError();
32
+ }
33
+ const target = (parsed.data.address ?? ctx.walletAddress);
34
+ if (target === undefined) {
35
+ throw new McpInvalidArgsError();
36
+ }
37
+ const ethBal = await ctx.transport.publicClient.getBalance({
38
+ address: target,
39
+ });
40
+ const out = {
41
+ ok: true,
42
+ address: target,
43
+ ethWei: ethBal.toString(),
44
+ };
45
+ if (parsed.data.token !== undefined) {
46
+ const tokenBal = (await ctx.transport.publicClient.readContract({
47
+ address: parsed.data.token,
48
+ abi: ERC20Abi,
49
+ functionName: 'balanceOf',
50
+ args: [target],
51
+ }));
52
+ out.token = parsed.data.token;
53
+ out.tokenBaseUnits = tokenBal.toString();
54
+ }
55
+ return out;
56
+ },
57
+ };
58
+ //# sourceMappingURL=balance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"balance.js","sourceRoot":"","sources":["../../../src/tools/balance.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAEhD,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,MAAM,UAAU,GAAG,CAAC;KACjB,MAAM,CAAC;IACN,OAAO,EAAE,aAAa,CAAC,QAAQ,EAAE;IACjC,KAAK,EAAE,aAAa,CAAC,QAAQ,EAAE;CAChC,CAAC;KACD,MAAM,EAAE,CAAC;AAEZ,MAAM,CAAC,MAAM,iBAAiB,GAAY;IACxC,IAAI,EAAE,gBAAgB;IACtB,WAAW,EACT,+IAA+I;IACjJ,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ;QACd,oBAAoB,EAAE,KAAK;QAC3B,UAAU,EAAE;YACV,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,qBAAqB,EAAE;YAC3D,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,qBAAqB,EAAE;SAC1D;KACF;IACD,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG;QACpB,MAAM,MAAM,GAAG,UAAU,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC;QAC/C,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,MAAM,IAAI,mBAAmB,EAAE,CAAC;QAClC,CAAC;QACD,MAAM,MAAM,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,IAAI,GAAG,CAAC,aAAa,CAE3C,CAAC;QACd,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,MAAM,IAAI,mBAAmB,EAAE,CAAC;QAClC,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,SAAS,CAAC,YAAY,CAAC,UAAU,CAAC;YACzD,OAAO,EAAE,MAAM;SAChB,CAAC,CAAC;QAEH,MAAM,GAAG,GAA4B;YACnC,EAAE,EAAE,IAAI;YACR,OAAO,EAAE,MAAM;YACf,MAAM,EAAE,MAAM,CAAC,QAAQ,EAAE;SAC1B,CAAC;QACF,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YACpC,MAAM,QAAQ,GAAG,CAAC,MAAM,GAAG,CAAC,SAAS,CAAC,YAAY,CAAC,YAAY,CAAC;gBAC9D,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,KAAsB;gBAC3C,GAAG,EAAE,QAAQ;gBACb,YAAY,EAAE,WAAW;gBACzB,IAAI,EAAE,CAAC,MAAM,CAAC;aACf,CAAC,CAAW,CAAC;YACd,GAAG,CAAC,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC;YAC9B,GAAG,CAAC,cAAc,GAAG,QAAQ,CAAC,QAAQ,EAAE,CAAC;QAC3C,CAAC;QACD,OAAO,GAAoB,CAAC;IAC9B,CAAC;CACF,CAAC"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Tool registry. Add new tools here so both stdio + http transports pick them up.
3
+ */
4
+ import type { McpTool } from '../types.js';
5
+ import { shroudRegisterTool } from './register.js';
6
+ import { shroudSendTool } from './send.js';
7
+ import { shroudSendToWalletTool } from './send-to-wallet.js';
8
+ import { shroudReceiveTool } from './receive.js';
9
+ import { shroudSweepTool } from './sweep.js';
10
+ import { shroudBalanceTool } from './balance.js';
11
+ import { shroudStatusTool } from './status.js';
12
+ import { shroudX402PayTool } from './x402-pay.js';
13
+ import { shroudX402ServeTool } from './x402-serve.js';
14
+ export declare const ALL_TOOLS: readonly McpTool[];
15
+ export declare function findTool(name: string): McpTool | undefined;
16
+ export { shroudRegisterTool, shroudSendTool, shroudSendToWalletTool, shroudReceiveTool, shroudSweepTool, shroudBalanceTool, shroudStatusTool, shroudX402PayTool, shroudX402ServeTool, };
17
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tools/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAEtD,eAAO,MAAM,SAAS,EAAE,SAAS,OAAO,EAUvC,CAAC;AAEF,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAE1D;AAED,OAAO,EACL,kBAAkB,EAClB,cAAc,EACd,sBAAsB,EACtB,iBAAiB,EACjB,eAAe,EACf,iBAAiB,EACjB,gBAAgB,EAChB,iBAAiB,EACjB,mBAAmB,GACpB,CAAC"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Tool registry. Add new tools here so both stdio + http transports pick them up.
3
+ */
4
+ import { shroudRegisterTool } from './register.js';
5
+ import { shroudSendTool } from './send.js';
6
+ import { shroudSendToWalletTool } from './send-to-wallet.js';
7
+ import { shroudReceiveTool } from './receive.js';
8
+ import { shroudSweepTool } from './sweep.js';
9
+ import { shroudBalanceTool } from './balance.js';
10
+ import { shroudStatusTool } from './status.js';
11
+ import { shroudX402PayTool } from './x402-pay.js';
12
+ import { shroudX402ServeTool } from './x402-serve.js';
13
+ export const ALL_TOOLS = [
14
+ shroudRegisterTool,
15
+ shroudSendTool,
16
+ shroudSendToWalletTool,
17
+ shroudReceiveTool,
18
+ shroudSweepTool,
19
+ shroudBalanceTool,
20
+ shroudStatusTool,
21
+ shroudX402PayTool,
22
+ shroudX402ServeTool,
23
+ ];
24
+ export function findTool(name) {
25
+ return ALL_TOOLS.find((t) => t.name === name);
26
+ }
27
+ export { shroudRegisterTool, shroudSendTool, shroudSendToWalletTool, shroudReceiveTool, shroudSweepTool, shroudBalanceTool, shroudStatusTool, shroudX402PayTool, shroudX402ServeTool, };
28
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tools/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAEtD,MAAM,CAAC,MAAM,SAAS,GAAuB;IAC3C,kBAAkB;IAClB,cAAc;IACd,sBAAsB;IACtB,iBAAiB;IACjB,eAAe;IACf,iBAAiB;IACjB,gBAAgB;IAChB,iBAAiB;IACjB,mBAAmB;CACpB,CAAC;AAEF,MAAM,UAAU,QAAQ,CAAC,IAAY;IACnC,OAAO,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;AAChD,CAAC;AAED,OAAO,EACL,kBAAkB,EAClB,cAAc,EACd,sBAAsB,EACtB,iBAAiB,EACjB,eAAe,EACf,iBAAiB,EACjB,gBAAgB,EAChB,iBAAiB,EACjB,mBAAmB,GACpB,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * shroud_receive — scan a block range for incoming stealth payments to the
3
+ * configured agent. Stateless: caller supplies fromBlock + toBlock; server
4
+ * returns every detection in that window.
5
+ *
6
+ * Privacy: stealthPrivateKey is exposed in the response because the caller is
7
+ * the same operator that holds the spending key in the server process — the
8
+ * key was derived from their own seed. The MCP transport must be local stdio
9
+ * or authenticated HTTP (EIP-191) to keep this safe. See HTTP transport gate.
10
+ */
11
+ import type { McpTool } from '../types.js';
12
+ export declare const shroudReceiveTool: McpTool;
13
+ //# sourceMappingURL=receive.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"receive.d.ts","sourceRoot":"","sources":["../../../src/tools/receive.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,OAAO,KAAK,EAAE,OAAO,EAAiB,MAAM,aAAa,CAAC;AAc1D,eAAO,MAAM,iBAAiB,EAAE,OA4E/B,CAAC"}
@@ -0,0 +1,97 @@
1
+ /**
2
+ * shroud_receive — scan a block range for incoming stealth payments to the
3
+ * configured agent. Stateless: caller supplies fromBlock + toBlock; server
4
+ * returns every detection in that window.
5
+ *
6
+ * Privacy: stealthPrivateKey is exposed in the response because the caller is
7
+ * the same operator that holds the spending key in the server process — the
8
+ * key was derived from their own seed. The MCP transport must be local stdio
9
+ * or authenticated HTTP (EIP-191) to keep this safe. See HTTP transport gate.
10
+ */
11
+ import { z } from 'zod';
12
+ import { createScanner } from '@shroud-fi/scanning';
13
+ import { McpInvalidArgsError } from '../errors.js';
14
+ import { Uint256StringSchema, toBigInt } from './schema.js';
15
+ const ArgsSchema = z
16
+ .object({
17
+ fromBlock: Uint256StringSchema,
18
+ toBlock: z.union([Uint256StringSchema, z.literal('latest')]).optional(),
19
+ finality: z.enum(['unsafe', 'safe', 'finalized']).optional(),
20
+ /** Hard cap on detections returned in a single call. Defaults to 100. */
21
+ limit: z.number().int().positive().max(1000).optional(),
22
+ })
23
+ .strict();
24
+ export const shroudReceiveTool = {
25
+ name: 'shroud_receive',
26
+ description: 'Scan a block range for incoming stealth payments to the agent. Returns the list of detections (each includes stealthAddress, ephemeralPubKey, stealthPrivateKey, txHash, blockNumber). Stateless: caller drives the cursor by passing fromBlock + toBlock.',
27
+ inputSchema: {
28
+ type: 'object',
29
+ additionalProperties: false,
30
+ properties: {
31
+ fromBlock: { type: 'string', pattern: '^\\d+$' },
32
+ toBlock: { oneOf: [{ type: 'string', pattern: '^\\d+$' }, { const: 'latest' }] },
33
+ finality: { type: 'string', enum: ['unsafe', 'safe', 'finalized'] },
34
+ limit: { type: 'integer', minimum: 1, maximum: 1000 },
35
+ },
36
+ required: ['fromBlock'],
37
+ },
38
+ async handler(ctx, raw) {
39
+ const parsed = ArgsSchema.safeParse(raw);
40
+ if (!parsed.success) {
41
+ throw new McpInvalidArgsError();
42
+ }
43
+ const { fromBlock, toBlock, finality, limit } = parsed.data;
44
+ const fromB = toBigInt(fromBlock);
45
+ let toB;
46
+ if (toBlock === undefined || toBlock === 'latest') {
47
+ const tag = finality === 'finalized'
48
+ ? 'finalized'
49
+ : finality === 'safe'
50
+ ? 'safe'
51
+ : 'latest';
52
+ const block = await ctx.transport.publicClient.getBlock({ blockTag: tag });
53
+ toB = block.number ?? fromB;
54
+ }
55
+ else {
56
+ toB = toBigInt(toBlock);
57
+ }
58
+ if (toB < fromB) {
59
+ return { ok: true, fromBlock: fromB.toString(), toBlock: toB.toString(), detections: [] };
60
+ }
61
+ const scanner = createScanner({
62
+ transport: ctx.transport,
63
+ scanningKey: ctx.agent.identity.keys.scanningKey,
64
+ spendingKey: ctx.agent.identity.keys.spendingKey,
65
+ startBlock: fromB,
66
+ ...(finality !== undefined ? { finality } : {}),
67
+ });
68
+ const out = [];
69
+ const cap = limit ?? 100;
70
+ try {
71
+ for await (const d of scanner.scanRange(fromB, toB)) {
72
+ out.push({
73
+ stealthAddress: d.stealthAddress,
74
+ ephemeralPubKey: d.ephemeralPubKey,
75
+ stealthPrivateKey: d.stealthPrivateKey,
76
+ txHash: d.txHash,
77
+ blockNumber: d.blockNumber.toString(),
78
+ blockHash: d.blockHash,
79
+ logIndex: d.logIndex,
80
+ finality: d.finality,
81
+ });
82
+ if (out.length >= cap)
83
+ break;
84
+ }
85
+ }
86
+ finally {
87
+ scanner.close();
88
+ }
89
+ return {
90
+ ok: true,
91
+ fromBlock: fromB.toString(),
92
+ toBlock: toB.toString(),
93
+ detections: out,
94
+ };
95
+ },
96
+ };
97
+ //# sourceMappingURL=receive.js.map