subgraph-registry-mcp 0.9.4 → 0.9.5
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/data/openapi.json +3 -3
- package/openapi.yaml +3 -3
- package/package.json +1 -1
- package/src/index.js +70 -9
package/data/openapi.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"info": {
|
|
4
4
|
"title": "Subgraph Registry",
|
|
5
5
|
"description": "Agent-friendly subgraph discovery on The Graph Network. 14,700+ classified subgraphs with semantic search, reliability scoring, schema-evolution tracking, and x402 query URLs ($0.01 USDC on Base, no API key).",
|
|
6
|
-
"version": "0.9.
|
|
6
|
+
"version": "0.9.5",
|
|
7
7
|
"license": {
|
|
8
8
|
"name": "MIT"
|
|
9
9
|
},
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"post": {
|
|
24
24
|
"operationId": "tool_search_subgraphs",
|
|
25
25
|
"summary": "Search and filter the classified subgraph registry (15,000+ subgraphs).",
|
|
26
|
-
"description": "Search and filter the classified subgraph registry (15,000+ subgraphs). Filter by domain (defi, nfts, dao, gaming, identity, infrastructure, social, analytics), network (mainnet, arbitrum-one, base, matic, bsc, optimism, avalanche), protocol_type (dex, lending, bridge, staking, options, perpetuals, nft-marketplace, yield-aggregator, governance, name-service), canonical entity type (liquidity_pool, trade, token, position, vault, loan, collateral, liquidation, nft_collection, nft_item, nft_sale, proposal, delegate, domain_name, account, transaction, daily_snapshot, hourly_snapshot), or free-text keyword. Returns subgraphs ranked by reliability score. Each result
|
|
26
|
+
"description": "Search and filter the classified subgraph registry (15,000+ subgraphs). Filter by domain (defi, nfts, dao, gaming, identity, infrastructure, social, analytics), network (mainnet, arbitrum-one, base, matic, bsc, optimism, avalanche), protocol_type (dex, lending, bridge, staking, options, perpetuals, nft-marketplace, yield-aggregator, governance, name-service), canonical entity type (liquidity_pool, trade, token, position, vault, loan, collateral, liquidation, nft_collection, nft_item, nft_sale, proposal, delegate, domain_name, account, transaction, daily_snapshot, hourly_snapshot), or free-text keyword. Returns subgraphs ranked by reliability score. Discovery only — this tool does not execute GraphQL. Each result carries the subgraph id, a ready-to-run example_query, and both query routes in `payment_options`: a keyed gateway URL (Authorization: Bearer) or an x402 URL ($0.01 USDC on Base, no key). Pass the id to your own Graph client if you have one. Plus age_days and maturity (new | emerging | established). Because reliability_score is cumulative it structurally favours older deployments, so a separate `emerging` list carries recent matches that ranked below the main cut for age rather than quality — read `emerging_caveat` before offering one to a user.",
|
|
27
27
|
"tags": [
|
|
28
28
|
"mcp-tools"
|
|
29
29
|
],
|
|
@@ -112,7 +112,7 @@
|
|
|
112
112
|
"post": {
|
|
113
113
|
"operationId": "tool_recommend_subgraph",
|
|
114
114
|
"summary": "Given a natural-language goal like 'find DEX trades on Arbitrum' or 'get lending liquidation data', returns the best…",
|
|
115
|
-
"description": "Given a natural-language goal like 'find DEX trades on Arbitrum' or 'get lending liquidation data', returns the best matching subgraphs with reliability scores. Automatically infers domain and protocol type from the goal. Each result
|
|
115
|
+
"description": "Given a natural-language goal like 'find DEX trades on Arbitrum' or 'get lending liquidation data', returns the best matching subgraphs with reliability scores. Automatically infers domain and protocol type from the goal. Discovery only — it returns ids and starter queries, it does not execute GraphQL. Each result carries both query routes in `payment_options`: a keyed gateway URL (Authorization: Bearer <STUDIO_API_KEY>) or an x402 URL ($0.01 USDC on Base, no key).",
|
|
116
116
|
"tags": [
|
|
117
117
|
"mcp-tools"
|
|
118
118
|
],
|
package/openapi.yaml
CHANGED
|
@@ -5,7 +5,7 @@ openapi: "3.1.0"
|
|
|
5
5
|
info:
|
|
6
6
|
title: "Subgraph Registry"
|
|
7
7
|
description: "Agent-friendly subgraph discovery on The Graph Network. 14,700+ classified subgraphs with semantic search, reliability scoring, schema-evolution tracking, and x402 query URLs ($0.01 USDC on Base, no API key)."
|
|
8
|
-
version: "0.9.
|
|
8
|
+
version: "0.9.5"
|
|
9
9
|
license:
|
|
10
10
|
name: "MIT"
|
|
11
11
|
contact:
|
|
@@ -19,7 +19,7 @@ paths:
|
|
|
19
19
|
post:
|
|
20
20
|
operationId: "tool_search_subgraphs"
|
|
21
21
|
summary: "Search and filter the classified subgraph registry (15,000+ subgraphs)."
|
|
22
|
-
description: "Search and filter the classified subgraph registry (15,000+ subgraphs). Filter by domain (defi, nfts, dao, gaming, identity, infrastructure, social, analytics), network (mainnet, arbitrum-one, base, matic, bsc, optimism, avalanche), protocol_type (dex, lending, bridge, staking, options, perpetuals, nft-marketplace, yield-aggregator, governance, name-service), canonical entity type (liquidity_pool, trade, token, position, vault, loan, collateral, liquidation, nft_collection, nft_item, nft_sale, proposal, delegate, domain_name, account, transaction, daily_snapshot, hourly_snapshot), or free-text keyword. Returns subgraphs ranked by reliability score. Each result
|
|
22
|
+
description: "Search and filter the classified subgraph registry (15,000+ subgraphs). Filter by domain (defi, nfts, dao, gaming, identity, infrastructure, social, analytics), network (mainnet, arbitrum-one, base, matic, bsc, optimism, avalanche), protocol_type (dex, lending, bridge, staking, options, perpetuals, nft-marketplace, yield-aggregator, governance, name-service), canonical entity type (liquidity_pool, trade, token, position, vault, loan, collateral, liquidation, nft_collection, nft_item, nft_sale, proposal, delegate, domain_name, account, transaction, daily_snapshot, hourly_snapshot), or free-text keyword. Returns subgraphs ranked by reliability score. Discovery only — this tool does not execute GraphQL. Each result carries the subgraph id, a ready-to-run example_query, and both query routes in `payment_options`: a keyed gateway URL (Authorization: Bearer) or an x402 URL ($0.01 USDC on Base, no key). Pass the id to your own Graph client if you have one. Plus age_days and maturity (new | emerging | established). Because reliability_score is cumulative it structurally favours older deployments, so a separate `emerging` list carries recent matches that ranked below the main cut for age rather than quality — read `emerging_caveat` before offering one to a user."
|
|
23
23
|
tags:
|
|
24
24
|
- "mcp-tools"
|
|
25
25
|
requestBody:
|
|
@@ -81,7 +81,7 @@ paths:
|
|
|
81
81
|
post:
|
|
82
82
|
operationId: "tool_recommend_subgraph"
|
|
83
83
|
summary: "Given a natural-language goal like 'find DEX trades on Arbitrum' or 'get lending liquidation data', returns the best…"
|
|
84
|
-
description: "Given a natural-language goal like 'find DEX trades on Arbitrum' or 'get lending liquidation data', returns the best matching subgraphs with reliability scores. Automatically infers domain and protocol type from the goal. Each result
|
|
84
|
+
description: "Given a natural-language goal like 'find DEX trades on Arbitrum' or 'get lending liquidation data', returns the best matching subgraphs with reliability scores. Automatically infers domain and protocol type from the goal. Discovery only — it returns ids and starter queries, it does not execute GraphQL. Each result carries both query routes in `payment_options`: a keyed gateway URL (Authorization: Bearer <STUDIO_API_KEY>) or an x402 URL ($0.01 USDC on Base, no key)."
|
|
85
85
|
tags:
|
|
86
86
|
- "mcp-tools"
|
|
87
87
|
requestBody:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "subgraph-registry-mcp",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.5",
|
|
4
4
|
"mcpName": "io.github.PaulieB14/subgraph-registry-mcp",
|
|
5
5
|
"description": "MCP server for agent-friendly subgraph discovery on The Graph Network. 15,330 classified subgraphs with x402 query URLs ($0.01 USDC on Base, no API key required), reliability scoring, and protocol classification.",
|
|
6
6
|
"type": "module",
|
package/src/index.js
CHANGED
|
@@ -90,8 +90,42 @@ const X402_PRICING = {
|
|
|
90
90
|
|
|
91
91
|
function buildQueryEndpoints(subgraphId) {
|
|
92
92
|
return {
|
|
93
|
-
|
|
93
|
+
// The keyed gateway URL. This used to carry `[api-key]` as a path segment,
|
|
94
|
+
// a form the gateway no longer uses — an agent that string-replaced the
|
|
95
|
+
// placeholder was building a URL that has not been correct for a while.
|
|
96
|
+
// The current form takes the key in a header:
|
|
97
|
+
// POST https://gateway.thegraph.com/api/subgraphs/id/<ID>
|
|
98
|
+
// Authorization: Bearer <STUDIO_KEY>
|
|
99
|
+
// Verified: without the header this returns HTTP 200 carrying a GraphQL
|
|
100
|
+
// error body, `auth error: missing authorization header` — GraphQL signals
|
|
101
|
+
// auth in the body, so do not treat 200 as success without reading it.
|
|
102
|
+
query_url: `https://gateway.thegraph.com/api/subgraphs/id/${subgraphId}`,
|
|
94
103
|
query_url_x402: `${X402_GATEWAY_BASE}/subgraphs/id/${subgraphId}`,
|
|
104
|
+
|
|
105
|
+
// Both routes, stated side by side, because which one is right depends
|
|
106
|
+
// entirely on what the caller already has. An agent embedded in a product
|
|
107
|
+
// with a Studio key should use its key; a headless agent with a funded
|
|
108
|
+
// wallet and no way to mint a key should use x402. Neither is "the
|
|
109
|
+
// recommended one" — the previous wording put x402 first and labelled it
|
|
110
|
+
// RECOMMENDED, which sent key-holding agents down a payment path they had
|
|
111
|
+
// no reason to take, and which some hosts forbid outright.
|
|
112
|
+
payment_options: {
|
|
113
|
+
api_key: {
|
|
114
|
+
url: `https://gateway.thegraph.com/api/subgraphs/id/${subgraphId}`,
|
|
115
|
+
method: "POST",
|
|
116
|
+
auth_header: "Authorization: Bearer <STUDIO_API_KEY>",
|
|
117
|
+
get_a_key: "https://thegraph.com/studio/apikeys/",
|
|
118
|
+
cost: "included in your Studio plan (100K free queries/month)",
|
|
119
|
+
use_when: "you already have, or can obtain, a Graph Studio API key",
|
|
120
|
+
},
|
|
121
|
+
x402: {
|
|
122
|
+
url: `${X402_GATEWAY_BASE}/subgraphs/id/${subgraphId}`,
|
|
123
|
+
method: "POST",
|
|
124
|
+
cost: "$0.01 USDC on Base per query",
|
|
125
|
+
flow: "gateway returns HTTP 402 with a payment manifest; an x402 client (@graphprotocol/client-x402, x402-fetch) signs and retries automatically",
|
|
126
|
+
use_when: "you have a funded wallet and no API key, and no human to mint one",
|
|
127
|
+
},
|
|
128
|
+
},
|
|
95
129
|
pricing: X402_PRICING,
|
|
96
130
|
};
|
|
97
131
|
}
|
|
@@ -309,7 +343,8 @@ const EMERGING_LIMIT = 3;
|
|
|
309
343
|
// the same columns — they feed the same row mapper.
|
|
310
344
|
const SEARCH_COLS = `id, display_name, description, auto_description, domain, protocol_type, network,
|
|
311
345
|
reliability_score, ipfs_hash, entity_count, canonical_entities,
|
|
312
|
-
powered_by_substreams, active_allocation_count, example_query, denied_at, created_at
|
|
346
|
+
powered_by_substreams, active_allocation_count, example_query, denied_at, created_at,
|
|
347
|
+
query_volume_30d`;
|
|
313
348
|
|
|
314
349
|
function ageDays(created_at) {
|
|
315
350
|
if (!created_at) return null;
|
|
@@ -487,6 +522,12 @@ function searchSubgraphs({
|
|
|
487
522
|
protocol_type: r.protocol_type,
|
|
488
523
|
network: r.network,
|
|
489
524
|
reliability_score: r.reliability_score,
|
|
525
|
+
// The registry has this number and the official Graph MCP's
|
|
526
|
+
// get_deployment_30day_query_counts was observed returning 0 for
|
|
527
|
+
// deployments that plainly serve traffic, so it could not break ties
|
|
528
|
+
// between a real protocol and its forks. Surfacing it here is what lets a
|
|
529
|
+
// caller tell Lido (4.7M queries/30d) from lido-copy.
|
|
530
|
+
query_volume_30d: r.query_volume_30d ?? null,
|
|
490
531
|
ipfs_hash: r.ipfs_hash,
|
|
491
532
|
entity_count: r.entity_count,
|
|
492
533
|
canonical_entities: JSON.parse(r.canonical_entities),
|
|
@@ -496,7 +537,6 @@ function searchSubgraphs({
|
|
|
496
537
|
// caller passed include_denied — surfaced so that choice stays visible
|
|
497
538
|
// in the result rather than being silently carried.
|
|
498
539
|
denied: Boolean(r.denied_at),
|
|
499
|
-
testnet: isTestnetNetwork(r.network),
|
|
500
540
|
testnet: isTestnetNetwork(r.network),
|
|
501
541
|
// Ready-to-run GraphQL generated from this subgraph's actual schema — so an
|
|
502
542
|
// agent can POST it to query_url_x402 immediately, no get_subgraph_detail round-trip.
|
|
@@ -524,6 +564,12 @@ function searchSubgraphs({
|
|
|
524
564
|
protocol_type: r.protocol_type,
|
|
525
565
|
network: r.network,
|
|
526
566
|
reliability_score: r.reliability_score,
|
|
567
|
+
// The registry has this number and the official Graph MCP's
|
|
568
|
+
// get_deployment_30day_query_counts was observed returning 0 for
|
|
569
|
+
// deployments that plainly serve traffic, so it could not break ties
|
|
570
|
+
// between a real protocol and its forks. Surfacing it here is what lets a
|
|
571
|
+
// caller tell Lido (4.7M queries/30d) from lido-copy.
|
|
572
|
+
query_volume_30d: r.query_volume_30d ?? null,
|
|
527
573
|
ipfs_hash: r.ipfs_hash,
|
|
528
574
|
entity_count: r.entity_count,
|
|
529
575
|
canonical_entities: JSON.parse(r.canonical_entities),
|
|
@@ -543,7 +589,7 @@ function searchSubgraphs({
|
|
|
543
589
|
...(emerging.length
|
|
544
590
|
? { emerging, emerging_caveat: EMERGING_CAVEAT }
|
|
545
591
|
: {}),
|
|
546
|
-
query_instructions: "
|
|
592
|
+
query_instructions: "This registry does DISCOVERY, not execution — it hands you the subgraph id and a ready-to-run `example_query`, and you run the query with whatever Graph client you already have. Two equally valid routes, pick by what you have: (a) API KEY — POST to `query_url` with header `Authorization: Bearer <STUDIO_API_KEY>` (get one at https://thegraph.com/studio/apikeys/, 100K free queries/month). Note the gateway returns HTTP 200 with a GraphQL error body when the header is missing, so read the body. (b) x402 — POST to `query_url_x402` and pay $0.01 USDC on Base per query, no key and no signup; the gateway answers 402 with a payment manifest and an x402 client signs and retries. Use (a) if you hold a key, (b) if you are headless with a funded wallet. If your client already has an official Graph MCP or gateway connector, just pass it the `id` from this result and ignore both URLs. See `payment_options` for the full shape of each.",
|
|
547
593
|
};
|
|
548
594
|
}
|
|
549
595
|
|
|
@@ -678,6 +724,12 @@ function recommendSubgraph({ goal, chain = "" }) {
|
|
|
678
724
|
protocol_type: r.protocol_type,
|
|
679
725
|
network: r.network,
|
|
680
726
|
reliability_score: r.reliability_score,
|
|
727
|
+
// The registry has this number and the official Graph MCP's
|
|
728
|
+
// get_deployment_30day_query_counts was observed returning 0 for
|
|
729
|
+
// deployments that plainly serve traffic, so it could not break ties
|
|
730
|
+
// between a real protocol and its forks. Surfacing it here is what lets a
|
|
731
|
+
// caller tell Lido (4.7M queries/30d) from lido-copy.
|
|
732
|
+
query_volume_30d: r.query_volume_30d ?? null,
|
|
681
733
|
ipfs_hash: r.ipfs_hash,
|
|
682
734
|
canonical_entities: JSON.parse(r.canonical_entities),
|
|
683
735
|
active_allocation_count: r.active_allocation_count || 0,
|
|
@@ -742,7 +794,11 @@ function getSubgraphDetail({ subgraph_id }) {
|
|
|
742
794
|
const exampleQuery = result.example_query || FALLBACK_EXAMPLE;
|
|
743
795
|
|
|
744
796
|
result.query_instructions = {
|
|
745
|
-
|
|
797
|
+
// No single recommendation: see payment_options on each result. Callers
|
|
798
|
+
// hold either a Studio key or a wallet, rarely both, and the registry has
|
|
799
|
+
// no way to know which — so it states both and lets the caller choose.
|
|
800
|
+
recommended: null,
|
|
801
|
+
routes: ["api_key", "x402"],
|
|
746
802
|
x402: {
|
|
747
803
|
url: endpoints.query_url_x402,
|
|
748
804
|
payment: endpoints.pricing,
|
|
@@ -1039,13 +1095,18 @@ async function semanticSearchSubgraphs({
|
|
|
1039
1095
|
protocol_type: r.protocol_type,
|
|
1040
1096
|
network: r.network,
|
|
1041
1097
|
reliability_score: r.reliability_score,
|
|
1098
|
+
// The registry has this number and the official Graph MCP's
|
|
1099
|
+
// get_deployment_30day_query_counts was observed returning 0 for
|
|
1100
|
+
// deployments that plainly serve traffic, so it could not break ties
|
|
1101
|
+
// between a real protocol and its forks. Surfacing it here is what lets a
|
|
1102
|
+
// caller tell Lido (4.7M queries/30d) from lido-copy.
|
|
1103
|
+
query_volume_30d: r.query_volume_30d ?? null,
|
|
1042
1104
|
ipfs_hash: r.ipfs_hash,
|
|
1043
1105
|
entity_count: r.entity_count,
|
|
1044
1106
|
canonical_entities: JSON.parse(r.canonical_entities),
|
|
1045
1107
|
powered_by_substreams: Boolean(r.powered_by_substreams),
|
|
1046
1108
|
active_allocation_count: r.active_allocation_count || 0,
|
|
1047
1109
|
denied: Boolean(r.denied_at),
|
|
1048
|
-
testnet: isTestnetNetwork(r.network),
|
|
1049
1110
|
testnet: isTestnetNetwork(r.network),
|
|
1050
1111
|
example_query: r.example_query || null,
|
|
1051
1112
|
// No `emerging` companion list here: this tool ranks by cosine score,
|
|
@@ -1067,7 +1128,7 @@ async function semanticSearchSubgraphs({
|
|
|
1067
1128
|
model: "sentence-transformers/all-MiniLM-L6-v2",
|
|
1068
1129
|
subgraphs: results,
|
|
1069
1130
|
query_instructions:
|
|
1070
|
-
"Each result includes
|
|
1131
|
+
"Each result includes both query routes in `payment_options` — a keyed gateway URL (Authorization: Bearer <STUDIO_API_KEY>) and an x402 URL ($0.01 USDC on Base, no key). Use whichever your client already has. semantic_score is cosine similarity in [0,1]; values >0.5 are typically strong matches.",
|
|
1071
1132
|
};
|
|
1072
1133
|
}
|
|
1073
1134
|
|
|
@@ -1237,7 +1298,7 @@ const TOOLS = [
|
|
|
1237
1298
|
{
|
|
1238
1299
|
name: "search_subgraphs",
|
|
1239
1300
|
description:
|
|
1240
|
-
"Search and filter the classified subgraph registry (15,000+ subgraphs). Filter by domain (defi, nfts, dao, gaming, identity, infrastructure, social, analytics), network (mainnet, arbitrum-one, base, matic, bsc, optimism, avalanche), protocol_type (dex, lending, bridge, staking, options, perpetuals, nft-marketplace, yield-aggregator, governance, name-service), canonical entity type (liquidity_pool, trade, token, position, vault, loan, collateral, liquidation, nft_collection, nft_item, nft_sale, proposal, delegate, domain_name, account, transaction, daily_snapshot, hourly_snapshot), or free-text keyword. Returns subgraphs ranked by reliability score. Each result
|
|
1301
|
+
"Search and filter the classified subgraph registry (15,000+ subgraphs). Filter by domain (defi, nfts, dao, gaming, identity, infrastructure, social, analytics), network (mainnet, arbitrum-one, base, matic, bsc, optimism, avalanche), protocol_type (dex, lending, bridge, staking, options, perpetuals, nft-marketplace, yield-aggregator, governance, name-service), canonical entity type (liquidity_pool, trade, token, position, vault, loan, collateral, liquidation, nft_collection, nft_item, nft_sale, proposal, delegate, domain_name, account, transaction, daily_snapshot, hourly_snapshot), or free-text keyword. Returns subgraphs ranked by reliability score. Discovery only — this tool does not execute GraphQL. Each result carries the subgraph id, a ready-to-run example_query, and both query routes in `payment_options`: a keyed gateway URL (Authorization: Bearer) or an x402 URL ($0.01 USDC on Base, no key). Pass the id to your own Graph client if you have one. Plus age_days and maturity (new | emerging | established). Because reliability_score is cumulative it structurally favours older deployments, so a separate `emerging` list carries recent matches that ranked below the main cut for age rather than quality — read `emerging_caveat` before offering one to a user.",
|
|
1241
1302
|
inputSchema: {
|
|
1242
1303
|
type: "object",
|
|
1243
1304
|
additionalProperties: false,
|
|
@@ -1270,7 +1331,7 @@ const TOOLS = [
|
|
|
1270
1331
|
{
|
|
1271
1332
|
name: "recommend_subgraph",
|
|
1272
1333
|
description:
|
|
1273
|
-
"Given a natural-language goal like 'find DEX trades on Arbitrum' or 'get lending liquidation data', returns the best matching subgraphs with reliability scores. Automatically infers domain and protocol type from the goal. Each result
|
|
1334
|
+
"Given a natural-language goal like 'find DEX trades on Arbitrum' or 'get lending liquidation data', returns the best matching subgraphs with reliability scores. Automatically infers domain and protocol type from the goal. Discovery only — it returns ids and starter queries, it does not execute GraphQL. Each result carries both query routes in `payment_options`: a keyed gateway URL (Authorization: Bearer <STUDIO_API_KEY>) or an x402 URL ($0.01 USDC on Base, no key).",
|
|
1274
1335
|
inputSchema: {
|
|
1275
1336
|
type: "object",
|
|
1276
1337
|
additionalProperties: false,
|