chain-insights 0.44.0 → 0.45.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 +8 -6
- package/bin/install.cjs +2 -4
- package/dist/cache-location-BO2XkfgI.mjs +11 -0
- package/dist/cache-location-BO2XkfgI.mjs.map +1 -0
- package/dist/cache-location-CBVzUIxq.cjs +23 -0
- package/dist/{capabilities-A8fsfP24.cjs → capabilities-BGkL9yAr.cjs} +6 -0
- package/dist/{capabilities-DfWL6n_g.mjs → capabilities-Cur8x6c7.mjs} +2 -2
- package/dist/{capabilities-DfWL6n_g.mjs.map → capabilities-Cur8x6c7.mjs.map} +1 -1
- package/dist/cli.cjs +32 -6
- package/dist/cli.mjs +32 -6
- package/dist/cli.mjs.map +1 -1
- package/dist/graph-schema-D1orCe5F.mjs +914 -0
- package/dist/graph-schema-D1orCe5F.mjs.map +1 -0
- package/dist/graph-schema-znb_9MYq.cjs +972 -0
- package/dist/mcp-proxy.cjs +43 -462
- package/dist/mcp-proxy.d.cts.map +1 -1
- package/dist/mcp-proxy.d.mts.map +1 -1
- package/dist/mcp-proxy.mjs +35 -454
- package/dist/mcp-proxy.mjs.map +1 -1
- package/dist/public-tools-CZyeptJQ.mjs.map +1 -1
- package/dist/{schema-cache-DJdU4MIP.mjs → schema-cache-BT-kHy_r.mjs} +4 -5
- package/dist/schema-cache-BT-kHy_r.mjs.map +1 -0
- package/dist/{schema-cache-n7Gbhvsj.cjs → schema-cache-DwddPLcY.cjs} +3 -5
- package/docs/architecture.md +2 -0
- package/docs/graph-query-compatibility.md +4 -5
- package/docs/graph-tools.md +22 -14
- package/docs/mcp-proxy.md +17 -5
- package/docs/stability.md +2 -1
- package/package.json +1 -1
- package/skills/chain-insights-cypher/SKILL.md +137 -67
- package/skills/chain-insights-cypher/agents/openai.yaml +1 -1
- package/dist/schema-cache-DJdU4MIP.mjs.map +0 -1
- package/skills/chain-insights-schema-evm/SKILL.md +0 -541
package/README.md
CHANGED
|
@@ -30,6 +30,7 @@ npx chain-insights@latest --help # run without installing
|
|
|
30
30
|
npm install -g chain-insights # or install the cia CLI globally
|
|
31
31
|
cia networks # network status + dataset overview
|
|
32
32
|
cia network robinhood # details for one network
|
|
33
|
+
cia network robinhood --schema # live graph schema, cached for 24 hours
|
|
33
34
|
cia mcp tools # list remote graph tools
|
|
34
35
|
```
|
|
35
36
|
|
|
@@ -52,10 +53,9 @@ cia mcp call --json graph_query \
|
|
|
52
53
|
The `plugin/` folder is the Chain Insights plugin for Claude. It starts the
|
|
53
54
|
local Chain Insights MCP proxy on your computer over stdio
|
|
54
55
|
(`chain-insights-mcp-proxy` from the npm package, through `npx`), and brings the
|
|
55
|
-
`chain-insights-cypher`
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
Insights Graph for the data.
|
|
56
|
+
`chain-insights-cypher` skill. The proxy serves the views itself (a graph, a
|
|
57
|
+
chart or a table, picked from the column names of a `graph_query` answer, and
|
|
58
|
+
the balance), and reaches the Chain Insights Graph for the data.
|
|
59
59
|
|
|
60
60
|
- **Runs in:** Claude Desktop, Cowork sessions on your computer, and Claude Code.
|
|
61
61
|
- **Cannot start it:** claude.ai on the web, the Claude mobile apps and Cowork
|
|
@@ -118,6 +118,7 @@ Never touches:
|
|
|
118
118
|
| `graph_query` | Run one read-only GQL/Cypher query against a Chain Insights Graph layer |
|
|
119
119
|
| `graph_query_batch` | Run related read-only graph queries as one MCP call |
|
|
120
120
|
| `meta_network_capabilities` | Check supported Chain Insights networks and graph tools |
|
|
121
|
+
| `meta_schema` | Read the live graph schema of a network: labels, link types, fields, indexes |
|
|
121
122
|
| `meta_usage_status` | Check the caller's daily free-tier graph query allowance |
|
|
122
123
|
| `meta_help` | Show Chain Insights tool and workflow guidance |
|
|
123
124
|
| `wallet_balance` | Show the local payment wallet amount |
|
|
@@ -189,8 +190,9 @@ on `:Address` without an exact address must scope itself with
|
|
|
189
190
|
database and `Address` carries no `network` property at all. See
|
|
190
191
|
[Graph query compatibility](docs/graph-query-compatibility.md).
|
|
191
192
|
|
|
192
|
-
Agent installs include `chain-insights-cypher` for graph-query dialect rules
|
|
193
|
-
|
|
193
|
+
Agent installs include `chain-insights-cypher` for graph-query dialect rules,
|
|
194
|
+
one query for each kind of graph search, and how to find the fields of the
|
|
195
|
+
EVM / Robinhood graph.
|
|
194
196
|
|
|
195
197
|
## Billing: Billable Units
|
|
196
198
|
|
package/bin/install.cjs
CHANGED
|
@@ -49,10 +49,7 @@ const homeDir = os.homedir()
|
|
|
49
49
|
const dataDir = path.join(homeDir, '.chain-insights')
|
|
50
50
|
const configPath = path.join(dataDir, 'config.json')
|
|
51
51
|
const srcSkillsDir = path.join(__dirname, '..', 'skills')
|
|
52
|
-
const PUBLIC_SKILL_NAMES = Object.freeze([
|
|
53
|
-
'chain-insights-cypher',
|
|
54
|
-
'chain-insights-schema-evm',
|
|
55
|
-
])
|
|
52
|
+
const PUBLIC_SKILL_NAMES = Object.freeze(['chain-insights-cypher'])
|
|
56
53
|
const RETIRED_SKILL_NAMES = Object.freeze([
|
|
57
54
|
'chain-insights-address-risk',
|
|
58
55
|
'chain-insights-bittensor-cypher',
|
|
@@ -60,6 +57,7 @@ const RETIRED_SKILL_NAMES = Object.freeze([
|
|
|
60
57
|
'chain-insights-investigation',
|
|
61
58
|
'chain-insights-monitoring',
|
|
62
59
|
'chain-insights-schema-bittensor',
|
|
60
|
+
'chain-insights-schema-evm',
|
|
63
61
|
'ci-status',
|
|
64
62
|
'test-chain-insights-graph',
|
|
65
63
|
])
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
//#region src/mcp/cache-location.ts
|
|
4
|
+
const CACHE_TTL_MS = 864e5;
|
|
5
|
+
function chainInsightsHome() {
|
|
6
|
+
return path.join(os.homedir(), ".chain-insights");
|
|
7
|
+
}
|
|
8
|
+
//#endregion
|
|
9
|
+
export { chainInsightsHome as n, CACHE_TTL_MS as t };
|
|
10
|
+
|
|
11
|
+
//# sourceMappingURL=cache-location-BO2XkfgI.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache-location-BO2XkfgI.mjs","names":[],"sources":["../src/mcp/cache-location.ts"],"sourcesContent":["import path from 'node:path'\nimport os from 'node:os'\n\n// One home and one lifetime for every file cache of the package: the tool list\n// (mcp-schema.json) and the graph schema (cache/schema-<network>-<endpoint>.json).\n// The home is read at call time so a test can point HOME at a temporary\n// directory.\n\nexport const CACHE_TTL_MS = 24 * 60 * 60 * 1000 // 24 hours\n\nexport function chainInsightsHome(): string {\n return path.join(os.homedir(), '.chain-insights')\n}\n"],"mappings":";;;AAQA,MAAa,eAAe;AAE5B,SAAgB,oBAA4B;CAC1C,OAAO,KAAK,KAAK,GAAG,QAAQ,GAAG,iBAAiB;AAClD"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
const require_rolldown_runtime = require("./rolldown-runtime-C0BPl7ul.cjs");
|
|
2
|
+
let node_path = require("node:path");
|
|
3
|
+
node_path = require_rolldown_runtime.__toESM(node_path, 1);
|
|
4
|
+
let node_os = require("node:os");
|
|
5
|
+
node_os = require_rolldown_runtime.__toESM(node_os, 1);
|
|
6
|
+
//#region src/mcp/cache-location.ts
|
|
7
|
+
const CACHE_TTL_MS = 864e5;
|
|
8
|
+
function chainInsightsHome() {
|
|
9
|
+
return node_path.default.join(node_os.default.homedir(), ".chain-insights");
|
|
10
|
+
}
|
|
11
|
+
//#endregion
|
|
12
|
+
Object.defineProperty(exports, "CACHE_TTL_MS", {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get: function() {
|
|
15
|
+
return CACHE_TTL_MS;
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
Object.defineProperty(exports, "chainInsightsHome", {
|
|
19
|
+
enumerable: true,
|
|
20
|
+
get: function() {
|
|
21
|
+
return chainInsightsHome;
|
|
22
|
+
}
|
|
23
|
+
});
|
|
@@ -203,6 +203,12 @@ Object.defineProperty(exports, "capabilities_exports", {
|
|
|
203
203
|
return capabilities_exports;
|
|
204
204
|
}
|
|
205
205
|
});
|
|
206
|
+
Object.defineProperty(exports, "findNetworkCapability", {
|
|
207
|
+
enumerable: true,
|
|
208
|
+
get: function() {
|
|
209
|
+
return findNetworkCapability;
|
|
210
|
+
}
|
|
211
|
+
});
|
|
206
212
|
Object.defineProperty(exports, "mirrorGraphNetworkCapabilities", {
|
|
207
213
|
enumerable: true,
|
|
208
214
|
get: function() {
|
|
@@ -197,6 +197,6 @@ function formatNetworkCapability(network) {
|
|
|
197
197
|
return rows.map(([label, value]) => `${label.padEnd(labelWidth)} ${value}`).join("\n");
|
|
198
198
|
}
|
|
199
199
|
//#endregion
|
|
200
|
-
export {
|
|
200
|
+
export { findNetworkCapability as n, mirrorGraphNetworkCapabilities as r, capabilities_exports as t };
|
|
201
201
|
|
|
202
|
-
//# sourceMappingURL=capabilities-
|
|
202
|
+
//# sourceMappingURL=capabilities-Cur8x6c7.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"capabilities-DfWL6n_g.mjs","names":[],"sources":["../src/mcp/capabilities.ts"],"sourcesContent":["import type { InvestigatorConfig } from '../config/schema.js'\nimport { applyMcpAuthHeaders, resolveGraphMcpEndpoint } from './client.js'\n\nexport interface NetworkTopologyLayer {\n enabled: boolean\n coverage?: {\n from_block?: number\n to_block?: number\n from_timestamp?: string\n to_timestamp?: string\n chain_tip_block?: number\n blocks_behind_tip?: number\n /** Lowest height among the raw-data lanes that have started. Above it an empty answer may mean \"not indexed yet\". */\n complete_through_block?: number\n }\n}\n\nexport interface NetworkLayerCapability {\n enabled: boolean\n live?: NetworkTopologyLayer\n archive?: NetworkTopologyLayer\n /** The relationships a facts layer serves, when the server lists them. */\n relationships?: string[]\n}\n\n/**\n * A block the server publishes about one layer's limits. The mirror repeats it\n * exactly as it came: the members named below are the ones known today, and\n * any other member the server adds is kept. Read a limit from the block, never\n * from a number written elsewhere.\n */\nexport type NetworkAdmissionBlock = Record<string, unknown>\n\n/** `USE chain`: the lookups, the ceilings and the slots of the chain layer. */\nexport interface ChainAdmission extends NetworkAdmissionBlock {\n enabled: boolean\n /** ok, or the reason the layer is off or behind. */\n status?: string\n rules_version?: string\n grammar?: string\n /** The labels of `USE chain`, such as Transaction, Block and Head. */\n lookups?: string[]\n ceiling_seconds?: Record<string, number>\n slots?: number\n past_slots?: number\n slots_per_caller?: number\n calls_per_second_per_caller?: number\n batch_max?: number\n call_gas?: number\n head_ttl_ms?: number\n max_head_age_seconds?: number\n}\n\n/** `USE topology`: the shape rules, when the server publishes them. */\nexport interface TopologyAdmission extends NetworkAdmissionBlock {\n rules_version?: string\n max_hops_per_path?: number\n max_limit?: number\n slots?: number\n}\n\n/** `USE facts`: the read contract, when the server publishes it. */\nexport interface FactsAdmission extends NetworkAdmissionBlock {\n rules_version?: string\n window_days?: number\n max_rows?: number\n max_hops?: number\n}\n\nexport interface NetworkCapability {\n network: string\n display_name?: string\n status: string\n default?: boolean\n /** The layers as the server sent them. Absent when the server sent none. */\n layers?: Record<string, NetworkLayerCapability>\n tools: Record<string, string>\n /** The three layer blocks below are repeated exactly as sent, and absent when not sent. */\n chain_admission?: ChainAdmission\n topology_admission?: TopologyAdmission\n facts_admission?: FactsAdmission\n coverage?: {\n from_block?: number\n to_block?: number\n from_timestamp?: string\n to_timestamp?: string\n chain_tip_block?: number\n blocks_behind_tip?: number\n /** Lowest height among the raw-data lanes that have started. Above it an empty answer may mean \"not indexed yet\". */\n complete_through_block?: number\n }\n freshness?: {\n last_processed_at?: string\n last_successful_sync_at?: string\n max_data_age_seconds?: number\n last_processing_duration_seconds?: number\n }\n lane_progress?: NetworkLaneProgress[]\n graph_progress?: NetworkGraphProgress\n}\n\n/** One writer lane's committed height. null: the lane has not started. */\nexport interface NetworkLaneProgress {\n lane: string\n height: number | null\n}\n\n/** How far each block layer of the topology graph reaches, and their lowest. */\nexport interface NetworkGraphProgress {\n complete_through_block: number\n layers: { layer: string; position: number }[]\n}\n\nexport interface NetworkCapabilitiesDocument {\n schema: 'chain-insights.network-capabilities.v1'\n networks: NetworkCapability[]\n}\n\nconst AVAILABLE_TOOLS_PER_LINE = 3\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nfunction advertisedTools(raw: unknown): Record<string, string> {\n if (!isRecord(raw)) return {}\n const tools: Record<string, string> = {}\n for (const [name, status] of Object.entries(raw)) {\n if (name.trim() !== '' && typeof status === 'string') tools[name] = status\n }\n return tools\n}\n\nfunction advertisedLaneProgress(raw: unknown): NetworkLaneProgress[] | undefined {\n if (!Array.isArray(raw)) return undefined\n const lanes: NetworkLaneProgress[] = []\n for (const entry of raw) {\n if (!isRecord(entry) || typeof entry.lane !== 'string' || entry.lane.trim() === '') continue\n if (typeof entry.height === 'number') lanes.push({ lane: entry.lane, height: entry.height })\n else if (entry.height === null) lanes.push({ lane: entry.lane, height: null })\n }\n return lanes\n}\n\nfunction advertisedGraphProgress(raw: unknown): NetworkGraphProgress | undefined {\n if (!isRecord(raw) || typeof raw.complete_through_block !== 'number') return undefined\n if (!Array.isArray(raw.layers)) return undefined\n const layers: NetworkGraphProgress['layers'] = []\n for (const entry of raw.layers) {\n if (!isRecord(entry) || typeof entry.layer !== 'string' || typeof entry.position !== 'number')\n continue\n layers.push({ layer: entry.layer, position: entry.position })\n }\n return { complete_through_block: raw.complete_through_block, layers }\n}\n\nfunction advertisedNetwork(raw: unknown): NetworkCapability | null {\n if (!isRecord(raw) || typeof raw.network !== 'string' || raw.network.trim() === '') {\n return null\n }\n const network = raw.network.trim()\n const capability: NetworkCapability = {\n network,\n display_name:\n typeof raw.display_name === 'string' && raw.display_name.trim() !== ''\n ? raw.display_name\n : network,\n status: typeof raw.status === 'string' && raw.status.trim() !== '' ? raw.status : 'live',\n tools: advertisedTools(raw.tools),\n }\n // The layer blocks are the server's own words about its limits. They pass\n // through exactly as sent: nothing is added, no default is invented and no\n // member is dropped. A block the server did not send stays absent.\n if (isRecord(raw.layers)) capability.layers = raw.layers as NetworkCapability['layers']\n if (isRecord(raw.chain_admission)) {\n capability.chain_admission = raw.chain_admission as unknown as ChainAdmission\n }\n if (isRecord(raw.topology_admission)) {\n capability.topology_admission = raw.topology_admission as TopologyAdmission\n }\n if (isRecord(raw.facts_admission)) {\n capability.facts_admission = raw.facts_admission as FactsAdmission\n }\n if (raw.default === true) capability.default = true\n if (raw.default === false) capability.default = false\n if (isRecord(raw.coverage)) capability.coverage = raw.coverage as NetworkCapability['coverage']\n if (isRecord(raw.freshness))\n capability.freshness = raw.freshness as NetworkCapability['freshness']\n const laneProgress = advertisedLaneProgress(raw.lane_progress)\n if (laneProgress) capability.lane_progress = laneProgress\n const graphProgress = advertisedGraphProgress(raw.graph_progress)\n if (graphProgress) capability.graph_progress = graphProgress\n return capability\n}\n\n/** Repeat GraphRAG's network list. CIA does not add, drop, or invent names. */\nexport function mirrorGraphNetworkCapabilities(document: {\n networks: unknown[]\n}): NetworkCapabilitiesDocument {\n return {\n schema: 'chain-insights.network-capabilities.v1',\n networks: document.networks\n .map((network) => advertisedNetwork(network))\n .filter((network): network is NetworkCapability => network !== null),\n }\n}\n\nfunction publicNetworkCapabilities(\n document: NetworkCapabilitiesDocument\n): NetworkCapabilitiesDocument {\n return mirrorGraphNetworkCapabilities(document)\n}\n\nfunction metadataNetworksUrl(endpoint: string): URL {\n const url = new URL(endpoint)\n url.pathname = '/metadata/networks'\n url.search = ''\n url.hash = ''\n return url\n}\n\nexport async function fetchNetworkCapabilities(\n config: Pick<InvestigatorConfig, 'graphMcpAuthToken' | 'graphMcpMode' | 'graphMcpEndpoint'>\n): Promise<NetworkCapabilitiesDocument> {\n const endpoint = resolveGraphMcpEndpoint(config)\n const request = metadataNetworksUrl(endpoint)\n const headers = new Headers()\n const token = config.graphMcpAuthToken?.trim()\n if (token) {\n applyMcpAuthHeaders(headers, token)\n }\n let response: Response\n try {\n response = await fetch(request, { headers })\n } catch (err) {\n throw new Error(`network capabilities unavailable at ${request}: ${(err as Error).message}`)\n }\n if (!response.ok) {\n throw new Error(`network capabilities unavailable at ${request}: HTTP ${response.status}`)\n }\n const parsed = (await response.json()) as NetworkCapabilitiesDocument\n if (\n parsed.schema !== 'chain-insights.network-capabilities.v1' ||\n !Array.isArray(parsed.networks)\n ) {\n throw new Error('network capabilities response has unsupported schema')\n }\n return publicNetworkCapabilities(parsed)\n}\n\nfunction availableTools(network: NetworkCapability): string[] {\n const tools = Object.entries(network.tools ?? {})\n .filter(([, status]) => status === 'available')\n .map(([name]) => name)\n return tools.sort()\n}\n\nfunction availableToolLines(network: NetworkCapability): string[] {\n const tools = availableTools(network)\n if (tools.length === 0) return ['none']\n const lines: string[] = []\n for (let index = 0; index < tools.length; index += AVAILABLE_TOOLS_PER_LINE) {\n lines.push(tools.slice(index, index + AVAILABLE_TOOLS_PER_LINE).join(', '))\n }\n return lines\n}\n\nfunction shortDate(value?: string): string {\n if (!value) return ''\n return value.slice(0, 10)\n}\n\nfunction datasetLabel(network: NetworkCapability): string {\n const coverage = network.coverage\n if (!coverage) return 'unknown'\n const blockRange =\n coverage.from_block !== undefined && coverage.to_block !== undefined\n ? `${coverage.from_block}..${coverage.to_block}`\n : 'blocks unknown'\n const dateRange =\n coverage.from_timestamp && coverage.to_timestamp\n ? `${shortDate(coverage.from_timestamp)}..${shortDate(coverage.to_timestamp)}`\n : ''\n if (blockRange === 'blocks unknown' && dateRange === '') return 'unknown'\n if (blockRange === 'blocks unknown') return dateRange\n if (dateRange === '') return blockRange\n return `${blockRange} / ${dateRange}`\n}\n\nfunction displayName(network: NetworkCapability): string {\n return network.display_name || network.network\n}\n\nfunction statusLabel(network: NetworkCapability): string {\n return network.default ? `${network.status} (default)` : network.status\n}\n\nfunction formatTable(headers: string[], rows: string[][], minimumWidths: number[]): string {\n const widths = headers.map((header, index) =>\n Math.max(\n minimumWidths[index] ?? 0,\n header.length,\n ...rows.map((row) => row[index]?.length ?? 0)\n )\n )\n const row = (values: string[]) =>\n values.map((value, index) => value.padEnd(widths[index]!)).join(' ')\n return [row(headers), widths.map((width) => '-'.repeat(width)).join(' '), ...rows.map(row)].join(\n '\\n'\n )\n}\n\nexport function formatNetworkOverview(document: NetworkCapabilitiesDocument): string {\n if (document.networks.length === 0) return 'No supported networks advertised.'\n const rows = document.networks.map((network) => [\n displayName(network),\n statusLabel(network),\n datasetLabel(network),\n ])\n return formatTable(['Network', 'Status', 'Dataset'], rows, [14, 10, 38])\n}\n\nexport function formatNetworkCapabilities(document: NetworkCapabilitiesDocument): string {\n if (document.networks.length === 0) return 'No supported networks advertised.'\n const networkRows = document.networks.flatMap((network) => {\n const toolLines = availableToolLines(network)\n return toolLines.map((toolLine, index) => [\n index === 0 ? displayName(network) : '',\n index === 0 ? datasetLabel(network) : '',\n toolLine,\n ])\n })\n return formatTable(['Network', 'Dataset', 'Chain Insights tools'], networkRows, [14, 38, 64])\n}\n\nexport function findNetworkCapability(\n document: NetworkCapabilitiesDocument,\n name: string\n): NetworkCapability | undefined {\n const normalizedName = name.trim().toLowerCase()\n if (!normalizedName) return undefined\n return document.networks.find((network) =>\n [network.network, network.display_name].some(\n (candidate) => candidate?.trim().toLowerCase() === normalizedName\n )\n )\n}\n\nexport function formatNetworkCapability(network: NetworkCapability): string {\n const rows = [\n ['Network', network.display_name || network.network],\n ['Identifier', network.network],\n ['Status', network.default ? `${network.status} (default)` : network.status],\n ['Dataset', datasetLabel(network)],\n ['Available tools', availableTools(network).join(', ') || 'none'],\n ]\n const labelWidth = Math.max(...rows.map(([label]) => label.length))\n return rows.map(([label, value]) => `${label.padEnd(labelWidth)} ${value}`).join('\\n')\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"capabilities-Cur8x6c7.mjs","names":[],"sources":["../src/mcp/capabilities.ts"],"sourcesContent":["import type { InvestigatorConfig } from '../config/schema.js'\nimport { applyMcpAuthHeaders, resolveGraphMcpEndpoint } from './client.js'\n\nexport interface NetworkTopologyLayer {\n enabled: boolean\n coverage?: {\n from_block?: number\n to_block?: number\n from_timestamp?: string\n to_timestamp?: string\n chain_tip_block?: number\n blocks_behind_tip?: number\n /** Lowest height among the raw-data lanes that have started. Above it an empty answer may mean \"not indexed yet\". */\n complete_through_block?: number\n }\n}\n\nexport interface NetworkLayerCapability {\n enabled: boolean\n live?: NetworkTopologyLayer\n archive?: NetworkTopologyLayer\n /** The relationships a facts layer serves, when the server lists them. */\n relationships?: string[]\n}\n\n/**\n * A block the server publishes about one layer's limits. The mirror repeats it\n * exactly as it came: the members named below are the ones known today, and\n * any other member the server adds is kept. Read a limit from the block, never\n * from a number written elsewhere.\n */\nexport type NetworkAdmissionBlock = Record<string, unknown>\n\n/** `USE chain`: the lookups, the ceilings and the slots of the chain layer. */\nexport interface ChainAdmission extends NetworkAdmissionBlock {\n enabled: boolean\n /** ok, or the reason the layer is off or behind. */\n status?: string\n rules_version?: string\n grammar?: string\n /** The labels of `USE chain`, such as Transaction, Block and Head. */\n lookups?: string[]\n ceiling_seconds?: Record<string, number>\n slots?: number\n past_slots?: number\n slots_per_caller?: number\n calls_per_second_per_caller?: number\n batch_max?: number\n call_gas?: number\n head_ttl_ms?: number\n max_head_age_seconds?: number\n}\n\n/** `USE topology`: the shape rules, when the server publishes them. */\nexport interface TopologyAdmission extends NetworkAdmissionBlock {\n rules_version?: string\n max_hops_per_path?: number\n max_limit?: number\n slots?: number\n}\n\n/** `USE facts`: the read contract, when the server publishes it. */\nexport interface FactsAdmission extends NetworkAdmissionBlock {\n rules_version?: string\n window_days?: number\n max_rows?: number\n max_hops?: number\n}\n\nexport interface NetworkCapability {\n network: string\n display_name?: string\n status: string\n default?: boolean\n /** The layers as the server sent them. Absent when the server sent none. */\n layers?: Record<string, NetworkLayerCapability>\n tools: Record<string, string>\n /** The three layer blocks below are repeated exactly as sent, and absent when not sent. */\n chain_admission?: ChainAdmission\n topology_admission?: TopologyAdmission\n facts_admission?: FactsAdmission\n coverage?: {\n from_block?: number\n to_block?: number\n from_timestamp?: string\n to_timestamp?: string\n chain_tip_block?: number\n blocks_behind_tip?: number\n /** Lowest height among the raw-data lanes that have started. Above it an empty answer may mean \"not indexed yet\". */\n complete_through_block?: number\n }\n freshness?: {\n last_processed_at?: string\n last_successful_sync_at?: string\n max_data_age_seconds?: number\n last_processing_duration_seconds?: number\n }\n lane_progress?: NetworkLaneProgress[]\n graph_progress?: NetworkGraphProgress\n}\n\n/** One writer lane's committed height. null: the lane has not started. */\nexport interface NetworkLaneProgress {\n lane: string\n height: number | null\n}\n\n/** How far each block layer of the topology graph reaches, and their lowest. */\nexport interface NetworkGraphProgress {\n complete_through_block: number\n layers: { layer: string; position: number }[]\n}\n\nexport interface NetworkCapabilitiesDocument {\n schema: 'chain-insights.network-capabilities.v1'\n networks: NetworkCapability[]\n}\n\nconst AVAILABLE_TOOLS_PER_LINE = 3\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nfunction advertisedTools(raw: unknown): Record<string, string> {\n if (!isRecord(raw)) return {}\n const tools: Record<string, string> = {}\n for (const [name, status] of Object.entries(raw)) {\n if (name.trim() !== '' && typeof status === 'string') tools[name] = status\n }\n return tools\n}\n\nfunction advertisedLaneProgress(raw: unknown): NetworkLaneProgress[] | undefined {\n if (!Array.isArray(raw)) return undefined\n const lanes: NetworkLaneProgress[] = []\n for (const entry of raw) {\n if (!isRecord(entry) || typeof entry.lane !== 'string' || entry.lane.trim() === '') continue\n if (typeof entry.height === 'number') lanes.push({ lane: entry.lane, height: entry.height })\n else if (entry.height === null) lanes.push({ lane: entry.lane, height: null })\n }\n return lanes\n}\n\nfunction advertisedGraphProgress(raw: unknown): NetworkGraphProgress | undefined {\n if (!isRecord(raw) || typeof raw.complete_through_block !== 'number') return undefined\n if (!Array.isArray(raw.layers)) return undefined\n const layers: NetworkGraphProgress['layers'] = []\n for (const entry of raw.layers) {\n if (!isRecord(entry) || typeof entry.layer !== 'string' || typeof entry.position !== 'number')\n continue\n layers.push({ layer: entry.layer, position: entry.position })\n }\n return { complete_through_block: raw.complete_through_block, layers }\n}\n\nfunction advertisedNetwork(raw: unknown): NetworkCapability | null {\n if (!isRecord(raw) || typeof raw.network !== 'string' || raw.network.trim() === '') {\n return null\n }\n const network = raw.network.trim()\n const capability: NetworkCapability = {\n network,\n display_name:\n typeof raw.display_name === 'string' && raw.display_name.trim() !== ''\n ? raw.display_name\n : network,\n status: typeof raw.status === 'string' && raw.status.trim() !== '' ? raw.status : 'live',\n tools: advertisedTools(raw.tools),\n }\n // The layer blocks are the server's own words about its limits. They pass\n // through exactly as sent: nothing is added, no default is invented and no\n // member is dropped. A block the server did not send stays absent.\n if (isRecord(raw.layers)) capability.layers = raw.layers as NetworkCapability['layers']\n if (isRecord(raw.chain_admission)) {\n capability.chain_admission = raw.chain_admission as unknown as ChainAdmission\n }\n if (isRecord(raw.topology_admission)) {\n capability.topology_admission = raw.topology_admission as TopologyAdmission\n }\n if (isRecord(raw.facts_admission)) {\n capability.facts_admission = raw.facts_admission as FactsAdmission\n }\n if (raw.default === true) capability.default = true\n if (raw.default === false) capability.default = false\n if (isRecord(raw.coverage)) capability.coverage = raw.coverage as NetworkCapability['coverage']\n if (isRecord(raw.freshness))\n capability.freshness = raw.freshness as NetworkCapability['freshness']\n const laneProgress = advertisedLaneProgress(raw.lane_progress)\n if (laneProgress) capability.lane_progress = laneProgress\n const graphProgress = advertisedGraphProgress(raw.graph_progress)\n if (graphProgress) capability.graph_progress = graphProgress\n return capability\n}\n\n/** Repeat GraphRAG's network list. CIA does not add, drop, or invent names. */\nexport function mirrorGraphNetworkCapabilities(document: {\n networks: unknown[]\n}): NetworkCapabilitiesDocument {\n return {\n schema: 'chain-insights.network-capabilities.v1',\n networks: document.networks\n .map((network) => advertisedNetwork(network))\n .filter((network): network is NetworkCapability => network !== null),\n }\n}\n\nfunction publicNetworkCapabilities(\n document: NetworkCapabilitiesDocument\n): NetworkCapabilitiesDocument {\n return mirrorGraphNetworkCapabilities(document)\n}\n\nfunction metadataNetworksUrl(endpoint: string): URL {\n const url = new URL(endpoint)\n url.pathname = '/metadata/networks'\n url.search = ''\n url.hash = ''\n return url\n}\n\nexport async function fetchNetworkCapabilities(\n config: Pick<InvestigatorConfig, 'graphMcpAuthToken' | 'graphMcpMode' | 'graphMcpEndpoint'>\n): Promise<NetworkCapabilitiesDocument> {\n const endpoint = resolveGraphMcpEndpoint(config)\n const request = metadataNetworksUrl(endpoint)\n const headers = new Headers()\n const token = config.graphMcpAuthToken?.trim()\n if (token) {\n applyMcpAuthHeaders(headers, token)\n }\n let response: Response\n try {\n response = await fetch(request, { headers })\n } catch (err) {\n throw new Error(`network capabilities unavailable at ${request}: ${(err as Error).message}`)\n }\n if (!response.ok) {\n throw new Error(`network capabilities unavailable at ${request}: HTTP ${response.status}`)\n }\n const parsed = (await response.json()) as NetworkCapabilitiesDocument\n if (\n parsed.schema !== 'chain-insights.network-capabilities.v1' ||\n !Array.isArray(parsed.networks)\n ) {\n throw new Error('network capabilities response has unsupported schema')\n }\n return publicNetworkCapabilities(parsed)\n}\n\nfunction availableTools(network: NetworkCapability): string[] {\n const tools = Object.entries(network.tools ?? {})\n .filter(([, status]) => status === 'available')\n .map(([name]) => name)\n return tools.sort()\n}\n\nfunction availableToolLines(network: NetworkCapability): string[] {\n const tools = availableTools(network)\n if (tools.length === 0) return ['none']\n const lines: string[] = []\n for (let index = 0; index < tools.length; index += AVAILABLE_TOOLS_PER_LINE) {\n lines.push(tools.slice(index, index + AVAILABLE_TOOLS_PER_LINE).join(', '))\n }\n return lines\n}\n\nfunction shortDate(value?: string): string {\n if (!value) return ''\n return value.slice(0, 10)\n}\n\nfunction datasetLabel(network: NetworkCapability): string {\n const coverage = network.coverage\n if (!coverage) return 'unknown'\n const blockRange =\n coverage.from_block !== undefined && coverage.to_block !== undefined\n ? `${coverage.from_block}..${coverage.to_block}`\n : 'blocks unknown'\n const dateRange =\n coverage.from_timestamp && coverage.to_timestamp\n ? `${shortDate(coverage.from_timestamp)}..${shortDate(coverage.to_timestamp)}`\n : ''\n if (blockRange === 'blocks unknown' && dateRange === '') return 'unknown'\n if (blockRange === 'blocks unknown') return dateRange\n if (dateRange === '') return blockRange\n return `${blockRange} / ${dateRange}`\n}\n\nfunction displayName(network: NetworkCapability): string {\n return network.display_name || network.network\n}\n\nfunction statusLabel(network: NetworkCapability): string {\n return network.default ? `${network.status} (default)` : network.status\n}\n\nfunction formatTable(headers: string[], rows: string[][], minimumWidths: number[]): string {\n const widths = headers.map((header, index) =>\n Math.max(\n minimumWidths[index] ?? 0,\n header.length,\n ...rows.map((row) => row[index]?.length ?? 0)\n )\n )\n const row = (values: string[]) =>\n values.map((value, index) => value.padEnd(widths[index]!)).join(' ')\n return [row(headers), widths.map((width) => '-'.repeat(width)).join(' '), ...rows.map(row)].join(\n '\\n'\n )\n}\n\nexport function formatNetworkOverview(document: NetworkCapabilitiesDocument): string {\n if (document.networks.length === 0) return 'No supported networks advertised.'\n const rows = document.networks.map((network) => [\n displayName(network),\n statusLabel(network),\n datasetLabel(network),\n ])\n return formatTable(['Network', 'Status', 'Dataset'], rows, [14, 10, 38])\n}\n\nexport function formatNetworkCapabilities(document: NetworkCapabilitiesDocument): string {\n if (document.networks.length === 0) return 'No supported networks advertised.'\n const networkRows = document.networks.flatMap((network) => {\n const toolLines = availableToolLines(network)\n return toolLines.map((toolLine, index) => [\n index === 0 ? displayName(network) : '',\n index === 0 ? datasetLabel(network) : '',\n toolLine,\n ])\n })\n return formatTable(['Network', 'Dataset', 'Chain Insights tools'], networkRows, [14, 38, 64])\n}\n\nexport function findNetworkCapability(\n document: NetworkCapabilitiesDocument,\n name: string\n): NetworkCapability | undefined {\n const normalizedName = name.trim().toLowerCase()\n if (!normalizedName) return undefined\n return document.networks.find((network) =>\n [network.network, network.display_name].some(\n (candidate) => candidate?.trim().toLowerCase() === normalizedName\n )\n )\n}\n\nexport function formatNetworkCapability(network: NetworkCapability): string {\n const rows = [\n ['Network', network.display_name || network.network],\n ['Identifier', network.network],\n ['Status', network.default ? `${network.status} (default)` : network.status],\n ['Dataset', datasetLabel(network)],\n ['Available tools', availableTools(network).join(', ') || 'none'],\n ]\n const labelWidth = Math.max(...rows.map(([label]) => label.length))\n return rows.map(([label, value]) => `${label.padEnd(labelWidth)} ${value}`).join('\\n')\n}\n"],"mappings":"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"}
|
package/dist/cli.cjs
CHANGED
|
@@ -120,21 +120,21 @@ async function withGraphMcpClient(name, fn) {
|
|
|
120
120
|
}
|
|
121
121
|
async function printNetworkCapabilities(opts) {
|
|
122
122
|
const { loadConfig } = await Promise.resolve().then(() => require("./config-BxtMoo9c.cjs")).then((n) => n.config_exports);
|
|
123
|
-
const { fetchNetworkCapabilities, formatNetworkCapabilities } = await Promise.resolve().then(() => require("./capabilities-
|
|
123
|
+
const { fetchNetworkCapabilities, formatNetworkCapabilities } = await Promise.resolve().then(() => require("./capabilities-BGkL9yAr.cjs")).then((n) => n.capabilities_exports);
|
|
124
124
|
const document = await fetchNetworkCapabilities(await loadConfig());
|
|
125
125
|
if (opts.json) console.log(JSON.stringify(document, null, 2));
|
|
126
126
|
else console.log(formatNetworkCapabilities(document));
|
|
127
127
|
}
|
|
128
128
|
async function printNetworkOverview(opts) {
|
|
129
129
|
const { loadConfig } = await Promise.resolve().then(() => require("./config-BxtMoo9c.cjs")).then((n) => n.config_exports);
|
|
130
|
-
const { fetchNetworkCapabilities, formatNetworkOverview } = await Promise.resolve().then(() => require("./capabilities-
|
|
130
|
+
const { fetchNetworkCapabilities, formatNetworkOverview } = await Promise.resolve().then(() => require("./capabilities-BGkL9yAr.cjs")).then((n) => n.capabilities_exports);
|
|
131
131
|
const document = await fetchNetworkCapabilities(await loadConfig());
|
|
132
132
|
if (opts.json) console.log(JSON.stringify(document, null, 2));
|
|
133
133
|
else console.log(formatNetworkOverview(document));
|
|
134
134
|
}
|
|
135
135
|
async function printNetworkCapability(name, opts) {
|
|
136
136
|
const { loadConfig } = await Promise.resolve().then(() => require("./config-BxtMoo9c.cjs")).then((n) => n.config_exports);
|
|
137
|
-
const { fetchNetworkCapabilities, findNetworkCapability, formatNetworkCapability } = await Promise.resolve().then(() => require("./capabilities-
|
|
137
|
+
const { fetchNetworkCapabilities, findNetworkCapability, formatNetworkCapability } = await Promise.resolve().then(() => require("./capabilities-BGkL9yAr.cjs")).then((n) => n.capabilities_exports);
|
|
138
138
|
const document = await fetchNetworkCapabilities(await loadConfig());
|
|
139
139
|
const network = findNetworkCapability(document, name);
|
|
140
140
|
if (!network) {
|
|
@@ -146,6 +146,23 @@ async function printNetworkCapability(name, opts) {
|
|
|
146
146
|
else console.log(formatNetworkCapability(network));
|
|
147
147
|
}
|
|
148
148
|
/**
|
|
149
|
+
* The live graph schema of one network (meta_schema). A fresh cache answers with
|
|
150
|
+
* no request; a build opens one session and reads through it.
|
|
151
|
+
*/
|
|
152
|
+
async function printNetworkSchema(name, opts) {
|
|
153
|
+
const { loadConfig } = await Promise.resolve().then(() => require("./config-BxtMoo9c.cjs")).then((n) => n.config_exports);
|
|
154
|
+
const { resolveGraphMcpEndpoint } = await Promise.resolve().then(() => require("./client-Ypw9BNbn.cjs")).then((n) => n.client_exports);
|
|
155
|
+
const { formatGraphSchemaText, getGraphSchema } = await Promise.resolve().then(() => require("./graph-schema-znb_9MYq.cjs")).then((n) => n.graph_schema_exports);
|
|
156
|
+
const config = await loadConfig();
|
|
157
|
+
const schema = await getGraphSchema({
|
|
158
|
+
network: name,
|
|
159
|
+
refresh: opts.refresh === true,
|
|
160
|
+
endpoint: resolveGraphMcpEndpoint(config),
|
|
161
|
+
withClient: (fn) => withGraphMcpClient("chain-insights-cli-schema", (client) => fn(client))
|
|
162
|
+
});
|
|
163
|
+
console.log(opts.json ? JSON.stringify(schema, null, 2) : formatGraphSchemaText(schema));
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
149
166
|
* Fetches the caller's subscription facts for the deposit pre-sign guard.
|
|
150
167
|
* The extension math is server-authoritative: the printed values come from
|
|
151
168
|
* `subscription_status`. Any failure (no wallet, unreachable endpoint,
|
|
@@ -234,9 +251,11 @@ program.command("networks").description("Show supported network status and datas
|
|
|
234
251
|
process.exit(1);
|
|
235
252
|
}
|
|
236
253
|
});
|
|
237
|
-
program.command("network").description("Show details for one supported graph network").argument("<name>", "Network identifier or display name (for example: robinhood)").option("--json", "Print raw capability JSON for this network").action(async (name, opts) => {
|
|
254
|
+
program.command("network").description("Show details for one supported graph network").argument("<name>", "Network identifier or display name (for example: robinhood)").option("--json", "Print raw capability JSON for this network (with --schema: the schema JSON)").option("--schema", "Show the live graph schema: labels, link types, fields and indexes (cached for 24 hours)").option("--refresh", "With --schema: rebuild the schema now instead of reading the cache").action(async (name, opts) => {
|
|
238
255
|
try {
|
|
239
|
-
|
|
256
|
+
if (opts.refresh && !opts.schema) throw new Error("--refresh needs --schema: run `cia network <name> --schema --refresh`.");
|
|
257
|
+
if (opts.schema) await printNetworkSchema(name, opts);
|
|
258
|
+
else await printNetworkCapability(name, opts);
|
|
240
259
|
} catch (err) {
|
|
241
260
|
console.error(err.message);
|
|
242
261
|
process.exit(1);
|
|
@@ -550,7 +569,7 @@ program.command("mcp").description("Low-level access to the Chain Insights MCP e
|
|
|
550
569
|
}
|
|
551
570
|
})).addCommand(createCliCommand("tools").description("List the remote GraphRAG MCP tools (cached for 24 hours)").option("--refresh", "Force refresh schema cache").action(async (opts) => {
|
|
552
571
|
try {
|
|
553
|
-
const { loadSchema, saveSchema } = await Promise.resolve().then(() => require("./schema-cache-
|
|
572
|
+
const { loadSchema, saveSchema } = await Promise.resolve().then(() => require("./schema-cache-DwddPLcY.cjs"));
|
|
554
573
|
const { formatToolsTable } = await Promise.resolve().then(() => require("./format-BjZuYDr8.cjs"));
|
|
555
574
|
const { visibleRemoteTools } = await Promise.resolve().then(() => require("./tool-visibility-CDe-ft0L.cjs")).then((n) => n.tool_visibility_exports);
|
|
556
575
|
const { loadConfig } = await Promise.resolve().then(() => require("./config-BxtMoo9c.cjs")).then((n) => n.config_exports);
|
|
@@ -595,6 +614,13 @@ program.command("mcp").description("Low-level access to the Chain Insights MCP e
|
|
|
595
614
|
await printNetworkCapabilities({ json: opts.json });
|
|
596
615
|
return;
|
|
597
616
|
}
|
|
617
|
+
if (tool === "meta_schema") {
|
|
618
|
+
await printNetworkSchema(String(args["network"] ?? ""), {
|
|
619
|
+
json: opts.json,
|
|
620
|
+
refresh: String(args["refresh"] ?? "").toLowerCase() === "true"
|
|
621
|
+
});
|
|
622
|
+
return;
|
|
623
|
+
}
|
|
598
624
|
if (tool === "graph_expand") throw new Error("graph_expand is used only by the Chain Insights view in Claude. Run `cia mcp call graph_query` with your own query instead.");
|
|
599
625
|
if (tool === "meta_help") {
|
|
600
626
|
console.log("Graph tools: graph_query and graph_query_batch. Metadata and payment tools: meta_* and wallet_balance.");
|
package/dist/cli.mjs
CHANGED
|
@@ -118,21 +118,21 @@ async function withGraphMcpClient(name, fn) {
|
|
|
118
118
|
}
|
|
119
119
|
async function printNetworkCapabilities(opts) {
|
|
120
120
|
const { loadConfig } = await import("./config-9MabJh5R.mjs").then((n) => n.t);
|
|
121
|
-
const { fetchNetworkCapabilities, formatNetworkCapabilities } = await import("./capabilities-
|
|
121
|
+
const { fetchNetworkCapabilities, formatNetworkCapabilities } = await import("./capabilities-Cur8x6c7.mjs").then((n) => n.t);
|
|
122
122
|
const document = await fetchNetworkCapabilities(await loadConfig());
|
|
123
123
|
if (opts.json) console.log(JSON.stringify(document, null, 2));
|
|
124
124
|
else console.log(formatNetworkCapabilities(document));
|
|
125
125
|
}
|
|
126
126
|
async function printNetworkOverview(opts) {
|
|
127
127
|
const { loadConfig } = await import("./config-9MabJh5R.mjs").then((n) => n.t);
|
|
128
|
-
const { fetchNetworkCapabilities, formatNetworkOverview } = await import("./capabilities-
|
|
128
|
+
const { fetchNetworkCapabilities, formatNetworkOverview } = await import("./capabilities-Cur8x6c7.mjs").then((n) => n.t);
|
|
129
129
|
const document = await fetchNetworkCapabilities(await loadConfig());
|
|
130
130
|
if (opts.json) console.log(JSON.stringify(document, null, 2));
|
|
131
131
|
else console.log(formatNetworkOverview(document));
|
|
132
132
|
}
|
|
133
133
|
async function printNetworkCapability(name, opts) {
|
|
134
134
|
const { loadConfig } = await import("./config-9MabJh5R.mjs").then((n) => n.t);
|
|
135
|
-
const { fetchNetworkCapabilities, findNetworkCapability, formatNetworkCapability } = await import("./capabilities-
|
|
135
|
+
const { fetchNetworkCapabilities, findNetworkCapability, formatNetworkCapability } = await import("./capabilities-Cur8x6c7.mjs").then((n) => n.t);
|
|
136
136
|
const document = await fetchNetworkCapabilities(await loadConfig());
|
|
137
137
|
const network = findNetworkCapability(document, name);
|
|
138
138
|
if (!network) {
|
|
@@ -144,6 +144,23 @@ async function printNetworkCapability(name, opts) {
|
|
|
144
144
|
else console.log(formatNetworkCapability(network));
|
|
145
145
|
}
|
|
146
146
|
/**
|
|
147
|
+
* The live graph schema of one network (meta_schema). A fresh cache answers with
|
|
148
|
+
* no request; a build opens one session and reads through it.
|
|
149
|
+
*/
|
|
150
|
+
async function printNetworkSchema(name, opts) {
|
|
151
|
+
const { loadConfig } = await import("./config-9MabJh5R.mjs").then((n) => n.t);
|
|
152
|
+
const { resolveGraphMcpEndpoint } = await import("./client-gsLi528K.mjs").then((n) => n.r);
|
|
153
|
+
const { formatGraphSchemaText, getGraphSchema } = await import("./graph-schema-D1orCe5F.mjs").then((n) => n.i);
|
|
154
|
+
const config = await loadConfig();
|
|
155
|
+
const schema = await getGraphSchema({
|
|
156
|
+
network: name,
|
|
157
|
+
refresh: opts.refresh === true,
|
|
158
|
+
endpoint: resolveGraphMcpEndpoint(config),
|
|
159
|
+
withClient: (fn) => withGraphMcpClient("chain-insights-cli-schema", (client) => fn(client))
|
|
160
|
+
});
|
|
161
|
+
console.log(opts.json ? JSON.stringify(schema, null, 2) : formatGraphSchemaText(schema));
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
147
164
|
* Fetches the caller's subscription facts for the deposit pre-sign guard.
|
|
148
165
|
* The extension math is server-authoritative: the printed values come from
|
|
149
166
|
* `subscription_status`. Any failure (no wallet, unreachable endpoint,
|
|
@@ -232,9 +249,11 @@ program.command("networks").description("Show supported network status and datas
|
|
|
232
249
|
process.exit(1);
|
|
233
250
|
}
|
|
234
251
|
});
|
|
235
|
-
program.command("network").description("Show details for one supported graph network").argument("<name>", "Network identifier or display name (for example: robinhood)").option("--json", "Print raw capability JSON for this network").action(async (name, opts) => {
|
|
252
|
+
program.command("network").description("Show details for one supported graph network").argument("<name>", "Network identifier or display name (for example: robinhood)").option("--json", "Print raw capability JSON for this network (with --schema: the schema JSON)").option("--schema", "Show the live graph schema: labels, link types, fields and indexes (cached for 24 hours)").option("--refresh", "With --schema: rebuild the schema now instead of reading the cache").action(async (name, opts) => {
|
|
236
253
|
try {
|
|
237
|
-
|
|
254
|
+
if (opts.refresh && !opts.schema) throw new Error("--refresh needs --schema: run `cia network <name> --schema --refresh`.");
|
|
255
|
+
if (opts.schema) await printNetworkSchema(name, opts);
|
|
256
|
+
else await printNetworkCapability(name, opts);
|
|
238
257
|
} catch (err) {
|
|
239
258
|
console.error(err.message);
|
|
240
259
|
process.exit(1);
|
|
@@ -548,7 +567,7 @@ program.command("mcp").description("Low-level access to the Chain Insights MCP e
|
|
|
548
567
|
}
|
|
549
568
|
})).addCommand(createCliCommand("tools").description("List the remote GraphRAG MCP tools (cached for 24 hours)").option("--refresh", "Force refresh schema cache").action(async (opts) => {
|
|
550
569
|
try {
|
|
551
|
-
const { loadSchema, saveSchema } = await import("./schema-cache-
|
|
570
|
+
const { loadSchema, saveSchema } = await import("./schema-cache-BT-kHy_r.mjs");
|
|
552
571
|
const { formatToolsTable } = await import("./format-DB2IH2U5.mjs");
|
|
553
572
|
const { visibleRemoteTools } = await import("./tool-visibility-P9wETx-d.mjs").then((n) => n.a);
|
|
554
573
|
const { loadConfig } = await import("./config-9MabJh5R.mjs").then((n) => n.t);
|
|
@@ -593,6 +612,13 @@ program.command("mcp").description("Low-level access to the Chain Insights MCP e
|
|
|
593
612
|
await printNetworkCapabilities({ json: opts.json });
|
|
594
613
|
return;
|
|
595
614
|
}
|
|
615
|
+
if (tool === "meta_schema") {
|
|
616
|
+
await printNetworkSchema(String(args["network"] ?? ""), {
|
|
617
|
+
json: opts.json,
|
|
618
|
+
refresh: String(args["refresh"] ?? "").toLowerCase() === "true"
|
|
619
|
+
});
|
|
620
|
+
return;
|
|
621
|
+
}
|
|
596
622
|
if (tool === "graph_expand") throw new Error("graph_expand is used only by the Chain Insights view in Claude. Run `cia mcp call graph_query` with your own query instead.");
|
|
597
623
|
if (tool === "meta_help") {
|
|
598
624
|
console.log("Graph tools: graph_query and graph_query_batch. Metadata and payment tools: meta_* and wallet_balance.");
|