subgraph-registry-mcp 0.5.0 → 0.6.2

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 CHANGED
@@ -18,8 +18,48 @@ Agents querying The Graph need to discover and select the right subgraph before
18
18
  2. **Fetches** the GraphQL schema for every deployment
19
19
  3. **Classifies** each subgraph by domain, protocol type, canonical entities, and schema family
20
20
  4. **Scores** reliability using on-chain signals (query fees, volume, curation, stake)
21
- 5. **Publishes** as SQLite database + REST API + MCP server
22
- 6. **Generates** visual dashboards and bot-readable category files (auto-updated with each sync)
21
+ 5. **Returns x402 + legacy query URLs** agents can pay $0.01 USDC on Base per query (no API key) or use a Studio key
22
+ 6. **Publishes** as SQLite database + REST API + MCP server
23
+ 7. **Generates** visual dashboards and bot-readable category files (auto-updated with each sync)
24
+
25
+ ---
26
+
27
+ ## Querying with x402 (no API key)
28
+
29
+ Every result includes `query_url_x402` alongside the legacy `query_url`. The Graph's public x402 gateway (live since 2026-05-08) accepts **$0.01 USDC on Base** per query with zero signup.
30
+
31
+ ```js
32
+ // An x402-native agent — discovery to data in two calls
33
+ const { recommendations } = await mcp.call("recommend_subgraph", {
34
+ goal: "find DEX trades on Arbitrum",
35
+ });
36
+ const top = recommendations[0];
37
+
38
+ // POST your GraphQL query. The first call returns HTTP 402 with a
39
+ // base64 `payment-required` header; the x402 client signs the
40
+ // EIP-3009 USDC transfer on Base and retries automatically.
41
+ const data = await x402Fetch(top.query_url_x402, {
42
+ method: "POST",
43
+ body: JSON.stringify({ query: "{ swaps(first: 5) { id amountUSD } }" }),
44
+ });
45
+ ```
46
+
47
+ Pricing manifest returned per subgraph:
48
+
49
+ ```json
50
+ {
51
+ "amount_usd": 0.01,
52
+ "asset": "USDC",
53
+ "asset_contract": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
54
+ "chain": "base",
55
+ "network": "eip155:8453",
56
+ "pay_to": "0x79DC34E41B2b591078d3dE222C43EcaaBD52FcCB",
57
+ "scheme": "exact",
58
+ "asset_transfer_method": "eip3009"
59
+ }
60
+ ```
61
+
62
+ Client libraries: [`@graphprotocol/client-x402`](https://www.npmjs.com/package/@graphprotocol/client-x402), `x402-fetch`, or any generic x402 wrapper.
23
63
 
24
64
  ---
25
65
 
package/data/registry.db CHANGED
Binary file
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "subgraph-registry-mcp",
3
- "version": "0.5.0",
3
+ "version": "0.6.2",
4
4
  "mcpName": "io.github.PaulieB14/subgraph-registry-mcp",
5
- "description": "MCP server for agent-friendly subgraph discovery on The Graph Network. 14,733 classified subgraphs with query hints with domain, protocol type, and reliability scoring.",
5
+ "description": "MCP server for agent-friendly subgraph discovery on The Graph Network. 14,733 classified subgraphs with x402 query URLs ($0.01 USDC on Base, no API key required), reliability scoring, and protocol classification.",
6
6
  "type": "module",
7
7
  "bin": {
8
8
  "subgraph-registry-mcp": "src/index.js"
package/src/index.js CHANGED
@@ -45,11 +45,37 @@ const GITHUB_DB_URL =
45
45
  // 3. Paste the new hash here and bump package.json version
46
46
  // 4. Update SKILL.md "Verifying the registry" section
47
47
  const EXPECTED_DB_SHA256 =
48
- "f81b79c53cc13c3428472024187fc7fd502f7418f5da20f0a6e01807dd4011c6";
48
+ "363084a27f22214f58553f48de42b15a7e4d7b7fb1ff6e0bcc4032465a8ae785";
49
49
  // Skip-verification escape hatch (set to "1" only if you're rebuilding the DB
50
50
  // locally and know what you're doing — never set in agent-runtime defaults).
51
51
  const SKIP_VERIFY = process.env.SUBGRAPH_REGISTRY_SKIP_VERIFY === "1";
52
52
 
53
+ // ── x402 gateway constants ─────────────────────────────────
54
+ // The Graph's public x402 gateway (live since 2026-05-08) lets agents pay
55
+ // per-query in USDC on Base without any API key. POST GraphQL to query_url_x402
56
+ // and the gateway returns HTTP 402 with a payment manifest; an x402 client
57
+ // (e.g. @graphprotocol/client-x402, x402-fetch) signs the EIP-3009 USDC
58
+ // transfer and retries automatically.
59
+ const X402_GATEWAY_BASE = "https://gateway.thegraph.com/api/x402";
60
+ const X402_PRICING = {
61
+ amount_usd: 0.01,
62
+ asset: "USDC",
63
+ asset_contract: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", // USDC on Base
64
+ chain: "base",
65
+ network: "eip155:8453",
66
+ pay_to: "0x79DC34E41B2b591078d3dE222C43EcaaBD52FcCB", // Graph x402 gateway
67
+ scheme: "exact",
68
+ asset_transfer_method: "eip3009",
69
+ };
70
+
71
+ function buildQueryEndpoints(subgraphId) {
72
+ return {
73
+ query_url: `https://gateway.thegraph.com/api/[api-key]/subgraphs/id/${subgraphId}`,
74
+ query_url_x402: `${X402_GATEWAY_BASE}/subgraphs/id/${subgraphId}`,
75
+ pricing: X402_PRICING,
76
+ };
77
+ }
78
+
53
79
  // ── Download DB from GitHub if missing ─────────────────────
54
80
 
55
81
  function sha256OfFile(path) {
@@ -140,11 +166,18 @@ function searchSubgraphs({
140
166
  protocol_type = "",
141
167
  entity = "",
142
168
  min_reliability = 0,
169
+ include_unserved = false,
143
170
  limit = 20,
144
171
  } = {}) {
145
172
  const conditions = [];
146
173
  const params = [];
147
174
 
175
+ // Default: hide deployments with 0 active indexer allocations — these
176
+ // return "subgraph not found: no allocations" even though the ID is valid.
177
+ if (!include_unserved) {
178
+ conditions.push("active_allocation_count > 0");
179
+ }
180
+
148
181
  if (domain) {
149
182
  conditions.push("domain = ?");
150
183
  params.push(domain);
@@ -183,7 +216,7 @@ function searchSubgraphs({
183
216
  const sql = `
184
217
  SELECT id, display_name, description, auto_description, domain, protocol_type, network,
185
218
  reliability_score, ipfs_hash, entity_count, canonical_entities,
186
- powered_by_substreams
219
+ powered_by_substreams, active_allocation_count
187
220
  FROM subgraphs
188
221
  ${where}
189
222
  ORDER BY reliability_score DESC
@@ -210,7 +243,8 @@ function searchSubgraphs({
210
243
  entity_count: r.entity_count,
211
244
  canonical_entities: JSON.parse(r.canonical_entities),
212
245
  powered_by_substreams: Boolean(r.powered_by_substreams),
213
- query_url: `https://gateway.thegraph.com/api/[api-key]/subgraphs/id/${r.id}`,
246
+ active_allocation_count: r.active_allocation_count || 0,
247
+ ...buildQueryEndpoints(r.id),
214
248
  });
215
249
  if (results.length >= limit) break;
216
250
  }
@@ -218,7 +252,7 @@ function searchSubgraphs({
218
252
  return {
219
253
  total: results.length,
220
254
  subgraphs: results,
221
- query_instructions: "To query a subgraph: POST a GraphQL query to the query_url (replace [api-key] with your Graph API key from https://thegraph.com/studio/apikeys/). First fetch the schema with get_subgraph_detail to see available entities and fields.",
255
+ query_instructions: "Two ways to query: (a) RECOMMENDED POST GraphQL to query_url_x402 and pay $0.01 USDC on Base per query via x402 (no API key required; gateway returns HTTP 402 with a payment manifest, use an x402 client like @graphprotocol/client-x402 to sign and retry). (b) LEGACY — replace [api-key] in query_url with a Graph API key from https://thegraph.com/studio/apikeys/. Call get_subgraph_detail first for the schema.",
222
256
  };
223
257
  }
224
258
 
@@ -253,7 +287,7 @@ function recommendSubgraph({ goal, chain = "" }) {
253
287
  .filter(([, kws]) => kws.some((k) => goalLower.includes(k)))
254
288
  .map(([t]) => t);
255
289
 
256
- const conditions = [];
290
+ const conditions = ["active_allocation_count > 0"];
257
291
  const params = [];
258
292
 
259
293
  if (chain) {
@@ -278,10 +312,10 @@ function recommendSubgraph({ goal, chain = "" }) {
278
312
  }
279
313
  }
280
314
 
281
- const where = conditions.length ? `WHERE ${conditions.join(" AND ")}` : "";
315
+ const where = `WHERE ${conditions.join(" AND ")}`;
282
316
  const sql = `
283
317
  SELECT id, display_name, description, auto_description, domain, protocol_type, network,
284
- reliability_score, ipfs_hash, canonical_entities
318
+ reliability_score, ipfs_hash, canonical_entities, active_allocation_count
285
319
  FROM subgraphs
286
320
  ${where}
287
321
  ORDER BY reliability_score DESC
@@ -304,7 +338,8 @@ function recommendSubgraph({ goal, chain = "" }) {
304
338
  reliability_score: r.reliability_score,
305
339
  ipfs_hash: r.ipfs_hash,
306
340
  canonical_entities: JSON.parse(r.canonical_entities),
307
- query_url: `https://gateway.thegraph.com/api/[api-key]/subgraphs/id/${r.id}`,
341
+ active_allocation_count: r.active_allocation_count || 0,
342
+ ...buildQueryEndpoints(r.id),
308
343
  });
309
344
  if (recommendations.length >= 5) break;
310
345
  }
@@ -333,12 +368,24 @@ function getSubgraphDetail({ subgraph_id }) {
333
368
  if (!result.description && result.auto_description) {
334
369
  result.description = result.auto_description;
335
370
  }
336
- result.query_url = `https://gateway.thegraph.com/api/[api-key]/subgraphs/id/${result.id}`;
371
+ const endpoints = buildQueryEndpoints(result.id);
372
+ result.query_url = endpoints.query_url;
373
+ result.query_url_x402 = endpoints.query_url_x402;
374
+ result.pricing = endpoints.pricing;
337
375
  result.query_instructions = {
338
- step_1: "Get an API key from https://thegraph.com/studio/apikeys/",
339
- step_2: `Replace [api-key] in the query_url: https://gateway.thegraph.com/api/YOUR_KEY/subgraphs/id/${result.id}`,
340
- step_3: "POST a GraphQL query to that URL. Example: { pools(first: 5, orderBy: totalValueLockedUSD, orderDirection: desc) { id token0 { symbol } token1 { symbol } totalValueLockedUSD } }",
341
- note: "Use the all_entities field above to see what entities and fields are available to query.",
376
+ recommended: "x402",
377
+ x402: {
378
+ url: endpoints.query_url_x402,
379
+ payment: endpoints.pricing,
380
+ flow: "POST GraphQL to url. Gateway returns HTTP 402 with a base64 payment-required header containing the payment manifest. Sign $0.01 USDC on Base with an x402 client and retry. No API key, no signup.",
381
+ client_libraries: ["@graphprotocol/client-x402", "x402-fetch"],
382
+ example_query: "{ pools(first: 5, orderBy: totalValueLockedUSD, orderDirection: desc) { id token0 { symbol } token1 { symbol } totalValueLockedUSD } }",
383
+ },
384
+ api_key_legacy: {
385
+ url: endpoints.query_url,
386
+ flow: "Get an API key from https://thegraph.com/studio/apikeys/, replace [api-key] in the url, then POST GraphQL.",
387
+ },
388
+ schema_hint: "Use the all_entities field above to see what entities and fields are available to query.",
342
389
  };
343
390
  return result;
344
391
  }
@@ -370,7 +417,7 @@ const TOOLS = [
370
417
  {
371
418
  name: "search_subgraphs",
372
419
  description:
373
- "Search and filter the classified subgraph registry (15,500+ 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 with query URLs. To query data: POST GraphQL to https://gateway.thegraph.com/api/[api-key]/subgraphs/id/[subgraph-id] (get API key from https://thegraph.com/studio/apikeys/).",
420
+ "Search and filter the classified subgraph registry (15,500+ 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 includes query_url_x402 (POST GraphQL and pay $0.01 USDC on Base per query no API key needed) and a legacy query_url (Studio API key required).",
374
421
  inputSchema: {
375
422
  type: "object",
376
423
  properties: {
@@ -387,7 +434,7 @@ const TOOLS = [
387
434
  {
388
435
  name: "recommend_subgraph",
389
436
  description:
390
- "Given a natural-language goal like 'find DEX trades on Arbitrum' or 'get lending liquidation data', returns the best matching subgraphs with reliability scores and query URLs. Automatically infers domain and protocol type from the goal. Each result includes a query_urlreplace [api-key] with your Graph API key to query live data.",
437
+ "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 includes query_url_x402 (preferredPOST GraphQL, pay $0.01 USDC on Base per query, no API key) and a legacy query_url for Studio-key flows.",
391
438
  inputSchema: {
392
439
  type: "object",
393
440
  properties: {
@@ -400,7 +447,7 @@ const TOOLS = [
400
447
  {
401
448
  name: "get_subgraph_detail",
402
449
  description:
403
- "Get full classification detail for a specific subgraph by its subgraph ID or IPFS hash. Returns domain, protocol type, canonical entities, all entity names with field counts, reliability score, signal data, query URL, and step-by-step query instructions.",
450
+ "Get full classification detail for a specific subgraph by its subgraph ID or IPFS hash. Returns domain, protocol type, canonical entities, all entity names with field counts, reliability score, signal data, both query URLs (x402 and legacy), the x402 pricing manifest ($0.01 USDC on Base), and step-by-step instructions for both query paths.",
404
451
  inputSchema: {
405
452
  type: "object",
406
453
  properties: {
@@ -429,7 +476,7 @@ const HANDLERS = {
429
476
 
430
477
  function createServer() {
431
478
  const server = new Server(
432
- { name: "subgraph-registry", version: "0.3.0" },
479
+ { name: "subgraph-registry", version: "0.6.0" },
433
480
  { capabilities: { tools: {} } }
434
481
  );
435
482