subgraph-registry-mcp 0.9.4 → 0.9.6

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 CHANGED
@@ -2,8 +2,8 @@
2
2
  "openapi": "3.1.0",
3
3
  "info": {
4
4
  "title": "Subgraph Registry",
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.4",
5
+ "description": "Agent-friendly subgraph discovery on The Graph Network. 15,330 classified subgraphs with semantic search, reliability scoring, 30-day query volume and schema-evolution tracking. Discovery only: returns subgraph ids and starter queries, which you run with a Graph Studio API key (Authorization: Bearer) or over x402 ($0.01 USDC on Base, no key).",
6
+ "version": "0.9.6",
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 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), 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.",
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 includes query_url_x402 (preferred — POST GraphQL, pay $0.01 USDC on Base per query, no API key) and a legacy query_url for Studio-key flows.",
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
@@ -4,8 +4,8 @@
4
4
  openapi: "3.1.0"
5
5
  info:
6
6
  title: "Subgraph Registry"
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.4"
7
+ description: "Agent-friendly subgraph discovery on The Graph Network. 15,330 classified subgraphs with semantic search, reliability scoring, 30-day query volume and schema-evolution tracking. Discovery only: returns subgraph ids and starter queries, which you run with a Graph Studio API key (Authorization: Bearer) or over x402 ($0.01 USDC on Base, no key)."
8
+ version: "0.9.6"
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 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), 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."
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 includes query_url_x402 (preferred — POST GraphQL, pay $0.01 USDC on Base per query, no API key) and a legacy query_url for Studio-key flows."
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,8 +1,8 @@
1
1
  {
2
2
  "name": "subgraph-registry-mcp",
3
- "version": "0.9.4",
3
+ "version": "0.9.6",
4
4
  "mcpName": "io.github.PaulieB14/subgraph-registry-mcp",
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.",
5
+ "description": "MCP server for agent-friendly subgraph discovery on The Graph Network. 15,330 classified subgraphs with reliability scoring, 30-day query volume, semantic search and protocol classification. Discovery only — returns subgraph ids and ready-to-run queries for you to run with a Graph Studio key or over x402.",
6
6
  "type": "module",
7
7
  "bin": {
8
8
  "subgraph-registry-mcp": "src/index.js"
package/src/index.js CHANGED
@@ -90,8 +90,42 @@ const X402_PRICING = {
90
90
 
91
91
  function buildQueryEndpoints(subgraphId) {
92
92
  return {
93
- query_url: `https://gateway.thegraph.com/api/[api-key]/subgraphs/id/${subgraphId}`,
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: "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/. Each result includes a ready-to-run `example_query` generated from that subgraph's real schema — POST it to query_url_x402 as-is, or adapt the entity/fields. Use get_subgraph_detail for the full schema.",
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
 
@@ -643,6 +689,7 @@ function recommendSubgraph({ goal, chain = "" }) {
643
689
  const sql = `
644
690
  SELECT id, display_name, description, auto_description, domain, protocol_type, network,
645
691
  reliability_score, ipfs_hash, canonical_entities, active_allocation_count, example_query,
692
+ query_volume_30d,
646
693
  (${goalScore}) AS goal_score
647
694
  FROM subgraphs
648
695
  ${where}
@@ -678,6 +725,12 @@ function recommendSubgraph({ goal, chain = "" }) {
678
725
  protocol_type: r.protocol_type,
679
726
  network: r.network,
680
727
  reliability_score: r.reliability_score,
728
+ // The registry has this number and the official Graph MCP's
729
+ // get_deployment_30day_query_counts was observed returning 0 for
730
+ // deployments that plainly serve traffic, so it could not break ties
731
+ // between a real protocol and its forks. Surfacing it here is what lets a
732
+ // caller tell Lido (4.7M queries/30d) from lido-copy.
733
+ query_volume_30d: r.query_volume_30d ?? null,
681
734
  ipfs_hash: r.ipfs_hash,
682
735
  canonical_entities: JSON.parse(r.canonical_entities),
683
736
  active_allocation_count: r.active_allocation_count || 0,
@@ -742,7 +795,11 @@ function getSubgraphDetail({ subgraph_id }) {
742
795
  const exampleQuery = result.example_query || FALLBACK_EXAMPLE;
743
796
 
744
797
  result.query_instructions = {
745
- recommended: "x402",
798
+ // No single recommendation: see payment_options on each result. Callers
799
+ // hold either a Studio key or a wallet, rarely both, and the registry has
800
+ // no way to know which — so it states both and lets the caller choose.
801
+ recommended: null,
802
+ routes: ["api_key", "x402"],
746
803
  x402: {
747
804
  url: endpoints.query_url_x402,
748
805
  payment: endpoints.pricing,
@@ -750,9 +807,13 @@ function getSubgraphDetail({ subgraph_id }) {
750
807
  client_libraries: ["@graphprotocol/client-x402", "x402-fetch"],
751
808
  example_query: exampleQuery,
752
809
  },
753
- api_key_legacy: {
810
+ // Not "legacy" — this is the route most callers should take, and the one
811
+ // some MCP hosts allow exclusively. The old text also told you to replace
812
+ // an `[api-key]` placeholder that no longer exists in the URL.
813
+ api_key: {
754
814
  url: endpoints.query_url,
755
- flow: "Get an API key from https://thegraph.com/studio/apikeys/, replace [api-key] in the url, then POST GraphQL.",
815
+ flow: "Get a key at https://thegraph.com/studio/apikeys/ (100K free queries/month), then POST GraphQL to url with header `Authorization: Bearer <STUDIO_API_KEY>`. The key goes in the header, not the path. A missing header returns HTTP 200 with a GraphQL error body, so read the body rather than trusting the status.",
816
+ example_query: exampleQuery,
756
817
  },
757
818
  schema_hint: result.example_query
758
819
  ? "example_query above was generated from this subgraph's actual schema. Adapt the entity name + field selection as needed."
@@ -993,7 +1054,8 @@ async function semanticSearchSubgraphs({
993
1054
  `SELECT id, display_name, description, auto_description, domain,
994
1055
  protocol_type, network, reliability_score, ipfs_hash,
995
1056
  entity_count, canonical_entities, powered_by_substreams,
996
- active_allocation_count, example_query, denied_at, created_at, embedding
1057
+ active_allocation_count, example_query, denied_at, created_at,
1058
+ query_volume_30d, embedding
997
1059
  FROM subgraphs
998
1060
  ${where}`,
999
1061
  )
@@ -1039,13 +1101,18 @@ async function semanticSearchSubgraphs({
1039
1101
  protocol_type: r.protocol_type,
1040
1102
  network: r.network,
1041
1103
  reliability_score: r.reliability_score,
1104
+ // The registry has this number and the official Graph MCP's
1105
+ // get_deployment_30day_query_counts was observed returning 0 for
1106
+ // deployments that plainly serve traffic, so it could not break ties
1107
+ // between a real protocol and its forks. Surfacing it here is what lets a
1108
+ // caller tell Lido (4.7M queries/30d) from lido-copy.
1109
+ query_volume_30d: r.query_volume_30d ?? null,
1042
1110
  ipfs_hash: r.ipfs_hash,
1043
1111
  entity_count: r.entity_count,
1044
1112
  canonical_entities: JSON.parse(r.canonical_entities),
1045
1113
  powered_by_substreams: Boolean(r.powered_by_substreams),
1046
1114
  active_allocation_count: r.active_allocation_count || 0,
1047
1115
  denied: Boolean(r.denied_at),
1048
- testnet: isTestnetNetwork(r.network),
1049
1116
  testnet: isTestnetNetwork(r.network),
1050
1117
  example_query: r.example_query || null,
1051
1118
  // No `emerging` companion list here: this tool ranks by cosine score,
@@ -1067,7 +1134,7 @@ async function semanticSearchSubgraphs({
1067
1134
  model: "sentence-transformers/all-MiniLM-L6-v2",
1068
1135
  subgraphs: results,
1069
1136
  query_instructions:
1070
- "Each result includes query_url_x402 (pay $0.01 USDC on Base, no API key) and a legacy query_url. semantic_score is cosine similarity in [0,1]; values >0.5 are typically strong matches.",
1137
+ "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
1138
  };
1072
1139
  }
1073
1140
 
@@ -1237,7 +1304,7 @@ const TOOLS = [
1237
1304
  {
1238
1305
  name: "search_subgraphs",
1239
1306
  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 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), 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.",
1307
+ "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
1308
  inputSchema: {
1242
1309
  type: "object",
1243
1310
  additionalProperties: false,
@@ -1270,7 +1337,7 @@ const TOOLS = [
1270
1337
  {
1271
1338
  name: "recommend_subgraph",
1272
1339
  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 includes query_url_x402 (preferred — POST GraphQL, pay $0.01 USDC on Base per query, no API key) and a legacy query_url for Studio-key flows.",
1340
+ "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
1341
  inputSchema: {
1275
1342
  type: "object",
1276
1343
  additionalProperties: false,