chain-insights 0.3.6 → 0.3.9
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 +18 -13
- package/dist/{capabilities-BC3Y5EOi.mjs → capabilities-BCvkTkIu.mjs} +3 -6
- package/dist/capabilities-BCvkTkIu.mjs.map +1 -0
- package/dist/{capabilities-D5PSx9Hj.cjs → capabilities-DOa6EFO-.cjs} +2 -5
- package/dist/cli.cjs +41 -14
- package/dist/cli.mjs +41 -14
- package/dist/cli.mjs.map +1 -1
- package/dist/{client-D4JE7fFF.mjs → client-BgmHjBHQ.mjs} +15 -7
- package/dist/client-BgmHjBHQ.mjs.map +1 -0
- package/dist/{client-Db6IV1tv.cjs → client-Y_zqKqJT.cjs} +19 -5
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/mcp-proxy.cjs +442 -408
- package/dist/mcp-proxy.d.cts +3 -1
- package/dist/mcp-proxy.d.cts.map +1 -1
- package/dist/mcp-proxy.d.mts +3 -1
- package/dist/mcp-proxy.d.mts.map +1 -1
- package/dist/mcp-proxy.mjs +442 -409
- package/dist/mcp-proxy.mjs.map +1 -1
- package/dist/{public-tools-xfVNz9NE.cjs → public-tools-BY3PTw6x.cjs} +59 -31
- package/dist/{public-tools-CyUZEz9B.mjs → public-tools-CvlZcysd.mjs} +60 -32
- package/dist/public-tools-CvlZcysd.mjs.map +1 -0
- package/dist/{runner-DWuSy1Se.mjs → runner-CVnjpqc-.mjs} +2 -2
- package/dist/{runner-DWuSy1Se.mjs.map → runner-CVnjpqc-.mjs.map} +1 -1
- package/dist/{runner-CVo41fjz.cjs → runner-bLy0pTr_.cjs} +1 -1
- package/dist/update-BJoXYucO.cjs +145 -0
- package/dist/update-CJUfGCxs.mjs +145 -0
- package/dist/update-CJUfGCxs.mjs.map +1 -0
- package/docs/graph-tools.md +8 -8
- package/docs/mcp-proxy.md +14 -14
- package/package.json +1 -1
- package/dist/capabilities-BC3Y5EOi.mjs.map +0 -1
- package/dist/client-D4JE7fFF.mjs.map +0 -1
- package/dist/public-tools-CyUZEz9B.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -19,7 +19,7 @@ MCP endpoint for development; hosted endpoints are set explicitly with
|
|
|
19
19
|
| `trace_victim_funds` | Trace victim/source funds forward to exchange deposit candidates |
|
|
20
20
|
| `trace_deposit_sources` | Trace backward from suspected deposit/cashout addresses to upstream sources and convergence |
|
|
21
21
|
| `trace_suspect_funds` | Trace suspected scammer, mule, operator, or laundering-ring funds forward to cashout topology |
|
|
22
|
-
| `usage_status` | Check the caller's
|
|
22
|
+
| `usage_status` | Check the caller's daily free-tier graph query allowance |
|
|
23
23
|
| `graph_query` | Run one read-only GQL/Cypher query against a GraphRAG MCP graph layer |
|
|
24
24
|
| `graph_query_batch` | Run related read-only graph queries as one MCP call |
|
|
25
25
|
|
|
@@ -35,8 +35,13 @@ Check the CLI:
|
|
|
35
35
|
|
|
36
36
|
```bash
|
|
37
37
|
cia --version
|
|
38
|
+
cia update --check
|
|
38
39
|
```
|
|
39
40
|
|
|
41
|
+
Run `cia update` to update a global npm install from the public npmjs registry.
|
|
42
|
+
`cia init` also checks for a newer npm release in interactive terminals and
|
|
43
|
+
prompts before updating.
|
|
44
|
+
|
|
40
45
|
From a local checkout:
|
|
41
46
|
|
|
42
47
|
```bash
|
|
@@ -117,14 +122,14 @@ If network or tool discovery fails, check the endpoint and access mode first.
|
|
|
117
122
|
The CLI can still initialize workspaces and manage cases without a reachable
|
|
118
123
|
GraphRAG MCP endpoint.
|
|
119
124
|
|
|
120
|
-
Hosted GraphRAG MCP
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
+
Hosted GraphRAG MCP includes a small public free tier for `graph_query` before
|
|
126
|
+
paid access is required. The default public free tier is 10 execution seconds
|
|
127
|
+
per IP per UTC day. Use `usage_status` to see the current caller allowance.
|
|
128
|
+
Prepared wallet users receive the daily free tier first, then paid access
|
|
129
|
+
continues automatically after the allowance is exhausted.
|
|
125
130
|
If you do not have a prepared wallet yet, use bounded single `graph_query`
|
|
126
|
-
calls
|
|
127
|
-
when the
|
|
131
|
+
calls within the free tier, then prepare a wallet or use an invited tester
|
|
132
|
+
access key when the allowance is exhausted.
|
|
128
133
|
|
|
129
134
|
Open a case and run a small investigation:
|
|
130
135
|
|
|
@@ -162,12 +167,12 @@ The export writes Markdown notes, `manifest.chain-insights.json`,
|
|
|
162
167
|
for Codex, Claude Code, and ChatGPT under `published/<case-slug>/`.
|
|
163
168
|
|
|
164
169
|
Private exports may include full addresses. Use `--mode partner` for controlled
|
|
165
|
-
handoff after review. Use `--mode public` only for shareable
|
|
170
|
+
handoff after review. Use `--mode public` only for shareable examples; public mode
|
|
166
171
|
aliases addresses and removes secrets by default. Vault workflow guidance lives
|
|
167
172
|
in [Obsidian vault workflow](docs/obsidian-vault.md); export bundle details
|
|
168
173
|
live in [Knowledge exports](docs/knowledge-exports.md).
|
|
169
174
|
|
|
170
|
-
##
|
|
175
|
+
## Examples
|
|
171
176
|
|
|
172
177
|
Run a direct live topology query:
|
|
173
178
|
|
|
@@ -185,9 +190,9 @@ cia mcp call graph_query_batch \
|
|
|
185
190
|
'queries=[{"id":"count","query":"USE live_topology MATCH (n) RETURN count(n) AS count LIMIT 1"},{"id":"archive_flows","query":"USE archive_topology MATCH (src:Address)-[f:FLOWS_TO]->(dst:Address) RETURN f.period_granularity AS granularity, src.address AS source, dst.address AS target LIMIT 3"},{"id":"facts_sample","query":"USE facts MATCH (a:Address)-[:HAS_FEATURE]->(f:AddressFeature) RETURN a.address AS address, f.sent_count AS sent_count LIMIT 3"}]'
|
|
186
191
|
```
|
|
187
192
|
|
|
188
|
-
For no-wallet public
|
|
189
|
-
reserve worst-case execution time and can ask for paid access even
|
|
190
|
-
free
|
|
193
|
+
For no-wallet public free-tier usage, prefer the single-query example first.
|
|
194
|
+
Batch calls reserve worst-case execution time and can ask for paid access even
|
|
195
|
+
when a small free allowance remains.
|
|
191
196
|
|
|
192
197
|
Run suspect topology without requiring an incident timestamp:
|
|
193
198
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { n as applyMcpAuthHeaders, o as resolveGraphMcpEndpoint } from "./client-BgmHjBHQ.mjs";
|
|
2
2
|
//#region src/mcp/capabilities.ts
|
|
3
3
|
function metadataNetworksUrl(endpoint) {
|
|
4
4
|
const url = new URL(endpoint);
|
|
@@ -11,10 +11,7 @@ async function fetchNetworkCapabilities(config) {
|
|
|
11
11
|
const request = metadataNetworksUrl(resolveGraphMcpEndpoint(config));
|
|
12
12
|
const headers = new Headers();
|
|
13
13
|
const token = config.graphMcpAuthToken?.trim() || config.mcpAuthToken?.trim();
|
|
14
|
-
if (token)
|
|
15
|
-
headers.set("X-MCP-Debug-Token", token);
|
|
16
|
-
headers.set("Authorization", `Bearer ${token}`);
|
|
17
|
-
}
|
|
14
|
+
if (token) applyMcpAuthHeaders(headers, token);
|
|
18
15
|
let response;
|
|
19
16
|
try {
|
|
20
17
|
response = await fetch(request, { headers });
|
|
@@ -81,4 +78,4 @@ function formatNetworkCapabilities(document) {
|
|
|
81
78
|
//#endregion
|
|
82
79
|
export { fetchNetworkCapabilities, formatNetworkCapabilities };
|
|
83
80
|
|
|
84
|
-
//# sourceMappingURL=capabilities-
|
|
81
|
+
//# sourceMappingURL=capabilities-BCvkTkIu.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capabilities-BCvkTkIu.mjs","names":[],"sources":["../src/mcp/capabilities.ts"],"sourcesContent":["import type { InvestigatorConfig } from '../config/schema.js'\nimport { applyMcpAuthHeaders, resolveGraphMcpEndpoint } from './client.js'\n\nexport interface NetworkRetention {\n mode: 'full_history' | 'rolling_window' | 'expanding_then_rolling' | 'bounded_range' | 'unknown' | string\n window_days?: number\n from_block?: number\n to_block?: number\n from_timestamp?: string\n to_timestamp?: string\n started_at?: string\n rolls_after_at?: string\n current_window_seconds?: number\n}\n\nexport interface NetworkLayerCapability {\n enabled: boolean\n retention?: NetworkRetention | null\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\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, 'mcpAuthToken' | 'graphMcpAuthToken' | 'graphMcpMode' | 'graphMcpEndpoint' | 'mcpEndpoint'>,\n): Promise<NetworkCapabilitiesDocument> {\n const endpoint = resolveGraphMcpEndpoint(config)\n const request = metadataNetworksUrl(endpoint)\n const headers = new Headers()\n const token = config.graphMcpAuthToken?.trim() || config.mcpAuthToken?.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 (parsed.schema !== 'chain-insights.network-capabilities.v1' || !Array.isArray(parsed.networks)) {\n throw new Error('network capabilities response has unsupported schema')\n }\n return parsed\n}\n\nfunction layerValue(network: NetworkCapability, layer: string): string {\n const capability = network.layers[layer]\n if (!capability?.enabled) return 'no'\n return 'yes'\n}\n\nfunction availableToolsLabel(network: NetworkCapability): string {\n const tools = Object.entries(network.tools ?? {})\n .filter(([, status]) => status === 'available')\n .map(([name]) => name)\n return tools.length > 0 ? tools.join(', ') : 'none'\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 = coverage.from_block !== undefined && coverage.to_block !== undefined\n ? `${coverage.from_block}..${coverage.to_block}`\n : 'blocks unknown'\n const dateRange = coverage.from_timestamp && coverage.to_timestamp\n ? `${shortDate(coverage.from_timestamp)}..${shortDate(coverage.to_timestamp)}`\n : 'dates unknown'\n if (blockRange === 'blocks unknown' && dateRange === 'dates unknown') return 'unknown'\n return `${blockRange} / ${dateRange}`\n}\n\nexport function formatNetworkCapabilities(document: NetworkCapabilitiesDocument): string {\n if (document.networks.length === 0) return 'No supported networks advertised.'\n const headers = ['Network', 'Topology', 'Facts', 'Risk', 'Dataset', 'Available tools']\n const widths = [14, 10, 8, 8, 38, 64]\n const row = (values: string[]) => values.map((value, index) => value.padEnd(widths[index]!)).join(' ')\n return [\n row(headers),\n widths.map((width) => '-'.repeat(width)).join(' '),\n ...document.networks.map((network) => row([\n network.display_name || network.network,\n layerValue(network, 'topology'),\n layerValue(network, 'facts'),\n layerValue(network, 'risk'),\n datasetLabel(network),\n availableToolsLabel(network),\n ])),\n ].join('\\n')\n}\n"],"mappings":";;AAgDA,SAAS,oBAAoB,UAAuB;CAClD,MAAM,MAAM,IAAI,IAAI,QAAQ;CAC5B,IAAI,WAAW;CACf,IAAI,SAAS;CACb,IAAI,OAAO;CACX,OAAO;AACT;AAEA,eAAsB,yBACpB,QACsC;CAEtC,MAAM,UAAU,oBADC,wBAAwB,MACE,CAAC;CAC5C,MAAM,UAAU,IAAI,QAAQ;CAC5B,MAAM,QAAQ,OAAO,mBAAmB,KAAK,KAAK,OAAO,cAAc,KAAK;CAC5E,IAAI,OACF,oBAAoB,SAAS,KAAK;CAEpC,IAAI;CACJ,IAAI;EACF,WAAW,MAAM,MAAM,SAAS,EAAE,QAAQ,CAAC;CAC7C,SAAS,KAAK;EACZ,MAAM,IAAI,MAAM,uCAAuC,QAAQ,IAAK,IAAc,SAAS;CAC7F;CACA,IAAI,CAAC,SAAS,IACZ,MAAM,IAAI,MAAM,uCAAuC,QAAQ,SAAS,SAAS,QAAQ;CAE3F,MAAM,SAAS,MAAM,SAAS,KAAK;CACnC,IAAI,OAAO,WAAW,4CAA4C,CAAC,MAAM,QAAQ,OAAO,QAAQ,GAC9F,MAAM,IAAI,MAAM,sDAAsD;CAExE,OAAO;AACT;AAEA,SAAS,WAAW,SAA4B,OAAuB;CAErE,IAAI,CADe,QAAQ,OAAO,QACjB,SAAS,OAAO;CACjC,OAAO;AACT;AAEA,SAAS,oBAAoB,SAAoC;CAC/D,MAAM,QAAQ,OAAO,QAAQ,QAAQ,SAAS,CAAC,CAAC,EAC7C,QAAQ,GAAG,YAAY,WAAW,WAAW,EAC7C,KAAK,CAAC,UAAU,IAAI;CACvB,OAAO,MAAM,SAAS,IAAI,MAAM,KAAK,IAAI,IAAI;AAC/C;AAEA,SAAS,UAAU,OAAwB;CACzC,IAAI,CAAC,OAAO,OAAO;CACnB,OAAO,MAAM,MAAM,GAAG,EAAE;AAC1B;AAEA,SAAS,aAAa,SAAoC;CACxD,MAAM,WAAW,QAAQ;CACzB,IAAI,CAAC,UAAU,OAAO;CACtB,MAAM,aAAa,SAAS,eAAe,KAAA,KAAa,SAAS,aAAa,KAAA,IAC1E,GAAG,SAAS,WAAW,IAAI,SAAS,aACpC;CACJ,MAAM,YAAY,SAAS,kBAAkB,SAAS,eAClD,GAAG,UAAU,SAAS,cAAc,EAAE,IAAI,UAAU,SAAS,YAAY,MACzE;CACJ,IAAI,eAAe,oBAAoB,cAAc,iBAAiB,OAAO;CAC7E,OAAO,GAAG,WAAW,KAAK;AAC5B;AAEA,SAAgB,0BAA0B,UAA+C;CACvF,IAAI,SAAS,SAAS,WAAW,GAAG,OAAO;CAC3C,MAAM,UAAU;EAAC;EAAW;EAAY;EAAS;EAAQ;EAAW;CAAiB;CACrF,MAAM,SAAS;EAAC;EAAI;EAAI;EAAG;EAAG;EAAI;CAAE;CACpC,MAAM,OAAO,WAAqB,OAAO,KAAK,OAAO,UAAU,MAAM,OAAO,OAAO,MAAO,CAAC,EAAE,KAAK,IAAI;CACtG,OAAO;EACL,IAAI,OAAO;EACX,OAAO,KAAK,UAAU,IAAI,OAAO,KAAK,CAAC,EAAE,KAAK,IAAI;EAClD,GAAG,SAAS,SAAS,KAAK,YAAY,IAAI;GACxC,QAAQ,gBAAgB,QAAQ;GAChC,WAAW,SAAS,UAAU;GAC9B,WAAW,SAAS,OAAO;GAC3B,WAAW,SAAS,MAAM;GAC1B,aAAa,OAAO;GACpB,oBAAoB,OAAO;EAC7B,CAAC,CAAC;CACJ,EAAE,KAAK,IAAI;AACb"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const require_client = require("./client-
|
|
1
|
+
const require_client = require("./client-Y_zqKqJT.cjs");
|
|
2
2
|
//#region src/mcp/capabilities.ts
|
|
3
3
|
function metadataNetworksUrl(endpoint) {
|
|
4
4
|
const url = new URL(endpoint);
|
|
@@ -11,10 +11,7 @@ async function fetchNetworkCapabilities(config) {
|
|
|
11
11
|
const request = metadataNetworksUrl(require_client.resolveGraphMcpEndpoint(config));
|
|
12
12
|
const headers = new Headers();
|
|
13
13
|
const token = config.graphMcpAuthToken?.trim() || config.mcpAuthToken?.trim();
|
|
14
|
-
if (token)
|
|
15
|
-
headers.set("X-MCP-Debug-Token", token);
|
|
16
|
-
headers.set("Authorization", `Bearer ${token}`);
|
|
17
|
-
}
|
|
14
|
+
if (token) require_client.applyMcpAuthHeaders(headers, token);
|
|
18
15
|
let response;
|
|
19
16
|
try {
|
|
20
17
|
response = await fetch(request, { headers });
|
package/dist/cli.cjs
CHANGED
|
@@ -72,7 +72,7 @@ function optionalNumberArg(value, name) {
|
|
|
72
72
|
async function withGraphMcpClient(name, fn) {
|
|
73
73
|
const { loadConfig } = await Promise.resolve().then(() => require("./config-BwVx19Og.cjs")).then((n) => n.config_exports);
|
|
74
74
|
const config = await loadConfig();
|
|
75
|
-
const { createConfiguredGraphMcpFetch, resolveGraphMcpEndpoint } = await Promise.resolve().then(() => require("./client-
|
|
75
|
+
const { createConfiguredGraphMcpFetch, resolveGraphMcpEndpoint } = await Promise.resolve().then(() => require("./client-Y_zqKqJT.cjs")).then((n) => n.client_exports);
|
|
76
76
|
const paymentFetch = await createConfiguredGraphMcpFetch(config);
|
|
77
77
|
const { Client } = await import("@modelcontextprotocol/sdk/client/index.js");
|
|
78
78
|
const { StreamableHTTPClientTransport } = await import("@modelcontextprotocol/sdk/client/streamableHttp.js");
|
|
@@ -92,7 +92,7 @@ function printMcpTextContent(result) {
|
|
|
92
92
|
}
|
|
93
93
|
async function printNetworkCapabilities(opts) {
|
|
94
94
|
const { loadConfig } = await Promise.resolve().then(() => require("./config-BwVx19Og.cjs")).then((n) => n.config_exports);
|
|
95
|
-
const { fetchNetworkCapabilities, formatNetworkCapabilities } = await Promise.resolve().then(() => require("./capabilities-
|
|
95
|
+
const { fetchNetworkCapabilities, formatNetworkCapabilities } = await Promise.resolve().then(() => require("./capabilities-DOa6EFO-.cjs"));
|
|
96
96
|
const document = await fetchNetworkCapabilities(await loadConfig());
|
|
97
97
|
if (opts.json) console.log(JSON.stringify(document, null, 2));
|
|
98
98
|
else console.log(formatNetworkCapabilities(document));
|
|
@@ -129,6 +129,31 @@ program.command("status").description("Show toolkit status and configuration").a
|
|
|
129
129
|
console.log("Graph MCP:", graphMcpStatus);
|
|
130
130
|
console.log("Graph endpoint:", config.graphMcpEndpoint);
|
|
131
131
|
});
|
|
132
|
+
program.command("update").description("Check npmjs for a newer Chain Insights release and update this CLI").option("--check", "Only check for a newer release").option("--dry-run", "Print the update command without running it").action(async (opts) => {
|
|
133
|
+
try {
|
|
134
|
+
const { checkForUpdate, runPackageUpdate } = await Promise.resolve().then(() => require("./update-BJoXYucO.cjs"));
|
|
135
|
+
const result = await checkForUpdate();
|
|
136
|
+
if (result.error) throw new Error(`Could not check npmjs for updates: ${result.error}`);
|
|
137
|
+
if (!result.updateAvailable || !result.latestVersion) {
|
|
138
|
+
console.log(`Chain Insights is up to date (${result.currentVersion}).`);
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
console.log(`Chain Insights ${result.latestVersion} is available (current ${result.currentVersion}).`);
|
|
142
|
+
if (opts.check) {
|
|
143
|
+
console.log(`Run: ${result.updateCommand}`);
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
if (opts.dryRun) {
|
|
147
|
+
console.log(`Would run: ${result.updateCommand}`);
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
console.log(`Running: ${result.updateCommand}`);
|
|
151
|
+
runPackageUpdate(result.packageName);
|
|
152
|
+
} catch (err) {
|
|
153
|
+
console.error(err.message);
|
|
154
|
+
process.exit(1);
|
|
155
|
+
}
|
|
156
|
+
});
|
|
132
157
|
program.command("obsidian").description("Manage the local Obsidian investigation vault").addCommand(new commander.Command("open").description("Open the current Chain Insights vault in Obsidian").argument("[path]", "Workspace path to open as an Obsidian vault").action(async (workspacePath) => {
|
|
133
158
|
try {
|
|
134
159
|
const { findActiveWorkspace } = await Promise.resolve().then(() => require("./active-BVr55kvW.cjs")).then((n) => n.active_exports);
|
|
@@ -240,6 +265,8 @@ program.command("init").description("Initialize an investigation workspace").arg
|
|
|
240
265
|
});
|
|
241
266
|
console.log(`Workspace initialized: ${result.workspaceRoot}`);
|
|
242
267
|
console.log(`Files written: ${result.filesWritten.length}`);
|
|
268
|
+
const { maybePromptForUpdate } = await Promise.resolve().then(() => require("./update-BJoXYucO.cjs"));
|
|
269
|
+
await maybePromptForUpdate();
|
|
243
270
|
} catch (err) {
|
|
244
271
|
console.error(err.message);
|
|
245
272
|
process.exit(1);
|
|
@@ -383,7 +410,7 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
|
|
|
383
410
|
const { formatToolsTable } = await Promise.resolve().then(() => require("./format-9NLBykEL.cjs"));
|
|
384
411
|
const { visibleRemoteTools } = await Promise.resolve().then(() => require("./tool-visibility-Buq7YdUZ.cjs")).then((n) => n.tool_visibility_exports);
|
|
385
412
|
const { loadConfig } = await Promise.resolve().then(() => require("./config-BwVx19Og.cjs")).then((n) => n.config_exports);
|
|
386
|
-
const { createConfiguredGraphMcpFetch, resolveGraphMcpEndpoint } = await Promise.resolve().then(() => require("./client-
|
|
413
|
+
const { createConfiguredGraphMcpFetch, resolveGraphMcpEndpoint } = await Promise.resolve().then(() => require("./client-Y_zqKqJT.cjs")).then((n) => n.client_exports);
|
|
387
414
|
const config = await loadConfig();
|
|
388
415
|
const graphMcpEndpoint = resolveGraphMcpEndpoint(config);
|
|
389
416
|
let tools = opts.refresh ? null : await loadSchema(graphMcpEndpoint);
|
|
@@ -422,7 +449,7 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
|
|
|
422
449
|
}));
|
|
423
450
|
return;
|
|
424
451
|
}
|
|
425
|
-
const { addressRisk } = await Promise.resolve().then(() => require("./public-tools-
|
|
452
|
+
const { addressRisk } = await Promise.resolve().then(() => require("./public-tools-BY3PTw6x.cjs"));
|
|
426
453
|
const result = await addressRisk(client, {
|
|
427
454
|
address: opts.address,
|
|
428
455
|
network: opts.network,
|
|
@@ -450,7 +477,7 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
|
|
|
450
477
|
}));
|
|
451
478
|
return;
|
|
452
479
|
}
|
|
453
|
-
const { traceVictimFunds } = await Promise.resolve().then(() => require("./public-tools-
|
|
480
|
+
const { traceVictimFunds } = await Promise.resolve().then(() => require("./public-tools-BY3PTw6x.cjs"));
|
|
454
481
|
const caseId = opts.case ? await resolveCaseSelector(opts.case) : void 0;
|
|
455
482
|
const result = await traceVictimFunds(client, config, {
|
|
456
483
|
victimAddresses: opts.victimAddresses,
|
|
@@ -474,7 +501,7 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
|
|
|
474
501
|
const { requireWorkspaceRoot } = await Promise.resolve().then(() => require("./output-root-YIbl6PwF.cjs")).then((n) => n.output_root_exports);
|
|
475
502
|
requireWorkspaceRoot();
|
|
476
503
|
await withGraphMcpClient("chain-insights-cli-trace-suspect-funds", async (client, config) => {
|
|
477
|
-
const { traceSuspectFunds } = await Promise.resolve().then(() => require("./public-tools-
|
|
504
|
+
const { traceSuspectFunds } = await Promise.resolve().then(() => require("./public-tools-BY3PTw6x.cjs"));
|
|
478
505
|
const caseId = opts.case ? await resolveCaseSelector(opts.case) : void 0;
|
|
479
506
|
const result = await traceSuspectFunds(client, config, {
|
|
480
507
|
suspectAddresses: opts.suspectAddresses,
|
|
@@ -497,7 +524,7 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
|
|
|
497
524
|
const { requireWorkspaceRoot } = await Promise.resolve().then(() => require("./output-root-YIbl6PwF.cjs")).then((n) => n.output_root_exports);
|
|
498
525
|
requireWorkspaceRoot();
|
|
499
526
|
await withGraphMcpClient("chain-insights-cli-trace-deposit-sources", async (client, config) => {
|
|
500
|
-
const { traceDepositSources } = await Promise.resolve().then(() => require("./public-tools-
|
|
527
|
+
const { traceDepositSources } = await Promise.resolve().then(() => require("./public-tools-BY3PTw6x.cjs"));
|
|
501
528
|
const caseId = opts.case ? await resolveCaseSelector(opts.case) : void 0;
|
|
502
529
|
const result = await traceDepositSources(client, config, {
|
|
503
530
|
depositAddresses: opts.depositAddresses,
|
|
@@ -515,7 +542,7 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
|
|
|
515
542
|
})).addCommand(new commander.Command("stake-insights").description("Explain Bittensor staking behavior around an address, coldkey, or hotkey").requiredOption("--network <network>", "Network to query. Run `cia mcp networks` for supported networks.").option("--address <address>", "Full Bittensor address to inspect as either coldkey or hotkey").option("--coldkey <address>", "Full Bittensor coldkey address to inspect").option("--hotkey <address>", "Full Bittensor hotkey address to inspect").option("--netuid <number>", "Optional subnet netuid filter").option("--start-timestamp-ms <milliseconds>", "Optional inclusive lower activity timestamp bound").option("--end-timestamp-ms <milliseconds>", "Optional inclusive upper activity timestamp bound").option("--start-block <number>", "Optional start block. Current stake graph parity may require timestamp windows instead.").option("--end-block <number>", "Optional end block. Current stake graph parity may require timestamp windows instead.").option("--depth <number>", "Optional expansion depth limit, default 1, max 3").action(async (opts) => {
|
|
516
543
|
try {
|
|
517
544
|
await withGraphMcpClient("chain-insights-cli-stake-insights", async (client) => {
|
|
518
|
-
const { stakeInsights } = await Promise.resolve().then(() => require("./public-tools-
|
|
545
|
+
const { stakeInsights } = await Promise.resolve().then(() => require("./public-tools-BY3PTw6x.cjs"));
|
|
519
546
|
const result = await stakeInsights(client, {
|
|
520
547
|
network: opts.network,
|
|
521
548
|
address: opts.address,
|
|
@@ -543,7 +570,7 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
|
|
|
543
570
|
assertPublicMcpToolName(tool);
|
|
544
571
|
await withGraphMcpClient("chain-insights-cli-call", async (client, config) => {
|
|
545
572
|
if (tool === "address_risk") {
|
|
546
|
-
const { addressRisk } = await Promise.resolve().then(() => require("./public-tools-
|
|
573
|
+
const { addressRisk } = await Promise.resolve().then(() => require("./public-tools-BY3PTw6x.cjs"));
|
|
547
574
|
const result = await addressRisk(client, {
|
|
548
575
|
address: String(args["address"] ?? ""),
|
|
549
576
|
network: String(args["network"] ?? ""),
|
|
@@ -553,7 +580,7 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
|
|
|
553
580
|
return;
|
|
554
581
|
}
|
|
555
582
|
if (tool === "trace_victim_funds") {
|
|
556
|
-
const { traceVictimFunds } = await Promise.resolve().then(() => require("./public-tools-
|
|
583
|
+
const { traceVictimFunds } = await Promise.resolve().then(() => require("./public-tools-BY3PTw6x.cjs"));
|
|
557
584
|
const result = await traceVictimFunds(client, config, {
|
|
558
585
|
victimAddresses: args["victim_addresses"] ?? "",
|
|
559
586
|
knownSuspectAddresses: args["known_suspect_addresses"],
|
|
@@ -569,7 +596,7 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
|
|
|
569
596
|
return;
|
|
570
597
|
}
|
|
571
598
|
if (tool === "trace_suspect_funds") {
|
|
572
|
-
const { traceSuspectFunds } = await Promise.resolve().then(() => require("./public-tools-
|
|
599
|
+
const { traceSuspectFunds } = await Promise.resolve().then(() => require("./public-tools-BY3PTw6x.cjs"));
|
|
573
600
|
const result = await traceSuspectFunds(client, config, {
|
|
574
601
|
suspectAddresses: args["suspect_addresses"] ?? "",
|
|
575
602
|
network: String(args["network"] ?? ""),
|
|
@@ -584,7 +611,7 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
|
|
|
584
611
|
return;
|
|
585
612
|
}
|
|
586
613
|
if (tool === "trace_deposit_sources") {
|
|
587
|
-
const { traceDepositSources } = await Promise.resolve().then(() => require("./public-tools-
|
|
614
|
+
const { traceDepositSources } = await Promise.resolve().then(() => require("./public-tools-BY3PTw6x.cjs"));
|
|
588
615
|
const result = await traceDepositSources(client, config, {
|
|
589
616
|
depositAddresses: args["deposit_addresses"] ?? "",
|
|
590
617
|
network: String(args["network"] ?? ""),
|
|
@@ -596,7 +623,7 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
|
|
|
596
623
|
return;
|
|
597
624
|
}
|
|
598
625
|
if (tool === "stake_insights") {
|
|
599
|
-
const { stakeInsights } = await Promise.resolve().then(() => require("./public-tools-
|
|
626
|
+
const { stakeInsights } = await Promise.resolve().then(() => require("./public-tools-BY3PTw6x.cjs"));
|
|
600
627
|
const result = await stakeInsights(client, {
|
|
601
628
|
network: String(args["network"] ?? ""),
|
|
602
629
|
address: args["address"] === void 0 ? void 0 : String(args["address"]),
|
|
@@ -850,7 +877,7 @@ program.command("playbook").description("Run and manage investigation playbooks"
|
|
|
850
877
|
console.error(`Invalid --from value: "${opts.from}". Must be a positive integer.`);
|
|
851
878
|
process.exit(1);
|
|
852
879
|
}
|
|
853
|
-
const { PlaybookRunner } = await Promise.resolve().then(() => require("./runner-
|
|
880
|
+
const { PlaybookRunner } = await Promise.resolve().then(() => require("./runner-bLy0pTr_.cjs"));
|
|
854
881
|
await PlaybookRunner.run(definition, {
|
|
855
882
|
caseId: opts.case,
|
|
856
883
|
from: fromN,
|
package/dist/cli.mjs
CHANGED
|
@@ -70,7 +70,7 @@ function optionalNumberArg(value, name) {
|
|
|
70
70
|
async function withGraphMcpClient(name, fn) {
|
|
71
71
|
const { loadConfig } = await import("./config-Drgc2HuF.mjs").then((n) => n.t);
|
|
72
72
|
const config = await loadConfig();
|
|
73
|
-
const { createConfiguredGraphMcpFetch, resolveGraphMcpEndpoint } = await import("./client-
|
|
73
|
+
const { createConfiguredGraphMcpFetch, resolveGraphMcpEndpoint } = await import("./client-BgmHjBHQ.mjs").then((n) => n.r);
|
|
74
74
|
const paymentFetch = await createConfiguredGraphMcpFetch(config);
|
|
75
75
|
const { Client } = await import("@modelcontextprotocol/sdk/client/index.js");
|
|
76
76
|
const { StreamableHTTPClientTransport } = await import("@modelcontextprotocol/sdk/client/streamableHttp.js");
|
|
@@ -90,7 +90,7 @@ function printMcpTextContent(result) {
|
|
|
90
90
|
}
|
|
91
91
|
async function printNetworkCapabilities(opts) {
|
|
92
92
|
const { loadConfig } = await import("./config-Drgc2HuF.mjs").then((n) => n.t);
|
|
93
|
-
const { fetchNetworkCapabilities, formatNetworkCapabilities } = await import("./capabilities-
|
|
93
|
+
const { fetchNetworkCapabilities, formatNetworkCapabilities } = await import("./capabilities-BCvkTkIu.mjs");
|
|
94
94
|
const document = await fetchNetworkCapabilities(await loadConfig());
|
|
95
95
|
if (opts.json) console.log(JSON.stringify(document, null, 2));
|
|
96
96
|
else console.log(formatNetworkCapabilities(document));
|
|
@@ -127,6 +127,31 @@ program.command("status").description("Show toolkit status and configuration").a
|
|
|
127
127
|
console.log("Graph MCP:", graphMcpStatus);
|
|
128
128
|
console.log("Graph endpoint:", config.graphMcpEndpoint);
|
|
129
129
|
});
|
|
130
|
+
program.command("update").description("Check npmjs for a newer Chain Insights release and update this CLI").option("--check", "Only check for a newer release").option("--dry-run", "Print the update command without running it").action(async (opts) => {
|
|
131
|
+
try {
|
|
132
|
+
const { checkForUpdate, runPackageUpdate } = await import("./update-CJUfGCxs.mjs");
|
|
133
|
+
const result = await checkForUpdate();
|
|
134
|
+
if (result.error) throw new Error(`Could not check npmjs for updates: ${result.error}`);
|
|
135
|
+
if (!result.updateAvailable || !result.latestVersion) {
|
|
136
|
+
console.log(`Chain Insights is up to date (${result.currentVersion}).`);
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
console.log(`Chain Insights ${result.latestVersion} is available (current ${result.currentVersion}).`);
|
|
140
|
+
if (opts.check) {
|
|
141
|
+
console.log(`Run: ${result.updateCommand}`);
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
if (opts.dryRun) {
|
|
145
|
+
console.log(`Would run: ${result.updateCommand}`);
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
console.log(`Running: ${result.updateCommand}`);
|
|
149
|
+
runPackageUpdate(result.packageName);
|
|
150
|
+
} catch (err) {
|
|
151
|
+
console.error(err.message);
|
|
152
|
+
process.exit(1);
|
|
153
|
+
}
|
|
154
|
+
});
|
|
130
155
|
program.command("obsidian").description("Manage the local Obsidian investigation vault").addCommand(new Command("open").description("Open the current Chain Insights vault in Obsidian").argument("[path]", "Workspace path to open as an Obsidian vault").action(async (workspacePath) => {
|
|
131
156
|
try {
|
|
132
157
|
const { findActiveWorkspace } = await import("./active-ByNgjuAg.mjs").then((n) => n.n);
|
|
@@ -238,6 +263,8 @@ program.command("init").description("Initialize an investigation workspace").arg
|
|
|
238
263
|
});
|
|
239
264
|
console.log(`Workspace initialized: ${result.workspaceRoot}`);
|
|
240
265
|
console.log(`Files written: ${result.filesWritten.length}`);
|
|
266
|
+
const { maybePromptForUpdate } = await import("./update-CJUfGCxs.mjs");
|
|
267
|
+
await maybePromptForUpdate();
|
|
241
268
|
} catch (err) {
|
|
242
269
|
console.error(err.message);
|
|
243
270
|
process.exit(1);
|
|
@@ -381,7 +408,7 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
|
|
|
381
408
|
const { formatToolsTable } = await import("./format-Bq94jSyw.mjs");
|
|
382
409
|
const { visibleRemoteTools } = await import("./tool-visibility-BpyZHRBi.mjs").then((n) => n.n);
|
|
383
410
|
const { loadConfig } = await import("./config-Drgc2HuF.mjs").then((n) => n.t);
|
|
384
|
-
const { createConfiguredGraphMcpFetch, resolveGraphMcpEndpoint } = await import("./client-
|
|
411
|
+
const { createConfiguredGraphMcpFetch, resolveGraphMcpEndpoint } = await import("./client-BgmHjBHQ.mjs").then((n) => n.r);
|
|
385
412
|
const config = await loadConfig();
|
|
386
413
|
const graphMcpEndpoint = resolveGraphMcpEndpoint(config);
|
|
387
414
|
let tools = opts.refresh ? null : await loadSchema(graphMcpEndpoint);
|
|
@@ -420,7 +447,7 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
|
|
|
420
447
|
}));
|
|
421
448
|
return;
|
|
422
449
|
}
|
|
423
|
-
const { addressRisk } = await import("./public-tools-
|
|
450
|
+
const { addressRisk } = await import("./public-tools-CvlZcysd.mjs");
|
|
424
451
|
const result = await addressRisk(client, {
|
|
425
452
|
address: opts.address,
|
|
426
453
|
network: opts.network,
|
|
@@ -448,7 +475,7 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
|
|
|
448
475
|
}));
|
|
449
476
|
return;
|
|
450
477
|
}
|
|
451
|
-
const { traceVictimFunds } = await import("./public-tools-
|
|
478
|
+
const { traceVictimFunds } = await import("./public-tools-CvlZcysd.mjs");
|
|
452
479
|
const caseId = opts.case ? await resolveCaseSelector(opts.case) : void 0;
|
|
453
480
|
const result = await traceVictimFunds(client, config, {
|
|
454
481
|
victimAddresses: opts.victimAddresses,
|
|
@@ -472,7 +499,7 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
|
|
|
472
499
|
const { requireWorkspaceRoot } = await import("./output-root-BRhzhhXZ.mjs").then((n) => n.t);
|
|
473
500
|
requireWorkspaceRoot();
|
|
474
501
|
await withGraphMcpClient("chain-insights-cli-trace-suspect-funds", async (client, config) => {
|
|
475
|
-
const { traceSuspectFunds } = await import("./public-tools-
|
|
502
|
+
const { traceSuspectFunds } = await import("./public-tools-CvlZcysd.mjs");
|
|
476
503
|
const caseId = opts.case ? await resolveCaseSelector(opts.case) : void 0;
|
|
477
504
|
const result = await traceSuspectFunds(client, config, {
|
|
478
505
|
suspectAddresses: opts.suspectAddresses,
|
|
@@ -495,7 +522,7 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
|
|
|
495
522
|
const { requireWorkspaceRoot } = await import("./output-root-BRhzhhXZ.mjs").then((n) => n.t);
|
|
496
523
|
requireWorkspaceRoot();
|
|
497
524
|
await withGraphMcpClient("chain-insights-cli-trace-deposit-sources", async (client, config) => {
|
|
498
|
-
const { traceDepositSources } = await import("./public-tools-
|
|
525
|
+
const { traceDepositSources } = await import("./public-tools-CvlZcysd.mjs");
|
|
499
526
|
const caseId = opts.case ? await resolveCaseSelector(opts.case) : void 0;
|
|
500
527
|
const result = await traceDepositSources(client, config, {
|
|
501
528
|
depositAddresses: opts.depositAddresses,
|
|
@@ -513,7 +540,7 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
|
|
|
513
540
|
})).addCommand(new Command("stake-insights").description("Explain Bittensor staking behavior around an address, coldkey, or hotkey").requiredOption("--network <network>", "Network to query. Run `cia mcp networks` for supported networks.").option("--address <address>", "Full Bittensor address to inspect as either coldkey or hotkey").option("--coldkey <address>", "Full Bittensor coldkey address to inspect").option("--hotkey <address>", "Full Bittensor hotkey address to inspect").option("--netuid <number>", "Optional subnet netuid filter").option("--start-timestamp-ms <milliseconds>", "Optional inclusive lower activity timestamp bound").option("--end-timestamp-ms <milliseconds>", "Optional inclusive upper activity timestamp bound").option("--start-block <number>", "Optional start block. Current stake graph parity may require timestamp windows instead.").option("--end-block <number>", "Optional end block. Current stake graph parity may require timestamp windows instead.").option("--depth <number>", "Optional expansion depth limit, default 1, max 3").action(async (opts) => {
|
|
514
541
|
try {
|
|
515
542
|
await withGraphMcpClient("chain-insights-cli-stake-insights", async (client) => {
|
|
516
|
-
const { stakeInsights } = await import("./public-tools-
|
|
543
|
+
const { stakeInsights } = await import("./public-tools-CvlZcysd.mjs");
|
|
517
544
|
const result = await stakeInsights(client, {
|
|
518
545
|
network: opts.network,
|
|
519
546
|
address: opts.address,
|
|
@@ -541,7 +568,7 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
|
|
|
541
568
|
assertPublicMcpToolName(tool);
|
|
542
569
|
await withGraphMcpClient("chain-insights-cli-call", async (client, config) => {
|
|
543
570
|
if (tool === "address_risk") {
|
|
544
|
-
const { addressRisk } = await import("./public-tools-
|
|
571
|
+
const { addressRisk } = await import("./public-tools-CvlZcysd.mjs");
|
|
545
572
|
const result = await addressRisk(client, {
|
|
546
573
|
address: String(args["address"] ?? ""),
|
|
547
574
|
network: String(args["network"] ?? ""),
|
|
@@ -551,7 +578,7 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
|
|
|
551
578
|
return;
|
|
552
579
|
}
|
|
553
580
|
if (tool === "trace_victim_funds") {
|
|
554
|
-
const { traceVictimFunds } = await import("./public-tools-
|
|
581
|
+
const { traceVictimFunds } = await import("./public-tools-CvlZcysd.mjs");
|
|
555
582
|
const result = await traceVictimFunds(client, config, {
|
|
556
583
|
victimAddresses: args["victim_addresses"] ?? "",
|
|
557
584
|
knownSuspectAddresses: args["known_suspect_addresses"],
|
|
@@ -567,7 +594,7 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
|
|
|
567
594
|
return;
|
|
568
595
|
}
|
|
569
596
|
if (tool === "trace_suspect_funds") {
|
|
570
|
-
const { traceSuspectFunds } = await import("./public-tools-
|
|
597
|
+
const { traceSuspectFunds } = await import("./public-tools-CvlZcysd.mjs");
|
|
571
598
|
const result = await traceSuspectFunds(client, config, {
|
|
572
599
|
suspectAddresses: args["suspect_addresses"] ?? "",
|
|
573
600
|
network: String(args["network"] ?? ""),
|
|
@@ -582,7 +609,7 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
|
|
|
582
609
|
return;
|
|
583
610
|
}
|
|
584
611
|
if (tool === "trace_deposit_sources") {
|
|
585
|
-
const { traceDepositSources } = await import("./public-tools-
|
|
612
|
+
const { traceDepositSources } = await import("./public-tools-CvlZcysd.mjs");
|
|
586
613
|
const result = await traceDepositSources(client, config, {
|
|
587
614
|
depositAddresses: args["deposit_addresses"] ?? "",
|
|
588
615
|
network: String(args["network"] ?? ""),
|
|
@@ -594,7 +621,7 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
|
|
|
594
621
|
return;
|
|
595
622
|
}
|
|
596
623
|
if (tool === "stake_insights") {
|
|
597
|
-
const { stakeInsights } = await import("./public-tools-
|
|
624
|
+
const { stakeInsights } = await import("./public-tools-CvlZcysd.mjs");
|
|
598
625
|
const result = await stakeInsights(client, {
|
|
599
626
|
network: String(args["network"] ?? ""),
|
|
600
627
|
address: args["address"] === void 0 ? void 0 : String(args["address"]),
|
|
@@ -848,7 +875,7 @@ program.command("playbook").description("Run and manage investigation playbooks"
|
|
|
848
875
|
console.error(`Invalid --from value: "${opts.from}". Must be a positive integer.`);
|
|
849
876
|
process.exit(1);
|
|
850
877
|
}
|
|
851
|
-
const { PlaybookRunner } = await import("./runner-
|
|
878
|
+
const { PlaybookRunner } = await import("./runner-CVnjpqc-.mjs");
|
|
852
879
|
await PlaybookRunner.run(definition, {
|
|
853
880
|
caseId: opts.case,
|
|
854
881
|
from: fromN,
|