@secondlayer/mcp 3.8.0 → 3.10.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.js CHANGED
@@ -15,21 +15,49 @@ import { TRAIT_STANDARDS } from "@secondlayer/stacks/clarity";
15
15
  import { TYPE_MAP } from "@secondlayer/subgraphs/schema";
16
16
 
17
17
  // src/lib/client.ts
18
- import { SecondLayer } from "@secondlayer/sdk";
18
+ import { SecondLayer, readX402Receipt, withX402 } from "@secondlayer/sdk";
19
+ import { privateKeyToAccount } from "@secondlayer/stacks/accounts";
19
20
  var instance = null;
20
21
  function readApiKey() {
21
22
  return process.env.SL_API_KEY;
22
23
  }
24
+ function buildFetchImpl() {
25
+ const key = process.env.X402_PRIVATE_KEY;
26
+ if (!key)
27
+ return;
28
+ const account = privateKeyToAccount(key);
29
+ const topUpUsd = Number(process.env.X402_TOPUP_USD ?? "");
30
+ const paid = withX402(fetch, {
31
+ account,
32
+ ...Number.isFinite(topUpUsd) && topUpUsd > 0 ? {
33
+ topUp: {
34
+ usd: topUpUsd,
35
+ whenBelow: Number(process.env.X402_TOPUP_WHEN_BELOW ?? "0.5")
36
+ }
37
+ } : {}
38
+ });
39
+ const wrapped = async (input, init) => {
40
+ const res = await paid(input, init);
41
+ const receipt = readX402Receipt(res);
42
+ if (receipt) {
43
+ console.error(`[x402] paid call settled tier=${receipt.state ?? "confirmed"} txid=${receipt.txid}`);
44
+ }
45
+ return res;
46
+ };
47
+ return wrapped;
48
+ }
23
49
  function getClient() {
24
50
  if (!instance) {
25
51
  const apiKey = readApiKey();
26
52
  const baseUrl = process.env.SECONDLAYER_API_URL;
27
53
  const dumpsBaseUrl = process.env.SL_STREAMS_DUMPS_URL;
54
+ const fetchImpl = buildFetchImpl();
28
55
  instance = new SecondLayer({
29
56
  ...apiKey ? { apiKey } : {},
30
57
  origin: "mcp",
31
58
  ...baseUrl ? { baseUrl } : {},
32
- ...dumpsBaseUrl ? { dumpsBaseUrl } : {}
59
+ ...dumpsBaseUrl ? { dumpsBaseUrl } : {},
60
+ ...fetchImpl ? { fetchImpl } : {}
33
61
  });
34
62
  }
35
63
  return instance;
@@ -58,11 +86,14 @@ async function apiRequest(method, path, body) {
58
86
 
59
87
  // src/lib/format.ts
60
88
  function formatSubgraphSummary(s) {
89
+ const apiUrl = process.env.SECONDLAYER_API_URL || "https://api.secondlayer.tools";
61
90
  return {
62
91
  name: s.name,
63
92
  status: s.status,
64
93
  tables: Array.isArray(s.tables) ? s.tables : Object.keys(s.tables),
65
- lastProcessedBlock: s.lastProcessedBlock
94
+ lastProcessedBlock: s.lastProcessedBlock,
95
+ ...s.visibility ? { visibility: s.visibility } : {},
96
+ ...s.visibility === "public" ? { publicUrl: `${apiUrl}/v1/subgraphs/${s.name}` } : {}
66
97
  };
67
98
  }
68
99
  function withCap(items, cap) {
@@ -167,7 +198,6 @@ var COLUMN_TYPES = [
167
198
  }
168
199
  ];
169
200
  var PRODUCT_BLURBS = {
170
- datasets: "public foundation datasets",
171
201
  index: "decoded L2 events, contract calls, blocks, transactions, stacking, mempool",
172
202
  streams: "raw canonical chain event firehose",
173
203
  contracts: "trait-based contract discovery",
@@ -178,7 +208,6 @@ var PRODUCT_BLURBS = {
178
208
  scaffold: "generate typed contract clients from a deployment or ABI"
179
209
  };
180
210
  var PRODUCT_ORDER = [
181
- "datasets",
182
211
  "index",
183
212
  "streams",
184
213
  "contracts",
@@ -207,21 +236,30 @@ function buildCapabilities() {
207
236
  });
208
237
  return {
209
238
  products,
210
- discoverFirst: "Call datasets_list / index_discover / contracts_find to learn what exists (and which filters each surface accepts) before querying."
239
+ discoverFirst: "Call index_discover / contracts_find to learn what exists (and which filters each surface accepts) before querying."
211
240
  };
212
241
  }
242
+ var X402_CAPABILITY = {
243
+ what: "Index and Streams reads (/v1/index/*, /v1/streams/*) accept x402 v2 pay-per-call (network stacks:1, sponsored transfers — the payer holds sBTC/STX/USDCx, never gas). Index grants 1,000 free reads/day/IP before any 402; a paid Streams call opens a 500-call/1h PAYMENT-SESSION.",
244
+ paidWrites: "POST /v1/subgraphs (x402 $2) deploys a subgraph owned by the paying wallet — live from deploy, 7-day TTL, renewable via POST /v1/subgraphs/{name}/renew ($0.50/wk); claiming the account clears the expiry.",
245
+ prepaid: "POST /v1/x402/deposit?usd=N loads a prepaid tab (PAYMENT-BALANCE token, $0.25 min) — calls debit it instantly, no per-call on-chain settle. GET /v1/x402/balance reads it.",
246
+ discovery: "GET /v1/x402/supported on the API host for scheme, assets, prices, quotas, sessions, and prepaid metadata.",
247
+ autopay: "Set X402_PRIVATE_KEY (a Stacks private key holding an accepted token) and this MCP server pays 402 challenges automatically (sessions replayed). Add X402_TOPUP_USD (and optionally X402_TOPUP_WHEN_BELOW) for an autonomous prepaid tab that refills itself. Receipts are logged per paid call."
248
+ };
213
249
  var READ_AUTH_TIERS = {
214
- datasets: "open — no API key required",
215
250
  index: "anonymous reads allowed; free-tier API keys are rejected (Build+ required)",
216
251
  streams: "API key required (SL_API_KEY) — keyless calls return 401",
217
- subgraphs: "reads public during open beta; writes require an API key"
252
+ subgraphs: "public subgraphs anon-readable at /v1/subgraphs/<name>/<table> ({ rows, next_cursor, tip } cursor envelope); private subgraphs need the owning account's API key (anon → 404); writes require an API key"
218
253
  };
219
254
  async function buildContext(deps = { clientProvider: getClient }) {
220
255
  const unavailable = "unavailable: set SL_API_KEY";
221
256
  const orNull = (v) => v == null ? unavailable : v;
222
257
  const snap = await deps.clientProvider().context().catch(() => null);
223
258
  return {
224
- authState: { apiKeySet: Boolean(process.env.SL_API_KEY) },
259
+ authState: {
260
+ apiKeySet: Boolean(process.env.SL_API_KEY),
261
+ x402WalletSet: Boolean(process.env.X402_PRIVATE_KEY)
262
+ },
225
263
  whatExists: {
226
264
  account: orNull(snap?.account),
227
265
  streamsTip: orNull(snap?.streamsTip),
@@ -233,7 +271,8 @@ async function buildContext(deps = { clientProvider: getClient }) {
233
271
  activeOperations: orNull(snap?.activeOperations)
234
272
  },
235
273
  whatYouCanDo: buildCapabilities(),
236
- readAuthTiers: READ_AUTH_TIERS
274
+ readAuthTiers: READ_AUTH_TIERS,
275
+ payPerCall: X402_CAPABILITY
237
276
  };
238
277
  }
239
278
  function registerResources(server) {
@@ -421,43 +460,20 @@ function registerContractTools(server, clientProvider = getClient) {
421
460
  });
422
461
  }
423
462
 
424
- // src/tools/datasets.ts
425
- import { z as z3 } from "zod/v4";
426
- function registerDatasetTools(server, clientProvider = getClient) {
427
- 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 () => {
428
- const catalog = await clientProvider().datasets.listDatasets();
429
- return jsonResponse(catalog);
430
- });
431
- defineTool(server, "datasets_query", 'Query ANY Foundation Dataset by slug — every family returned by datasets_list is queryable, including bespoke ones (bns/resolve with {"fqn":"alice.btc"}, bns/names, bns/namespaces, network-health/summary) and any dataset added later. Accepts family ("sbtc-events") or path ("sbtc/events") slug forms. Filters are passed through as documented query params (e.g. {"sender": "SP...", "from_block": "150000"}). Returns { rows, next_cursor, tip }; single-record datasets like bns/resolve return 0-or-1 rows (empty = not found). Call datasets_list first to discover slugs and their filters.', {
432
- slug: z3.string().describe("Dataset slug from datasets_list (e.g. stx-transfers)"),
433
- filters: z3.record(z3.string(), z3.string()).optional().describe("Documented per-dataset query params (snake_case values)"),
434
- limit: z3.number().optional().describe("Max rows for this page"),
435
- cursor: z3.string().optional().describe("Opaque cursor from a prior response's next_cursor")
436
- }, async ({ slug, filters, limit, cursor }) => {
437
- const params = { ...filters ?? {} };
438
- if (limit !== undefined)
439
- params.limit = limit;
440
- if (cursor !== undefined)
441
- params.cursor = cursor;
442
- const result = await clientProvider().datasets.get(slug, params);
443
- return jsonResponse(result);
444
- });
445
- }
446
-
447
463
  // src/tools/index.ts
448
464
  import { DECODED_EVENT_TYPES as DECODED_EVENT_TYPES2 } from "@secondlayer/shared";
449
465
  import {
450
466
  INDEX_CODEGEN_TABLES,
451
467
  generateIndexSchema
452
468
  } from "@secondlayer/subgraphs";
453
- import { z as z4 } from "zod/v4";
469
+ import { z as z3 } from "zod/v4";
454
470
  var INDEX_EVENT_TYPES = DECODED_EVENT_TYPES2;
455
471
  var rangeFilters = {
456
- contractId: z4.string().optional().describe("Filter by contract id"),
457
- fromHeight: z4.number().optional().describe("Start block height (inclusive)"),
458
- toHeight: z4.number().optional().describe("End block height (inclusive)"),
459
- cursor: z4.string().optional().describe("Opaque cursor from a prior response's next_cursor"),
460
- limit: z4.number().optional().describe("Max rows for this page")
472
+ contractId: z3.string().optional().describe("Filter by contract id"),
473
+ fromHeight: z3.number().optional().describe("Start block height (inclusive)"),
474
+ toHeight: z3.number().optional().describe("End block height (inclusive)"),
475
+ cursor: z3.string().optional().describe("Opaque cursor from a prior response's next_cursor"),
476
+ limit: z3.number().optional().describe("Max rows for this page")
461
477
  };
462
478
  var heightFilters = {
463
479
  fromHeight: rangeFilters.fromHeight,
@@ -469,89 +485,95 @@ var notFound = (message) => jsonResponse({ error: { type: "not_found", status: 4
469
485
  function registerIndexTools(server, clientProvider = getClient) {
470
486
  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).", {
471
487
  ...rangeFilters,
472
- sender: z4.string().optional().describe("Filter by sender principal"),
473
- recipient: z4.string().optional().describe("Filter by recipient principal")
488
+ sender: z3.string().optional().describe("Filter by sender principal"),
489
+ recipient: z3.string().optional().describe("Filter by recipient principal")
474
490
  }, async (params) => jsonResponse(await clientProvider().index.ftTransfers.list(params)));
475
491
  defineTool(server, "index_nft_transfers", "List decoded SIP-009 non-fungible-token transfers from the Index. Anonymous reads allowed (free-tier keys rejected).", {
476
492
  ...rangeFilters,
477
- sender: z4.string().optional().describe("Filter by sender principal"),
478
- recipient: z4.string().optional().describe("Filter by recipient principal"),
479
- assetIdentifier: z4.string().optional().describe("Filter by asset identifier (contract::asset)")
493
+ sender: z3.string().optional().describe("Filter by sender principal"),
494
+ recipient: z3.string().optional().describe("Filter by recipient principal"),
495
+ assetIdentifier: z3.string().optional().describe("Filter by asset identifier (contract::asset)")
480
496
  }, async (params) => jsonResponse(await clientProvider().index.nftTransfers.list(params)));
481
497
  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), and for trait-scoped queries: set `trait` (e.g. sip-010) to match all contracts conforming to a standard — pair with contracts_find to discover traits. For ft/nft transfers without a trait prefer index_ft_transfers / index_nft_transfers.", {
482
- eventType: z4.enum(INDEX_EVENT_TYPES).describe("Required. Decoded event type to list."),
498
+ eventType: z3.enum(INDEX_EVENT_TYPES).describe("Required. Decoded event type to list."),
483
499
  ...rangeFilters,
484
- sender: z4.string().optional().describe("Filter by sender principal"),
485
- recipient: z4.string().optional().describe("Filter by recipient principal"),
486
- assetIdentifier: z4.string().optional().describe("Filter by asset identifier where applicable"),
487
- trait: z4.string().optional().describe("Match contracts conforming to a trait/standard (e.g. sip-010). Mutually exclusive with contractId; contract-keyed event types only.")
500
+ sender: z3.string().optional().describe("Filter by sender principal"),
501
+ recipient: z3.string().optional().describe("Filter by recipient principal"),
502
+ assetIdentifier: z3.string().optional().describe("Filter by asset identifier where applicable"),
503
+ trait: z3.string().optional().describe("Match contracts conforming to a trait/standard (e.g. sip-010). Mutually exclusive with contractId; contract-keyed event types only.")
488
504
  }, async (params) => jsonResponse(await clientProvider().index.events.list(params)));
489
505
  defineTool(server, "index_contract_calls", "List decoded contract calls from the Index (function name, args, result). Set `trait` (e.g. sip-010) to match calls to all contracts conforming to a standard. Note: contract-call cursors are a SEPARATE keyspace from event cursors — they are not interchangeable.", {
490
506
  ...rangeFilters,
491
- functionName: z4.string().optional().describe("Filter by called function name"),
492
- sender: z4.string().optional().describe("Filter by caller principal"),
493
- trait: z4.string().optional().describe("Match contracts conforming to a trait/standard (e.g. sip-010). Mutually exclusive with contractId.")
507
+ functionName: z3.string().optional().describe("Filter by called function name"),
508
+ sender: z3.string().optional().describe("Filter by caller principal"),
509
+ trait: z3.string().optional().describe("Match contracts conforming to a trait/standard (e.g. sip-010). Mutually exclusive with contractId.")
494
510
  }, async (params) => jsonResponse(await clientProvider().index.contractCalls.list(params)));
495
511
  defineTool(server, "index_canonical", "List the canonical Stacks block sequence from the Index (height + hash). Anonymous reads allowed (free-tier keys rejected).", { ...heightFilters }, async (params) => jsonResponse(await clientProvider().index.canonical.list(params)));
496
512
  defineTool(server, "index_blocks", "List decoded blocks from the Index. Anonymous reads allowed (free-tier keys rejected).", { ...heightFilters }, async (params) => jsonResponse(await clientProvider().index.blocks.list(params)));
497
513
  defineTool(server, "index_block", "Get a single block from the Index by height or block hash. Returns not_found if unknown.", {
498
- ref: z4.string().describe("Block height (digits) or block hash (0x… string)")
514
+ ref: z3.string().describe("Block height (digits) or block hash (0x… string)")
499
515
  }, async ({ ref }) => {
500
516
  const block = await clientProvider().index.blocks.get(/^\d+$/.test(ref) ? Number(ref) : ref);
501
517
  return block ? jsonResponse(block) : notFound(`No block for ref ${ref}`);
502
518
  });
503
519
  defineTool(server, "index_transactions", "List decoded transactions from the Index. Filter by type, sender, or contract. Anonymous reads allowed (free-tier keys rejected).", {
504
520
  ...rangeFilters,
505
- type: z4.string().optional().describe("Filter by transaction type"),
506
- sender: z4.string().optional().describe("Filter by sender principal")
521
+ type: z3.string().optional().describe("Filter by transaction type"),
522
+ sender: z3.string().optional().describe("Filter by sender principal")
507
523
  }, async (params) => jsonResponse(await clientProvider().index.transactions.list(params)));
508
- defineTool(server, "index_transaction", "Get a single transaction from the Index by tx_id. Returns not_found if unknown.", { txId: z4.string().describe("Transaction id (0x… hash)") }, async ({ txId }) => {
524
+ defineTool(server, "index_transaction", "Get a single transaction from the Index by tx_id. Returns not_found if unknown.", { txId: z3.string().describe("Transaction id (0x… hash)") }, async ({ txId }) => {
509
525
  const tx = await clientProvider().index.transactions.get(txId);
510
526
  return tx ? jsonResponse(tx) : notFound(`No transaction for ${txId}`);
511
527
  });
512
- defineTool(server, "index_transaction_proof", "Fetch a transaction's inclusion proof (raw tx + signed Nakamoto block header + merkle path) so it can be verified trustlessly client-side with the SDK's verifyTransactionProof. Returns not_found if the tx/block is unknown; a 503 means the proof can't be assembled on this deployment right now (PROOF_TX_SET_INCOMPLETE, or PROOF_NODE_UNAVAILABLE when the stacks-node header source isn't configured).", { txId: z4.string().describe("Transaction id (0x… hash)") }, async ({ txId }) => {
528
+ defineTool(server, "index_transaction_proof", "Fetch a transaction's inclusion proof (raw tx + signed Nakamoto block header + merkle path) so it can be verified trustlessly client-side with the SDK's verifyTransactionProof. Returns not_found if the tx/block is unknown; a 503 means the proof can't be assembled on this deployment right now (PROOF_TX_SET_INCOMPLETE, or PROOF_NODE_UNAVAILABLE when the stacks-node header source isn't configured).", { txId: z3.string().describe("Transaction id (0x… hash)") }, async ({ txId }) => {
513
529
  const proof = await clientProvider().index.transactions.getProof(txId);
514
530
  return proof ? jsonResponse(proof) : notFound(`No proof available for ${txId}`);
515
531
  });
516
532
  defineTool(server, "index_stacking", "List decoded PoX-4 stacking actions from the Index (stack-stx, delegate-stx, etc.). Anonymous reads allowed (free-tier keys rejected).", {
517
533
  ...heightFilters,
518
- functionName: z4.string().optional().describe("Filter by PoX function name"),
519
- stacker: z4.string().optional().describe("Filter by stacker principal"),
520
- caller: z4.string().optional().describe("Filter by caller principal")
534
+ functionName: z3.string().optional().describe("Filter by PoX function name"),
535
+ stacker: z3.string().optional().describe("Filter by stacker principal"),
536
+ caller: z3.string().optional().describe("Filter by caller principal")
521
537
  }, async (params) => jsonResponse(await clientProvider().index.stacking.list(params)));
522
538
  defineTool(server, "index_mempool", "List pending (unconfirmed) transactions from the Index mempool. Sequence-cursor paginated (no height range). Anonymous reads allowed (free-tier keys rejected).", {
523
- sender: z4.string().optional().describe("Filter by sender principal"),
524
- type: z4.string().optional().describe("Filter by transaction type"),
525
- contractId: z4.string().optional().describe("Filter to pending calls to a single contract"),
526
- cursor: z4.string().optional().describe("Opaque cursor from a prior response's next_cursor"),
527
- limit: z4.number().optional().describe("Max rows for this page")
539
+ sender: z3.string().optional().describe("Filter by sender principal"),
540
+ type: z3.string().optional().describe("Filter by transaction type"),
541
+ contractId: z3.string().optional().describe("Filter to pending calls to a single contract"),
542
+ cursor: z3.string().optional().describe("Opaque cursor from a prior response's next_cursor"),
543
+ limit: z3.number().optional().describe("Max rows for this page")
528
544
  }, async (params) => jsonResponse(await clientProvider().index.mempool.list(params)));
529
- defineTool(server, "index_mempool_tx", "Get a single pending transaction from the Index mempool by tx_id. Returns not_found once it is mined or dropped.", { txId: z4.string().describe("Transaction id (0x… hash)") }, async ({ txId }) => {
545
+ defineTool(server, "index_mempool_tx", "Get a single pending transaction from the Index mempool by tx_id. Returns not_found once it is mined or dropped.", { txId: z3.string().describe("Transaction id (0x… hash)") }, async ({ txId }) => {
530
546
  const tx = await clientProvider().index.mempool.get(txId);
531
547
  return tx ? jsonResponse(tx) : notFound(`No pending tx for ${txId}`);
532
548
  });
533
549
  defineTool(server, "index_discover", "Discover the Index vocabulary: every event type and its columns, allowed/equality filters, and required-non-null fields (and which types accept `trait`). Read this before building Index queries instead of guessing filters. Anonymous read.", {}, async () => jsonResponse(await clientProvider().index.discover()));
534
550
  defineTool(server, "index_usage", "Your own Index consumption (decoded events today + this month) and tier limits. Requires a Build+ API key (anonymous reads can't report usage).", {}, async () => jsonResponse(await clientProvider().index.usage()));
535
551
  defineTool(server, "index_codegen", `Generate a typed schema (Prisma, Kysely, Drizzle, or JSON-Schema) for the public Index domain tables so they can be mirrored into a BYO database with full types. Returns the schema as text. Tables: ${INDEX_CODEGEN_TABLES.join(", ")}.`, {
536
- target: z4.enum(["prisma", "kysely", "drizzle", "json-schema"]).optional().describe("Output target (default kysely)"),
537
- tables: z4.array(z4.string()).optional().describe("Subset of Index tables (default: all)"),
538
- schemaName: z4.string().optional().describe("Postgres schema to qualify table names with")
552
+ target: z3.enum(["prisma", "kysely", "drizzle", "json-schema"]).optional().describe("Output target (default kysely)"),
553
+ tables: z3.array(z3.string()).optional().describe("Subset of Index tables (default: all)"),
554
+ schemaName: z3.string().optional().describe("Postgres schema to qualify table names with")
539
555
  }, async ({ target = "kysely", tables, schemaName }) => {
540
556
  const out = generateIndexSchema(target, { tables, schemaName });
541
557
  return { content: [{ type: "text", text: out }] };
542
558
  });
559
+ defineTool(server, "batch_query", "Run up to 10 public /v1 reads in one round trip (POST /v1/batch). Each item keeps its own auth/quota/pay-per-call semantics; results return in order with per-item status. Paths must start with /v1/index, /v1/subgraphs, /v1/streams, or /v1/contracts.", {
560
+ requests: z3.array(z3.object({
561
+ path: z3.string().describe("Public /v1 read path"),
562
+ params: z3.record(z3.string(), z3.string()).optional()
563
+ })).min(1).max(10).describe("Read descriptors, executed concurrently")
564
+ }, async (params) => jsonResponse(await clientProvider().batch(params.requests)));
543
565
  }
544
566
 
545
567
  // src/tools/projects.ts
546
- import { z as z5 } from "zod/v4";
568
+ import { z as z4 } from "zod/v4";
547
569
  function registerProjectTools(server, clientProvider = getClient) {
548
570
  defineTool(server, "project_list", "List the account's projects. Requires an account-level (owner) API key.", {}, async () => jsonResponse(await clientProvider().projects.list()));
549
- defineTool(server, "project_get", "Get a single project by slug.", { slug: z5.string().describe("Project slug") }, async ({ slug }) => jsonResponse(await clientProvider().projects.get(slug)));
571
+ defineTool(server, "project_get", "Get a single project by slug.", { slug: z4.string().describe("Project slug") }, async ({ slug }) => jsonResponse(await clientProvider().projects.get(slug)));
550
572
  defineTool(server, "project_create", "Create a project. The slug is derived from the name when omitted. Requires an account-level (owner) API key.", {
551
- name: z5.string().describe("Project name"),
552
- slug: z5.string().optional().describe("URL slug (auto-derived from name if omitted)"),
553
- network: z5.string().optional().describe("Network (e.g. mainnet, testnet)"),
554
- nodeRpc: z5.string().optional().describe("Custom node RPC URL")
573
+ name: z4.string().describe("Project name"),
574
+ slug: z4.string().optional().describe("URL slug (auto-derived from name if omitted)"),
575
+ network: z4.string().optional().describe("Network (e.g. mainnet, testnet)"),
576
+ nodeRpc: z4.string().optional().describe("Custom node RPC URL")
555
577
  }, async ({ name, slug, network, nodeRpc }) => jsonResponse(await clientProvider().projects.create({
556
578
  name,
557
579
  slug,
@@ -559,12 +581,12 @@ function registerProjectTools(server, clientProvider = getClient) {
559
581
  nodeRpc
560
582
  })));
561
583
  defineTool(server, "project_update", "Update a project. `slug` selects the project; `newSlug` renames it. Requires an account-level (owner) API key.", {
562
- slug: z5.string().describe("Slug of the project to update"),
563
- newSlug: z5.string().optional().describe("New slug (renames the project)"),
564
- name: z5.string().optional().describe("New display name"),
565
- network: z5.string().optional().describe("Network (e.g. mainnet, testnet)"),
566
- nodeRpc: z5.string().optional().describe("Custom node RPC URL"),
567
- settings: z5.record(z5.string(), z5.unknown()).optional().describe("Arbitrary project settings to merge")
584
+ slug: z4.string().describe("Slug of the project to update"),
585
+ newSlug: z4.string().optional().describe("New slug (renames the project)"),
586
+ name: z4.string().optional().describe("New display name"),
587
+ network: z4.string().optional().describe("Network (e.g. mainnet, testnet)"),
588
+ nodeRpc: z4.string().optional().describe("Custom node RPC URL"),
589
+ settings: z4.record(z4.string(), z4.unknown()).optional().describe("Arbitrary project settings to merge")
568
590
  }, async ({ slug, newSlug, name, network, nodeRpc, settings }) => jsonResponse(await clientProvider().projects.update(slug, {
569
591
  ...newSlug !== undefined ? { slug: newSlug } : {},
570
592
  ...name !== undefined ? { name } : {},
@@ -572,8 +594,8 @@ function registerProjectTools(server, clientProvider = getClient) {
572
594
  ...nodeRpc !== undefined ? { nodeRpc } : {},
573
595
  ...settings !== undefined ? { settings } : {}
574
596
  })));
575
- defineTool(server, "project_delete", "Delete a project permanently. The account's last remaining project cannot be deleted.", { slug: z5.string().describe("Project slug") }, async ({ slug }) => jsonResponse(await clientProvider().projects.delete(slug)));
576
- defineTool(server, "project_team_list", "List a project's team members and pending invitations.", { slug: z5.string().describe("Project slug") }, async ({ slug }) => jsonResponse(await clientProvider().projects.team(slug)));
597
+ defineTool(server, "project_delete", "Delete a project permanently. The account's last remaining project cannot be deleted.", { slug: z4.string().describe("Project slug") }, async ({ slug }) => jsonResponse(await clientProvider().projects.delete(slug)));
598
+ defineTool(server, "project_team_list", "List a project's team members and pending invitations.", { slug: z4.string().describe("Project slug") }, async ({ slug }) => jsonResponse(await clientProvider().projects.team(slug)));
577
599
  }
578
600
 
579
601
  // src/tools/scaffold.ts
@@ -582,7 +604,7 @@ import {
582
604
  generateTraitSubgraph
583
605
  } from "@secondlayer/scaffold";
584
606
  import { TRAIT_STANDARDS as TRAIT_STANDARDS2 } from "@secondlayer/stacks/clarity";
585
- import { z as z6 } from "zod/v4";
607
+ import { z as z5 } from "zod/v4";
586
608
  async function fetchAbi(contractId) {
587
609
  const contract = await getClient().contracts.get(contractId, {
588
610
  includeAbi: true
@@ -597,24 +619,24 @@ async function fetchAbi(contractId) {
597
619
  }
598
620
  function registerScaffoldTools(server) {
599
621
  defineTool(server, "scaffold_from_trait", "Generate a deploy-ready subgraph scaffold that indexes EVERY contract conforming to a SIP trait (no specific contract needed) — sip-009 → an nft_transfer source, sip-010/sip-013 → ft_transfer. Use scaffold_from_contract/abi instead when targeting one contract. See the secondlayer://traits resource for valid trait ids.", {
600
- trait: z6.enum(TRAIT_STANDARDS2).describe("SIP standard to index (sip-009 | sip-010 | sip-013)"),
601
- subgraphName: z6.string().optional().describe("Override the subgraph name (defaults to <trait>-transfers)")
622
+ trait: z5.enum(TRAIT_STANDARDS2).describe("SIP standard to index (sip-009 | sip-010 | sip-013)"),
623
+ subgraphName: z5.string().optional().describe("Override the subgraph name (defaults to <trait>-transfers)")
602
624
  }, async ({ trait, subgraphName }) => {
603
625
  const code = generateTraitSubgraph({ trait, name: subgraphName });
604
626
  return { content: [{ type: "text", text: code }] };
605
627
  });
606
628
  defineTool(server, "scaffold_from_contract", "Generate a subgraph scaffold from a deployed Stacks contract. Fetches the ABI automatically.", {
607
- contractId: z6.string().describe("Fully qualified contract ID (e.g. SP102V8P0F7JX67ARQ77WEA3D3CFB5XW39REDT0AM.amm-pool-v2-01)"),
608
- subgraphName: z6.string().optional().describe("Override the subgraph name (defaults to contract name)")
629
+ contractId: z5.string().describe("Fully qualified contract ID (e.g. SP102V8P0F7JX67ARQ77WEA3D3CFB5XW39REDT0AM.amm-pool-v2-01)"),
630
+ subgraphName: z5.string().optional().describe("Override the subgraph name (defaults to contract name)")
609
631
  }, async ({ contractId, subgraphName }) => {
610
632
  const { functions, maps } = await fetchAbi(contractId);
611
633
  const code = generateSubgraphCode(contractId, functions, subgraphName, maps);
612
634
  return { content: [{ type: "text", text: code }] };
613
635
  });
614
636
  defineTool(server, "scaffold_from_abi", "Generate a subgraph scaffold from a provided ABI JSON. Use when you already have the ABI.", {
615
- abi: z6.string().describe("ABI JSON string (the full contract ABI object)"),
616
- contractId: z6.string().describe("Fully qualified contract ID"),
617
- subgraphName: z6.string().optional().describe("Override the subgraph name")
637
+ abi: z5.string().describe("ABI JSON string (the full contract ABI object)"),
638
+ contractId: z5.string().describe("Fully qualified contract ID"),
639
+ subgraphName: z5.string().optional().describe("Override the subgraph name")
618
640
  }, async ({ abi, contractId, subgraphName }) => {
619
641
  let parsed;
620
642
  try {
@@ -633,7 +655,7 @@ function registerScaffoldTools(server) {
633
655
  // src/tools/streams.ts
634
656
  import { AuthError } from "@secondlayer/sdk";
635
657
  import { DECODED_EVENT_TYPES as DECODED_EVENT_TYPES3 } from "@secondlayer/shared";
636
- import { z as z7 } from "zod/v4";
658
+ import { z as z6 } from "zod/v4";
637
659
  var STREAMS_EVENT_TYPES = DECODED_EVENT_TYPES3;
638
660
  async function withStreamsAuthHint(fn) {
639
661
  try {
@@ -648,28 +670,28 @@ async function withStreamsAuthHint(fn) {
648
670
  function registerStreamsTools(server, clientProvider = getClient) {
649
671
  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())));
650
672
  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.", {
651
- types: z7.array(z7.enum(STREAMS_EVENT_TYPES)).optional().describe("Event types to include"),
652
- notTypes: z7.array(z7.enum(STREAMS_EVENT_TYPES)).optional().describe("Event types to exclude (applied after types)"),
653
- contractId: z7.string().optional().describe("Filter by contract id"),
654
- sender: z7.string().optional().describe("Filter by sender principal"),
655
- recipient: z7.string().optional().describe("Filter by recipient principal"),
656
- assetIdentifier: z7.string().optional().describe("Filter by asset identifier"),
657
- fromHeight: z7.number().optional().describe("Start block height (inclusive)"),
658
- toHeight: z7.number().optional().describe("End block height (inclusive)"),
659
- cursor: z7.string().optional().describe("Opaque cursor from a prior response"),
660
- limit: z7.number().optional().describe("Max events for this page")
673
+ types: z6.array(z6.enum(STREAMS_EVENT_TYPES)).optional().describe("Event types to include"),
674
+ notTypes: z6.array(z6.enum(STREAMS_EVENT_TYPES)).optional().describe("Event types to exclude (applied after types)"),
675
+ contractId: z6.string().optional().describe("Filter by contract id"),
676
+ sender: z6.string().optional().describe("Filter by sender principal"),
677
+ recipient: z6.string().optional().describe("Filter by recipient principal"),
678
+ assetIdentifier: z6.string().optional().describe("Filter by asset identifier"),
679
+ fromHeight: z6.number().optional().describe("Start block height (inclusive)"),
680
+ toHeight: z6.number().optional().describe("End block height (inclusive)"),
681
+ cursor: z6.string().optional().describe("Opaque cursor from a prior response"),
682
+ limit: z6.number().optional().describe("Max events for this page")
661
683
  }, async (params) => withStreamsAuthHint(async () => jsonResponse(await clientProvider().streams.events.list(params))));
662
684
  defineTool(server, "streams_consume", "Consume a bounded, reorg-aware run of Streams events from a cursor. Walks up to maxPages pages and returns the events, any reorgs observed, and a resume `cursor` to pass back as fromCursor next call — the agent-native consume/resume primitive. Streams requires an API key (SL_API_KEY).", {
663
- fromCursor: z7.string().optional().describe("Resume cursor from a prior consume (omit to start at genesis)"),
664
- types: z7.array(z7.enum(STREAMS_EVENT_TYPES)).optional().describe("Event types to include"),
665
- notTypes: z7.array(z7.enum(STREAMS_EVENT_TYPES)).optional().describe("Event types to exclude"),
666
- contractId: z7.string().optional().describe("Filter by contract id"),
667
- sender: z7.string().optional().describe("Filter by sender principal"),
668
- recipient: z7.string().optional().describe("Filter by recipient principal"),
669
- assetIdentifier: z7.string().optional().describe("Filter by asset identifier"),
670
- batchSize: z7.number().optional().describe("Events per page (1–1000, default 100)"),
671
- maxPages: z7.number().optional().describe("Max pages to walk this call (1–20, default 5)"),
672
- finalizedOnly: z7.boolean().optional().describe("Only emit finalized events; skip reorg handling")
685
+ fromCursor: z6.string().optional().describe("Resume cursor from a prior consume (omit to start at genesis)"),
686
+ types: z6.array(z6.enum(STREAMS_EVENT_TYPES)).optional().describe("Event types to include"),
687
+ notTypes: z6.array(z6.enum(STREAMS_EVENT_TYPES)).optional().describe("Event types to exclude"),
688
+ contractId: z6.string().optional().describe("Filter by contract id"),
689
+ sender: z6.string().optional().describe("Filter by sender principal"),
690
+ recipient: z6.string().optional().describe("Filter by recipient principal"),
691
+ assetIdentifier: z6.string().optional().describe("Filter by asset identifier"),
692
+ batchSize: z6.number().optional().describe("Events per page (1–1000, default 100)"),
693
+ maxPages: z6.number().optional().describe("Max pages to walk this call (1–20, default 5)"),
694
+ finalizedOnly: z6.boolean().optional().describe("Only emit finalized events; skip reorg handling")
673
695
  }, async (params) => withStreamsAuthHint(async () => {
674
696
  const maxPages = Math.min(Math.max(params.maxPages ?? 5, 1), 20);
675
697
  const batchSize = Math.min(Math.max(params.batchSize ?? 100, 1), 1000);
@@ -701,15 +723,15 @@ function registerStreamsTools(server, clientProvider = getClient) {
701
723
  pages: result.pages
702
724
  });
703
725
  }));
704
- defineTool(server, "streams_event_by_txid", "List all Streams events emitted by a single transaction. Streams requires an API key (SL_API_KEY).", { txId: z7.string().describe("Transaction id (0x… hash)") }, async ({ txId }) => withStreamsAuthHint(async () => jsonResponse(await clientProvider().streams.events.byTxId(txId))));
726
+ defineTool(server, "streams_event_by_txid", "List all Streams events emitted by a single transaction. Streams requires an API key (SL_API_KEY).", { txId: z6.string().describe("Transaction id (0x… hash)") }, async ({ txId }) => withStreamsAuthHint(async () => jsonResponse(await clientProvider().streams.events.byTxId(txId))));
705
727
  defineTool(server, "streams_block_events", "List all Streams events in a single block, by height or block hash. Streams requires an API key (SL_API_KEY).", {
706
- heightOrHash: z7.string().describe("Block height (digits) or block hash (0x… string)")
728
+ heightOrHash: z6.string().describe("Block height (digits) or block hash (0x… string)")
707
729
  }, async ({ heightOrHash }) => withStreamsAuthHint(async () => jsonResponse(await clientProvider().streams.blocks.events(/^\d+$/.test(heightOrHash) ? Number(heightOrHash) : heightOrHash))));
708
730
  defineTool(server, "streams_reorgs", "List chain reorgs observed by Streams since a cursor. Streams requires an API key (SL_API_KEY).", {
709
- since: z7.string().describe("Cursor to list reorgs since (block:index or ISO timestamp)"),
710
- limit: z7.number().optional().describe("Max reorgs to return")
731
+ since: z6.string().describe("Cursor to list reorgs since (block:index or ISO timestamp)"),
732
+ limit: z6.number().optional().describe("Max reorgs to return")
711
733
  }, async (params) => withStreamsAuthHint(async () => jsonResponse(await clientProvider().streams.reorgs.list(params))));
712
- defineTool(server, "streams_canonical", "Get the canonical block at a given height from Streams (height + hashes + is_canonical). Streams requires an API key (SL_API_KEY).", { height: z7.number().describe("Block height") }, async ({ height }) => withStreamsAuthHint(async () => jsonResponse(await clientProvider().streams.canonical(height))));
734
+ defineTool(server, "streams_canonical", "Get the canonical block at a given height from Streams (height + hashes + is_canonical). Streams requires an API key (SL_API_KEY).", { height: z6.number().describe("Block height") }, async ({ height }) => withStreamsAuthHint(async () => jsonResponse(await clientProvider().streams.canonical(height))));
713
735
  defineTool(server, "streams_usage", "Your own Streams consumption (events today + this month) and tier limits (rate limit, retention). Streams requires an API key (SL_API_KEY).", {}, async () => withStreamsAuthHint(async () => jsonResponse(await clientProvider().streams.usage())));
714
736
  defineTool(server, "streams_dumps", "List the Streams bulk parquet dumps manifest — coverage range, latest_finalized_cursor, and per-file metadata (block range, row count, size, sha256, signed URL). This is the cold backfill path for downloading all raw data; fetch the file URLs directly (e.g. with DuckDB). Requires the dumps base URL to be configured (SL_STREAMS_DUMPS_URL).", {}, async () => jsonResponse(await clientProvider().streams.dumps.list()));
715
737
  }
@@ -722,9 +744,9 @@ import {
722
744
  generateKyselySchema,
723
745
  generatePrismaSchema
724
746
  } from "@secondlayer/subgraphs";
725
- import { z as z8 } from "zod/v4";
747
+ import { z as z7 } from "zod/v4";
726
748
  function registerSubgraphTools(server, clientProvider = getClient) {
727
- defineTool(server, "subgraphs_list", "List all deployed subgraphs. Returns summary fields only.", {}, async () => {
749
+ defineTool(server, "subgraphs_list", "List all deployed subgraphs. Returns summary fields only, including visibility — public subgraphs are anon-readable at /v1/subgraphs/<name>.", {}, async () => {
728
750
  const { data } = await clientProvider().subgraphs.list();
729
751
  return {
730
752
  content: [
@@ -735,16 +757,16 @@ function registerSubgraphTools(server, clientProvider = getClient) {
735
757
  ]
736
758
  };
737
759
  });
738
- defineTool(server, "subgraphs_get", "Get full details of a subgraph including schema, health, and table columns.", { name: z8.string().describe("Subgraph name") }, async ({ name }) => {
760
+ defineTool(server, "subgraphs_get", "Get full details of a subgraph including schema, health, and table columns.", { name: z7.string().describe("Subgraph name") }, async ({ name }) => {
739
761
  const detail = await clientProvider().subgraphs.get(name);
740
762
  return {
741
763
  content: [{ type: "text", text: JSON.stringify(detail, null, 2) }]
742
764
  };
743
765
  });
744
766
  defineTool(server, "subgraphs_spec", "Get generated API documentation for a subgraph. Defaults to compact agent schema; supports OpenAPI JSON and Markdown.", {
745
- name: z8.string().describe("Subgraph name"),
746
- format: z8.enum(["agent", "openapi", "markdown"]).optional().describe("Spec format to return. Defaults to agent."),
747
- serverUrl: z8.string().optional().describe("Override the server URL embedded in generated docs.")
767
+ name: z7.string().describe("Subgraph name"),
768
+ format: z7.enum(["agent", "openapi", "markdown"]).optional().describe("Spec format to return. Defaults to agent."),
769
+ serverUrl: z7.string().optional().describe("Override the server URL embedded in generated docs.")
748
770
  }, async ({ name, format = "agent", serverUrl }) => {
749
771
  const options = serverUrl ? { serverUrl } : undefined;
750
772
  const spec = format === "openapi" ? await clientProvider().subgraphs.openapi(name, options) : format === "markdown" ? await clientProvider().subgraphs.markdown(name, options) : await clientProvider().subgraphs.schema(name, options);
@@ -757,16 +779,16 @@ function registerSubgraphTools(server, clientProvider = getClient) {
757
779
  ]
758
780
  };
759
781
  });
760
- 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. To TAIL new rows (no streaming over MCP): sort=_id, order=desc for the latest, then poll forward with the filter {"_id.gt": "<last _id seen>"}, order=asc. Fetch one row by id with {"_id": "<id>"}.', {
761
- name: z8.string().describe("Subgraph name"),
762
- table: z8.string().describe("Table name"),
763
- filters: z8.record(z8.string(), z8.string()).optional().describe('Column filters — plain values or with operators (e.g. {"amount.gte": "1000", "sender": "SP..."})'),
764
- sort: z8.string().optional().describe("Column to sort by"),
765
- order: z8.enum(["asc", "desc"]).optional().describe("Sort order"),
766
- limit: z8.number().max(200).optional().describe("Max rows (default 50, max 200)"),
767
- offset: z8.number().optional().describe("Offset for pagination"),
768
- fields: z8.string().optional().describe('Comma-separated column list to return (e.g. "sender,amount")'),
769
- count: z8.boolean().optional().describe("If true, return row count instead of rows")
782
+ 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. To TAIL new rows (no streaming over MCP): sort=_id, order=desc for the latest, then poll forward with the filter {"_id.gt": "<last _id seen>"}, order=asc. Fetch one row by id with {"_id": "<id>"}. Public subgraphs are also keyless over HTTP at GET /v1/subgraphs/<name>/<table> — { rows, next_cursor, tip } envelope, resume with ?cursor=<next_cursor> + _order=asc|desc (no _offset/_sort on /v1); hand that URL to third parties.', {
783
+ name: z7.string().describe("Subgraph name"),
784
+ table: z7.string().describe("Table name"),
785
+ filters: z7.record(z7.string(), z7.string()).optional().describe('Column filters — plain values or with operators (e.g. {"amount.gte": "1000", "sender": "SP..."})'),
786
+ sort: z7.string().optional().describe("Column to sort by"),
787
+ order: z7.enum(["asc", "desc"]).optional().describe("Sort order"),
788
+ limit: z7.number().max(200).optional().describe("Max rows (default 50, max 200)"),
789
+ offset: z7.number().optional().describe("Offset for pagination"),
790
+ fields: z7.string().optional().describe('Comma-separated column list to return (e.g. "sender,amount")'),
791
+ count: z7.boolean().optional().describe("If true, return row count instead of rows")
770
792
  }, async ({
771
793
  name,
772
794
  table,
@@ -799,14 +821,14 @@ function registerSubgraphTools(server, clientProvider = getClient) {
799
821
  };
800
822
  });
801
823
  defineTool(server, "subgraphs_aggregate", `Compute scalar aggregates over a subgraph table's filtered rows. Supports count, countDistinct, and sum/min/max (numeric columns only — uint/int plus the system _block_height). Filters use the same grammar as subgraphs_query (e.g. {"amount.gte": "1000"}). sum/min/max come back as lossless strings; counts as numbers. With no aggregate requested, returns the row count.`, {
802
- name: z8.string().describe("Subgraph name"),
803
- table: z8.string().describe("Table name"),
804
- filters: z8.record(z8.string(), z8.string()).optional().describe('Column filters — plain values or with operators (e.g. {"amount.gte": "1000", "sender": "SP..."})'),
805
- count: z8.boolean().optional().describe("Include COUNT(*) of matching rows"),
806
- countDistinct: z8.array(z8.string()).optional().describe("Columns to count distinct values of"),
807
- sum: z8.array(z8.string()).optional().describe("Numeric columns to sum (lossless string result)"),
808
- min: z8.array(z8.string()).optional().describe("Numeric columns to take the minimum of"),
809
- max: z8.array(z8.string()).optional().describe("Numeric columns to take the maximum of")
824
+ name: z7.string().describe("Subgraph name"),
825
+ table: z7.string().describe("Table name"),
826
+ filters: z7.record(z7.string(), z7.string()).optional().describe('Column filters — plain values or with operators (e.g. {"amount.gte": "1000", "sender": "SP..."})'),
827
+ count: z7.boolean().optional().describe("Include COUNT(*) of matching rows"),
828
+ countDistinct: z7.array(z7.string()).optional().describe("Columns to count distinct values of"),
829
+ sum: z7.array(z7.string()).optional().describe("Numeric columns to sum (lossless string result)"),
830
+ min: z7.array(z7.string()).optional().describe("Numeric columns to take the minimum of"),
831
+ max: z7.array(z7.string()).optional().describe("Numeric columns to take the maximum of")
810
832
  }, async ({ name, table, filters, count, countDistinct, sum, min, max }) => {
811
833
  const result = await clientProvider().subgraphs.queryTableAggregate(name, table, { filters, count, countDistinct, sum, min, max });
812
834
  return {
@@ -814,9 +836,9 @@ function registerSubgraphTools(server, clientProvider = getClient) {
814
836
  };
815
837
  });
816
838
  defineTool(server, "subgraphs_reindex", "Reindex a subgraph from a specific block range. Returns an operationId — poll subgraphs_operation to track progress to completion.", {
817
- name: z8.string().describe("Subgraph name"),
818
- fromBlock: z8.number().optional().describe("Start block (defaults to beginning)"),
819
- toBlock: z8.number().optional().describe("End block (defaults to latest)")
839
+ name: z7.string().describe("Subgraph name"),
840
+ fromBlock: z7.number().optional().describe("Start block (defaults to beginning)"),
841
+ toBlock: z7.number().optional().describe("End block (defaults to latest)")
820
842
  }, async ({ name, fromBlock, toBlock }) => {
821
843
  const result = await clientProvider().subgraphs.reindex(name, {
822
844
  fromBlock,
@@ -827,8 +849,8 @@ function registerSubgraphTools(server, clientProvider = getClient) {
827
849
  };
828
850
  });
829
851
  defineTool(server, "subgraphs_operation", "Check reindex/backfill progress. With operationId, returns that operation's status (poll until status is completed/failed/cancelled); without it, lists recent operations for the subgraph.", {
830
- name: z8.string().describe("Subgraph name"),
831
- operationId: z8.string().optional().describe("Operation id from reindex/backfill/stop; omit to list recent operations")
852
+ name: z7.string().describe("Subgraph name"),
853
+ operationId: z7.string().optional().describe("Operation id from reindex/backfill/stop; omit to list recent operations")
832
854
  }, async ({ name, operationId }) => {
833
855
  const result = operationId ? await clientProvider().subgraphs.getOperation(name, operationId) : await clientProvider().subgraphs.operations(name);
834
856
  return {
@@ -836,9 +858,9 @@ function registerSubgraphTools(server, clientProvider = getClient) {
836
858
  };
837
859
  });
838
860
  defineTool(server, "subgraphs_backfill", "Backfill a subgraph over a block range. Non-destructive forward fill (does not drop existing data) — unlike subgraphs_reindex, and the only data-fill path for BYO subgraphs (reindex is blocked there). Both blocks required. Returns an operationId — poll subgraphs_operation to track progress.", {
839
- name: z8.string().describe("Subgraph name"),
840
- fromBlock: z8.number().int().nonnegative().describe("Start block (inclusive)"),
841
- toBlock: z8.number().int().nonnegative().describe("End block (inclusive)")
861
+ name: z7.string().describe("Subgraph name"),
862
+ fromBlock: z7.number().int().nonnegative().describe("Start block (inclusive)"),
863
+ toBlock: z7.number().int().nonnegative().describe("End block (inclusive)")
842
864
  }, async ({ name, fromBlock, toBlock }) => {
843
865
  const result = await clientProvider().subgraphs.backfill(name, {
844
866
  fromBlock,
@@ -848,17 +870,17 @@ function registerSubgraphTools(server, clientProvider = getClient) {
848
870
  content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
849
871
  };
850
872
  });
851
- defineTool(server, "subgraphs_stop", "Cancel an in-flight reindex or backfill operation for a subgraph. Returns the stop request status; poll subgraphs_operation to confirm it reaches a terminal state.", { name: z8.string().describe("Subgraph name") }, async ({ name }) => {
873
+ defineTool(server, "subgraphs_stop", "Cancel an in-flight reindex or backfill operation for a subgraph. Returns the stop request status; poll subgraphs_operation to confirm it reaches a terminal state.", { name: z7.string().describe("Subgraph name") }, async ({ name }) => {
852
874
  const result = await clientProvider().subgraphs.stop(name);
853
875
  return {
854
876
  content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
855
877
  };
856
878
  });
857
879
  defineTool(server, "subgraphs_gaps", "List indexing gaps (missing block ranges) for a subgraph. Each gap reports start/end/size, reason, and detected/resolved timestamps. Feed an unresolved gap's range into subgraphs_backfill to fill it. Defaults to unresolved gaps.", {
858
- name: z8.string().describe("Subgraph name"),
859
- limit: z8.number().int().positive().optional().describe("Max gaps to return"),
860
- offset: z8.number().int().nonnegative().optional().describe("Pagination offset"),
861
- resolved: z8.boolean().optional().describe("Filter by resolved state (omit for unresolved only)")
880
+ name: z7.string().describe("Subgraph name"),
881
+ limit: z7.number().int().positive().optional().describe("Max gaps to return"),
882
+ offset: z7.number().int().nonnegative().optional().describe("Pagination offset"),
883
+ resolved: z7.boolean().optional().describe("Filter by resolved state (omit for unresolved only)")
862
884
  }, async ({ name, limit, offset, resolved }) => {
863
885
  const result = await clientProvider().subgraphs.gaps(name, {
864
886
  limit,
@@ -869,16 +891,17 @@ function registerSubgraphTools(server, clientProvider = getClient) {
869
891
  content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
870
892
  };
871
893
  });
872
- defineTool(server, "subgraphs_delete", "Delete a subgraph permanently.", { name: z8.string().describe("Subgraph name") }, async ({ name }) => {
894
+ defineTool(server, "subgraphs_delete", "Delete a subgraph permanently.", { name: z7.string().describe("Subgraph name") }, async ({ name }) => {
873
895
  const result = await clientProvider().subgraphs.delete(name);
874
896
  return { content: [{ type: "text", text: result.message }] };
875
897
  });
876
- 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. Set dryRun to validate and preview the schema/DDL without writing anything. Set databaseUrl to deploy to your own Postgres (BYO data plane) — the server verifies the connection first; with dryRun it returns the DDL + grant script. A breaking BYO schema change is refused and returns a migration plan (drop + rebuild DDL) instead of deploying. Call `subgraphs_reindex` separately if you need a forced reindex.", {
877
- code: z8.string().describe("TypeScript source code containing a defineSubgraph() call"),
878
- startBlock: z8.number().int().nonnegative().optional().describe("Override the definition startBlock for this deploy"),
879
- databaseUrl: z8.string().optional().describe("BYO data plane: Postgres connection string to host the subgraph's schema and rows in your own database"),
880
- dryRun: z8.boolean().optional().describe("Validate and preview the deploy (schema/DDL, BYO connection) without writing changes")
881
- }, async ({ code, startBlock, databaseUrl, dryRun }) => {
898
+ 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. Set dryRun to validate and preview the schema/DDL without writing anything. Set databaseUrl to deploy to your own Postgres (BYO data plane) — the server verifies the connection first; with dryRun it returns the DDL + grant script. A breaking BYO schema change is refused and returns a migration plan (drop + rebuild DDL) instead of deploying. Visibility defaults: managed deploys are public (anon-readable at /v1/subgraphs/<name>, name claimed in the global public namespace), BYO deploys are private. Call `subgraphs_reindex` separately if you need a forced reindex.", {
899
+ code: z7.string().describe("TypeScript source code containing a defineSubgraph() call"),
900
+ startBlock: z7.number().int().nonnegative().optional().describe("Override the definition startBlock for this deploy"),
901
+ databaseUrl: z7.string().optional().describe("BYO data plane: Postgres connection string to host the subgraph's schema and rows in your own database"),
902
+ dryRun: z7.boolean().optional().describe("Validate and preview the deploy (schema/DDL, BYO connection) without writing changes"),
903
+ visibility: z7.enum(["public", "private"]).optional().describe("Read visibility: public = anon /v1 reads + global name claim; private = owning account's key only. Defaults: managed → public, BYO → private.")
904
+ }, async ({ code, startBlock, databaseUrl, dryRun, visibility }) => {
882
905
  const bundled = await bundleSubgraphCode(code);
883
906
  try {
884
907
  const result = await clientProvider().subgraphs.deploy({
@@ -891,7 +914,8 @@ function registerSubgraphTools(server, clientProvider = getClient) {
891
914
  sourceCode: code,
892
915
  ...startBlock !== undefined ? { startBlock } : {},
893
916
  ...databaseUrl !== undefined ? { databaseUrl } : {},
894
- ...dryRun !== undefined ? { dryRun } : {}
917
+ ...dryRun !== undefined ? { dryRun } : {},
918
+ ...visibility !== undefined ? { visibility } : {}
895
919
  });
896
920
  return {
897
921
  content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
@@ -910,17 +934,29 @@ function registerSubgraphTools(server, clientProvider = getClient) {
910
934
  throw err;
911
935
  }
912
936
  });
913
- 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: z8.string().describe("Subgraph name") }, async ({ name }) => {
937
+ defineTool(server, "subgraphs_publish", "Make a subgraph publicly readable at /v1/subgraphs/<name> — anyone (or any agent) can read it without a key. Claims the name in the global public namespace; fails with PUBLIC_NAME_TAKEN if another account holds it.", { name: z7.string().describe("Subgraph name") }, async ({ name }) => {
938
+ const result = await clientProvider().subgraphs.publish(name);
939
+ return {
940
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
941
+ };
942
+ });
943
+ defineTool(server, "subgraphs_unpublish", "Make a subgraph private again — /v1 reads then require the owning account's bearer key, and the global public name claim is released.", { name: z7.string().describe("Subgraph name") }, async ({ name }) => {
944
+ const result = await clientProvider().subgraphs.unpublish(name);
945
+ return {
946
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
947
+ };
948
+ });
949
+ 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 }) => {
914
950
  const source = await clientProvider().subgraphs.getSource(name);
915
951
  return {
916
952
  content: [{ type: "text", text: JSON.stringify(source, null, 2) }]
917
953
  };
918
954
  });
919
955
  defineTool(server, "subgraphs_codegen", "Generate a typed ORM schema (Prisma, Drizzle, or Kysely) for a subgraph's tables so they can be queried from a BYO database. Pass either `code` (defineSubgraph source) or `name` (a deployed subgraph — its captured source is used). Returns the schema as text.", {
920
- code: z8.string().optional().describe("defineSubgraph() source (mutually exclusive with name)"),
921
- name: z8.string().optional().describe("Deployed subgraph name (mutually exclusive with code)"),
922
- target: z8.enum(["prisma", "drizzle", "kysely"]).optional().describe("ORM target (default prisma)"),
923
- schemaName: z8.string().optional().describe("Postgres schema name (defaults to subgraph_<name>)")
956
+ code: z7.string().optional().describe("defineSubgraph() source (mutually exclusive with name)"),
957
+ name: z7.string().optional().describe("Deployed subgraph name (mutually exclusive with code)"),
958
+ target: z7.enum(["prisma", "drizzle", "kysely"]).optional().describe("ORM target (default prisma)"),
959
+ schemaName: z7.string().optional().describe("Postgres schema name (defaults to subgraph_<name>)")
924
960
  }, async ({ code, name, target = "prisma", schemaName }) => {
925
961
  if (code && name || !code && !name) {
926
962
  throw new Error("Provide exactly one of `code` or `name`.");
@@ -949,7 +985,7 @@ function registerSubgraphTools(server, clientProvider = getClient) {
949
985
 
950
986
  // src/tools/subscriptions.ts
951
987
  import { CHAIN_TRIGGER_TYPES } from "@secondlayer/shared";
952
- import { z as z9 } from "zod/v4";
988
+ import { z as z8 } from "zod/v4";
953
989
  function registerSubscriptionTools(server, clientProvider = getClient) {
954
990
  defineTool(server, "subscriptions_list", "List all subscriptions for the current account. Returns summary fields (no secrets).", {}, async () => {
955
991
  const { data } = await clientProvider().subscriptions.list();
@@ -957,34 +993,34 @@ function registerSubscriptionTools(server, clientProvider = getClient) {
957
993
  content: [{ type: "text", text: JSON.stringify(data, null, 2) }]
958
994
  };
959
995
  });
960
- defineTool(server, "subscriptions_get", "Get full detail for a subscription (filter, auth, retry config, circuit state).", { id: z9.string().describe("Subscription id") }, async ({ id }) => {
996
+ defineTool(server, "subscriptions_get", "Get full detail for a subscription (filter, auth, retry config, circuit state).", { id: z8.string().describe("Subscription id") }, async ({ id }) => {
961
997
  const detail = await clientProvider().subscriptions.get(id);
962
998
  return {
963
999
  content: [{ type: "text", text: JSON.stringify(detail, null, 2) }]
964
1000
  };
965
1001
  });
966
1002
  defineTool(server, "subscriptions_create", "Create a subscription. Two kinds (mutually exclusive): a SUBGRAPH subscription fires on a subgraph table's rows (set subgraphName + tableName + optional filter); a CHAIN subscription fires on raw chain events with no subgraph (set triggers). Returns `signingSecret` ONCE — forward it to the user so they can wire it into their receiver.", {
967
- name: z9.string().describe("Human-readable name, unique per account"),
968
- subgraphName: z9.string().optional().describe("Subgraph to subscribe to (subgraph subscription)"),
969
- tableName: z9.string().optional().describe("Table within the subgraph (subgraph subscription)"),
970
- triggers: z9.array(z9.object({
971
- type: z9.enum(CHAIN_TRIGGER_TYPES),
972
- contractId: z9.string().optional(),
973
- functionName: z9.string().optional(),
974
- caller: z9.string().optional(),
975
- sender: z9.string().optional(),
976
- recipient: z9.string().optional(),
977
- assetIdentifier: z9.string().optional(),
978
- deployer: z9.string().optional(),
979
- contractName: z9.string().optional(),
980
- topic: z9.string().optional(),
981
- lockedAddress: z9.string().optional(),
982
- trait: z9.string().optional(),
983
- minAmount: z9.union([z9.string(), z9.number()]).optional(),
984
- maxAmount: z9.union([z9.string(), z9.number()]).optional()
1003
+ name: z8.string().describe("Human-readable name, unique per account"),
1004
+ subgraphName: z8.string().optional().describe("Subgraph to subscribe to (subgraph subscription)"),
1005
+ tableName: z8.string().optional().describe("Table within the subgraph (subgraph subscription)"),
1006
+ triggers: z8.array(z8.object({
1007
+ type: z8.enum(CHAIN_TRIGGER_TYPES),
1008
+ contractId: z8.string().optional(),
1009
+ functionName: z8.string().optional(),
1010
+ caller: z8.string().optional(),
1011
+ sender: z8.string().optional(),
1012
+ recipient: z8.string().optional(),
1013
+ assetIdentifier: z8.string().optional(),
1014
+ deployer: z8.string().optional(),
1015
+ contractName: z8.string().optional(),
1016
+ topic: z8.string().optional(),
1017
+ lockedAddress: z8.string().optional(),
1018
+ trait: z8.string().optional(),
1019
+ minAmount: z8.union([z8.string(), z8.number()]).optional(),
1020
+ maxAmount: z8.union([z8.string(), z8.number()]).optional()
985
1021
  })).optional().describe("Chain triggers (chain subscription) — provide INSTEAD of subgraphName/tableName. Each targets a raw chain event/tx; string fields accept `*` wildcards, `trait` scopes to a SIP/trait. Per-type accepted fields: see the secondlayer://chain-triggers resource. Forward-looking: starts at chain tip, no backfill."),
986
- url: z9.string().describe("Webhook URL"),
987
- format: z9.enum([
1022
+ url: z8.string().describe("Webhook URL"),
1023
+ format: z8.enum([
988
1024
  "standard-webhooks",
989
1025
  "inngest",
990
1026
  "trigger",
@@ -992,9 +1028,9 @@ function registerSubscriptionTools(server, clientProvider = getClient) {
992
1028
  "cloudevents",
993
1029
  "raw"
994
1030
  ]).optional().describe("Wire format (default standard-webhooks)"),
995
- runtime: z9.enum(["inngest", "trigger", "cloudflare", "node"]).optional().describe("Receiver runtime label (display only)"),
996
- filter: z9.record(z9.string(), z9.unknown()).optional().describe('Scalar filter DSL, e.g. {"amount": {"gte": 100}, "sender": "SP..."}'),
997
- authConfig: z9.record(z9.string(), z9.unknown()).optional().describe('Receiver auth sent with each delivery, e.g. {"type": "bearer", "token": "..."}')
1031
+ runtime: z8.enum(["inngest", "trigger", "cloudflare", "node"]).optional().describe("Receiver runtime label (display only)"),
1032
+ filter: z8.record(z8.string(), z8.unknown()).optional().describe('Scalar filter DSL, e.g. {"amount": {"gte": 100}, "sender": "SP..."}'),
1033
+ authConfig: z8.record(z8.string(), z8.unknown()).optional().describe('Receiver auth sent with each delivery, e.g. {"type": "bearer", "token": "..."}')
998
1034
  }, async (input) => {
999
1035
  const res = await clientProvider().subscriptions.create(input);
1000
1036
  return {
@@ -1002,12 +1038,12 @@ function registerSubscriptionTools(server, clientProvider = getClient) {
1002
1038
  };
1003
1039
  });
1004
1040
  defineTool(server, "subscriptions_update", "Patch a subscription (name, url, filter, authConfig, format, runtime, retry, timeout, concurrency).", {
1005
- id: z9.string(),
1006
- name: z9.string().optional().describe("Rename the subscription"),
1007
- url: z9.string().optional(),
1008
- filter: z9.record(z9.string(), z9.unknown()).optional(),
1009
- authConfig: z9.record(z9.string(), z9.unknown()).optional().describe("Receiver auth sent with each delivery (bearer/etc.)"),
1010
- format: z9.enum([
1041
+ id: z8.string(),
1042
+ name: z8.string().optional().describe("Rename the subscription"),
1043
+ url: z8.string().optional(),
1044
+ filter: z8.record(z8.string(), z8.unknown()).optional(),
1045
+ authConfig: z8.record(z8.string(), z8.unknown()).optional().describe("Receiver auth sent with each delivery (bearer/etc.)"),
1046
+ format: z8.enum([
1011
1047
  "standard-webhooks",
1012
1048
  "inngest",
1013
1049
  "trigger",
@@ -1015,51 +1051,51 @@ function registerSubscriptionTools(server, clientProvider = getClient) {
1015
1051
  "cloudevents",
1016
1052
  "raw"
1017
1053
  ]).optional(),
1018
- runtime: z9.enum(["inngest", "trigger", "cloudflare", "node"]).nullable().optional(),
1019
- maxRetries: z9.number().int().min(0).optional(),
1020
- timeoutMs: z9.number().int().min(100).optional(),
1021
- concurrency: z9.number().int().min(1).optional()
1054
+ runtime: z8.enum(["inngest", "trigger", "cloudflare", "node"]).nullable().optional(),
1055
+ maxRetries: z8.number().int().min(0).optional(),
1056
+ timeoutMs: z8.number().int().min(100).optional(),
1057
+ concurrency: z8.number().int().min(1).optional()
1022
1058
  }, async ({ id, ...patch }) => {
1023
1059
  const res = await clientProvider().subscriptions.update(id, patch);
1024
1060
  return {
1025
1061
  content: [{ type: "text", text: JSON.stringify(res, null, 2) }]
1026
1062
  };
1027
1063
  });
1028
- defineTool(server, "subscriptions_pause", "Pause a subscription. Pending rows remain queued until resumed.", { id: z9.string() }, async ({ id }) => {
1064
+ defineTool(server, "subscriptions_pause", "Pause a subscription. Pending rows remain queued until resumed.", { id: z8.string() }, async ({ id }) => {
1029
1065
  const res = await clientProvider().subscriptions.pause(id);
1030
1066
  return {
1031
1067
  content: [{ type: "text", text: JSON.stringify(res, null, 2) }]
1032
1068
  };
1033
1069
  });
1034
- defineTool(server, "subscriptions_resume", "Resume a paused or circuit-open subscription and reset circuit failures.", { id: z9.string() }, async ({ id }) => {
1070
+ defineTool(server, "subscriptions_resume", "Resume a paused or circuit-open subscription and reset circuit failures.", { id: z8.string() }, async ({ id }) => {
1035
1071
  const res = await clientProvider().subscriptions.resume(id);
1036
1072
  return {
1037
1073
  content: [{ type: "text", text: JSON.stringify(res, null, 2) }]
1038
1074
  };
1039
1075
  });
1040
- defineTool(server, "subscriptions_delete", "Delete a subscription. Pending outbox rows are cascade-deleted.", { id: z9.string() }, async ({ id }) => {
1076
+ defineTool(server, "subscriptions_delete", "Delete a subscription. Pending outbox rows are cascade-deleted.", { id: z8.string() }, async ({ id }) => {
1041
1077
  const res = await clientProvider().subscriptions.delete(id);
1042
1078
  return {
1043
1079
  content: [{ type: "text", text: JSON.stringify(res, null, 2) }]
1044
1080
  };
1045
1081
  });
1046
- defineTool(server, "subscriptions_rotate_secret", "Rotate a subscription signing secret. Returns the new plaintext secret once.", { id: z9.string() }, async ({ id }) => {
1082
+ defineTool(server, "subscriptions_rotate_secret", "Rotate a subscription signing secret. Returns the new plaintext secret once.", { id: z8.string() }, async ({ id }) => {
1047
1083
  const res = await clientProvider().subscriptions.rotateSecret(id);
1048
1084
  return {
1049
1085
  content: [{ type: "text", text: JSON.stringify(res, null, 2) }]
1050
1086
  };
1051
1087
  });
1052
- defineTool(server, "subscriptions_test", "Send a one-off test webhook to a subscription's URL (built for its format, SSRF-guarded). Logged as a delivery row — check subscriptions_recent_deliveries. Returns {ok, statusCode, error, durationMs, deliveryId}.", { id: z9.string().describe("Subscription id") }, async ({ id }) => {
1088
+ defineTool(server, "subscriptions_test", "Send a one-off test webhook to a subscription's URL (built for its format, SSRF-guarded). Logged as a delivery row — check subscriptions_recent_deliveries. Returns {ok, statusCode, error, durationMs, deliveryId}.", { id: z8.string().describe("Subscription id") }, async ({ id }) => {
1053
1089
  const res = await clientProvider().subscriptions.test(id);
1054
1090
  return {
1055
1091
  content: [{ type: "text", text: JSON.stringify(res, null, 2) }]
1056
1092
  };
1057
1093
  });
1058
1094
  defineTool(server, "subscriptions_replay", "Replay a block range for a subscription. Replays run at 10% of batch capacity — use sparingly. Pass `force` (a short idempotency suffix) to re-run a range that was already replayed.", {
1059
- id: z9.string(),
1060
- fromBlock: z9.number().int().nonnegative(),
1061
- toBlock: z9.number().int().nonnegative(),
1062
- force: z9.string().optional().describe("Idempotency suffix to force a duplicate replay of the range")
1095
+ id: z8.string(),
1096
+ fromBlock: z8.number().int().nonnegative(),
1097
+ toBlock: z8.number().int().nonnegative(),
1098
+ force: z8.string().optional().describe("Idempotency suffix to force a duplicate replay of the range")
1063
1099
  }, async ({ id, fromBlock, toBlock, force }) => {
1064
1100
  const res = await clientProvider().subscriptions.replay(id, {
1065
1101
  fromBlock,
@@ -1070,22 +1106,22 @@ function registerSubscriptionTools(server, clientProvider = getClient) {
1070
1106
  content: [{ type: "text", text: JSON.stringify(res, null, 2) }]
1071
1107
  };
1072
1108
  });
1073
- defineTool(server, "subscriptions_dead", "Return the last 100 dead-letter outbox rows for a subscription.", { id: z9.string() }, async ({ id }) => {
1109
+ defineTool(server, "subscriptions_dead", "Return the last 100 dead-letter outbox rows for a subscription.", { id: z8.string() }, async ({ id }) => {
1074
1110
  const { data } = await clientProvider().subscriptions.dead(id);
1075
1111
  return {
1076
1112
  content: [{ type: "text", text: JSON.stringify(data, null, 2) }]
1077
1113
  };
1078
1114
  });
1079
1115
  defineTool(server, "subscriptions_requeue_dead", "Requeue one dead-letter outbox row for delivery retry.", {
1080
- id: z9.string(),
1081
- outboxId: z9.string()
1116
+ id: z8.string(),
1117
+ outboxId: z8.string()
1082
1118
  }, async ({ id, outboxId }) => {
1083
1119
  const res = await clientProvider().subscriptions.requeueDead(id, outboxId);
1084
1120
  return {
1085
1121
  content: [{ type: "text", text: JSON.stringify(res, null, 2) }]
1086
1122
  };
1087
1123
  });
1088
- defineTool(server, "subscriptions_recent_deliveries", "Return the last 100 delivery attempts (attempt #, status code, duration, truncated response).", { id: z9.string() }, async ({ id }) => {
1124
+ defineTool(server, "subscriptions_recent_deliveries", "Return the last 100 delivery attempts (attempt #, status code, duration, truncated response).", { id: z8.string() }, async ({ id }) => {
1089
1125
  const { data } = await clientProvider().subscriptions.recentDeliveries(id);
1090
1126
  return {
1091
1127
  content: [{ type: "text", text: JSON.stringify(data, null, 2) }]
@@ -1106,7 +1142,6 @@ function createServer() {
1106
1142
  registerSubscriptionTools(server);
1107
1143
  registerAccountTools(server);
1108
1144
  registerProjectTools(server);
1109
- registerDatasetTools(server);
1110
1145
  registerIndexTools(server);
1111
1146
  registerStreamsTools(server);
1112
1147
  registerContractTools(server);
@@ -1119,5 +1154,5 @@ var server = createServer();
1119
1154
  var transport = new StdioServerTransport;
1120
1155
  await server.connect(transport);
1121
1156
 
1122
- //# debugId=184F15FD475E1A2164756E2164756E21
1157
+ //# debugId=DF363B254E9A96CE64756E2164756E21
1123
1158
  //# sourceMappingURL=bin.js.map