@secondlayer/mcp 3.6.0 → 3.8.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 +156 -35
- package/dist/bin-http.js.map +11 -11
- package/dist/bin.js +156 -35
- package/dist/bin.js.map +11 -11
- package/dist/index.js +156 -35
- package/dist/index.js.map +11 -11
- package/package.json +5 -4
package/dist/bin.js
CHANGED
|
@@ -10,6 +10,8 @@ import { fileURLToPath } from "node:url";
|
|
|
10
10
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
11
11
|
|
|
12
12
|
// src/resources.ts
|
|
13
|
+
import { CHAIN_TRIGGER_FIELDS, DECODED_EVENT_TYPES } from "@secondlayer/shared";
|
|
14
|
+
import { TRAIT_STANDARDS } from "@secondlayer/stacks/clarity";
|
|
13
15
|
import { TYPE_MAP } from "@secondlayer/subgraphs/schema";
|
|
14
16
|
|
|
15
17
|
// src/lib/client.ts
|
|
@@ -22,10 +24,12 @@ function getClient() {
|
|
|
22
24
|
if (!instance) {
|
|
23
25
|
const apiKey = readApiKey();
|
|
24
26
|
const baseUrl = process.env.SECONDLAYER_API_URL;
|
|
27
|
+
const dumpsBaseUrl = process.env.SL_STREAMS_DUMPS_URL;
|
|
25
28
|
instance = new SecondLayer({
|
|
26
29
|
...apiKey ? { apiKey } : {},
|
|
27
30
|
origin: "mcp",
|
|
28
|
-
...baseUrl ? { baseUrl } : {}
|
|
31
|
+
...baseUrl ? { baseUrl } : {},
|
|
32
|
+
...dumpsBaseUrl ? { dumpsBaseUrl } : {}
|
|
29
33
|
});
|
|
30
34
|
}
|
|
31
35
|
return instance;
|
|
@@ -104,6 +108,11 @@ function defineTool(server, name, description, schema, handler) {
|
|
|
104
108
|
}
|
|
105
109
|
|
|
106
110
|
// src/resources.ts
|
|
111
|
+
var TRAIT_BLURBS = {
|
|
112
|
+
"sip-009": "Non-fungible token (NFT) standard",
|
|
113
|
+
"sip-010": "Fungible token standard",
|
|
114
|
+
"sip-013": "Semi-fungible token standard"
|
|
115
|
+
};
|
|
107
116
|
var FILTERS_REFERENCE = [
|
|
108
117
|
{
|
|
109
118
|
type: "stx_transfer",
|
|
@@ -198,7 +207,7 @@ function buildCapabilities() {
|
|
|
198
207
|
});
|
|
199
208
|
return {
|
|
200
209
|
products,
|
|
201
|
-
discoverFirst: "Call datasets_list / contracts_find to learn what exists before querying."
|
|
210
|
+
discoverFirst: "Call datasets_list / index_discover / contracts_find to learn what exists (and which filters each surface accepts) before querying."
|
|
202
211
|
};
|
|
203
212
|
}
|
|
204
213
|
var READ_AUTH_TIERS = {
|
|
@@ -257,6 +266,56 @@ function registerResources(server) {
|
|
|
257
266
|
}
|
|
258
267
|
]
|
|
259
268
|
}));
|
|
269
|
+
server.resource("traits", "secondlayer://traits", {
|
|
270
|
+
description: "SIP trait standards the platform can classify and scaffold against — the valid values for contracts_find `trait` and subgraph scaffold `--trait`."
|
|
271
|
+
}, async () => ({
|
|
272
|
+
contents: [
|
|
273
|
+
{
|
|
274
|
+
uri: "secondlayer://traits",
|
|
275
|
+
mimeType: "application/json",
|
|
276
|
+
text: JSON.stringify({
|
|
277
|
+
traits: TRAIT_STANDARDS.map((id) => ({
|
|
278
|
+
id,
|
|
279
|
+
description: TRAIT_BLURBS[id]
|
|
280
|
+
}))
|
|
281
|
+
}, null, 2)
|
|
282
|
+
}
|
|
283
|
+
]
|
|
284
|
+
}));
|
|
285
|
+
server.resource("streams-filters", "secondlayer://streams-filters", {
|
|
286
|
+
description: "Streams firehose vocabulary — the decoded event types and the filter fields accepted by streams_events / streams_consume."
|
|
287
|
+
}, async () => ({
|
|
288
|
+
contents: [
|
|
289
|
+
{
|
|
290
|
+
uri: "secondlayer://streams-filters",
|
|
291
|
+
mimeType: "application/json",
|
|
292
|
+
text: JSON.stringify({
|
|
293
|
+
eventTypes: [...DECODED_EVENT_TYPES],
|
|
294
|
+
filters: {
|
|
295
|
+
types: "include only these event types (array)",
|
|
296
|
+
notTypes: "exclude these event types (array)",
|
|
297
|
+
contractId: "match a contract id",
|
|
298
|
+
sender: "match the sender principal",
|
|
299
|
+
recipient: "match the recipient principal",
|
|
300
|
+
assetIdentifier: "match the asset identifier (contract::asset)",
|
|
301
|
+
fromHeight: "start block height (inclusive)",
|
|
302
|
+
toHeight: "end block height (inclusive)"
|
|
303
|
+
}
|
|
304
|
+
}, null, 2)
|
|
305
|
+
}
|
|
306
|
+
]
|
|
307
|
+
}));
|
|
308
|
+
server.resource("chain-triggers", "secondlayer://chain-triggers", {
|
|
309
|
+
description: "Chain-subscription trigger types and the filter fields each accepts (for subscriptions_create triggers)."
|
|
310
|
+
}, async () => ({
|
|
311
|
+
contents: [
|
|
312
|
+
{
|
|
313
|
+
uri: "secondlayer://chain-triggers",
|
|
314
|
+
mimeType: "application/json",
|
|
315
|
+
text: JSON.stringify(CHAIN_TRIGGER_FIELDS, null, 2)
|
|
316
|
+
}
|
|
317
|
+
]
|
|
318
|
+
}));
|
|
260
319
|
}
|
|
261
320
|
|
|
262
321
|
// src/tools/account.ts
|
|
@@ -281,7 +340,7 @@ function registerAccountTools(server) {
|
|
|
281
340
|
const result = await apiRequest("PATCH", "/api/accounts/me", body);
|
|
282
341
|
return jsonResponse(result);
|
|
283
342
|
});
|
|
284
|
-
defineTool(server, "account_billing", "Show the account's plan and subscription/billing status. Requires an API key.", {}, async () => {
|
|
343
|
+
defineTool(server, "account_billing", "Show the account's plan and subscription/billing status. Requires an API key. (Plan upgrade / Stripe portal / checkout are deliberately not agent tools — they are session-only human-payment flows; use account_set_caps to bound spend.)", {}, async () => {
|
|
285
344
|
const result = await apiRequest("GET", "/api/billing/status");
|
|
286
345
|
return jsonResponse(result);
|
|
287
346
|
});
|
|
@@ -309,6 +368,7 @@ function registerAccountTools(server) {
|
|
|
309
368
|
}
|
|
310
369
|
|
|
311
370
|
// src/tools/contracts.ts
|
|
371
|
+
import { generateContractInterface } from "@secondlayer/scaffold";
|
|
312
372
|
import { z as z2 } from "zod/v4";
|
|
313
373
|
function registerContractTools(server, clientProvider = getClient) {
|
|
314
374
|
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.', {
|
|
@@ -318,6 +378,47 @@ function registerContractTools(server, clientProvider = getClient) {
|
|
|
318
378
|
limit: z2.number().optional().describe("Page size, 1–500 (default 100)"),
|
|
319
379
|
cursor: z2.string().optional().describe("Opaque cursor from a prior response's next_cursor")
|
|
320
380
|
}, async (params) => jsonResponse(await clientProvider().contracts.list(params)));
|
|
381
|
+
defineTool(server, "get_contract_abi", "Fetch a single deployed contract's ABI from the registry (prod-safe). Returns the contract's metadata + full ABI (functions, maps, variables, fungible/non-fungible tokens). Returns not_found if the contract isn't in the registry. Feed the ABI into scaffold_from_abi or generate a typed client.", {
|
|
382
|
+
contractId: z2.string().describe("Fully qualified contract id (e.g. SP….amm-pool-v2-01)")
|
|
383
|
+
}, async ({ contractId }) => {
|
|
384
|
+
const contract = await clientProvider().contracts.get(contractId, {
|
|
385
|
+
includeAbi: true
|
|
386
|
+
});
|
|
387
|
+
return contract ? jsonResponse(contract) : jsonResponse({
|
|
388
|
+
error: {
|
|
389
|
+
type: "not_found",
|
|
390
|
+
status: 404,
|
|
391
|
+
message: `Contract not in registry: ${contractId}`
|
|
392
|
+
}
|
|
393
|
+
}, true);
|
|
394
|
+
});
|
|
395
|
+
defineTool(server, "generate_contract_interface", "Generate a typed TypeScript contract-client interface (typed methods + map/var/constant readers) from a deployed contract's ABI (fetched from the registry). Returns not_found if the contract isn't in the registry.", {
|
|
396
|
+
contractId: z2.string().describe("Fully qualified contract id (e.g. SP….amm-pool-v2-01)")
|
|
397
|
+
}, async ({ contractId }) => {
|
|
398
|
+
const c = await clientProvider().contracts.get(contractId, {
|
|
399
|
+
includeAbi: true
|
|
400
|
+
});
|
|
401
|
+
if (!c || !c.abi) {
|
|
402
|
+
return jsonResponse({
|
|
403
|
+
error: {
|
|
404
|
+
type: "not_found",
|
|
405
|
+
status: 404,
|
|
406
|
+
message: `Contract not in registry: ${contractId}`
|
|
407
|
+
}
|
|
408
|
+
}, true);
|
|
409
|
+
}
|
|
410
|
+
const [address, contractName] = contractId.split(".");
|
|
411
|
+
const name = (contractName ?? contractId).replace(/[^a-zA-Z0-9]/g, "_");
|
|
412
|
+
const code = generateContractInterface([
|
|
413
|
+
{
|
|
414
|
+
name,
|
|
415
|
+
address,
|
|
416
|
+
contractName: contractName ?? "",
|
|
417
|
+
abi: c.abi
|
|
418
|
+
}
|
|
419
|
+
]);
|
|
420
|
+
return { content: [{ type: "text", text: code }] };
|
|
421
|
+
});
|
|
321
422
|
}
|
|
322
423
|
|
|
323
424
|
// src/tools/datasets.ts
|
|
@@ -344,13 +445,13 @@ function registerDatasetTools(server, clientProvider = getClient) {
|
|
|
344
445
|
}
|
|
345
446
|
|
|
346
447
|
// src/tools/index.ts
|
|
347
|
-
import { DECODED_EVENT_TYPES } from "@secondlayer/shared";
|
|
448
|
+
import { DECODED_EVENT_TYPES as DECODED_EVENT_TYPES2 } from "@secondlayer/shared";
|
|
348
449
|
import {
|
|
349
|
-
|
|
350
|
-
|
|
450
|
+
INDEX_CODEGEN_TABLES,
|
|
451
|
+
generateIndexSchema
|
|
351
452
|
} from "@secondlayer/subgraphs";
|
|
352
453
|
import { z as z4 } from "zod/v4";
|
|
353
|
-
var INDEX_EVENT_TYPES =
|
|
454
|
+
var INDEX_EVENT_TYPES = DECODED_EVENT_TYPES2;
|
|
354
455
|
var rangeFilters = {
|
|
355
456
|
contractId: z4.string().optional().describe("Filter by contract id"),
|
|
356
457
|
fromHeight: z4.number().optional().describe("Start block height (inclusive)"),
|
|
@@ -377,17 +478,19 @@ function registerIndexTools(server, clientProvider = getClient) {
|
|
|
377
478
|
recipient: z4.string().optional().describe("Filter by recipient principal"),
|
|
378
479
|
assetIdentifier: z4.string().optional().describe("Filter by asset identifier (contract::asset)")
|
|
379
480
|
}, async (params) => jsonResponse(await clientProvider().index.nftTransfers.list(params)));
|
|
380
|
-
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.", {
|
|
481
|
+
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.", {
|
|
381
482
|
eventType: z4.enum(INDEX_EVENT_TYPES).describe("Required. Decoded event type to list."),
|
|
382
483
|
...rangeFilters,
|
|
383
484
|
sender: z4.string().optional().describe("Filter by sender principal"),
|
|
384
485
|
recipient: z4.string().optional().describe("Filter by recipient principal"),
|
|
385
|
-
assetIdentifier: z4.string().optional().describe("Filter by asset identifier where applicable")
|
|
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.")
|
|
386
488
|
}, async (params) => jsonResponse(await clientProvider().index.events.list(params)));
|
|
387
|
-
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.", {
|
|
489
|
+
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.", {
|
|
388
490
|
...rangeFilters,
|
|
389
491
|
functionName: z4.string().optional().describe("Filter by called function name"),
|
|
390
|
-
sender: z4.string().optional().describe("Filter by caller principal")
|
|
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.")
|
|
391
494
|
}, async (params) => jsonResponse(await clientProvider().index.contractCalls.list(params)));
|
|
392
495
|
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)));
|
|
393
496
|
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)));
|
|
@@ -406,6 +509,10 @@ function registerIndexTools(server, clientProvider = getClient) {
|
|
|
406
509
|
const tx = await clientProvider().index.transactions.get(txId);
|
|
407
510
|
return tx ? jsonResponse(tx) : notFound(`No transaction for ${txId}`);
|
|
408
511
|
});
|
|
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 }) => {
|
|
513
|
+
const proof = await clientProvider().index.transactions.getProof(txId);
|
|
514
|
+
return proof ? jsonResponse(proof) : notFound(`No proof available for ${txId}`);
|
|
515
|
+
});
|
|
409
516
|
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).", {
|
|
410
517
|
...heightFilters,
|
|
411
518
|
functionName: z4.string().optional().describe("Filter by PoX function name"),
|
|
@@ -423,6 +530,7 @@ function registerIndexTools(server, clientProvider = getClient) {
|
|
|
423
530
|
const tx = await clientProvider().index.mempool.get(txId);
|
|
424
531
|
return tx ? jsonResponse(tx) : notFound(`No pending tx for ${txId}`);
|
|
425
532
|
});
|
|
533
|
+
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()));
|
|
426
534
|
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()));
|
|
427
535
|
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(", ")}.`, {
|
|
428
536
|
target: z4.enum(["prisma", "kysely", "drizzle", "json-schema"]).optional().describe("Output target (default kysely)"),
|
|
@@ -469,25 +577,32 @@ function registerProjectTools(server, clientProvider = getClient) {
|
|
|
469
577
|
}
|
|
470
578
|
|
|
471
579
|
// src/tools/scaffold.ts
|
|
472
|
-
import {
|
|
580
|
+
import {
|
|
581
|
+
generateSubgraphCode,
|
|
582
|
+
generateTraitSubgraph
|
|
583
|
+
} from "@secondlayer/scaffold";
|
|
584
|
+
import { TRAIT_STANDARDS as TRAIT_STANDARDS2 } from "@secondlayer/stacks/clarity";
|
|
473
585
|
import { z as z6 } from "zod/v4";
|
|
474
|
-
var API_BASE = process.env.SECONDLAYER_API_URL || "https://api.secondlayer.tools";
|
|
475
586
|
async function fetchAbi(contractId) {
|
|
476
|
-
const
|
|
477
|
-
|
|
587
|
+
const contract = await getClient().contracts.get(contractId, {
|
|
588
|
+
includeAbi: true
|
|
478
589
|
});
|
|
479
|
-
if (!
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
590
|
+
if (!contract)
|
|
591
|
+
throw new Error(`Contract not found: ${contractId}`);
|
|
592
|
+
const abi = contract.abi;
|
|
593
|
+
if (!abi) {
|
|
594
|
+
throw new Error(`No ABI available for ${contractId} (abi_status: ${contract.abi_status})`);
|
|
483
595
|
}
|
|
484
|
-
|
|
485
|
-
return {
|
|
486
|
-
functions: abi.functions ?? [],
|
|
487
|
-
maps: abi.maps ?? []
|
|
488
|
-
};
|
|
596
|
+
return { functions: abi.functions ?? [], maps: abi.maps ?? [] };
|
|
489
597
|
}
|
|
490
598
|
function registerScaffoldTools(server) {
|
|
599
|
+
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)")
|
|
602
|
+
}, async ({ trait, subgraphName }) => {
|
|
603
|
+
const code = generateTraitSubgraph({ trait, name: subgraphName });
|
|
604
|
+
return { content: [{ type: "text", text: code }] };
|
|
605
|
+
});
|
|
491
606
|
defineTool(server, "scaffold_from_contract", "Generate a subgraph scaffold from a deployed Stacks contract. Fetches the ABI automatically.", {
|
|
492
607
|
contractId: z6.string().describe("Fully qualified contract ID (e.g. SP102V8P0F7JX67ARQ77WEA3D3CFB5XW39REDT0AM.amm-pool-v2-01)"),
|
|
493
608
|
subgraphName: z6.string().optional().describe("Override the subgraph name (defaults to contract name)")
|
|
@@ -517,9 +632,9 @@ function registerScaffoldTools(server) {
|
|
|
517
632
|
|
|
518
633
|
// src/tools/streams.ts
|
|
519
634
|
import { AuthError } from "@secondlayer/sdk";
|
|
520
|
-
import { DECODED_EVENT_TYPES as
|
|
635
|
+
import { DECODED_EVENT_TYPES as DECODED_EVENT_TYPES3 } from "@secondlayer/shared";
|
|
521
636
|
import { z as z7 } from "zod/v4";
|
|
522
|
-
var STREAMS_EVENT_TYPES =
|
|
637
|
+
var STREAMS_EVENT_TYPES = DECODED_EVENT_TYPES3;
|
|
523
638
|
async function withStreamsAuthHint(fn) {
|
|
524
639
|
try {
|
|
525
640
|
return await fn();
|
|
@@ -596,6 +711,7 @@ function registerStreamsTools(server, clientProvider = getClient) {
|
|
|
596
711
|
}, async (params) => withStreamsAuthHint(async () => jsonResponse(await clientProvider().streams.reorgs.list(params))));
|
|
597
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))));
|
|
598
713
|
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
|
+
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()));
|
|
599
715
|
}
|
|
600
716
|
|
|
601
717
|
// src/tools/subgraphs.ts
|
|
@@ -641,7 +757,7 @@ function registerSubgraphTools(server, clientProvider = getClient) {
|
|
|
641
757
|
]
|
|
642
758
|
};
|
|
643
759
|
});
|
|
644
|
-
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.', {
|
|
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>"}.', {
|
|
645
761
|
name: z8.string().describe("Subgraph name"),
|
|
646
762
|
table: z8.string().describe("Table name"),
|
|
647
763
|
filters: z8.record(z8.string(), z8.string()).optional().describe('Column filters — plain values or with operators (e.g. {"amount.gte": "1000", "sender": "SP..."})'),
|
|
@@ -866,7 +982,7 @@ function registerSubscriptionTools(server, clientProvider = getClient) {
|
|
|
866
982
|
trait: z9.string().optional(),
|
|
867
983
|
minAmount: z9.union([z9.string(), z9.number()]).optional(),
|
|
868
984
|
maxAmount: z9.union([z9.string(), z9.number()]).optional()
|
|
869
|
-
})).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. Forward-looking: starts at chain tip, no backfill."),
|
|
985
|
+
})).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."),
|
|
870
986
|
url: z9.string().describe("Webhook URL"),
|
|
871
987
|
format: z9.enum([
|
|
872
988
|
"standard-webhooks",
|
|
@@ -877,17 +993,20 @@ function registerSubscriptionTools(server, clientProvider = getClient) {
|
|
|
877
993
|
"raw"
|
|
878
994
|
]).optional().describe("Wire format (default standard-webhooks)"),
|
|
879
995
|
runtime: z9.enum(["inngest", "trigger", "cloudflare", "node"]).optional().describe("Receiver runtime label (display only)"),
|
|
880
|
-
filter: z9.record(z9.string(), z9.unknown()).optional().describe('Scalar filter DSL, e.g. {"amount": {"gte": 100}, "sender": "SP..."}')
|
|
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": "..."}')
|
|
881
998
|
}, async (input) => {
|
|
882
999
|
const res = await clientProvider().subscriptions.create(input);
|
|
883
1000
|
return {
|
|
884
1001
|
content: [{ type: "text", text: JSON.stringify(res, null, 2) }]
|
|
885
1002
|
};
|
|
886
1003
|
});
|
|
887
|
-
defineTool(server, "subscriptions_update", "Patch a subscription (url, filter, format, runtime, retry, timeout, concurrency).", {
|
|
1004
|
+
defineTool(server, "subscriptions_update", "Patch a subscription (name, url, filter, authConfig, format, runtime, retry, timeout, concurrency).", {
|
|
888
1005
|
id: z9.string(),
|
|
1006
|
+
name: z9.string().optional().describe("Rename the subscription"),
|
|
889
1007
|
url: z9.string().optional(),
|
|
890
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.)"),
|
|
891
1010
|
format: z9.enum([
|
|
892
1011
|
"standard-webhooks",
|
|
893
1012
|
"inngest",
|
|
@@ -936,14 +1055,16 @@ function registerSubscriptionTools(server, clientProvider = getClient) {
|
|
|
936
1055
|
content: [{ type: "text", text: JSON.stringify(res, null, 2) }]
|
|
937
1056
|
};
|
|
938
1057
|
});
|
|
939
|
-
defineTool(server, "subscriptions_replay", "Replay a block range for a subscription. Replays run at 10% of batch capacity — use sparingly.", {
|
|
1058
|
+
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.", {
|
|
940
1059
|
id: z9.string(),
|
|
941
1060
|
fromBlock: z9.number().int().nonnegative(),
|
|
942
|
-
toBlock: z9.number().int().nonnegative()
|
|
943
|
-
|
|
1061
|
+
toBlock: z9.number().int().nonnegative(),
|
|
1062
|
+
force: z9.string().optional().describe("Idempotency suffix to force a duplicate replay of the range")
|
|
1063
|
+
}, async ({ id, fromBlock, toBlock, force }) => {
|
|
944
1064
|
const res = await clientProvider().subscriptions.replay(id, {
|
|
945
1065
|
fromBlock,
|
|
946
|
-
toBlock
|
|
1066
|
+
toBlock,
|
|
1067
|
+
...force !== undefined ? { force } : {}
|
|
947
1068
|
});
|
|
948
1069
|
return {
|
|
949
1070
|
content: [{ type: "text", text: JSON.stringify(res, null, 2) }]
|
|
@@ -998,5 +1119,5 @@ var server = createServer();
|
|
|
998
1119
|
var transport = new StdioServerTransport;
|
|
999
1120
|
await server.connect(transport);
|
|
1000
1121
|
|
|
1001
|
-
//# debugId=
|
|
1122
|
+
//# debugId=184F15FD475E1A2164756E2164756E21
|
|
1002
1123
|
//# sourceMappingURL=bin.js.map
|