chain-insights 0.24.0 → 0.24.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
@@ -23,11 +23,11 @@ as-is on macOS; on Windows use WSL.
23
23
  npx chain-insights@latest --help # run without installing
24
24
  npm install -g chain-insights # or install the cia CLI globally
25
25
  cia mcp call aml_address_risk network=robinhood address=0xYourAddressHere
26
- cia networks # all supported networks
26
+ cia networks # network status + dataset overview
27
27
  cia network robinhood # details for one network
28
28
  ```
29
29
 
30
- Sixty seconds gets you the CLI and the live tool catalog.
30
+ Sixty seconds gets you the CLI, a network overview, and the remote tool catalog.
31
31
  To call the same tools from an agent, register the MCP proxy:
32
32
  `cia setup claude-code` (or `codex` / `hermes`).
33
33
 
@@ -327,13 +327,16 @@ Health checks (each is runnable):
327
327
  # Configured endpoint
328
328
  cia config get graphMcpEndpoint
329
329
 
330
- # Endpoint reachable, networks listed
330
+ # User-facing network overview
331
+ cia networks
332
+
333
+ # Detailed Chain Insights capability matrix
331
334
  cia mcp networks
332
335
 
333
336
  # Caller allowance / metering status
334
337
  cia mcp call meta_usage_status
335
338
 
336
- # Fresh tool discovery
339
+ # Fresh remote tool discovery
337
340
  cia mcp tools --refresh
338
341
 
339
342
  # Installed CLI sanity
@@ -7,6 +7,7 @@ var capabilities_exports = /* @__PURE__ */ __exportAll({
7
7
  findNetworkCapability: () => findNetworkCapability,
8
8
  formatNetworkCapabilities: () => formatNetworkCapabilities,
9
9
  formatNetworkCapability: () => formatNetworkCapability,
10
+ formatNetworkOverview: () => formatNetworkOverview,
10
11
  mirrorGraphNetworkCapabilities: () => mirrorGraphNetworkCapabilities
11
12
  });
12
13
  const PUBLIC_CHAIN_INSIGHTS_TOOL_STATUS = {
@@ -99,31 +100,54 @@ function datasetLabel(network) {
99
100
  if (dateRange === "") return blockRange;
100
101
  return `${blockRange} / ${dateRange}`;
101
102
  }
103
+ function displayName(network) {
104
+ return network.display_name || network.network;
105
+ }
106
+ function statusLabel(network) {
107
+ return network.default ? `${network.status} (default)` : network.status;
108
+ }
109
+ function formatTable(headers, rows, minimumWidths) {
110
+ const widths = headers.map((header, index) => Math.max(minimumWidths[index] ?? 0, header.length, ...rows.map((row) => row[index]?.length ?? 0)));
111
+ const row = (values) => values.map((value, index) => value.padEnd(widths[index])).join(" ");
112
+ return [
113
+ row(headers),
114
+ widths.map((width) => "-".repeat(width)).join(" "),
115
+ ...rows.map(row)
116
+ ].join("\n");
117
+ }
118
+ function formatNetworkOverview(document) {
119
+ if (document.networks.length === 0) return "No supported networks advertised.";
120
+ return formatTable([
121
+ "Network",
122
+ "Status",
123
+ "Dataset"
124
+ ], document.networks.map((network) => [
125
+ displayName(network),
126
+ statusLabel(network),
127
+ datasetLabel(network)
128
+ ]), [
129
+ 14,
130
+ 10,
131
+ 38
132
+ ]);
133
+ }
102
134
  function formatNetworkCapabilities(document) {
103
135
  if (document.networks.length === 0) return "No supported networks advertised.";
104
- const headers = [
136
+ return formatTable([
105
137
  "Network",
106
138
  "Dataset",
107
- "Available tools"
108
- ];
109
- const widths = [
139
+ "Chain Insights tools"
140
+ ], document.networks.flatMap((network) => {
141
+ return availableToolLines(network).map((toolLine, index) => [
142
+ index === 0 ? displayName(network) : "",
143
+ index === 0 ? datasetLabel(network) : "",
144
+ toolLine
145
+ ]);
146
+ }), [
110
147
  14,
111
148
  38,
112
149
  64
113
- ];
114
- const row = (values) => values.map((value, index) => value.padEnd(widths[index])).join(" ");
115
- const networkRows = document.networks.flatMap((network) => {
116
- return availableToolLines(network).map((toolLine, index) => row([
117
- index === 0 ? network.display_name || network.network : "",
118
- index === 0 ? datasetLabel(network) : "",
119
- toolLine
120
- ]));
121
- });
122
- return [
123
- row(headers),
124
- widths.map((width) => "-".repeat(width)).join(" "),
125
- ...networkRows
126
- ].join("\n");
150
+ ]);
127
151
  }
128
152
  function findNetworkCapability(document, name) {
129
153
  const normalizedName = name.trim().toLowerCase();
@@ -144,4 +168,4 @@ function formatNetworkCapability(network) {
144
168
  //#endregion
145
169
  export { mirrorGraphNetworkCapabilities as n, capabilities_exports as t };
146
170
 
147
- //# sourceMappingURL=capabilities-BPnw6nP_.mjs.map
171
+ //# sourceMappingURL=capabilities-CY3Ok5ls.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capabilities-CY3Ok5ls.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 }\n}\n\nexport interface NetworkLayerCapability {\n enabled: boolean\n live?: NetworkTopologyLayer\n archive?: NetworkTopologyLayer\n}\n\nexport interface NetworkCapability {\n network: string\n display_name?: string\n status: string\n default?: boolean\n layers: Record<string, NetworkLayerCapability>\n tools: Record<string, string>\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 }\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}\n\nexport interface NetworkCapabilitiesDocument {\n schema: 'chain-insights.network-capabilities.v1'\n networks: NetworkCapability[]\n}\n\nexport const PUBLIC_CHAIN_INSIGHTS_TOOL_STATUS = {\n aml_address_risk: 'available',\n graph_query: 'available',\n graph_query_batch: 'available',\n meta_network_capabilities: 'available',\n meta_usage_status: 'available',\n meta_help: 'available',\n wallet_balance: 'available',\n} as const\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 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 layers: {},\n tools: { ...PUBLIC_CHAIN_INSIGHTS_TOOL_STATUS },\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 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 effectiveTools = {\n ...(network.tools ?? {}),\n ...PUBLIC_CHAIN_INSIGHTS_TOOL_STATUS,\n }\n const tools = Object.entries(effectiveTools)\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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"}
@@ -7,6 +7,7 @@ var capabilities_exports = /* @__PURE__ */ require_rolldown_runtime.__exportAll(
7
7
  findNetworkCapability: () => findNetworkCapability,
8
8
  formatNetworkCapabilities: () => formatNetworkCapabilities,
9
9
  formatNetworkCapability: () => formatNetworkCapability,
10
+ formatNetworkOverview: () => formatNetworkOverview,
10
11
  mirrorGraphNetworkCapabilities: () => mirrorGraphNetworkCapabilities
11
12
  });
12
13
  const PUBLIC_CHAIN_INSIGHTS_TOOL_STATUS = {
@@ -99,31 +100,54 @@ function datasetLabel(network) {
99
100
  if (dateRange === "") return blockRange;
100
101
  return `${blockRange} / ${dateRange}`;
101
102
  }
103
+ function displayName(network) {
104
+ return network.display_name || network.network;
105
+ }
106
+ function statusLabel(network) {
107
+ return network.default ? `${network.status} (default)` : network.status;
108
+ }
109
+ function formatTable(headers, rows, minimumWidths) {
110
+ const widths = headers.map((header, index) => Math.max(minimumWidths[index] ?? 0, header.length, ...rows.map((row) => row[index]?.length ?? 0)));
111
+ const row = (values) => values.map((value, index) => value.padEnd(widths[index])).join(" ");
112
+ return [
113
+ row(headers),
114
+ widths.map((width) => "-".repeat(width)).join(" "),
115
+ ...rows.map(row)
116
+ ].join("\n");
117
+ }
118
+ function formatNetworkOverview(document) {
119
+ if (document.networks.length === 0) return "No supported networks advertised.";
120
+ return formatTable([
121
+ "Network",
122
+ "Status",
123
+ "Dataset"
124
+ ], document.networks.map((network) => [
125
+ displayName(network),
126
+ statusLabel(network),
127
+ datasetLabel(network)
128
+ ]), [
129
+ 14,
130
+ 10,
131
+ 38
132
+ ]);
133
+ }
102
134
  function formatNetworkCapabilities(document) {
103
135
  if (document.networks.length === 0) return "No supported networks advertised.";
104
- const headers = [
136
+ return formatTable([
105
137
  "Network",
106
138
  "Dataset",
107
- "Available tools"
108
- ];
109
- const widths = [
139
+ "Chain Insights tools"
140
+ ], document.networks.flatMap((network) => {
141
+ return availableToolLines(network).map((toolLine, index) => [
142
+ index === 0 ? displayName(network) : "",
143
+ index === 0 ? datasetLabel(network) : "",
144
+ toolLine
145
+ ]);
146
+ }), [
110
147
  14,
111
148
  38,
112
149
  64
113
- ];
114
- const row = (values) => values.map((value, index) => value.padEnd(widths[index])).join(" ");
115
- const networkRows = document.networks.flatMap((network) => {
116
- return availableToolLines(network).map((toolLine, index) => row([
117
- index === 0 ? network.display_name || network.network : "",
118
- index === 0 ? datasetLabel(network) : "",
119
- toolLine
120
- ]));
121
- });
122
- return [
123
- row(headers),
124
- widths.map((width) => "-".repeat(width)).join(" "),
125
- ...networkRows
126
- ].join("\n");
150
+ ]);
127
151
  }
128
152
  function findNetworkCapability(document, name) {
129
153
  const normalizedName = name.trim().toLowerCase();
package/dist/cli.cjs CHANGED
@@ -23,7 +23,10 @@ function printMcpTextContent(result) {
23
23
  const __dirname$1 = node_path.default.dirname((0, node_url.fileURLToPath)(require("url").pathToFileURL(__filename).href));
24
24
  const installerPath = node_path.default.resolve(__dirname$1, "..", "bin", "install.cjs");
25
25
  const program = new commander.Command();
26
- program.name("cia").description("AML investigation toolkit for blockchain analysis").version(require_version.PACKAGE_INFO.version).option("--claude", "Install Claude Code skills globally to ~/.claude/skills/").option("--codex", "Install Codex skills globally to ~/.codex/skills/ and register MCP").option("--hermes", "Install Hermes skills globally to ~/.hermes/skills/chain-insights/ and register MCP");
26
+ function createCliCommand(name) {
27
+ return new commander.Command(name).showHelpAfterError();
28
+ }
29
+ program.name("cia").description("AML investigation toolkit for blockchain analysis").version(require_version.PACKAGE_INFO.version).showHelpAfterError().option("--claude", "Install Claude Code skills globally to ~/.claude/skills/").option("--codex", "Install Codex skills globally to ~/.codex/skills/ and register MCP").option("--hermes", "Install Hermes skills globally to ~/.hermes/skills/chain-insights/ and register MCP");
27
30
  const rawArgs = process.argv.slice(2);
28
31
  const installerFlags = rawArgs.filter((a) => a === "--claude" || a === "--codex" || a === "--hermes");
29
32
  const wantsHelpOrVersion = rawArgs.some((a) => a === "--help" || a === "-h" || a === "--version" || a === "-V");
@@ -71,14 +74,21 @@ async function withGraphMcpClient(name, fn) {
71
74
  }
72
75
  async function printNetworkCapabilities(opts) {
73
76
  const { loadConfig } = await Promise.resolve().then(() => require("./config-B542AM4w.cjs")).then((n) => n.config_exports);
74
- const { fetchNetworkCapabilities, formatNetworkCapabilities } = await Promise.resolve().then(() => require("./capabilities-EMRzwPBU.cjs")).then((n) => n.capabilities_exports);
77
+ const { fetchNetworkCapabilities, formatNetworkCapabilities } = await Promise.resolve().then(() => require("./capabilities-CjpGnrVg.cjs")).then((n) => n.capabilities_exports);
75
78
  const document = await fetchNetworkCapabilities(await loadConfig());
76
79
  if (opts.json) console.log(JSON.stringify(document, null, 2));
77
80
  else console.log(formatNetworkCapabilities(document));
78
81
  }
82
+ async function printNetworkOverview(opts) {
83
+ const { loadConfig } = await Promise.resolve().then(() => require("./config-B542AM4w.cjs")).then((n) => n.config_exports);
84
+ const { fetchNetworkCapabilities, formatNetworkOverview } = await Promise.resolve().then(() => require("./capabilities-CjpGnrVg.cjs")).then((n) => n.capabilities_exports);
85
+ const document = await fetchNetworkCapabilities(await loadConfig());
86
+ if (opts.json) console.log(JSON.stringify(document, null, 2));
87
+ else console.log(formatNetworkOverview(document));
88
+ }
79
89
  async function printNetworkCapability(name, opts) {
80
90
  const { loadConfig } = await Promise.resolve().then(() => require("./config-B542AM4w.cjs")).then((n) => n.config_exports);
81
- const { fetchNetworkCapabilities, findNetworkCapability, formatNetworkCapability } = await Promise.resolve().then(() => require("./capabilities-EMRzwPBU.cjs")).then((n) => n.capabilities_exports);
91
+ const { fetchNetworkCapabilities, findNetworkCapability, formatNetworkCapability } = await Promise.resolve().then(() => require("./capabilities-CjpGnrVg.cjs")).then((n) => n.capabilities_exports);
82
92
  const document = await fetchNetworkCapabilities(await loadConfig());
83
93
  const network = findNetworkCapability(document, name);
84
94
  if (!network) {
@@ -89,9 +99,27 @@ async function printNetworkCapability(name, opts) {
89
99
  if (opts.json) console.log(JSON.stringify(network, null, 2));
90
100
  else console.log(formatNetworkCapability(network));
91
101
  }
92
- program.command("networks").description("List supported graph networks, capability layers, and available tools").option("--json", "Print raw capability JSON").action(async (opts) => {
102
+ function addAmlAddressRiskCommand(parent, networksCommand) {
103
+ parent.addCommand(createCliCommand("aml-address-risk").description("Screen an address for AML risk, exchange behavior, and optional comparison with another address").requiredOption("--address <address>", "Full blockchain address to screen").requiredOption("--network <network>", `Network to query. Run \`${networksCommand}\` for supported networks.`).option("--compare-address <address>", "Optional second address to compare against the screened address").action(async (opts) => {
104
+ try {
105
+ await withGraphMcpClient("chain-insights-cli-aml-address-risk", async (client) => {
106
+ const { addressRisk } = await Promise.resolve().then(() => require("./public-tools-Bou25cki.cjs"));
107
+ const result = await addressRisk(client, {
108
+ address: opts.address,
109
+ network: opts.network,
110
+ compareAddress: opts.compareAddress
111
+ });
112
+ console.log(result.summaryText);
113
+ });
114
+ } catch (err) {
115
+ console.error(err.message);
116
+ process.exit(1);
117
+ }
118
+ }));
119
+ }
120
+ program.command("networks").description("Show supported network status and dataset overview").option("--json", "Print raw capability JSON").action(async (opts) => {
93
121
  try {
94
- await printNetworkCapabilities(opts);
122
+ await printNetworkOverview(opts);
95
123
  } catch (err) {
96
124
  console.error(err.message);
97
125
  process.exit(1);
@@ -138,7 +166,7 @@ program.command("update").description("Check npmjs for a newer Chain Insights re
138
166
  process.exit(1);
139
167
  }
140
168
  });
141
- program.command("debug").description("Configure Chain Insights Graph debug mode").addCommand(new commander.Command("on").description("Enable Chain Insights Graph debug mode without x402 payments").requiredOption("--token <token>", "Debug bearer token").option("--endpoint <url>", "Chain Insights Graph endpoint").action(async (opts) => {
169
+ program.command("debug").description("Configure Chain Insights Graph debug mode").addCommand(createCliCommand("on").description("Enable Chain Insights Graph debug mode without x402 payments").requiredOption("--token <token>", "Debug bearer token").option("--endpoint <url>", "Chain Insights Graph endpoint").action(async (opts) => {
142
170
  try {
143
171
  const { saveConfig } = await Promise.resolve().then(() => require("./config-B542AM4w.cjs")).then((n) => n.config_exports);
144
172
  await saveConfig({
@@ -153,7 +181,7 @@ program.command("debug").description("Configure Chain Insights Graph debug mode"
153
181
  console.error(err.message);
154
182
  process.exit(1);
155
183
  }
156
- })).addCommand(new commander.Command("off").description("Disable Chain Insights Graph debug mode and use paid x402 calls").action(async () => {
184
+ })).addCommand(createCliCommand("off").description("Disable Chain Insights Graph debug mode and use paid x402 calls").action(async () => {
157
185
  try {
158
186
  const { saveConfig } = await Promise.resolve().then(() => require("./config-B542AM4w.cjs")).then((n) => n.config_exports);
159
187
  await saveConfig({
@@ -166,7 +194,7 @@ program.command("debug").description("Configure Chain Insights Graph debug mode"
166
194
  console.error(err.message);
167
195
  process.exit(1);
168
196
  }
169
- })).addCommand(new commander.Command("status").description("Show Chain Insights Graph payment/debug mode").action(async () => {
197
+ })).addCommand(createCliCommand("status").description("Show Chain Insights Graph payment/debug mode").action(async () => {
170
198
  try {
171
199
  const { loadConfig } = await Promise.resolve().then(() => require("./config-B542AM4w.cjs")).then((n) => n.config_exports);
172
200
  const config = await loadConfig();
@@ -179,7 +207,7 @@ program.command("debug").description("Configure Chain Insights Graph debug mode"
179
207
  process.exit(1);
180
208
  }
181
209
  }));
182
- program.command("access-key").description("Configure Chain Insights Graph test access key mode").addCommand(new commander.Command("set").description("Use a Chain Insights Graph test access key without x402 payments").argument("<key>", "Test access key").option("--endpoint <url>", "Chain Insights Graph endpoint").action(async (key, opts) => {
210
+ program.command("access-key").description("Configure Chain Insights Graph test access key mode").addCommand(createCliCommand("set").description("Use a Chain Insights Graph test access key without x402 payments").argument("<key>", "Test access key").option("--endpoint <url>", "Chain Insights Graph endpoint").action(async (key, opts) => {
183
211
  try {
184
212
  const normalizedKey = key.trim();
185
213
  if (!normalizedKey) throw new Error("Test access key is required");
@@ -196,7 +224,7 @@ program.command("access-key").description("Configure Chain Insights Graph test a
196
224
  console.error(err.message);
197
225
  process.exit(1);
198
226
  }
199
- })).addCommand(new commander.Command("clear").description("Remove the Chain Insights Graph test access key and use paid x402 calls").action(async () => {
227
+ })).addCommand(createCliCommand("clear").description("Remove the Chain Insights Graph test access key and use paid x402 calls").action(async () => {
200
228
  try {
201
229
  const { saveConfig } = await Promise.resolve().then(() => require("./config-B542AM4w.cjs")).then((n) => n.config_exports);
202
230
  await saveConfig({
@@ -209,7 +237,7 @@ program.command("access-key").description("Configure Chain Insights Graph test a
209
237
  console.error(err.message);
210
238
  process.exit(1);
211
239
  }
212
- })).addCommand(new commander.Command("status").description("Show Chain Insights Graph test access key status").action(async () => {
240
+ })).addCommand(createCliCommand("status").description("Show Chain Insights Graph test access key status").action(async () => {
213
241
  try {
214
242
  const { loadConfig } = await Promise.resolve().then(() => require("./config-B542AM4w.cjs")).then((n) => n.config_exports);
215
243
  const config = await loadConfig();
@@ -221,14 +249,14 @@ program.command("access-key").description("Configure Chain Insights Graph test a
221
249
  process.exit(1);
222
250
  }
223
251
  }));
224
- program.command("setup").description("Configure external MCP clients").addCommand(new commander.Command("claude-code").alias("claude").description("Install Claude Code skills and register the MCP proxy").action(() => {
252
+ program.command("setup").description("Configure external MCP clients").addCommand(createCliCommand("claude-code").alias("claude").description("Install Claude Code skills and register the MCP proxy").action(() => {
225
253
  runInstaller("--claude");
226
- })).addCommand(new commander.Command("codex").description("Install Codex skills and register the MCP proxy").action(() => {
254
+ })).addCommand(createCliCommand("codex").description("Install Codex skills and register the MCP proxy").action(() => {
227
255
  runInstaller("--codex");
228
- })).addCommand(new commander.Command("hermes").description("Install Hermes skills and register the MCP proxy").action(() => {
256
+ })).addCommand(createCliCommand("hermes").description("Install Hermes skills and register the MCP proxy").action(() => {
229
257
  runInstaller("--hermes");
230
258
  }));
231
- program.command("config").description("Read or write configuration values").addCommand(new commander.Command("get").argument("<key>", "Config key to read").action(async (key) => {
259
+ program.command("config").description("Read or write configuration values").addCommand(createCliCommand("get").description("Read one Chain Insights configuration value").argument("<key>", "Config key to read").action(async (key) => {
232
260
  const { loadConfig } = await Promise.resolve().then(() => require("./config-B542AM4w.cjs")).then((n) => n.config_exports);
233
261
  const { CONFIG_KEYS } = await Promise.resolve().then(() => require("./schema-CtFWYoJz.cjs")).then((n) => n.schema_exports);
234
262
  if (!CONFIG_KEYS.includes(key)) {
@@ -237,7 +265,7 @@ program.command("config").description("Read or write configuration values").addC
237
265
  }
238
266
  const value = (await loadConfig())[key];
239
267
  console.log(value ?? "");
240
- })).addCommand(new commander.Command("set").argument("<key>", "Config key to write").argument("<value>", "Value to set").action(async (key, value) => {
268
+ })).addCommand(createCliCommand("set").description("Write one Chain Insights configuration value").argument("<key>", "Config key to write").argument("<value>", "Value to set").action(async (key, value) => {
241
269
  if (key === "walletPrivateKey") {
242
270
  try {
243
271
  const { setWalletPrivateKey } = await Promise.resolve().then(() => require("./wallet-B3hAr70M.cjs")).then((n) => n.wallet_exports);
@@ -264,7 +292,7 @@ program.command("config").description("Read or write configuration values").addC
264
292
  const displayed = key.toLowerCase().includes("token") ? "[redacted]" : coerced;
265
293
  console.log(`Set ${key} = ${displayed}`);
266
294
  }));
267
- program.command("wallet").description("Manage the local Base USDC payment wallet").addCommand(new commander.Command("create").description("Generate a new local Base payment wallet").action(async () => {
295
+ program.command("wallet").description("Manage the local Base USDC payment wallet").addCommand(createCliCommand("create").description("Generate a new local Base payment wallet").action(async () => {
268
296
  try {
269
297
  const { isWalletConfigured, setWalletPrivateKey, walletPath } = await Promise.resolve().then(() => require("./wallet-B3hAr70M.cjs")).then((n) => n.wallet_exports);
270
298
  const { createInterface } = await import("node:readline/promises");
@@ -293,7 +321,7 @@ program.command("wallet").description("Manage the local Base USDC payment wallet
293
321
  console.error(err.message);
294
322
  process.exit(1);
295
323
  }
296
- })).addCommand(new commander.Command("import").description("Import a Base payment wallet").argument("<private-key>", "0x-prefixed EVM private key").option("--force", "Replace an existing wallet (the previous key is backed up next to wallet.json)").action(async (privateKey, opts) => {
324
+ })).addCommand(createCliCommand("import").description("Import a Base payment wallet").argument("<private-key>", "0x-prefixed EVM private key").option("--force", "Replace an existing wallet (the previous key is backed up next to wallet.json)").action(async (privateKey, opts) => {
297
325
  try {
298
326
  const { setWalletPrivateKey, isWalletConfigured } = await Promise.resolve().then(() => require("./wallet-B3hAr70M.cjs")).then((n) => n.wallet_exports);
299
327
  const replacing = opts.force === true && await isWalletConfigured();
@@ -307,7 +335,7 @@ program.command("wallet").description("Manage the local Base USDC payment wallet
307
335
  console.error(err.message);
308
336
  process.exit(1);
309
337
  }
310
- })).addCommand(new commander.Command("address").description("Print the local payment wallet address").action(async () => {
338
+ })).addCommand(createCliCommand("address").description("Print the local payment wallet address").action(async () => {
311
339
  try {
312
340
  const { getWalletAccount } = await Promise.resolve().then(() => require("./tools-BHfphgy9.cjs")).then((n) => n.tools_exports);
313
341
  const account = await getWalletAccount();
@@ -316,7 +344,7 @@ program.command("wallet").description("Manage the local Base USDC payment wallet
316
344
  console.error(err.message);
317
345
  process.exit(1);
318
346
  }
319
- })).addCommand(new commander.Command("balance").description("Show the local payment wallet Base USDC balance").action(async () => {
347
+ })).addCommand(createCliCommand("balance").description("Show the local payment wallet Base USDC balance").action(async () => {
320
348
  try {
321
349
  const { getWalletBalanceText } = await Promise.resolve().then(() => require("./tools-BHfphgy9.cjs")).then((n) => n.tools_exports);
322
350
  console.log(await getWalletBalanceText());
@@ -324,7 +352,7 @@ program.command("wallet").description("Manage the local Base USDC payment wallet
324
352
  console.error(err.message);
325
353
  process.exit(1);
326
354
  }
327
- })).addCommand(new commander.Command("ready").description("Check and prepare the wallet for paid Chain Insights Graph calls").option("--check-only", "Only check readiness; do not submit the one-time payment setup").addOption(new commander.Option("--no-approve", "Deprecated alias for --check-only").hideHelp()).option("--payment-usdc <amount>", "USDC setup cap to prepare for paid calls", "1").addOption(new commander.Option("--approval-usdc <amount>", "Deprecated alias for --payment-usdc").hideHelp()).option("--json", "Print machine-readable readiness metadata").action(async (opts) => {
355
+ })).addCommand(createCliCommand("ready").description("Check and prepare the wallet for paid Chain Insights Graph calls").option("--check-only", "Only check readiness; do not submit the one-time payment setup").addOption(new commander.Option("--no-approve", "Deprecated alias for --check-only").hideHelp()).option("--payment-usdc <amount>", "USDC setup cap to prepare for paid calls", "1").addOption(new commander.Option("--approval-usdc <amount>", "Deprecated alias for --payment-usdc").hideHelp()).option("--json", "Print machine-readable readiness metadata").action(async (opts) => {
328
356
  try {
329
357
  const { formatWalletReadiness, parsePaymentApprovalUnits, prepareWalletForPaidCalls } = await Promise.resolve().then(() => require("./tools-BHfphgy9.cjs")).then((n) => n.tools_exports);
330
358
  const result = await prepareWalletForPaidCalls({
@@ -340,7 +368,7 @@ program.command("wallet").description("Manage the local Base USDC payment wallet
340
368
  console.error(err.message);
341
369
  process.exit(1);
342
370
  }
343
- })).addCommand(new commander.Command("topup").description("Open a local browser page to top up the payment wallet").option("--no-open", "Print the top-up URL without opening a browser").option("--json", "Print machine-readable top-up metadata").action(async (opts) => {
371
+ })).addCommand(createCliCommand("topup").description("Open a local browser page to top up the payment wallet").option("--no-open", "Print the top-up URL without opening a browser").option("--json", "Print machine-readable top-up metadata").action(async (opts) => {
344
372
  try {
345
373
  const { buildTopupInfo, getWalletAccount } = await Promise.resolve().then(() => require("./tools-BHfphgy9.cjs")).then((n) => n.tools_exports);
346
374
  const { startTopupServer } = await Promise.resolve().then(() => require("./topup-server-YN3iHrHW.cjs")).then((n) => n.topup_server_exports);
@@ -364,18 +392,19 @@ program.command("wallet").description("Manage the local Base USDC payment wallet
364
392
  process.exit(1);
365
393
  }
366
394
  }));
367
- program.command("mcp").description("Interact with the Chain Insights MCP endpoint").allowExcessArguments(false).addCommand(new commander.Command("networks").description("List supported graph networks, capability layers, dataset coverage, and available tools").option("--json", "Print raw capability JSON").action(async (opts) => {
395
+ addAmlAddressRiskCommand(program, "cia networks");
396
+ const mcpCommand = program.command("mcp").description("Interact with the Chain Insights MCP endpoint").allowExcessArguments(false).addCommand(createCliCommand("networks").description("List the detailed Chain Insights capability matrix and tool support").option("--json", "Print raw capability JSON").action(async (opts) => {
368
397
  try {
369
398
  await printNetworkCapabilities(opts);
370
399
  } catch (err) {
371
400
  console.error(err.message);
372
401
  process.exit(1);
373
402
  }
374
- })).addCommand(new commander.Command("tools").description("List available MCP tools (cached 24h)").option("--refresh", "Force refresh schema cache").action(async (opts) => {
403
+ })).addCommand(createCliCommand("tools").description("List remote GraphRAG MCP tools (cached for 24 hours)").option("--refresh", "Force refresh schema cache").action(async (opts) => {
375
404
  try {
376
405
  const { loadSchema, saveSchema } = await Promise.resolve().then(() => require("./schema-cache-n7Gbhvsj.cjs"));
377
- const { formatToolsTable } = await Promise.resolve().then(() => require("./format-9NLBykEL.cjs"));
378
- const { visibleRemoteTools } = await Promise.resolve().then(() => require("./tool-visibility-C8F9Yoxy.cjs")).then((n) => n.tool_visibility_exports);
406
+ const { formatToolsTable } = await Promise.resolve().then(() => require("./format-BjZuYDr8.cjs"));
407
+ const { visibleRemoteTools } = await Promise.resolve().then(() => require("./tool-visibility-DA4pOuJt.cjs")).then((n) => n.tool_visibility_exports);
379
408
  const { loadConfig } = await Promise.resolve().then(() => require("./config-B542AM4w.cjs")).then((n) => n.config_exports);
380
409
  const { createConfiguredGraphMcpFetch, resolveGraphMcpEndpoint } = await Promise.resolve().then(() => require("./client-Ypw9BNbn.cjs")).then((n) => n.client_exports);
381
410
  const config = await loadConfig();
@@ -402,25 +431,12 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
402
431
  console.error(err.message);
403
432
  process.exit(1);
404
433
  }
405
- })).addCommand(new commander.Command("aml-address-risk").description("Screen an address for AML risk, exchange behavior, and optional comparison with another address").requiredOption("--address <address>", "Full blockchain address to screen").requiredOption("--network <network>", "Network to query. Run `cia mcp networks` for supported networks.").option("--compare-address <address>", "Optional second address to compare against the screened address").action(async (opts) => {
406
- try {
407
- await withGraphMcpClient("chain-insights-cli-aml-address-risk", async (client) => {
408
- const { addressRisk } = await Promise.resolve().then(() => require("./public-tools-Bou25cki.cjs"));
409
- const result = await addressRisk(client, {
410
- address: opts.address,
411
- network: opts.network,
412
- compareAddress: opts.compareAddress
413
- });
414
- console.log(result.summaryText);
415
- });
416
- } catch (err) {
417
- console.error(err.message);
418
- process.exit(1);
419
- }
420
- })).addCommand(new commander.Command("call").description("Call an MCP tool directly (debug)").argument("<tool>", "Tool name to call").argument("[args...]", "Key=value arguments (e.g. address=0x1234... network=robinhood)").action(async (tool, rawArgs) => {
434
+ }));
435
+ addAmlAddressRiskCommand(mcpCommand, "cia mcp networks");
436
+ mcpCommand.addCommand(createCliCommand("call").description("Call an MCP tool directly (debug)").argument("<tool>", "Tool name to call").argument("[args...]", "Key=value arguments (e.g. address=0x1234... network=robinhood)").action(async (tool, rawArgs) => {
421
437
  try {
422
438
  const { parseMcpCallArgs } = await Promise.resolve().then(() => require("./call-args-DAiQSDmD.cjs"));
423
- const { assertPublicMcpToolName, validatePublicMcpToolArguments } = await Promise.resolve().then(() => require("./tool-visibility-C8F9Yoxy.cjs")).then((n) => n.tool_visibility_exports);
439
+ const { assertPublicMcpToolName, validatePublicMcpToolArguments } = await Promise.resolve().then(() => require("./tool-visibility-DA4pOuJt.cjs")).then((n) => n.tool_visibility_exports);
424
440
  const args = parseMcpCallArgs(rawArgs);
425
441
  assertPublicMcpToolName(tool);
426
442
  validatePublicMcpToolArguments(tool, args);
@@ -468,7 +484,8 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
468
484
  }));
469
485
  });
470
486
  } catch (err) {
471
- console.error(err.message);
487
+ const { formatMcpCallError } = await Promise.resolve().then(() => require("./tool-visibility-DA4pOuJt.cjs")).then((n) => n.tool_visibility_exports);
488
+ console.error(formatMcpCallError(tool, err));
472
489
  process.exit(1);
473
490
  }
474
491
  }));