chain-insights 0.2.30 → 0.2.31

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
@@ -194,6 +194,10 @@ result envelope. Use explicit `LIMIT` and pagination in your query when you
194
194
  want bounded result sets. Endpoint access and authentication are configured
195
195
  separately; see [MCP proxy](docs/mcp-proxy.md).
196
196
 
197
+ Agent installs include `chain-insights-cypher` for generic layer-aware
198
+ GQL/Cypher work and `chain-insights-bittensor-cypher` for Bittensor-specific
199
+ schema notes and examples.
200
+
197
201
  ## AML Tools
198
202
 
199
203
  The high-level AML tools are Chain Insights workflows built around graph access
@@ -37,6 +37,13 @@ assumed to exist on the GraphRAG MCP endpoint.
37
37
  - `per_query_timeout_seconds` is optional and capped at `10` by default.
38
38
  - Returned rows live in `structuredContent.facts`.
39
39
 
40
+ Agent installers ship two graph-query skills:
41
+
42
+ - `chain-insights-cypher`: generic layer selection, schema capture, and
43
+ portable read-only GQL/Cypher examples.
44
+ - `chain-insights-bittensor-cypher`: Bittensor-specific schema notes for SS58
45
+ and EVM-pallet addresses under `network=bittensor`.
46
+
40
47
  Check public-free usage:
41
48
 
42
49
  ```bash
@@ -313,12 +320,19 @@ Large JSON belongs under workspace report directories, not inline in evidence.
313
320
  Fresh workspaces include a runtime schema skill and schema capture directory.
314
321
  Before the first case query against a network, capture the live graph schema and
315
322
  use the observed labels, relationship types, and property names in subsequent
316
- queries.
323
+ queries. Different networks can expose different fact nodes and relationship
324
+ properties, so do not assume a query that works on Bittensor will work on Base,
325
+ Ethereum, or TRON without a fresh schema probe.
317
326
 
318
327
  Useful schema probes:
319
328
 
320
329
  ```bash
321
330
  cia mcp call graph_query_batch \
322
331
  network=bittensor \
323
- 'queries=[{"id":"live_address_sample","query":"USE live_topology MATCH (n:Address) RETURN n.address AS address, n.labels AS labels LIMIT 5"},{"id":"archive_flow_sample","query":"USE archive_topology MATCH (src:Address)-[f:FLOWS_TO]->(dst:Address) RETURN src.address AS source, dst.address AS target, f.period_granularity AS granularity LIMIT 5"},{"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 5"}]'
332
+ per_query_timeout_seconds=5 \
333
+ 'queries=[{"id":"live_address_sample","query":"USE live_topology MATCH (n:Address) RETURN n.address AS address, n.labels AS labels, n.is_exchange AS is_exchange LIMIT 10"},{"id":"live_flow_sample","query":"USE live_topology MATCH (src:Address)-[flow:FLOWS_TO]->(dst:Address) RETURN src.address AS from_address, dst.address AS to_address, flow.amount_sum AS amount_sum, flow.amount_usd_sum AS amount_usd_sum, flow.tx_count AS tx_count LIMIT 10"},{"id":"archive_flow_sample","query":"USE archive_topology MATCH (src:Address)-[flow:FLOWS_TO]->(dst:Address) RETURN src.address AS from_address, dst.address AS to_address, flow.period_granularity AS period_granularity, flow.amount_sum AS amount_sum, flow.amount_usd_sum AS amount_usd_sum, flow.tx_count AS tx_count LIMIT 10"},{"id":"facts_address_sample","query":"USE facts MATCH (a:Address) RETURN a.address AS address, a.labels AS labels, a.is_exchange AS is_exchange LIMIT 10"}]'
324
334
  ```
335
+
336
+ Use projections like `n.address` and `flow.tx_count` in probes. Metadata
337
+ functions such as `keys()`, `labels()`, and `type()` are not portable across
338
+ every GraphRAG MCP layer.
package/docs/mcp-proxy.md CHANGED
@@ -165,6 +165,11 @@ directory and registers the stdio MCP proxy in the Hermes config.
165
165
  After installing, open an initialized investigation workspace in the agent and
166
166
  operate over the workspace files.
167
167
 
168
+ For manual graph-language work, agents should use the shipped
169
+ `chain-insights-cypher` skill. For Bittensor queries, load
170
+ `chain-insights-bittensor-cypher` after the generic skill so SS58 and
171
+ EVM-pallet addresses stay under `network=bittensor`.
172
+
168
173
  ## Claude Desktop
169
174
 
170
175
  Claude Desktop is supported for basic MCP calls. It is not the primary
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chain-insights",
3
- "version": "0.2.30",
3
+ "version": "0.2.31",
4
4
  "description": "AML investigation CLI and MCP proxy for blockchain risk, fund-flow tracing, case reports, and GraphRAG MCP access",
5
5
  "homepage": "https://chain-insights.ai",
6
6
  "repository": {
@@ -0,0 +1,136 @@
1
+ ---
2
+ name: chain-insights-bittensor-cypher
3
+ description: Use when writing Chain Insights graph_query or graph_query_batch reads for network=bittensor, Bittensor SS58 and EVM-pallet addresses, TAO FLOWS_TO, STAKES_IN, hotkey/coldkey/neuron facts, or Bittensor-specific schema checks.
4
+ ---
5
+
6
+ # Chain Insights Bittensor Cypher
7
+
8
+ Load `chain-insights-cypher` first for generic layer rules. This skill adds the
9
+ Bittensor schema and examples.
10
+
11
+ ## Network Rule
12
+
13
+ Bittensor contains both native Substrate/SS58 addresses such as `5...` and
14
+ EVM-pallet `0x...` addresses in one investigation network:
15
+
16
+ - Use `network=bittensor` for both address families.
17
+ - Do not switch networks just because an address is `0x...`.
18
+ - Preserve the exact returned `address`, `address_type`, and `network` fields.
19
+ - If an endpoint advertises legacy `bittensor_evm`, treat it as compatibility
20
+ evidence, not a reason to split the investigation unless the user asks.
21
+
22
+ ## Current Schema Notes
23
+
24
+ Observed against staging on 2026-05-29:
25
+
26
+ - `network_capabilities` advertises Bittensor as default with topology, facts,
27
+ risk, `graph_query`, and `graph_query_batch` available; dataset coverage was
28
+ `unknown`.
29
+ - `live_topology` accepted `Address` and `FLOWS_TO` projection queries. Sample
30
+ `Address` rows included `address`, `network`, and `address_type`; `labels`,
31
+ `is_exchange`, degree, and tx-count fields were sparse in the sample.
32
+ - `live_topology` accepted `STAKES_IN` count/projection shape but returned zero
33
+ rows in the staging sample.
34
+ - `archive_topology` accepted `Address` to `FLOWS_TO` historical queries and
35
+ returned SS58 addresses with `edge_id`, `period_granularity`, amount fields,
36
+ tx count, and first/last timestamps.
37
+ - `archive_topology` exposed `TopologySnapshot` in the staging sample.
38
+ - Source mappings include archive `STAKES_IN` and facts labels/features/neuron
39
+ context, but staging returned generic backend errors for those sample reads;
40
+ verify them with a fresh schema probe before relying on them.
41
+
42
+ ## Bittensor Shapes
43
+
44
+ Live topology:
45
+
46
+ ```cypher
47
+ USE live_topology
48
+ MATCH (src:Address)-[flow:FLOWS_TO]->(dst:Address)
49
+ RETURN src.address AS from_address,
50
+ dst.address AS to_address,
51
+ flow.amount_sum AS amount_sum,
52
+ flow.amount_usd_sum AS amount_usd_sum,
53
+ flow.tx_count AS tx_count,
54
+ flow.first_seen_timestamp AS first_seen_timestamp,
55
+ flow.last_seen_timestamp AS last_seen_timestamp
56
+ LIMIT 25
57
+ ```
58
+
59
+ Archive topology:
60
+
61
+ ```cypher
62
+ USE archive_topology
63
+ MATCH (src:Address)-[flow:FLOWS_TO]->(dst:Address)
64
+ RETURN src.address AS from_address,
65
+ dst.address AS to_address,
66
+ flow.edge_id AS edge_id,
67
+ flow.period_granularity AS period_granularity,
68
+ flow.amount_sum AS amount_sum,
69
+ flow.amount_usd_sum AS amount_usd_sum,
70
+ flow.tx_count AS tx_count,
71
+ flow.first_seen_timestamp AS first_seen_timestamp,
72
+ flow.last_seen_timestamp AS last_seen_timestamp
73
+ LIMIT 25
74
+ ```
75
+
76
+ Stake topology, when the endpoint proves it:
77
+
78
+ ```cypher
79
+ USE live_topology
80
+ MATCH (coldkey:Address)-[stake:STAKES_IN]->(hotkey:Address)
81
+ RETURN coldkey.address AS coldkey,
82
+ hotkey.address AS hotkey,
83
+ stake.netuid AS netuid,
84
+ stake.amount AS amount,
85
+ stake.source_role AS source_role,
86
+ stake.destination_role AS destination_role,
87
+ stake.source_backend AS source_backend
88
+ LIMIT 25
89
+ ```
90
+
91
+ Facts, when the endpoint proves the mapping:
92
+
93
+ ```cypher
94
+ USE facts
95
+ MATCH (coldkey:Address)-[:REGISTERED_NEURON]->(hotkey:Hotkey)-[:SERVED_FROM]->(ip:IPAddress)
96
+ RETURN coldkey.address AS coldkey,
97
+ hotkey.address AS hotkey,
98
+ ip.ip_address AS ip_address
99
+ LIMIT 25
100
+ ```
101
+
102
+ ## Schema Probe
103
+
104
+ Use this before a custom Bittensor query session:
105
+
106
+ ```bash
107
+ cia mcp call graph_query_batch \
108
+ network=bittensor \
109
+ per_query_timeout_seconds=5 \
110
+ 'queries=[{"id":"live_address_projection","query":"USE live_topology MATCH (n:Address) RETURN n.address AS address, n.labels AS labels, n.is_exchange AS is_exchange, n.address_type AS address_type, n.network AS network LIMIT 10"},{"id":"live_flow_sample","query":"USE live_topology MATCH (src:Address)-[flow:FLOWS_TO]->(dst:Address) RETURN src.address AS from_address, dst.address AS to_address, flow.amount_sum AS amount_sum, flow.amount_usd_sum AS amount_usd_sum, flow.tx_count AS tx_count LIMIT 10"},{"id":"live_stake_count","query":"USE live_topology MATCH (:Address)-[stake:STAKES_IN]->(:Address) RETURN count(stake) AS stake_edges LIMIT 1"},{"id":"archive_flow_sample","query":"USE archive_topology MATCH (src:Address)-[flow:FLOWS_TO]->(dst:Address) RETURN src.address AS from_address, dst.address AS to_address, flow.edge_id AS edge_id, flow.period_granularity AS period_granularity, flow.amount_sum AS amount_sum, flow.amount_usd_sum AS amount_usd_sum, flow.tx_count AS tx_count LIMIT 10"},{"id":"archive_snapshot","query":"USE archive_topology MATCH (s:TopologySnapshot) RETURN s.graph_name AS graph_name, s.default_period_granularity AS default_period_granularity, s.available_granularities AS available_granularities LIMIT 5"},{"id":"facts_address_sample","query":"USE facts MATCH (a:Address) RETURN a.address AS address, a.labels AS labels, a.is_exchange AS is_exchange LIMIT 10"}]'
111
+ ```
112
+
113
+ Avoid `keys()`, `labels()`, `type()`, native BFS syntax, and variable-length
114
+ paths in schema probes. They may be valid in a direct Memgraph console but are
115
+ not portable across the GraphRAG MCP federation path.
116
+
117
+ ## Investigation Patterns
118
+
119
+ Outflows from a SS58 or `0x...` Bittensor address:
120
+
121
+ ```bash
122
+ cia mcp call graph_query \
123
+ network=bittensor \
124
+ 'query=USE live_topology MATCH (src:Address {address: "FULL_BITTENSOR_ADDRESS"})-[flow:FLOWS_TO]->(dst:Address) RETURN dst.address AS to_address, flow.amount_sum AS amount_sum, flow.amount_usd_sum AS amount_usd_sum, flow.tx_count AS tx_count, flow.last_seen_timestamp AS last_seen_timestamp ORDER BY flow.amount_usd_sum DESC LIMIT 50'
125
+ ```
126
+
127
+ Historical archive read for the same address:
128
+
129
+ ```bash
130
+ cia mcp call graph_query \
131
+ network=bittensor \
132
+ 'query=USE archive_topology MATCH (src:Address {address: "FULL_BITTENSOR_ADDRESS"})-[flow:FLOWS_TO]->(dst:Address) RETURN dst.address AS to_address, flow.period_granularity AS period_granularity, flow.amount_sum AS amount_sum, flow.amount_usd_sum AS amount_usd_sum, flow.tx_count AS tx_count, flow.first_seen_timestamp AS first_seen_timestamp, flow.last_seen_timestamp AS last_seen_timestamp ORDER BY flow.last_seen_timestamp DESC LIMIT 50'
133
+ ```
134
+
135
+ When comparing amounts, remember that archive StarRocks-backed numeric fields
136
+ may arrive as strings while live Memgraph fields may arrive as numbers.
@@ -0,0 +1,4 @@
1
+ interface:
2
+ display_name: "Bittensor Cypher"
3
+ short_description: "Write Bittensor-specific Chain Insights graph reads"
4
+ default_prompt: "Use Chain Insights graph_query or graph_query_batch on network=bittensor with SS58 and EVM-pallet address handling, Bittensor topology fields, bounded Cypher, and fresh schema probes."
@@ -0,0 +1,105 @@
1
+ ---
2
+ name: chain-insights-cypher
3
+ description: Use when writing, reviewing, or debugging Chain Insights graph_query or graph_query_batch GQL/Cypher, choosing live_topology, archive_topology, or facts, capturing schema, or making schema-aware graph reads across networks.
4
+ ---
5
+
6
+ # Chain Insights Cypher
7
+
8
+ Use this for manual `graph_query` and `graph_query_batch` work. For case work,
9
+ combine it with `chain-insights-investigation`. If a network-specific Cypher
10
+ skill exists, load it after this one.
11
+
12
+ ## First Moves
13
+
14
+ 1. Inspect the endpoint before writing network-specific queries:
15
+ ```bash
16
+ cia mcp networks
17
+ cia mcp call usage_status
18
+ ```
19
+ 2. Always pass an explicit `network`.
20
+ 3. Always add your own `LIMIT`; GraphRAG MCP does not append one.
21
+ 4. Use `graph_query_batch` for related schema, topology, and facts reads.
22
+ 5. Save material query output as workspace evidence before summarizing it.
23
+
24
+ ## Layer Choice
25
+
26
+ | Layer | Use for | Query style |
27
+ | --- | --- | --- |
28
+ | `USE live_topology` | Current or recent route discovery and fast topology reads | Memgraph-backed Cypher over topology nodes and relationships. Prefer directed `MATCH` patterns and narrow projections. |
29
+ | `USE archive_topology` | Historical money-flow and long-window topology facts | StarRocks/MemGQL GQL-Cypher subset. Keep to simple `MATCH`, `WHERE`, property projections, aggregates, `ORDER BY`, and `LIMIT`. |
30
+ | `USE facts` | Labels, address features, risk scores, assets, and enrichment | StarRocks/MemGQL facts mapping. Verify the current network schema before assuming fact labels or relationships exist. |
31
+
32
+ Treat `archive_topology` and `facts` as mapped graph views, not full Memgraph.
33
+ Avoid backend-specific functions such as `keys()`, `labels()`, `type()`,
34
+ procedures, native BFS syntax, catalog operations, and variable-length path
35
+ tricks unless the current endpoint has just accepted the exact pattern.
36
+
37
+ ## Common Schema
38
+
39
+ Topology is intentionally stable across networks:
40
+
41
+ - Node: `(:Address)` with `address`, usually sparse `labels` and `is_exchange`.
42
+ - Edge: `(:Address)-[:FLOWS_TO]->(:Address)` for money flow.
43
+ - Archive flow fields commonly include `edge_id`, `from_address`, `to_address`,
44
+ `period_granularity`, `period_start_date`, `period_end_date`,
45
+ `asset_contract`, `asset_symbol`, `tx_count`, `amount_sum`,
46
+ `amount_usd_sum`, `first_seen_timestamp`, `last_seen_timestamp`,
47
+ `first_tx_id`, and `last_tx_id`.
48
+ - Facts may expose `AddressFeature`, `AddressLabel`, `RiskScore`, `Asset`, and
49
+ network-specific fact nodes.
50
+
51
+ Different networks expose different schemas. Do not reuse a Bittensor stake
52
+ query on Base or Ethereum unless that network advertises and proves the same
53
+ labels and fields.
54
+
55
+ ## Schema Capture
56
+
57
+ Use projections instead of metadata functions so the same probe works on both
58
+ Memgraph-backed and mapped layers:
59
+
60
+ ```bash
61
+ cia mcp call graph_query_batch \
62
+ network=<network> \
63
+ per_query_timeout_seconds=5 \
64
+ 'queries=[{"id":"live_address_sample","query":"USE live_topology MATCH (n:Address) RETURN n.address AS address, n.labels AS labels, n.is_exchange AS is_exchange LIMIT 10"},{"id":"live_flow_sample","query":"USE live_topology MATCH (src:Address)-[flow:FLOWS_TO]->(dst:Address) RETURN src.address AS from_address, dst.address AS to_address, flow.amount_sum AS amount_sum, flow.amount_usd_sum AS amount_usd_sum, flow.tx_count AS tx_count, flow.first_seen_timestamp AS first_seen_timestamp, flow.last_seen_timestamp AS last_seen_timestamp LIMIT 10"},{"id":"archive_flow_sample","query":"USE archive_topology MATCH (src:Address)-[flow:FLOWS_TO]->(dst:Address) RETURN src.address AS from_address, dst.address AS to_address, flow.period_granularity AS period_granularity, flow.amount_sum AS amount_sum, flow.amount_usd_sum AS amount_usd_sum, flow.tx_count AS tx_count LIMIT 10"},{"id":"facts_address_sample","query":"USE facts MATCH (a:Address) RETURN a.address AS address, a.labels AS labels, a.is_exchange AS is_exchange LIMIT 10"}]'
65
+ ```
66
+
67
+ If a query fails with a generic backend error, narrow it before changing the
68
+ investigation claim: remove metadata functions, remove cross-graph joins, use
69
+ one relationship, project fewer fields, and lower the limit.
70
+
71
+ ## Query Examples
72
+
73
+ Live outflows from one address:
74
+
75
+ ```bash
76
+ cia mcp call graph_query \
77
+ network=<network> \
78
+ 'query=USE live_topology MATCH (src:Address {address: "FULL_ADDRESS"})-[flow:FLOWS_TO]->(dst:Address) RETURN dst.address AS to_address, flow.amount_sum AS amount_sum, flow.amount_usd_sum AS amount_usd_sum, flow.tx_count AS tx_count, flow.first_seen_timestamp AS first_seen_timestamp, flow.last_seen_timestamp AS last_seen_timestamp ORDER BY flow.amount_usd_sum DESC LIMIT 50'
79
+ ```
80
+
81
+ Archive flow history:
82
+
83
+ ```bash
84
+ cia mcp call graph_query \
85
+ network=<network> \
86
+ 'query=USE archive_topology MATCH (src:Address {address: "FULL_ADDRESS"})-[flow:FLOWS_TO]->(dst:Address) RETURN dst.address AS to_address, flow.period_granularity AS period_granularity, flow.amount_sum AS amount_sum, flow.amount_usd_sum AS amount_usd_sum, flow.tx_count AS tx_count, flow.first_seen_timestamp AS first_seen_timestamp, flow.last_seen_timestamp AS last_seen_timestamp ORDER BY flow.last_seen_timestamp DESC LIMIT 50'
87
+ ```
88
+
89
+ Facts lookup after schema proof:
90
+
91
+ ```bash
92
+ cia mcp call graph_query \
93
+ network=<network> \
94
+ 'query=USE facts MATCH (a:Address {address: "FULL_ADDRESS"})-[:HAS_LABEL]->(label:AddressLabel) RETURN label.label AS label, label.entity_type AS entity_type, label.address_type AS address_type, label.source AS source LIMIT 25'
95
+ ```
96
+
97
+ ## Hard Stops
98
+
99
+ - No writes or catalog changes: no `CREATE`, `MERGE`, `SET`, `DELETE`,
100
+ `REMOVE`, `DROP`, `ADD`, `CONNECT`, or `CALL`.
101
+ - No raw StarRocks table names through GraphRAG MCP.
102
+ - Do not rely on dynamic labels such as `:Exchange`; use `is_exchange` or
103
+ label facts when the schema proves they exist.
104
+ - Empty results mean no indexed match in the selected layer, not proof of
105
+ safety or non-existence.
@@ -0,0 +1,4 @@
1
+ interface:
2
+ display_name: "Chain Insights Cypher"
3
+ short_description: "Write schema-aware GraphRAG MCP GQL/Cypher"
4
+ default_prompt: "Use Chain Insights graph_query or graph_query_batch with explicit network, layer selection, bounded read-only Cypher, schema capture, and evidence-safe output handling."
@@ -40,6 +40,10 @@ Chain Insights tools should be implemented as local AML workflows over these
40
40
  generic graph primitives unless there is a product reason to add a new
41
41
  primitive.
42
42
 
43
+ For manual graph-language guidance, use the shipped `chain-insights-cypher`
44
+ skill. For Bittensor schema-specific queries, load
45
+ `chain-insights-bittensor-cypher` after the generic skill.
46
+
43
47
  ## Topology Language
44
48
 
45
49
  Use these names consistently:
@@ -188,6 +188,8 @@ Use manual `graph_query_batch` for custom topology or fact questions. Use
188
188
  `USE live_topology` for recent topology, `USE archive_topology` for historical
189
189
  topology, and `USE facts` for facts and enrichment.
190
190
  Use `graph_query` or `graph_query_batch` for all graph-language reads.
191
+ When writing custom Cypher, use the shipped `chain-insights-cypher` skill; for
192
+ Bittensor, also use `chain-insights-bittensor-cypher`.
191
193
 
192
194
  ## Query And Evidence Loop
193
195