chain-insights 0.2.30 → 0.2.32
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 +4 -0
- package/docs/graph-tools.md +19 -2
- package/docs/mcp-proxy.md +10 -0
- package/package.json +1 -1
- package/skills/chain-insights-bittensor-cypher/SKILL.md +160 -0
- package/skills/chain-insights-bittensor-cypher/agents/openai.yaml +4 -0
- package/skills/chain-insights-cypher/SKILL.md +114 -0
- package/skills/chain-insights-cypher/agents/openai.yaml +4 -0
- package/skills/chain-insights-cypher/references/memgraph-examples.md +193 -0
- package/skills/chain-insights-developer-experience/SKILL.md +4 -0
- package/skills/chain-insights-investigation/SKILL.md +2 -0
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
|
package/docs/graph-tools.md
CHANGED
|
@@ -37,6 +37,16 @@ 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. Its
|
|
44
|
+
`references/memgraph-examples.md` file includes staging-tested Memgraph-style
|
|
45
|
+
recipes, archive/facts reads, and fixed-hop traversal fallbacks for native
|
|
46
|
+
Memgraph deep traversal syntax that the hosted GraphRAG MCP path may reject.
|
|
47
|
+
- `chain-insights-bittensor-cypher`: Bittensor-specific schema notes for SS58
|
|
48
|
+
and EVM-pallet addresses under `network=bittensor`.
|
|
49
|
+
|
|
40
50
|
Check public-free usage:
|
|
41
51
|
|
|
42
52
|
```bash
|
|
@@ -313,12 +323,19 @@ Large JSON belongs under workspace report directories, not inline in evidence.
|
|
|
313
323
|
Fresh workspaces include a runtime schema skill and schema capture directory.
|
|
314
324
|
Before the first case query against a network, capture the live graph schema and
|
|
315
325
|
use the observed labels, relationship types, and property names in subsequent
|
|
316
|
-
queries.
|
|
326
|
+
queries. Different networks can expose different fact nodes and relationship
|
|
327
|
+
properties, so do not assume a query that works on Bittensor will work on Base,
|
|
328
|
+
Ethereum, or TRON without a fresh schema probe.
|
|
317
329
|
|
|
318
330
|
Useful schema probes:
|
|
319
331
|
|
|
320
332
|
```bash
|
|
321
333
|
cia mcp call graph_query_batch \
|
|
322
334
|
network=bittensor \
|
|
323
|
-
|
|
335
|
+
per_query_timeout_seconds=5 \
|
|
336
|
+
'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
337
|
```
|
|
338
|
+
|
|
339
|
+
Use projections like `n.address` and `flow.tx_count` in probes. Metadata
|
|
340
|
+
functions such as `keys()`, `labels()`, and `type()` are not portable across
|
|
341
|
+
every GraphRAG MCP layer.
|
package/docs/mcp-proxy.md
CHANGED
|
@@ -132,6 +132,11 @@ current caller's quota status. Public free access does not include
|
|
|
132
132
|
usage and batches. Use explicit LIMIT and pagination in your query when you
|
|
133
133
|
want bounded result sets.
|
|
134
134
|
|
|
135
|
+
For custom graph reads, install the shipped `chain-insights-cypher` skill. Its
|
|
136
|
+
Memgraph examples reference distinguishes staging-tested GraphRAG MCP query
|
|
137
|
+
patterns from direct Memgraph deep traversal syntax that needs a fixed-hop
|
|
138
|
+
`graph_query_batch` fallback through the hosted endpoint.
|
|
139
|
+
|
|
135
140
|
Paid x402 mode:
|
|
136
141
|
|
|
137
142
|
```bash
|
|
@@ -165,6 +170,11 @@ directory and registers the stdio MCP proxy in the Hermes config.
|
|
|
165
170
|
After installing, open an initialized investigation workspace in the agent and
|
|
166
171
|
operate over the workspace files.
|
|
167
172
|
|
|
173
|
+
For manual graph-language work, agents should use the shipped
|
|
174
|
+
`chain-insights-cypher` skill. For Bittensor queries, load
|
|
175
|
+
`chain-insights-bittensor-cypher` after the generic skill so SS58 and
|
|
176
|
+
EVM-pallet addresses stay under `network=bittensor`.
|
|
177
|
+
|
|
168
178
|
## Claude Desktop
|
|
169
179
|
|
|
170
180
|
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.
|
|
3
|
+
"version": "0.2.32",
|
|
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,160 @@
|
|
|
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
|
+
- On 2026-05-29, staging accepted practical Memgraph-style reads such as
|
|
42
|
+
`WHERE STARTS WITH`, `WITH` aggregations, `CASE`, address-family counts, and
|
|
43
|
+
fixed-hop `FLOWS_TO` patterns. It rejected native Memgraph deep traversal
|
|
44
|
+
operators through the hosted GraphRAG MCP path, including `*BFS`,
|
|
45
|
+
`*WSHORTEST`, `*ALLSHORTEST`, `*KSHORTEST`, and variable-length relationship
|
|
46
|
+
syntax. Use the generic skill reference
|
|
47
|
+
`references/memgraph-examples.md` for tested examples and fixed-hop
|
|
48
|
+
fallbacks.
|
|
49
|
+
|
|
50
|
+
## Bittensor Shapes
|
|
51
|
+
|
|
52
|
+
Live topology:
|
|
53
|
+
|
|
54
|
+
```cypher
|
|
55
|
+
USE live_topology
|
|
56
|
+
MATCH (src:Address)-[flow:FLOWS_TO]->(dst:Address)
|
|
57
|
+
RETURN src.address AS from_address,
|
|
58
|
+
dst.address AS to_address,
|
|
59
|
+
flow.amount_sum AS amount_sum,
|
|
60
|
+
flow.amount_usd_sum AS amount_usd_sum,
|
|
61
|
+
flow.tx_count AS tx_count,
|
|
62
|
+
flow.first_seen_timestamp AS first_seen_timestamp,
|
|
63
|
+
flow.last_seen_timestamp AS last_seen_timestamp
|
|
64
|
+
LIMIT 25
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Archive topology:
|
|
68
|
+
|
|
69
|
+
```cypher
|
|
70
|
+
USE archive_topology
|
|
71
|
+
MATCH (src:Address)-[flow:FLOWS_TO]->(dst:Address)
|
|
72
|
+
RETURN src.address AS from_address,
|
|
73
|
+
dst.address AS to_address,
|
|
74
|
+
flow.edge_id AS edge_id,
|
|
75
|
+
flow.period_granularity AS period_granularity,
|
|
76
|
+
flow.amount_sum AS amount_sum,
|
|
77
|
+
flow.amount_usd_sum AS amount_usd_sum,
|
|
78
|
+
flow.tx_count AS tx_count,
|
|
79
|
+
flow.first_seen_timestamp AS first_seen_timestamp,
|
|
80
|
+
flow.last_seen_timestamp AS last_seen_timestamp
|
|
81
|
+
LIMIT 25
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Stake topology, when the endpoint proves it:
|
|
85
|
+
|
|
86
|
+
```cypher
|
|
87
|
+
USE live_topology
|
|
88
|
+
MATCH (coldkey:Address)-[stake:STAKES_IN]->(hotkey:Address)
|
|
89
|
+
RETURN coldkey.address AS coldkey,
|
|
90
|
+
hotkey.address AS hotkey,
|
|
91
|
+
stake.netuid AS netuid,
|
|
92
|
+
stake.amount AS amount,
|
|
93
|
+
stake.source_role AS source_role,
|
|
94
|
+
stake.destination_role AS destination_role,
|
|
95
|
+
stake.source_backend AS source_backend
|
|
96
|
+
LIMIT 25
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Facts, when the endpoint proves the mapping:
|
|
100
|
+
|
|
101
|
+
```cypher
|
|
102
|
+
USE facts
|
|
103
|
+
MATCH (coldkey:Address)-[:REGISTERED_NEURON]->(hotkey:Hotkey)-[:SERVED_FROM]->(ip:IPAddress)
|
|
104
|
+
RETURN coldkey.address AS coldkey,
|
|
105
|
+
hotkey.address AS hotkey,
|
|
106
|
+
ip.ip_address AS ip_address
|
|
107
|
+
LIMIT 25
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## Schema Probe
|
|
111
|
+
|
|
112
|
+
Use this before a custom Bittensor query session:
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
cia mcp call graph_query_batch \
|
|
116
|
+
network=bittensor \
|
|
117
|
+
per_query_timeout_seconds=5 \
|
|
118
|
+
'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"}]'
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Avoid `keys()`, `labels()`, `type()`, native BFS syntax, and variable-length
|
|
122
|
+
paths in schema probes. They may be valid in a direct Memgraph console but are
|
|
123
|
+
not portable across the GraphRAG MCP federation path.
|
|
124
|
+
|
|
125
|
+
## Investigation Patterns
|
|
126
|
+
|
|
127
|
+
Outflows from a SS58 or `0x...` Bittensor address:
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
cia mcp call graph_query \
|
|
131
|
+
network=bittensor \
|
|
132
|
+
'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'
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Find likely address completions from a prefix:
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
cia mcp call graph_query \
|
|
139
|
+
network=bittensor \
|
|
140
|
+
'query=USE live_topology MATCH (a:Address) WHERE a.address STARTS WITH "5Ggf" RETURN a.address AS address, a.address_type AS address_type, a.network AS network LIMIT 10'
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Show how the combined Bittensor network currently splits address families:
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
cia mcp call graph_query \
|
|
147
|
+
network=bittensor \
|
|
148
|
+
'query=USE live_topology MATCH (a:Address) RETURN a.address_type AS address_type, a.network AS source_network, count(a) AS addresses ORDER BY addresses DESC LIMIT 10'
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Historical archive read for the same address:
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
cia mcp call graph_query \
|
|
155
|
+
network=bittensor \
|
|
156
|
+
'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'
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
When comparing amounts, remember that archive StarRocks-backed numeric fields
|
|
160
|
+
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,114 @@
|
|
|
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
|
+
For practical query recipes and Memgraph deep traversal fallbacks, read
|
|
25
|
+
`references/memgraph-examples.md`. It contains staging-tested examples for
|
|
26
|
+
`MATCH`, `WHERE`, `WITH`, aggregates, `CASE`, archive/facts projections, and
|
|
27
|
+
fixed-hop traversal batches.
|
|
28
|
+
|
|
29
|
+
## Layer Choice
|
|
30
|
+
|
|
31
|
+
| Layer | Use for | Query style |
|
|
32
|
+
| --- | --- | --- |
|
|
33
|
+
| `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. |
|
|
34
|
+
| `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`. |
|
|
35
|
+
| `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. |
|
|
36
|
+
|
|
37
|
+
Treat `archive_topology` and `facts` as mapped graph views, not full Memgraph.
|
|
38
|
+
Avoid backend-specific functions such as `keys()`, `labels()`, `type()`,
|
|
39
|
+
procedures, native BFS syntax, catalog operations, and variable-length path
|
|
40
|
+
tricks unless the current endpoint has just accepted the exact pattern. When a
|
|
41
|
+
Memgraph deep traversal pattern fails, rewrite it as a bounded
|
|
42
|
+
`graph_query_batch` of explicit fixed-hop `FLOWS_TO` patterns.
|
|
43
|
+
|
|
44
|
+
## Common Schema
|
|
45
|
+
|
|
46
|
+
Topology is intentionally stable across networks:
|
|
47
|
+
|
|
48
|
+
- Node: `(:Address)` with `address`, usually sparse `labels` and `is_exchange`.
|
|
49
|
+
- Edge: `(:Address)-[:FLOWS_TO]->(:Address)` for money flow.
|
|
50
|
+
- Archive flow fields commonly include `edge_id`, `from_address`, `to_address`,
|
|
51
|
+
`period_granularity`, `period_start_date`, `period_end_date`,
|
|
52
|
+
`asset_contract`, `asset_symbol`, `tx_count`, `amount_sum`,
|
|
53
|
+
`amount_usd_sum`, `first_seen_timestamp`, `last_seen_timestamp`,
|
|
54
|
+
`first_tx_id`, and `last_tx_id`.
|
|
55
|
+
- Facts may expose `AddressFeature`, `AddressLabel`, `RiskScore`, `Asset`, and
|
|
56
|
+
network-specific fact nodes.
|
|
57
|
+
|
|
58
|
+
Different networks expose different schemas. Do not reuse a Bittensor stake
|
|
59
|
+
query on Base or Ethereum unless that network advertises and proves the same
|
|
60
|
+
labels and fields.
|
|
61
|
+
|
|
62
|
+
## Schema Capture
|
|
63
|
+
|
|
64
|
+
Use projections instead of metadata functions so the same probe works on both
|
|
65
|
+
Memgraph-backed and mapped layers:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
cia mcp call graph_query_batch \
|
|
69
|
+
network=<network> \
|
|
70
|
+
per_query_timeout_seconds=5 \
|
|
71
|
+
'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"}]'
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
If a query fails with a generic backend error, narrow it before changing the
|
|
75
|
+
investigation claim: remove metadata functions, remove cross-graph joins, use
|
|
76
|
+
one relationship, project fewer fields, and lower the limit.
|
|
77
|
+
|
|
78
|
+
## Query Examples
|
|
79
|
+
|
|
80
|
+
Live outflows from one address:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
cia mcp call graph_query \
|
|
84
|
+
network=<network> \
|
|
85
|
+
'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'
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Archive flow history:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
cia mcp call graph_query \
|
|
92
|
+
network=<network> \
|
|
93
|
+
'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'
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Facts lookup after schema proof:
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
cia mcp call graph_query \
|
|
100
|
+
network=<network> \
|
|
101
|
+
'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'
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
More examples: `references/memgraph-examples.md`.
|
|
105
|
+
|
|
106
|
+
## Hard Stops
|
|
107
|
+
|
|
108
|
+
- No writes or catalog changes: no `CREATE`, `MERGE`, `SET`, `DELETE`,
|
|
109
|
+
`REMOVE`, `DROP`, `ADD`, `CONNECT`, or `CALL`.
|
|
110
|
+
- No raw StarRocks table names through GraphRAG MCP.
|
|
111
|
+
- Do not rely on dynamic labels such as `:Exchange`; use `is_exchange` or
|
|
112
|
+
label facts when the schema proves they exist.
|
|
113
|
+
- Empty results mean no indexed match in the selected layer, not proof of
|
|
114
|
+
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."
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
# GraphRAG MCP Cypher Examples
|
|
2
|
+
|
|
3
|
+
Use these examples when an investigation needs practical graph-language reads
|
|
4
|
+
instead of only schema probes. They are adapted from Memgraph query and deep
|
|
5
|
+
path traversal features, then bounded to the Chain Insights GraphRAG MCP
|
|
6
|
+
surface.
|
|
7
|
+
|
|
8
|
+
Official Memgraph references:
|
|
9
|
+
|
|
10
|
+
- Querying: https://memgraph.com/docs/querying
|
|
11
|
+
- Deep path traversal: https://memgraph.com/docs/advanced-algorithms/deep-path-traversal
|
|
12
|
+
|
|
13
|
+
## Staging Validation
|
|
14
|
+
|
|
15
|
+
Validated against hosted staging on 2026-05-29 with `network=bittensor` and
|
|
16
|
+
`per_query_timeout_seconds=5`.
|
|
17
|
+
|
|
18
|
+
Accepted through GraphRAG MCP:
|
|
19
|
+
|
|
20
|
+
- `MATCH`, directed relationship patterns, property equality, `WHERE`
|
|
21
|
+
- `STARTS WITH`
|
|
22
|
+
- `WITH`, `count`, `sum`
|
|
23
|
+
- `CASE`
|
|
24
|
+
- `ORDER BY`, explicit `LIMIT`
|
|
25
|
+
- fixed-hop patterns written as explicit relationships
|
|
26
|
+
- simple `archive_topology` counts and filtered projections
|
|
27
|
+
- `facts` `Address` projection
|
|
28
|
+
|
|
29
|
+
Rejected through the current hosted path with a generic backend error:
|
|
30
|
+
|
|
31
|
+
- variable-length relationship syntax such as `[:FLOWS_TO*1..2]`
|
|
32
|
+
- Memgraph native BFS syntax such as `*BFS` and `USING HOPS LIMIT`
|
|
33
|
+
- weighted/all/K shortest path operators: `*WSHORTEST`, `*ALLSHORTEST`,
|
|
34
|
+
`*KSHORTEST`
|
|
35
|
+
- `OPTIONAL MATCH`
|
|
36
|
+
- `UNION ALL`
|
|
37
|
+
|
|
38
|
+
Treat rejected syntax as direct-Memgraph reference material only unless the
|
|
39
|
+
current endpoint accepts the exact query. For Chain Insights agents, use the
|
|
40
|
+
fixed-hop `graph_query_batch` fallback below for traversal.
|
|
41
|
+
|
|
42
|
+
## Live Topology Examples
|
|
43
|
+
|
|
44
|
+
Top outflows by amount:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
cia mcp call graph_query \
|
|
48
|
+
network=bittensor \
|
|
49
|
+
'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.last_seen_timestamp AS last_seen_timestamp ORDER BY flow.amount_sum DESC LIMIT 25'
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Rank addresses by live out-degree and transferred amount:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
cia mcp call graph_query \
|
|
56
|
+
network=bittensor \
|
|
57
|
+
'query=USE live_topology MATCH (src:Address)-[flow:FLOWS_TO]->(dst:Address) WITH src, count(dst) AS out_degree, sum(flow.amount_sum) AS total_amount RETURN src.address AS address, out_degree, total_amount ORDER BY out_degree DESC LIMIT 25'
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Bucket flows for quick triage:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
cia mcp call graph_query \
|
|
64
|
+
network=bittensor \
|
|
65
|
+
'query=USE live_topology MATCH (src:Address)-[flow:FLOWS_TO]->(dst:Address) RETURN src.address AS from_address, dst.address AS to_address, CASE WHEN flow.amount_sum IS NULL THEN "unknown" WHEN flow.amount_sum >= 100 THEN "large" WHEN flow.amount_sum >= 10 THEN "medium" ELSE "small" END AS amount_bucket, flow.amount_sum AS amount_sum LIMIT 25'
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Prefix search for address completion:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
cia mcp call graph_query \
|
|
72
|
+
network=bittensor \
|
|
73
|
+
'query=USE live_topology MATCH (a:Address) WHERE a.address STARTS WITH "5Ggf" RETURN a.address AS address, a.address_type AS address_type, a.network AS network LIMIT 10'
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Address-family census for a combined network:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
cia mcp call graph_query \
|
|
80
|
+
network=bittensor \
|
|
81
|
+
'query=USE live_topology MATCH (a:Address) RETURN a.address_type AS address_type, a.network AS source_network, count(a) AS addresses ORDER BY addresses DESC LIMIT 10'
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Bittensor EVM-pallet flow under the same investigation network:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
cia mcp call graph_query \
|
|
88
|
+
network=bittensor \
|
|
89
|
+
'query=USE live_topology MATCH (src:Address {address: "0x20d09f2881602eee806147ceee9275d33ff31df8"})-[flow:FLOWS_TO]->(dst:Address) RETURN src.address AS from_address, src.address_type AS from_type, src.network AS from_network, dst.address AS to_address, dst.address_type AS to_type, dst.network AS to_network, flow.amount_sum AS amount_sum LIMIT 10'
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Archive Topology Examples
|
|
93
|
+
|
|
94
|
+
Recent historical flows:
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
cia mcp call graph_query \
|
|
98
|
+
network=bittensor \
|
|
99
|
+
'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.tx_count AS tx_count, flow.last_seen_timestamp AS last_seen_timestamp ORDER BY flow.last_seen_timestamp DESC LIMIT 25'
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Count archive flow edges by granularity:
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
cia mcp call graph_query \
|
|
106
|
+
network=bittensor \
|
|
107
|
+
'query=USE archive_topology MATCH (:Address)-[flow:FLOWS_TO]->(:Address) RETURN flow.period_granularity AS period_granularity, count(flow) AS flow_edges LIMIT 10'
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Filter daily archive flows:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
cia mcp call graph_query \
|
|
114
|
+
network=bittensor \
|
|
115
|
+
'query=USE archive_topology MATCH (src:Address)-[flow:FLOWS_TO]->(dst:Address) WHERE flow.period_granularity = "daily" RETURN src.address AS from_address, dst.address AS to_address, flow.amount_sum AS amount_sum, flow.tx_count AS tx_count ORDER BY flow.amount_sum DESC LIMIT 25'
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Remember that archive numeric fields may arrive as strings.
|
|
119
|
+
|
|
120
|
+
## Facts Examples
|
|
121
|
+
|
|
122
|
+
Facts `Address` projection:
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
cia mcp call graph_query \
|
|
126
|
+
network=bittensor \
|
|
127
|
+
'query=USE facts MATCH (a:Address) RETURN a.address AS address, a.labels AS labels, a.is_exchange AS is_exchange LIMIT 25'
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Only use richer fact labels or relationships after a fresh schema probe proves
|
|
131
|
+
the current network exposes them. On 2026-05-29, staging accepted facts
|
|
132
|
+
`Address` projection but rejected `Address` to `AddressLabel` relationship
|
|
133
|
+
samples.
|
|
134
|
+
|
|
135
|
+
## Fixed-Hop Traversal Fallback
|
|
136
|
+
|
|
137
|
+
Memgraph deep traversal docs cover BFS, weighted shortest path, all shortest
|
|
138
|
+
paths, and K shortest paths. Through the current GraphRAG MCP path, those
|
|
139
|
+
native operators were rejected on staging. Use explicit fixed-hop batches for
|
|
140
|
+
Chain Insights traversal instead.
|
|
141
|
+
|
|
142
|
+
One-hop path:
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
cia mcp call graph_query_batch \
|
|
146
|
+
network=bittensor \
|
|
147
|
+
per_query_timeout_seconds=5 \
|
|
148
|
+
'queries=[{"id":"hop_1","query":"USE live_topology MATCH (src:Address {address: \"FULL_SOURCE_ADDRESS\"})-[r1:FLOWS_TO]->(dst:Address {address: \"FULL_TARGET_ADDRESS\"}) RETURN src.address AS from_address, dst.address AS to_address, 1 AS hops, r1.amount_sum AS amount_sum, r1.tx_count AS tx_count LIMIT 25"}]'
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Two-hop expansion with exchange-stopped intermediate nodes:
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
cia mcp call graph_query_batch \
|
|
155
|
+
network=bittensor \
|
|
156
|
+
per_query_timeout_seconds=5 \
|
|
157
|
+
'queries=[{"id":"hop_2","query":"USE live_topology MATCH (src:Address {address: \"FULL_SOURCE_ADDRESS\"})-[r1:FLOWS_TO]->(mid:Address)-[r2:FLOWS_TO]->(dst:Address) WHERE mid.is_exchange IS NULL RETURN src.address AS from_address, mid.address AS mid_address, dst.address AS to_address, 2 AS hops, r1.amount_sum AS first_amount, r2.amount_sum AS second_amount LIMIT 25"}]'
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
Generate one query per depth when investigating a path. Keep each query
|
|
161
|
+
directed, stop expansion at exchange nodes, preserve full addresses, and use a
|
|
162
|
+
small `LIMIT` while exploring.
|
|
163
|
+
|
|
164
|
+
## Direct Memgraph Reference Syntax
|
|
165
|
+
|
|
166
|
+
Use this syntax only in a direct Memgraph console or after the GraphRAG MCP
|
|
167
|
+
endpoint accepts the same pattern.
|
|
168
|
+
|
|
169
|
+
Native BFS:
|
|
170
|
+
|
|
171
|
+
```cypher
|
|
172
|
+
MATCH path=(src:Address {address: "FULL_SOURCE_ADDRESS"})-[:FLOWS_TO *BFS]->(dst:Address {address: "FULL_TARGET_ADDRESS"})
|
|
173
|
+
RETURN path
|
|
174
|
+
LIMIT 5;
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
Weighted shortest path:
|
|
178
|
+
|
|
179
|
+
```cypher
|
|
180
|
+
MATCH path=(src:Address {address: "FULL_SOURCE_ADDRESS"})-[:FLOWS_TO *WSHORTEST (r, n | coalesce(r.amount_sum, 1)) total_weight]->(dst:Address {address: "FULL_TARGET_ADDRESS"})
|
|
181
|
+
RETURN path, total_weight
|
|
182
|
+
LIMIT 5;
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
K shortest alternatives:
|
|
186
|
+
|
|
187
|
+
```cypher
|
|
188
|
+
MATCH (src:Address {address: "FULL_SOURCE_ADDRESS"}), (dst:Address {address: "FULL_TARGET_ADDRESS"})
|
|
189
|
+
WITH src, dst
|
|
190
|
+
MATCH path=(src)-[:FLOWS_TO *KSHORTEST|3]->(dst)
|
|
191
|
+
RETURN path
|
|
192
|
+
LIMIT 3;
|
|
193
|
+
```
|
|
@@ -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
|
|