@secondlayer/mcp 3.0.0 → 3.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.
package/dist/bin-http.js CHANGED
@@ -12,6 +12,69 @@ import { dirname, join } from "node:path";
12
12
  import { fileURLToPath } from "node:url";
13
13
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
14
14
 
15
+ // src/lib/client.ts
16
+ import { SecondLayer } from "@secondlayer/sdk";
17
+ var instance = null;
18
+ function readApiKey() {
19
+ return process.env.SL_API_KEY;
20
+ }
21
+ function getClient() {
22
+ if (!instance) {
23
+ const apiKey = readApiKey();
24
+ const baseUrl = process.env.SECONDLAYER_API_URL;
25
+ instance = new SecondLayer({
26
+ ...apiKey ? { apiKey } : {},
27
+ origin: "mcp",
28
+ ...baseUrl ? { baseUrl } : {}
29
+ });
30
+ }
31
+ return instance;
32
+ }
33
+ var keyHint = " — set SL_API_KEY to an sk-sl_ API key from " + "https://secondlayer.tools/platform/api-keys for write and account operations";
34
+ async function apiRequest(method, path, body) {
35
+ const apiKey = readApiKey();
36
+ const baseUrl = process.env.SECONDLAYER_API_URL || "https://api.secondlayer.tools";
37
+ const res = await fetch(`${baseUrl}${path}`, {
38
+ method,
39
+ headers: {
40
+ "Content-Type": "application/json",
41
+ ...apiKey ? { Authorization: `Bearer ${apiKey}` } : {}
42
+ },
43
+ body: body ? JSON.stringify(body) : undefined
44
+ });
45
+ if (!res.ok) {
46
+ const text = await res.text().catch(() => "");
47
+ const needsKey = !apiKey && (res.status === 401 || res.status === 403);
48
+ throw Object.assign(new Error((text || `HTTP ${res.status}`) + (needsKey ? keyHint : "")), { status: res.status });
49
+ }
50
+ if (res.status === 204)
51
+ return;
52
+ return res.json();
53
+ }
54
+
55
+ // src/lib/format.ts
56
+ function formatSubgraphSummary(s) {
57
+ return {
58
+ name: s.name,
59
+ status: s.status,
60
+ tables: Array.isArray(s.tables) ? s.tables : Object.keys(s.tables),
61
+ lastProcessedBlock: s.lastProcessedBlock
62
+ };
63
+ }
64
+ function withCap(items, cap) {
65
+ return {
66
+ items: items.slice(0, cap),
67
+ truncated: items.length > cap,
68
+ total: items.length
69
+ };
70
+ }
71
+ function jsonResponse(data, isError) {
72
+ return {
73
+ content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
74
+ ...isError && { isError: true }
75
+ };
76
+ }
77
+
15
78
  // src/resources.ts
16
79
  var FILTERS_REFERENCE = [
17
80
  {
@@ -67,7 +130,54 @@ var COLUMN_TYPES = [
67
130
  description: "Column options: nullable allows NULL, indexed creates a B-tree index, search enables full-text search"
68
131
  }
69
132
  ];
133
+ var CAPABILITIES = {
134
+ products: [
135
+ "datasets — public foundation datasets (datasets_list, datasets_query)",
136
+ "index — decoded L2 events + contract calls (index_ft_transfers, index_nft_transfers, index_events, index_contract_calls)",
137
+ "streams — raw chain event firehose (streams_tip, streams_events)",
138
+ "contracts — trait-based contract discovery (contracts_find)",
139
+ "subgraphs — author/deploy/query custom indexes (subgraphs_deploy, subgraphs_query, subgraphs_list, subgraphs_get, subgraphs_reindex, subgraphs_delete)",
140
+ "subscriptions — webhook delivery of subgraph rows (subscriptions_create, subscriptions_list, subscriptions_update, …)",
141
+ "account — identity + plan (account_whoami)"
142
+ ],
143
+ discoverFirst: "Call datasets_list / contracts_find to learn what exists before querying."
144
+ };
145
+ var READ_AUTH_TIERS = {
146
+ datasets: "open — no API key required",
147
+ index: "anonymous reads allowed; free-tier API keys are rejected (Build+ required)",
148
+ streams: "API key required (SL_API_KEY) — keyless calls return 401",
149
+ subgraphs: "reads public during open beta; writes require an API key"
150
+ };
151
+ async function buildContext(deps = {
152
+ clientProvider: getClient,
153
+ accountRequest: () => apiRequest("GET", "/api/accounts/me")
154
+ }) {
155
+ const unavailable = "unavailable: set SL_API_KEY";
156
+ const subgraphs = await deps.clientProvider().subgraphs.list().then((r) => r.data.map(formatSubgraphSummary)).catch(() => unavailable);
157
+ const subscriptions = await deps.clientProvider().subscriptions.list().then((r) => ({
158
+ count: r.data.length,
159
+ statuses: r.data.map((s) => s.status)
160
+ })).catch(() => unavailable);
161
+ const account = await deps.accountRequest().catch(() => unavailable);
162
+ return {
163
+ authState: { apiKeySet: Boolean(process.env.SL_API_KEY) },
164
+ whatExists: { subgraphs, subscriptions, account },
165
+ whatYouCanDo: CAPABILITIES,
166
+ readAuthTiers: READ_AUTH_TIERS
167
+ };
168
+ }
70
169
  function registerResources(server) {
170
+ server.resource("context", "secondlayer://context", {
171
+ description: "Live agent context — what exists (your subgraphs, subscriptions, account), what you can do, and read-auth tiers. Read this first."
172
+ }, async () => ({
173
+ contents: [
174
+ {
175
+ uri: "secondlayer://context",
176
+ mimeType: "application/json",
177
+ text: JSON.stringify(await buildContext(), null, 2)
178
+ }
179
+ ]
180
+ }));
71
181
  server.resource("filters", "secondlayer://filters", { description: "Event filter types and their available fields" }, async () => ({
72
182
  contents: [
73
183
  {
@@ -88,68 +198,8 @@ function registerResources(server) {
88
198
  }));
89
199
  }
90
200
 
91
- // src/lib/client.ts
92
- import { SecondLayer } from "@secondlayer/sdk";
93
- var instance = null;
94
- function readApiKey() {
95
- return process.env.SL_API_KEY;
96
- }
97
- function getClient() {
98
- if (!instance) {
99
- const apiKey = readApiKey();
100
- const baseUrl = process.env.SECONDLAYER_API_URL;
101
- instance = new SecondLayer({
102
- ...apiKey ? { apiKey } : {},
103
- origin: "mcp",
104
- ...baseUrl ? { baseUrl } : {}
105
- });
106
- }
107
- return instance;
108
- }
109
- var keyHint = " — set SL_API_KEY to an sk-sl_ API key from " + "https://secondlayer.tools/platform/api-keys for write and account operations";
110
- async function apiRequest(method, path, body) {
111
- const apiKey = readApiKey();
112
- const baseUrl = process.env.SECONDLAYER_API_URL || "https://api.secondlayer.tools";
113
- const res = await fetch(`${baseUrl}${path}`, {
114
- method,
115
- headers: {
116
- "Content-Type": "application/json",
117
- ...apiKey ? { Authorization: `Bearer ${apiKey}` } : {}
118
- },
119
- body: body ? JSON.stringify(body) : undefined
120
- });
121
- if (!res.ok) {
122
- const text = await res.text().catch(() => "");
123
- const needsKey = !apiKey && (res.status === 401 || res.status === 403);
124
- throw Object.assign(new Error((text || `HTTP ${res.status}`) + (needsKey ? keyHint : "")), { status: res.status });
125
- }
126
- if (res.status === 204)
127
- return;
128
- return res.json();
129
- }
130
-
131
- // src/lib/format.ts
132
- function formatSubgraphSummary(s) {
133
- return {
134
- name: s.name,
135
- status: s.status,
136
- tables: Array.isArray(s.tables) ? s.tables : Object.keys(s.tables),
137
- lastProcessedBlock: s.lastProcessedBlock
138
- };
139
- }
140
- function withCap(items, cap) {
141
- return {
142
- items: items.slice(0, cap),
143
- truncated: items.length > cap,
144
- total: items.length
145
- };
146
- }
147
- function jsonResponse(data, isError) {
148
- return {
149
- content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
150
- ...isError && { isError: true }
151
- };
152
- }
201
+ // src/tools/account.ts
202
+ import { z } from "zod/v4";
153
203
 
154
204
  // src/lib/tool.ts
155
205
  function defineTool(server, name, description, schema, handler) {
@@ -180,11 +230,113 @@ function registerAccountTools(server) {
180
230
  const result = await apiRequest("GET", "/api/accounts/me");
181
231
  return jsonResponse(result);
182
232
  });
233
+ defineTool(server, "account_update", "Update the authenticated account's profile. Requires an API key.", {
234
+ displayName: z.string().optional().describe("Display name"),
235
+ bio: z.string().optional().describe("Profile bio"),
236
+ slug: z.string().optional().describe("Account URL slug")
237
+ }, async ({ displayName, bio, slug }) => {
238
+ const body = {};
239
+ if (displayName !== undefined)
240
+ body.display_name = displayName;
241
+ if (bio !== undefined)
242
+ body.bio = bio;
243
+ if (slug !== undefined)
244
+ body.slug = slug;
245
+ const result = await apiRequest("PATCH", "/api/accounts/me", body);
246
+ return jsonResponse(result);
247
+ });
248
+ defineTool(server, "account_billing", "Show the account's plan and subscription/billing status. Requires an API key.", {}, async () => {
249
+ const result = await apiRequest("GET", "/api/billing/status");
250
+ return jsonResponse(result);
251
+ });
252
+ }
253
+
254
+ // src/tools/contracts.ts
255
+ import { z as z2 } from "zod/v4";
256
+ function registerContractTools(server, clientProvider = getClient) {
257
+ defineTool(server, "contracts_find", 'Discover deployed Stacks contracts conforming to a trait (e.g. "sip-010", "sip-009", "sip-013"). The discovery endpoint for "which contracts implement X". Reads are public.', {
258
+ trait: z2.string().describe('Required. Trait to match (e.g. "sip-010").'),
259
+ conformance: z2.enum(["declared", "inferred", "any"]).optional().describe("declared = parsed from source, inferred = ABI shape-match, any = either (default)"),
260
+ include: z2.literal("abi").optional().describe(`Set to "abi" to include each contract's full ABI`),
261
+ limit: z2.number().optional().describe("Page size, 1–500 (default 100)"),
262
+ cursor: z2.string().optional().describe("Opaque cursor from a prior response's next_cursor")
263
+ }, async (params) => jsonResponse(await clientProvider().contracts.list(params)));
264
+ }
265
+
266
+ // src/tools/datasets.ts
267
+ import { z as z3 } from "zod/v4";
268
+ function registerDatasetTools(server, clientProvider = getClient) {
269
+ defineTool(server, "datasets_list", "List the Foundation Datasets catalog with freshness — the discovery endpoint for what dataset slugs exist and how current each is. Reads are public.", {}, async () => {
270
+ const catalog = await clientProvider().datasets.listDatasets();
271
+ return jsonResponse(catalog);
272
+ });
273
+ defineTool(server, "datasets_query", 'Query a cursor-paginated Foundation Dataset by slug (e.g. "stx-transfers", "sbtc/events", "pox-4/calls", "bns/events"). Filters are passed through as documented query params (e.g. {"sender": "SP...", "from_block": "150000"}). Returns { rows, next_cursor, tip }. Call datasets_list first to discover slugs.', {
274
+ slug: z3.string().describe("Dataset slug from datasets_list (e.g. stx-transfers)"),
275
+ filters: z3.record(z3.string(), z3.string()).optional().describe("Documented per-dataset query params (snake_case values)"),
276
+ limit: z3.number().optional().describe("Max rows for this page"),
277
+ cursor: z3.string().optional().describe("Opaque cursor from a prior response's next_cursor")
278
+ }, async ({ slug, filters, limit, cursor }) => {
279
+ const params = { ...filters ?? {} };
280
+ if (limit !== undefined)
281
+ params.limit = limit;
282
+ if (cursor !== undefined)
283
+ params.cursor = cursor;
284
+ const result = await clientProvider().datasets.query(slug, params);
285
+ return jsonResponse(result);
286
+ });
287
+ }
288
+
289
+ // src/tools/index.ts
290
+ import { z as z4 } from "zod/v4";
291
+ var INDEX_EVENT_TYPES = [
292
+ "ft_transfer",
293
+ "nft_transfer",
294
+ "stx_transfer",
295
+ "stx_mint",
296
+ "stx_burn",
297
+ "stx_lock",
298
+ "ft_mint",
299
+ "ft_burn",
300
+ "nft_mint",
301
+ "nft_burn",
302
+ "print"
303
+ ];
304
+ var rangeFilters = {
305
+ contractId: z4.string().optional().describe("Filter by contract id"),
306
+ fromHeight: z4.number().optional().describe("Start block height (inclusive)"),
307
+ toHeight: z4.number().optional().describe("End block height (inclusive)"),
308
+ cursor: z4.string().optional().describe("Opaque cursor from a prior response's next_cursor"),
309
+ limit: z4.number().optional().describe("Max rows for this page")
310
+ };
311
+ function registerIndexTools(server, clientProvider = getClient) {
312
+ defineTool(server, "index_ft_transfers", "List decoded SIP-010 fungible-token transfers from the Index (L2 decoded layer). Anonymous reads allowed (free-tier API keys are rejected — Build+ required).", {
313
+ ...rangeFilters,
314
+ sender: z4.string().optional().describe("Filter by sender principal"),
315
+ recipient: z4.string().optional().describe("Filter by recipient principal")
316
+ }, async (params) => jsonResponse(await clientProvider().index.ftTransfers.list(params)));
317
+ defineTool(server, "index_nft_transfers", "List decoded SIP-009 non-fungible-token transfers from the Index. Anonymous reads allowed (free-tier keys rejected).", {
318
+ ...rangeFilters,
319
+ sender: z4.string().optional().describe("Filter by sender principal"),
320
+ recipient: z4.string().optional().describe("Filter by recipient principal"),
321
+ assetIdentifier: z4.string().optional().describe("Filter by asset identifier (contract::asset)")
322
+ }, async (params) => jsonResponse(await clientProvider().index.nftTransfers.list(params)));
323
+ defineTool(server, "index_events", "List decoded chain events from the Index by event type. Use this for event types without a dedicated tool (stx_*, ft_mint/burn, nft_mint/burn, print). For ft/nft transfers prefer index_ft_transfers / index_nft_transfers.", {
324
+ eventType: z4.enum(INDEX_EVENT_TYPES).describe("Required. Decoded event type to list."),
325
+ ...rangeFilters,
326
+ sender: z4.string().optional().describe("Filter by sender principal"),
327
+ recipient: z4.string().optional().describe("Filter by recipient principal"),
328
+ assetIdentifier: z4.string().optional().describe("Filter by asset identifier where applicable")
329
+ }, async (params) => jsonResponse(await clientProvider().index.events.list(params)));
330
+ defineTool(server, "index_contract_calls", "List decoded contract calls from the Index (function name, args, result). Note: contract-call cursors are a SEPARATE keyspace from event cursors — they are not interchangeable.", {
331
+ ...rangeFilters,
332
+ functionName: z4.string().optional().describe("Filter by called function name"),
333
+ sender: z4.string().optional().describe("Filter by caller principal")
334
+ }, async (params) => jsonResponse(await clientProvider().index.contractCalls.list(params)));
183
335
  }
184
336
 
185
337
  // src/tools/scaffold.ts
186
338
  import { generateSubgraphCode } from "@secondlayer/scaffold";
187
- import { z } from "zod/v4";
339
+ import { z as z5 } from "zod/v4";
188
340
  var API_BASE = process.env.SECONDLAYER_API_URL || "https://api.secondlayer.tools";
189
341
  async function fetchAbi(contractId) {
190
342
  const res = await fetch(`${API_BASE}/api/node/contracts/${contractId}/abi`, {
@@ -203,17 +355,17 @@ async function fetchAbi(contractId) {
203
355
  }
204
356
  function registerScaffoldTools(server) {
205
357
  defineTool(server, "scaffold_from_contract", "Generate a subgraph scaffold from a deployed Stacks contract. Fetches the ABI automatically.", {
206
- contractId: z.string().describe("Fully qualified contract ID (e.g. SP102V8P0F7JX67ARQ77WEA3D3CFB5XW39REDT0AM.amm-pool-v2-01)"),
207
- subgraphName: z.string().optional().describe("Override the subgraph name (defaults to contract name)")
358
+ contractId: z5.string().describe("Fully qualified contract ID (e.g. SP102V8P0F7JX67ARQ77WEA3D3CFB5XW39REDT0AM.amm-pool-v2-01)"),
359
+ subgraphName: z5.string().optional().describe("Override the subgraph name (defaults to contract name)")
208
360
  }, async ({ contractId, subgraphName }) => {
209
361
  const { functions, maps } = await fetchAbi(contractId);
210
362
  const code = generateSubgraphCode(contractId, functions, subgraphName, maps);
211
363
  return { content: [{ type: "text", text: code }] };
212
364
  });
213
365
  defineTool(server, "scaffold_from_abi", "Generate a subgraph scaffold from a provided ABI JSON. Use when you already have the ABI.", {
214
- abi: z.string().describe("ABI JSON string (the full contract ABI object)"),
215
- contractId: z.string().describe("Fully qualified contract ID"),
216
- subgraphName: z.string().optional().describe("Override the subgraph name")
366
+ abi: z5.string().describe("ABI JSON string (the full contract ABI object)"),
367
+ contractId: z5.string().describe("Fully qualified contract ID"),
368
+ subgraphName: z5.string().optional().describe("Override the subgraph name")
217
369
  }, async ({ abi, contractId, subgraphName }) => {
218
370
  let parsed;
219
371
  try {
@@ -229,9 +381,51 @@ function registerScaffoldTools(server) {
229
381
  });
230
382
  }
231
383
 
384
+ // src/tools/streams.ts
385
+ import { AuthError } from "@secondlayer/sdk";
386
+ import { z as z6 } from "zod/v4";
387
+ var STREAMS_EVENT_TYPES = [
388
+ "stx_transfer",
389
+ "stx_mint",
390
+ "stx_burn",
391
+ "stx_lock",
392
+ "ft_transfer",
393
+ "ft_mint",
394
+ "ft_burn",
395
+ "nft_transfer",
396
+ "nft_mint",
397
+ "nft_burn",
398
+ "print"
399
+ ];
400
+ async function withStreamsAuthHint(fn) {
401
+ try {
402
+ return await fn();
403
+ } catch (err) {
404
+ if (err instanceof AuthError) {
405
+ throw Object.assign(new Error(err.message + keyHint), { status: 401 });
406
+ }
407
+ throw err;
408
+ }
409
+ }
410
+ function registerStreamsTools(server, clientProvider = getClient) {
411
+ defineTool(server, "streams_tip", "Get the current Streams chain tip (latest processed block + lag). Streams requires an API key (SL_API_KEY).", {}, async () => withStreamsAuthHint(async () => jsonResponse(await clientProvider().streams.tip())));
412
+ defineTool(server, "streams_events", "List raw chain events from the Streams firehose. Streams requires an API key (SL_API_KEY). Filter by event types, principals, contract, asset, or block range; page with cursor.", {
413
+ types: z6.array(z6.enum(STREAMS_EVENT_TYPES)).optional().describe("Event types to include"),
414
+ notTypes: z6.array(z6.enum(STREAMS_EVENT_TYPES)).optional().describe("Event types to exclude (applied after types)"),
415
+ contractId: z6.string().optional().describe("Filter by contract id"),
416
+ sender: z6.string().optional().describe("Filter by sender principal"),
417
+ recipient: z6.string().optional().describe("Filter by recipient principal"),
418
+ assetIdentifier: z6.string().optional().describe("Filter by asset identifier"),
419
+ fromBlock: z6.number().optional().describe("Start block (inclusive)"),
420
+ toBlock: z6.number().optional().describe("End block (inclusive)"),
421
+ cursor: z6.string().optional().describe("Opaque cursor from a prior response"),
422
+ limit: z6.number().optional().describe("Max events for this page")
423
+ }, async (params) => withStreamsAuthHint(async () => jsonResponse(await clientProvider().streams.events.list(params))));
424
+ }
425
+
232
426
  // src/tools/subgraphs.ts
233
427
  import { bundleSubgraphCode } from "@secondlayer/bundler";
234
- import { z as z2 } from "zod/v4";
428
+ import { z as z7 } from "zod/v4";
235
429
  function registerSubgraphTools(server, clientProvider = getClient) {
236
430
  defineTool(server, "subgraphs_list", "List all deployed subgraphs. Returns summary fields only.", {}, async () => {
237
431
  const { data } = await clientProvider().subgraphs.list();
@@ -244,16 +438,16 @@ function registerSubgraphTools(server, clientProvider = getClient) {
244
438
  ]
245
439
  };
246
440
  });
247
- defineTool(server, "subgraphs_get", "Get full details of a subgraph including schema, health, and table columns.", { name: z2.string().describe("Subgraph name") }, async ({ name }) => {
441
+ defineTool(server, "subgraphs_get", "Get full details of a subgraph including schema, health, and table columns.", { name: z7.string().describe("Subgraph name") }, async ({ name }) => {
248
442
  const detail = await clientProvider().subgraphs.get(name);
249
443
  return {
250
444
  content: [{ type: "text", text: JSON.stringify(detail, null, 2) }]
251
445
  };
252
446
  });
253
447
  defineTool(server, "subgraphs_spec", "Get generated API documentation for a subgraph. Defaults to compact agent schema; supports OpenAPI JSON and Markdown.", {
254
- name: z2.string().describe("Subgraph name"),
255
- format: z2.enum(["agent", "openapi", "markdown"]).optional().describe("Spec format to return. Defaults to agent."),
256
- serverUrl: z2.string().optional().describe("Override the server URL embedded in generated docs.")
448
+ name: z7.string().describe("Subgraph name"),
449
+ format: z7.enum(["agent", "openapi", "markdown"]).optional().describe("Spec format to return. Defaults to agent."),
450
+ serverUrl: z7.string().optional().describe("Override the server URL embedded in generated docs.")
257
451
  }, async ({ name, format = "agent", serverUrl }) => {
258
452
  const options = serverUrl ? { serverUrl } : undefined;
259
453
  const spec = format === "openapi" ? await clientProvider().subgraphs.openapi(name, options) : format === "markdown" ? await clientProvider().subgraphs.markdown(name, options) : await clientProvider().subgraphs.schema(name, options);
@@ -267,15 +461,15 @@ function registerSubgraphTools(server, clientProvider = getClient) {
267
461
  };
268
462
  });
269
463
  defineTool(server, "subgraphs_query", 'Query rows from a subgraph table (max 200 rows). Filters support operators: "amount.gte": "1000", "sender.neq": "SP...", "name.like": "%token%". Available operators: eq, neq, gt, gte, lt, lte, like.', {
270
- name: z2.string().describe("Subgraph name"),
271
- table: z2.string().describe("Table name"),
272
- filters: z2.record(z2.string(), z2.string()).optional().describe('Column filters — plain values or with operators (e.g. {"amount.gte": "1000", "sender": "SP..."})'),
273
- sort: z2.string().optional().describe("Column to sort by"),
274
- order: z2.enum(["asc", "desc"]).optional().describe("Sort order"),
275
- limit: z2.number().max(200).optional().describe("Max rows (default 50, max 200)"),
276
- offset: z2.number().optional().describe("Offset for pagination"),
277
- fields: z2.string().optional().describe('Comma-separated column list to return (e.g. "sender,amount")'),
278
- count: z2.boolean().optional().describe("If true, return row count instead of rows")
464
+ name: z7.string().describe("Subgraph name"),
465
+ table: z7.string().describe("Table name"),
466
+ filters: z7.record(z7.string(), z7.string()).optional().describe('Column filters — plain values or with operators (e.g. {"amount.gte": "1000", "sender": "SP..."})'),
467
+ sort: z7.string().optional().describe("Column to sort by"),
468
+ order: z7.enum(["asc", "desc"]).optional().describe("Sort order"),
469
+ limit: z7.number().max(200).optional().describe("Max rows (default 50, max 200)"),
470
+ offset: z7.number().optional().describe("Offset for pagination"),
471
+ fields: z7.string().optional().describe('Comma-separated column list to return (e.g. "sender,amount")'),
472
+ count: z7.boolean().optional().describe("If true, return row count instead of rows")
279
473
  }, async ({
280
474
  name,
281
475
  table,
@@ -308,9 +502,9 @@ function registerSubgraphTools(server, clientProvider = getClient) {
308
502
  };
309
503
  });
310
504
  defineTool(server, "subgraphs_reindex", "Reindex a subgraph from a specific block range.", {
311
- name: z2.string().describe("Subgraph name"),
312
- fromBlock: z2.number().optional().describe("Start block (defaults to beginning)"),
313
- toBlock: z2.number().optional().describe("End block (defaults to latest)")
505
+ name: z7.string().describe("Subgraph name"),
506
+ fromBlock: z7.number().optional().describe("Start block (defaults to beginning)"),
507
+ toBlock: z7.number().optional().describe("End block (defaults to latest)")
314
508
  }, async ({ name, fromBlock, toBlock }) => {
315
509
  const result = await clientProvider().subgraphs.reindex(name, {
316
510
  fromBlock,
@@ -320,13 +514,13 @@ function registerSubgraphTools(server, clientProvider = getClient) {
320
514
  content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
321
515
  };
322
516
  });
323
- defineTool(server, "subgraphs_delete", "Delete a subgraph permanently.", { name: z2.string().describe("Subgraph name") }, async ({ name }) => {
517
+ defineTool(server, "subgraphs_delete", "Delete a subgraph permanently.", { name: z7.string().describe("Subgraph name") }, async ({ name }) => {
324
518
  const result = await clientProvider().subgraphs.delete(name);
325
519
  return { content: [{ type: "text", text: result.message }] };
326
520
  });
327
521
  defineTool(server, "subgraphs_deploy", "Deploy a subgraph from TypeScript code. Pass the full defineSubgraph() source — it will be bundled, validated, and deployed. Optional startBlock overrides the source definition for this deploy. Call `subgraphs_reindex` separately if you need a forced reindex.", {
328
- code: z2.string().describe("TypeScript source code containing a defineSubgraph() call"),
329
- startBlock: z2.number().int().nonnegative().optional().describe("Override the definition startBlock for this deploy")
522
+ code: z7.string().describe("TypeScript source code containing a defineSubgraph() call"),
523
+ startBlock: z7.number().int().nonnegative().optional().describe("Override the definition startBlock for this deploy")
330
524
  }, async ({ code, startBlock }) => {
331
525
  const bundled = await bundleSubgraphCode(code);
332
526
  const result = await clientProvider().subgraphs.deploy({
@@ -343,7 +537,7 @@ function registerSubgraphTools(server, clientProvider = getClient) {
343
537
  content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
344
538
  };
345
539
  });
346
- defineTool(server, "subgraphs_read_source", "Fetch the deployed TypeScript source of a subgraph (plus its stored version). Returns a readOnly payload for subgraphs deployed before source capture — in that case the caller should redeploy via CLI before editing.", { name: z2.string().describe("Subgraph name") }, async ({ name }) => {
540
+ defineTool(server, "subgraphs_read_source", "Fetch the deployed TypeScript source of a subgraph (plus its stored version). Returns a readOnly payload for subgraphs deployed before source capture — in that case the caller should redeploy via CLI before editing.", { name: z7.string().describe("Subgraph name") }, async ({ name }) => {
347
541
  const source = await clientProvider().subgraphs.getSource(name);
348
542
  return {
349
543
  content: [{ type: "text", text: JSON.stringify(source, null, 2) }]
@@ -352,7 +546,7 @@ function registerSubgraphTools(server, clientProvider = getClient) {
352
546
  }
353
547
 
354
548
  // src/tools/subscriptions.ts
355
- import { z as z3 } from "zod/v4";
549
+ import { z as z8 } from "zod/v4";
356
550
  function registerSubscriptionTools(server, clientProvider = getClient) {
357
551
  defineTool(server, "subscriptions_list", "List all subscriptions for the current account. Returns summary fields (no secrets).", {}, async () => {
358
552
  const { data } = await clientProvider().subscriptions.list();
@@ -360,18 +554,18 @@ function registerSubscriptionTools(server, clientProvider = getClient) {
360
554
  content: [{ type: "text", text: JSON.stringify(data, null, 2) }]
361
555
  };
362
556
  });
363
- defineTool(server, "subscriptions_get", "Get full detail for a subscription (filter, auth, retry config, circuit state).", { id: z3.string().describe("Subscription id") }, async ({ id }) => {
557
+ defineTool(server, "subscriptions_get", "Get full detail for a subscription (filter, auth, retry config, circuit state).", { id: z8.string().describe("Subscription id") }, async ({ id }) => {
364
558
  const detail = await clientProvider().subscriptions.get(id);
365
559
  return {
366
560
  content: [{ type: "text", text: JSON.stringify(detail, null, 2) }]
367
561
  };
368
562
  });
369
563
  defineTool(server, "subscriptions_create", "Create a subscription. Returns `signingSecret` ONCE — forward it to the user so they can wire it into their receiver.", {
370
- name: z3.string().describe("Human-readable name, unique per account"),
371
- subgraphName: z3.string().describe("Subgraph to subscribe to"),
372
- tableName: z3.string().describe("Table within the subgraph"),
373
- url: z3.string().describe("Webhook URL"),
374
- format: z3.enum([
564
+ name: z8.string().describe("Human-readable name, unique per account"),
565
+ subgraphName: z8.string().describe("Subgraph to subscribe to"),
566
+ tableName: z8.string().describe("Table within the subgraph"),
567
+ url: z8.string().describe("Webhook URL"),
568
+ format: z8.enum([
375
569
  "standard-webhooks",
376
570
  "inngest",
377
571
  "trigger",
@@ -379,8 +573,8 @@ function registerSubscriptionTools(server, clientProvider = getClient) {
379
573
  "cloudevents",
380
574
  "raw"
381
575
  ]).optional().describe("Wire format (default standard-webhooks)"),
382
- runtime: z3.enum(["inngest", "trigger", "cloudflare", "node"]).optional().describe("Receiver runtime label (display only)"),
383
- filter: z3.record(z3.string(), z3.unknown()).optional().describe('Scalar filter DSL, e.g. {"amount": {"gte": 100}, "sender": "SP..."}')
576
+ runtime: z8.enum(["inngest", "trigger", "cloudflare", "node"]).optional().describe("Receiver runtime label (display only)"),
577
+ filter: z8.record(z8.string(), z8.unknown()).optional().describe('Scalar filter DSL, e.g. {"amount": {"gte": 100}, "sender": "SP..."}')
384
578
  }, async (input) => {
385
579
  const res = await clientProvider().subscriptions.create(input);
386
580
  return {
@@ -388,10 +582,10 @@ function registerSubscriptionTools(server, clientProvider = getClient) {
388
582
  };
389
583
  });
390
584
  defineTool(server, "subscriptions_update", "Patch a subscription (url, filter, format, runtime, retry, timeout, concurrency).", {
391
- id: z3.string(),
392
- url: z3.string().optional(),
393
- filter: z3.record(z3.string(), z3.unknown()).optional(),
394
- format: z3.enum([
585
+ id: z8.string(),
586
+ url: z8.string().optional(),
587
+ filter: z8.record(z8.string(), z8.unknown()).optional(),
588
+ format: z8.enum([
395
589
  "standard-webhooks",
396
590
  "inngest",
397
591
  "trigger",
@@ -399,44 +593,44 @@ function registerSubscriptionTools(server, clientProvider = getClient) {
399
593
  "cloudevents",
400
594
  "raw"
401
595
  ]).optional(),
402
- runtime: z3.enum(["inngest", "trigger", "cloudflare", "node"]).nullable().optional(),
403
- maxRetries: z3.number().int().min(0).optional(),
404
- timeoutMs: z3.number().int().min(100).optional(),
405
- concurrency: z3.number().int().min(1).optional()
596
+ runtime: z8.enum(["inngest", "trigger", "cloudflare", "node"]).nullable().optional(),
597
+ maxRetries: z8.number().int().min(0).optional(),
598
+ timeoutMs: z8.number().int().min(100).optional(),
599
+ concurrency: z8.number().int().min(1).optional()
406
600
  }, async ({ id, ...patch }) => {
407
601
  const res = await clientProvider().subscriptions.update(id, patch);
408
602
  return {
409
603
  content: [{ type: "text", text: JSON.stringify(res, null, 2) }]
410
604
  };
411
605
  });
412
- defineTool(server, "subscriptions_pause", "Pause a subscription. Pending rows remain queued until resumed.", { id: z3.string() }, async ({ id }) => {
606
+ defineTool(server, "subscriptions_pause", "Pause a subscription. Pending rows remain queued until resumed.", { id: z8.string() }, async ({ id }) => {
413
607
  const res = await clientProvider().subscriptions.pause(id);
414
608
  return {
415
609
  content: [{ type: "text", text: JSON.stringify(res, null, 2) }]
416
610
  };
417
611
  });
418
- defineTool(server, "subscriptions_resume", "Resume a paused or circuit-open subscription and reset circuit failures.", { id: z3.string() }, async ({ id }) => {
612
+ defineTool(server, "subscriptions_resume", "Resume a paused or circuit-open subscription and reset circuit failures.", { id: z8.string() }, async ({ id }) => {
419
613
  const res = await clientProvider().subscriptions.resume(id);
420
614
  return {
421
615
  content: [{ type: "text", text: JSON.stringify(res, null, 2) }]
422
616
  };
423
617
  });
424
- defineTool(server, "subscriptions_delete", "Delete a subscription. Pending outbox rows are cascade-deleted.", { id: z3.string() }, async ({ id }) => {
618
+ defineTool(server, "subscriptions_delete", "Delete a subscription. Pending outbox rows are cascade-deleted.", { id: z8.string() }, async ({ id }) => {
425
619
  const res = await clientProvider().subscriptions.delete(id);
426
620
  return {
427
621
  content: [{ type: "text", text: JSON.stringify(res, null, 2) }]
428
622
  };
429
623
  });
430
- defineTool(server, "subscriptions_rotate_secret", "Rotate a subscription signing secret. Returns the new plaintext secret once.", { id: z3.string() }, async ({ id }) => {
624
+ defineTool(server, "subscriptions_rotate_secret", "Rotate a subscription signing secret. Returns the new plaintext secret once.", { id: z8.string() }, async ({ id }) => {
431
625
  const res = await clientProvider().subscriptions.rotateSecret(id);
432
626
  return {
433
627
  content: [{ type: "text", text: JSON.stringify(res, null, 2) }]
434
628
  };
435
629
  });
436
630
  defineTool(server, "subscriptions_replay", "Replay a block range for a subscription. Replays run at 10% of batch capacity — use sparingly.", {
437
- id: z3.string(),
438
- fromBlock: z3.number().int().nonnegative(),
439
- toBlock: z3.number().int().nonnegative()
631
+ id: z8.string(),
632
+ fromBlock: z8.number().int().nonnegative(),
633
+ toBlock: z8.number().int().nonnegative()
440
634
  }, async ({ id, fromBlock, toBlock }) => {
441
635
  const res = await clientProvider().subscriptions.replay(id, {
442
636
  fromBlock,
@@ -446,22 +640,22 @@ function registerSubscriptionTools(server, clientProvider = getClient) {
446
640
  content: [{ type: "text", text: JSON.stringify(res, null, 2) }]
447
641
  };
448
642
  });
449
- defineTool(server, "subscriptions_dead", "Return the last 100 dead-letter outbox rows for a subscription.", { id: z3.string() }, async ({ id }) => {
643
+ defineTool(server, "subscriptions_dead", "Return the last 100 dead-letter outbox rows for a subscription.", { id: z8.string() }, async ({ id }) => {
450
644
  const { data } = await clientProvider().subscriptions.dead(id);
451
645
  return {
452
646
  content: [{ type: "text", text: JSON.stringify(data, null, 2) }]
453
647
  };
454
648
  });
455
649
  defineTool(server, "subscriptions_requeue_dead", "Requeue one dead-letter outbox row for delivery retry.", {
456
- id: z3.string(),
457
- outboxId: z3.string()
650
+ id: z8.string(),
651
+ outboxId: z8.string()
458
652
  }, async ({ id, outboxId }) => {
459
653
  const res = await clientProvider().subscriptions.requeueDead(id, outboxId);
460
654
  return {
461
655
  content: [{ type: "text", text: JSON.stringify(res, null, 2) }]
462
656
  };
463
657
  });
464
- defineTool(server, "subscriptions_recent_deliveries", "Return the last 100 delivery attempts (attempt #, status code, duration, truncated response).", { id: z3.string() }, async ({ id }) => {
658
+ defineTool(server, "subscriptions_recent_deliveries", "Return the last 100 delivery attempts (attempt #, status code, duration, truncated response).", { id: z8.string() }, async ({ id }) => {
465
659
  const { data } = await clientProvider().subscriptions.recentDeliveries(id);
466
660
  return {
467
661
  content: [{ type: "text", text: JSON.stringify(data, null, 2) }]
@@ -481,6 +675,10 @@ function createServer() {
481
675
  registerSubgraphTools(server);
482
676
  registerSubscriptionTools(server);
483
677
  registerAccountTools(server);
678
+ registerDatasetTools(server);
679
+ registerIndexTools(server);
680
+ registerStreamsTools(server);
681
+ registerContractTools(server);
484
682
  registerResources(server);
485
683
  return server;
486
684
  }
@@ -571,5 +769,5 @@ httpServer.listen(port, () => {
571
769
  console.error("Warning: SECONDLAYER_MCP_SECRET not set, authentication disabled");
572
770
  });
573
771
 
574
- //# debugId=37A599FB33524CF364756E2164756E21
772
+ //# debugId=D41ACEAFF3E3A4CC64756E2164756E21
575
773
  //# sourceMappingURL=bin-http.js.map