@secondlayer/mcp 3.8.0 → 3.9.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/README.md +6 -2
- package/dist/bin-http.js +26 -9
- package/dist/bin-http.js.map +5 -5
- package/dist/bin.js +26 -9
- package/dist/bin.js.map +5 -5
- package/dist/index.js +26 -9
- package/dist/index.js.map +5 -5
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@ bun add @secondlayer/mcp
|
|
|
10
10
|
|
|
11
11
|
## Auth
|
|
12
12
|
|
|
13
|
-
Most reads are public —
|
|
13
|
+
Most reads are public — `datasets_*`, `index_*`, and `contracts_find` work with no key. Subgraph tools need an `SL_API_KEY`; separately, **public** subgraphs are anon-readable over HTTP at `GET /v1/subgraphs/<name>/<table>` (`{ rows, next_cursor, tip }` cursor envelope), while private ones need the owning account's key (anon → 404). **`streams_*` requires an `SL_API_KEY`** (and the Index tools reject free-tier keys — Build+ for keyed access). Writes (deploy, publish/unpublish, reindex, delete, subscriptions) and account tools need a key: create one (prefixed `sk-sl_`) in the platform console at https://secondlayer.tools/platform/api-keys and set it as `SL_API_KEY`. Read `secondlayer://context` first — it reports auth state and read-auth tiers.
|
|
14
14
|
|
|
15
15
|
## Quick Start — Stdio (IDE)
|
|
16
16
|
|
|
@@ -52,7 +52,7 @@ bunx -p @secondlayer/mcp secondlayer-mcp-http
|
|
|
52
52
|
|
|
53
53
|
| Domain | Tools |
|
|
54
54
|
| --- | --- |
|
|
55
|
-
| **Subgraphs** (
|
|
55
|
+
| **Subgraphs** (16) | `subgraphs_list`, `subgraphs_get`, `subgraphs_spec`, `subgraphs_query`, `subgraphs_aggregate`, `subgraphs_reindex`, `subgraphs_operation`, `subgraphs_backfill`, `subgraphs_stop`, `subgraphs_gaps`, `subgraphs_delete`, `subgraphs_deploy`, `subgraphs_publish`, `subgraphs_unpublish`, `subgraphs_read_source`, `subgraphs_codegen` |
|
|
56
56
|
| **Subscriptions** (12) | `subscriptions_list`, `subscriptions_get`, `subscriptions_create`, `subscriptions_update`, `subscriptions_pause`, `subscriptions_resume`, `subscriptions_delete`, `subscriptions_rotate_secret`, `subscriptions_replay`, `subscriptions_recent_deliveries`, `subscriptions_dead`, `subscriptions_requeue_dead` |
|
|
57
57
|
| **Datasets** (2) | `datasets_list`, `datasets_query` |
|
|
58
58
|
| **Index** (4) | `index_ft_transfers`, `index_nft_transfers`, `index_events`, `index_contract_calls` |
|
|
@@ -75,6 +75,10 @@ a webhook on raw chain events (contract / event / function / trait) with no
|
|
|
75
75
|
subgraph (e.g. `[{ "type": "contract_call", "contractId": "SP....amm",
|
|
76
76
|
"functionName": "swap-*" }]`).
|
|
77
77
|
|
|
78
|
+
### Subgraph visibility
|
|
79
|
+
|
|
80
|
+
`subgraphs_deploy` takes a `visibility` param (`public` | `private`; defaults: managed → public, BYO `databaseUrl` → private). Flip later with `subgraphs_publish` / `subgraphs_unpublish` — publishing claims the name in the single global public namespace (409 `PUBLIC_NAME_TAKEN` if claimed). Public subgraphs are anon-readable at `GET /v1/subgraphs/<name>/<table>`.
|
|
81
|
+
|
|
78
82
|
### `subgraphs_query` enhancements
|
|
79
83
|
|
|
80
84
|
- `fields` — comma-separated column projection (e.g. `"sender,amount_x"`)
|
package/dist/bin-http.js
CHANGED
|
@@ -61,11 +61,14 @@ async function apiRequest(method, path, body) {
|
|
|
61
61
|
|
|
62
62
|
// src/lib/format.ts
|
|
63
63
|
function formatSubgraphSummary(s) {
|
|
64
|
+
const apiUrl = process.env.SECONDLAYER_API_URL || "https://api.secondlayer.tools";
|
|
64
65
|
return {
|
|
65
66
|
name: s.name,
|
|
66
67
|
status: s.status,
|
|
67
68
|
tables: Array.isArray(s.tables) ? s.tables : Object.keys(s.tables),
|
|
68
|
-
lastProcessedBlock: s.lastProcessedBlock
|
|
69
|
+
lastProcessedBlock: s.lastProcessedBlock,
|
|
70
|
+
...s.visibility ? { visibility: s.visibility } : {},
|
|
71
|
+
...s.visibility === "public" ? { publicUrl: `${apiUrl}/v1/subgraphs/${s.name}` } : {}
|
|
69
72
|
};
|
|
70
73
|
}
|
|
71
74
|
function withCap(items, cap) {
|
|
@@ -217,7 +220,7 @@ var READ_AUTH_TIERS = {
|
|
|
217
220
|
datasets: "open — no API key required",
|
|
218
221
|
index: "anonymous reads allowed; free-tier API keys are rejected (Build+ required)",
|
|
219
222
|
streams: "API key required (SL_API_KEY) — keyless calls return 401",
|
|
220
|
-
subgraphs: "
|
|
223
|
+
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"
|
|
221
224
|
};
|
|
222
225
|
async function buildContext(deps = { clientProvider: getClient }) {
|
|
223
226
|
const unavailable = "unavailable: set SL_API_KEY";
|
|
@@ -727,7 +730,7 @@ import {
|
|
|
727
730
|
} from "@secondlayer/subgraphs";
|
|
728
731
|
import { z as z8 } from "zod/v4";
|
|
729
732
|
function registerSubgraphTools(server, clientProvider = getClient) {
|
|
730
|
-
defineTool(server, "subgraphs_list", "List all deployed subgraphs. Returns summary fields only
|
|
733
|
+
defineTool(server, "subgraphs_list", "List all deployed subgraphs. Returns summary fields only, including visibility — public subgraphs are anon-readable at /v1/subgraphs/<name>.", {}, async () => {
|
|
731
734
|
const { data } = await clientProvider().subgraphs.list();
|
|
732
735
|
return {
|
|
733
736
|
content: [
|
|
@@ -760,7 +763,7 @@ function registerSubgraphTools(server, clientProvider = getClient) {
|
|
|
760
763
|
]
|
|
761
764
|
};
|
|
762
765
|
});
|
|
763
|
-
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>"}.', {
|
|
766
|
+
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.', {
|
|
764
767
|
name: z8.string().describe("Subgraph name"),
|
|
765
768
|
table: z8.string().describe("Table name"),
|
|
766
769
|
filters: z8.record(z8.string(), z8.string()).optional().describe('Column filters — plain values or with operators (e.g. {"amount.gte": "1000", "sender": "SP..."})'),
|
|
@@ -876,12 +879,13 @@ function registerSubgraphTools(server, clientProvider = getClient) {
|
|
|
876
879
|
const result = await clientProvider().subgraphs.delete(name);
|
|
877
880
|
return { content: [{ type: "text", text: result.message }] };
|
|
878
881
|
});
|
|
879
|
-
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.", {
|
|
882
|
+
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.", {
|
|
880
883
|
code: z8.string().describe("TypeScript source code containing a defineSubgraph() call"),
|
|
881
884
|
startBlock: z8.number().int().nonnegative().optional().describe("Override the definition startBlock for this deploy"),
|
|
882
885
|
databaseUrl: z8.string().optional().describe("BYO data plane: Postgres connection string to host the subgraph's schema and rows in your own database"),
|
|
883
|
-
dryRun: z8.boolean().optional().describe("Validate and preview the deploy (schema/DDL, BYO connection) without writing changes")
|
|
884
|
-
|
|
886
|
+
dryRun: z8.boolean().optional().describe("Validate and preview the deploy (schema/DDL, BYO connection) without writing changes"),
|
|
887
|
+
visibility: z8.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.")
|
|
888
|
+
}, async ({ code, startBlock, databaseUrl, dryRun, visibility }) => {
|
|
885
889
|
const bundled = await bundleSubgraphCode(code);
|
|
886
890
|
try {
|
|
887
891
|
const result = await clientProvider().subgraphs.deploy({
|
|
@@ -894,7 +898,8 @@ function registerSubgraphTools(server, clientProvider = getClient) {
|
|
|
894
898
|
sourceCode: code,
|
|
895
899
|
...startBlock !== undefined ? { startBlock } : {},
|
|
896
900
|
...databaseUrl !== undefined ? { databaseUrl } : {},
|
|
897
|
-
...dryRun !== undefined ? { dryRun } : {}
|
|
901
|
+
...dryRun !== undefined ? { dryRun } : {},
|
|
902
|
+
...visibility !== undefined ? { visibility } : {}
|
|
898
903
|
});
|
|
899
904
|
return {
|
|
900
905
|
content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
|
|
@@ -913,6 +918,18 @@ function registerSubgraphTools(server, clientProvider = getClient) {
|
|
|
913
918
|
throw err;
|
|
914
919
|
}
|
|
915
920
|
});
|
|
921
|
+
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: z8.string().describe("Subgraph name") }, async ({ name }) => {
|
|
922
|
+
const result = await clientProvider().subgraphs.publish(name);
|
|
923
|
+
return {
|
|
924
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
|
|
925
|
+
};
|
|
926
|
+
});
|
|
927
|
+
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: z8.string().describe("Subgraph name") }, async ({ name }) => {
|
|
928
|
+
const result = await clientProvider().subgraphs.unpublish(name);
|
|
929
|
+
return {
|
|
930
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
|
|
931
|
+
};
|
|
932
|
+
});
|
|
916
933
|
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 }) => {
|
|
917
934
|
const source = await clientProvider().subgraphs.getSource(name);
|
|
918
935
|
return {
|
|
@@ -1203,5 +1220,5 @@ httpServer.listen(port, () => {
|
|
|
1203
1220
|
console.error("Warning: SECONDLAYER_MCP_SECRET not set, authentication disabled");
|
|
1204
1221
|
});
|
|
1205
1222
|
|
|
1206
|
-
//# debugId=
|
|
1223
|
+
//# debugId=38C3E42509C42A3264756E2164756E21
|
|
1207
1224
|
//# sourceMappingURL=bin-http.js.map
|