@animalabs/connectome-host 0.3.1
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/.env.example +20 -0
- package/.github/workflows/publish.yml +65 -0
- package/ARCHITECTURE.md +355 -0
- package/CHANGELOG.md +30 -0
- package/HEADLESS-FLEET-PLAN.md +330 -0
- package/README.md +189 -0
- package/UNIFIED-TREE-PLAN.md +242 -0
- package/bun.lock +288 -0
- package/docs/AGENT-MEMORY-GUIDE.md +214 -0
- package/docs/AGENT-ONBOARDING.md +541 -0
- package/docs/ATTENTION-AND-GATING.md +120 -0
- package/docs/DEPLOYMENTS.md +130 -0
- package/docs/DEV-ENVIRONMENT.md +215 -0
- package/docs/LIBRARY-PIPELINE.md +286 -0
- package/docs/LOCUS-ROUTING-DESIGN.md +115 -0
- package/docs/claudeai-evacuation.md +228 -0
- package/docs/debug-context-api.md +208 -0
- package/docs/webui-deployment.md +219 -0
- package/package.json +33 -0
- package/recipes/SETUP.md +308 -0
- package/recipes/TRIUMVIRATE-SETUP.md +467 -0
- package/recipes/claude-export-revive.json +19 -0
- package/recipes/clerk.json +157 -0
- package/recipes/knowledge-miner.json +174 -0
- package/recipes/knowledge-reviewer.json +76 -0
- package/recipes/mcpl-editor-test.json +38 -0
- package/recipes/prompts/transplant-addendum.md +17 -0
- package/recipes/triumvirate.json +63 -0
- package/recipes/webui-fleet-test.json +27 -0
- package/recipes/webui-test.json +16 -0
- package/recipes/zulip-miner.json +87 -0
- package/scripts/connectome-doctor +373 -0
- package/scripts/evacuator.ts +956 -0
- package/scripts/import-claudeai-export.ts +747 -0
- package/scripts/lib/line-reader.ts +53 -0
- package/scripts/test-historical-thinking.ts +148 -0
- package/scripts/warmup-session.ts +336 -0
- package/src/agent-name.ts +58 -0
- package/src/commands.ts +1074 -0
- package/src/headless.ts +528 -0
- package/src/index.ts +867 -0
- package/src/logging-adapter.ts +208 -0
- package/src/mcpl-config.ts +199 -0
- package/src/modules/activity-module.ts +270 -0
- package/src/modules/channel-mode-module.ts +260 -0
- package/src/modules/fleet-module.ts +1705 -0
- package/src/modules/fleet-types.ts +225 -0
- package/src/modules/lessons-module.ts +465 -0
- package/src/modules/mcpl-admin-module.ts +345 -0
- package/src/modules/retrieval-module.ts +327 -0
- package/src/modules/settings-module.ts +143 -0
- package/src/modules/subagent-module.ts +2074 -0
- package/src/modules/subscription-gc-module.ts +322 -0
- package/src/modules/time-module.ts +85 -0
- package/src/modules/tui-module.ts +76 -0
- package/src/modules/web-ui-curve-page.ts +249 -0
- package/src/modules/web-ui-module.ts +2595 -0
- package/src/recipe.ts +1003 -0
- package/src/session-manager.ts +278 -0
- package/src/state/agent-tree-reducer.ts +431 -0
- package/src/state/fleet-tree-aggregator.ts +195 -0
- package/src/strategies/frontdesk-strategy.ts +364 -0
- package/src/synesthete.ts +68 -0
- package/src/tui.ts +2200 -0
- package/src/types/bun-ffi.d.ts +6 -0
- package/src/web/protocol.ts +648 -0
- package/test/agent-name.test.ts +62 -0
- package/test/agent-tree-fleet-launch.test.ts +64 -0
- package/test/agent-tree-reducer-parity.test.ts +194 -0
- package/test/agent-tree-reducer.test.ts +443 -0
- package/test/agent-tree-rollup.test.ts +109 -0
- package/test/autobio-progress-snapshot.test.ts +40 -0
- package/test/claudeai-export-importer.test.ts +386 -0
- package/test/evacuator.test.ts +332 -0
- package/test/fleet-commands.test.ts +244 -0
- package/test/fleet-no-subfleets.test.ts +147 -0
- package/test/fleet-orchestration.test.ts +353 -0
- package/test/fleet-recipe.test.ts +124 -0
- package/test/fleet-route.test.ts +44 -0
- package/test/fleet-smoke.test.ts +479 -0
- package/test/fleet-subscribe-union-e2e.test.ts +123 -0
- package/test/fleet-subscribe-union.test.ts +85 -0
- package/test/fleet-tree-aggregator-e2e.test.ts +110 -0
- package/test/fleet-tree-aggregator.test.ts +215 -0
- package/test/frontdesk-strategy.test.ts +326 -0
- package/test/headless-describe.test.ts +182 -0
- package/test/headless-smoke.test.ts +190 -0
- package/test/logging-adapter.test.ts +87 -0
- package/test/mcpl-admin-module.test.ts +213 -0
- package/test/mcpl-agent-overlay.test.ts +126 -0
- package/test/mock-headless-child.ts +133 -0
- package/test/recipe-cache-ttl.test.ts +37 -0
- package/test/recipe-env.test.ts +157 -0
- package/test/recipe-path-resolution.test.ts +170 -0
- package/test/subagent-async-timeout.test.ts +381 -0
- package/test/subagent-fork-materialise.test.ts +241 -0
- package/test/subagent-peek-scoping.test.ts +180 -0
- package/test/subagent-peek-zombie.test.ts +148 -0
- package/test/subagent-reaper-in-flight.test.ts +229 -0
- package/test/subscription-gc-module.test.ts +136 -0
- package/test/warmup-handoff.test.ts +150 -0
- package/test/web-ui-bind.test.ts +51 -0
- package/test/web-ui-module.test.ts +246 -0
- package/test/web-ui-protocol.test.ts +0 -0
- package/tsconfig.json +14 -0
- package/web/bun.lock +357 -0
- package/web/index.html +12 -0
- package/web/package.json +24 -0
- package/web/src/App.tsx +1931 -0
- package/web/src/Context.tsx +158 -0
- package/web/src/ContextDocument.tsx +150 -0
- package/web/src/Files.tsx +271 -0
- package/web/src/Lessons.tsx +164 -0
- package/web/src/Mcpl.tsx +310 -0
- package/web/src/Stream.tsx +119 -0
- package/web/src/TreeSidebar.tsx +283 -0
- package/web/src/Usage.tsx +182 -0
- package/web/src/main.tsx +7 -0
- package/web/src/styles.css +26 -0
- package/web/src/tree.ts +268 -0
- package/web/src/wire.ts +120 -0
- package/web/tsconfig.json +21 -0
- package/web/vite.config.ts +32 -0
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
# WebUI Deployment
|
|
2
|
+
|
|
3
|
+
The `webui` module is a plain HTTP + WebSocket server. It owns no
|
|
4
|
+
TLS, no outer authentication, no certificate management. Those are the
|
|
5
|
+
reverse proxy's job. This is intentional — it keeps the host code small
|
|
6
|
+
and lets the deployer pick whatever auth and cert mechanism the org
|
|
7
|
+
already uses.
|
|
8
|
+
|
|
9
|
+
This guide covers the typical deployment shape: a remote VM accessed
|
|
10
|
+
over a VPN, with Caddy fronting the host process.
|
|
11
|
+
|
|
12
|
+
## Module config
|
|
13
|
+
|
|
14
|
+
In your recipe:
|
|
15
|
+
|
|
16
|
+
```json
|
|
17
|
+
{
|
|
18
|
+
"modules": {
|
|
19
|
+
"webui": {
|
|
20
|
+
"port": 7340,
|
|
21
|
+
"host": "127.0.0.1"
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
The defaults are `0.0.0.0:7340` — connectome deployments are remote, not
|
|
28
|
+
local, so the module binds all interfaces by default. Because that is a
|
|
29
|
+
non-loopback bind, the module **refuses to start unless `basicAuth` is
|
|
30
|
+
configured**: any recipe that enables webui must supply credentials. There
|
|
31
|
+
is no unauthenticated escape hatch — even behind a reverse proxy, app-level
|
|
32
|
+
Basic-Auth is required. Set `host: "127.0.0.1"` to bind loopback-only for
|
|
33
|
+
local development, which skips the auth requirement.
|
|
34
|
+
|
|
35
|
+
Front the module with a reverse proxy (Caddy/nginx) to terminate TLS; the
|
|
36
|
+
proxy handles transport security while Basic-Auth gates the app layer.
|
|
37
|
+
|
|
38
|
+
Add Basic-Auth credentials sourced from `.env` (never literal in the recipe):
|
|
39
|
+
|
|
40
|
+
```json
|
|
41
|
+
{
|
|
42
|
+
"modules": {
|
|
43
|
+
"webui": {
|
|
44
|
+
"host": "0.0.0.0",
|
|
45
|
+
"basicAuth": {
|
|
46
|
+
"username": "${WEBUI_USER}",
|
|
47
|
+
"password": "${WEBUI_PASS}"
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
`${VAR}` substitution happens at recipe-load time, so credentials live in
|
|
55
|
+
your gitignored `.env` rather than committed to the recipe.
|
|
56
|
+
|
|
57
|
+
## Caddy
|
|
58
|
+
|
|
59
|
+
Front Caddy as a system service. The `Caddyfile` for a single recipe:
|
|
60
|
+
|
|
61
|
+
```caddy
|
|
62
|
+
admin.example.internal {
|
|
63
|
+
encode gzip
|
|
64
|
+
|
|
65
|
+
# Basic authentication, swap for forward_auth/oauth/etc as needed.
|
|
66
|
+
basic_auth {
|
|
67
|
+
admin $2a$14$...your-bcrypted-password...
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
# The WebUI ships static assets and a /ws upgrade. Caddy's reverse_proxy
|
|
71
|
+
# handles WebSocket upgrades transparently — no extra config needed.
|
|
72
|
+
reverse_proxy 127.0.0.1:7340
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
If multiple recipes run on one VM, give each a distinct port and a
|
|
77
|
+
distinct Caddy block (subdomain or path-based routing both work).
|
|
78
|
+
|
|
79
|
+
Caddy auto-issues TLS certificates for any public hostname. For
|
|
80
|
+
**VPN-only DNS** (where Let's Encrypt can't reach the host), use a
|
|
81
|
+
private CA — Caddy supports ACME with internal issuers via the
|
|
82
|
+
`tls internal` directive:
|
|
83
|
+
|
|
84
|
+
```caddy
|
|
85
|
+
admin.vpn.internal {
|
|
86
|
+
tls internal
|
|
87
|
+
reverse_proxy 127.0.0.1:7340
|
|
88
|
+
# ...
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## systemd unit
|
|
93
|
+
|
|
94
|
+
`/etc/systemd/system/connectome-host.service`:
|
|
95
|
+
|
|
96
|
+
```ini
|
|
97
|
+
[Unit]
|
|
98
|
+
Description=connectome-host (admin recipe)
|
|
99
|
+
After=network.target
|
|
100
|
+
|
|
101
|
+
[Service]
|
|
102
|
+
Type=simple
|
|
103
|
+
User=connectome
|
|
104
|
+
WorkingDirectory=/opt/connectome-host
|
|
105
|
+
Environment=ANTHROPIC_API_KEY=...
|
|
106
|
+
EnvironmentFile=/etc/connectome-host/env
|
|
107
|
+
ExecStart=/home/connectome/.bun/bin/bun src/index.ts recipes/admin.json --headless
|
|
108
|
+
Restart=on-failure
|
|
109
|
+
RestartSec=5
|
|
110
|
+
StandardOutput=journal
|
|
111
|
+
StandardError=journal
|
|
112
|
+
|
|
113
|
+
[Install]
|
|
114
|
+
WantedBy=multi-user.target
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
`--headless` keeps the daemon alive without a TTY. The webui module
|
|
118
|
+
serves the admin UI; the headless IPC socket is a separate channel
|
|
119
|
+
(intended for parent-process supervision; not used by the WebUI).
|
|
120
|
+
|
|
121
|
+
## Tailscale-style hostnames
|
|
122
|
+
|
|
123
|
+
If the VM is on Tailscale, MagicDNS gives you a stable name like
|
|
124
|
+
`admin.tailnet-name.ts.net`. Caddy with `tls internal` works there
|
|
125
|
+
directly. No DNS or firewall holes needed beyond the existing tailnet.
|
|
126
|
+
|
|
127
|
+
## Verifying the deployment
|
|
128
|
+
|
|
129
|
+
After bringing the host up:
|
|
130
|
+
|
|
131
|
+
```sh
|
|
132
|
+
# Health check — should return 200 and HTML.
|
|
133
|
+
curl -fsSL https://admin.example.internal/
|
|
134
|
+
|
|
135
|
+
# WebSocket upgrade — open the URL in a browser. The connection-state
|
|
136
|
+
# pill in the header should turn green within a second of page load.
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
The header pill is your primary signal:
|
|
140
|
+
|
|
141
|
+
- green: connected, traces flowing
|
|
142
|
+
- amber: reconnecting
|
|
143
|
+
- red: socket unreachable (the SPA shows a banner with elapsed time)
|
|
144
|
+
|
|
145
|
+
## Debug: context preview
|
|
146
|
+
|
|
147
|
+
`GET /debug/context` returns the **membrane-normalized request that would be
|
|
148
|
+
emitted if the agent were activated right now** — the compiled messages,
|
|
149
|
+
system prompt, model config, and filtered tool set. Useful for inspecting
|
|
150
|
+
exactly what the model would see.
|
|
151
|
+
|
|
152
|
+
**Transparent by default.** The endpoint is side-effect-free: it runs no
|
|
153
|
+
inference, writes nothing to Chronicle, and contacts no external MCPL server.
|
|
154
|
+
It leaves the system state untouched, so you can poll it freely. The cost is
|
|
155
|
+
that it omits the *dynamically-gathered* injections (lessons / retrieval /
|
|
156
|
+
MCPL context), because gathering those is not transparent.
|
|
157
|
+
|
|
158
|
+
Query params:
|
|
159
|
+
|
|
160
|
+
- `agent=<name>` — defaults to the recipe's root agent
|
|
161
|
+
- `injections=1` — opt into full fidelity: gather the dynamic injections too.
|
|
162
|
+
**Not transparent** — this can run inference (e.g. the retrieval module's
|
|
163
|
+
Haiku calls cost tokens) and fires MCPL `beforeInference` hooks (whose paired
|
|
164
|
+
`afterInference` is never sent, so a stateful server may be left half-open).
|
|
165
|
+
- `pretty=1` — pretty-print the JSON
|
|
166
|
+
|
|
167
|
+
The response includes `"transparent": true|false` so callers can confirm which
|
|
168
|
+
mode ran.
|
|
169
|
+
|
|
170
|
+
```sh
|
|
171
|
+
# Transparent preview (default) — behind the proxy, with the same Basic-Auth
|
|
172
|
+
# as the rest of the surface:
|
|
173
|
+
curl -fsSL -u "$WEBUI_USER:$WEBUI_PASS" \
|
|
174
|
+
'https://admin.example.internal/debug/context?pretty=1'
|
|
175
|
+
|
|
176
|
+
# Full-fidelity preview (spends tokens, fires MCPL hooks):
|
|
177
|
+
curl -fsSL -u "$WEBUI_USER:$WEBUI_PASS" \
|
|
178
|
+
'https://admin.example.internal/debug/context?injections=1&pretty=1'
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
It is gated by the same Basic-Auth as every other route — note the response
|
|
182
|
+
contains the full system prompt and conversation, so treat it as sensitive.
|
|
183
|
+
|
|
184
|
+
See [`debug-context-api.md`](./debug-context-api.md) for the full reference:
|
|
185
|
+
response shape, `jq` recipes, and the transparency contract.
|
|
186
|
+
|
|
187
|
+
## Multi-VM admin
|
|
188
|
+
|
|
189
|
+
The module has no built-in cross-VM aggregation. For a fleet of admin
|
|
190
|
+
hosts, the simplest pattern is a Caddy block per instance with a
|
|
191
|
+
landing page or path prefix:
|
|
192
|
+
|
|
193
|
+
```caddy
|
|
194
|
+
admin.example.internal {
|
|
195
|
+
handle /vm-a/* {
|
|
196
|
+
reverse_proxy 10.0.0.10:7340
|
|
197
|
+
}
|
|
198
|
+
handle /vm-b/* {
|
|
199
|
+
reverse_proxy 10.0.0.11:7340
|
|
200
|
+
}
|
|
201
|
+
# ...
|
|
202
|
+
}
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
A future iteration may add a dedicated aggregator service that speaks
|
|
206
|
+
the same WS protocol; the module's wire shape is forward-compatible
|
|
207
|
+
with that pattern.
|
|
208
|
+
|
|
209
|
+
## Troubleshooting
|
|
210
|
+
|
|
211
|
+
- **`refuses to bind ... without auth`**: the default bind is `0.0.0.0`,
|
|
212
|
+
which requires `basicAuth`. Either add credentials, or switch `host` to
|
|
213
|
+
`127.0.0.1` for a loopback-only (local-dev) bind.
|
|
214
|
+
- **WebUI bundle not found at .../dist/web**: run `bun install` at the
|
|
215
|
+
package root; the `postinstall` script builds the SPA. For dev, run
|
|
216
|
+
`bun run build:web` from the package root.
|
|
217
|
+
- **Disconnect banner stuck**: the host process may have crashed. Check
|
|
218
|
+
`journalctl -u connectome-host -n 100` (or the equivalent for your
|
|
219
|
+
init system). The SPA reconnects automatically once the host is back.
|
package/package.json
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@animalabs/connectome-host",
|
|
3
|
+
"version": "0.3.1",
|
|
4
|
+
"description": "General-purpose agent TUI host with recipe-based configuration",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"start": "bun src/index.ts",
|
|
8
|
+
"dev": "bun --watch src/index.ts",
|
|
9
|
+
"test": "bun test",
|
|
10
|
+
"build:web": "cd web && bun install && bun run build",
|
|
11
|
+
"postinstall": "test -d web && cd web && bun install && bun run build || true"
|
|
12
|
+
},
|
|
13
|
+
"dependencies": {
|
|
14
|
+
"@animalabs/agent-framework": "^0.6.0",
|
|
15
|
+
"@animalabs/chronicle": "^0.2.0",
|
|
16
|
+
"@animalabs/context-manager": "^0.5.5",
|
|
17
|
+
"@animalabs/membrane": "^0.5.68",
|
|
18
|
+
"@opentui/core": "^0.1.82"
|
|
19
|
+
},
|
|
20
|
+
"devDependencies": {
|
|
21
|
+
"@types/bun": "^1.3.13",
|
|
22
|
+
"@types/node": "^22.0.0",
|
|
23
|
+
"typescript": "^5.7.0"
|
|
24
|
+
},
|
|
25
|
+
"repository": {
|
|
26
|
+
"type": "git",
|
|
27
|
+
"url": "git+https://github.com/anima-research/connectome-host.git"
|
|
28
|
+
},
|
|
29
|
+
"homepage": "https://github.com/anima-research/connectome-host#readme",
|
|
30
|
+
"bugs": {
|
|
31
|
+
"url": "https://github.com/anima-research/connectome-host/issues"
|
|
32
|
+
}
|
|
33
|
+
}
|
package/recipes/SETUP.md
ADDED
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
# Knowledge Miner Setup Guide
|
|
2
|
+
|
|
3
|
+
A step-by-step guide to setting up ConnectomeHost with the knowledge-miner recipe for extracting structured knowledge from your organization's Zulip, Notion, and GitLab.
|
|
4
|
+
|
|
5
|
+
## What you get
|
|
6
|
+
|
|
7
|
+
An AI research agent that can:
|
|
8
|
+
- **Read** your team's Zulip conversations, Notion docs, and GitLab issues/MRs/code
|
|
9
|
+
- **Fork** parallel sub-agents to investigate multiple sources simultaneously
|
|
10
|
+
- **Extract** persistent lessons — tagged, scored knowledge that survives across sessions
|
|
11
|
+
- **Write** reports and analysis documents to disk
|
|
12
|
+
- **Cross-reference** information across all three platforms
|
|
13
|
+
|
|
14
|
+
## Prerequisites
|
|
15
|
+
|
|
16
|
+
| Tool | Why | Install |
|
|
17
|
+
|------|-----|---------|
|
|
18
|
+
| [Node.js](https://nodejs.org/) 20+ | Runtime | `nvm install 20` or download from nodejs.org |
|
|
19
|
+
| [Bun](https://bun.sh/) | App runner | `curl -fsSL https://bun.sh/install \| bash` |
|
|
20
|
+
| [Anthropic API key](https://console.anthropic.com/) | LLM access | Sign up at console.anthropic.com |
|
|
21
|
+
|
|
22
|
+
## Step 1: Install ConnectomeHost
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
git clone https://github.com/anima-research/connectome-host.git
|
|
26
|
+
cd connectome-host
|
|
27
|
+
npm install
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Step 2: Set up your data sources
|
|
31
|
+
|
|
32
|
+
You need credentials for each platform you want to connect. You can start with just one and add more later — the agent adapts to whatever tools are available.
|
|
33
|
+
|
|
34
|
+
### Zulip
|
|
35
|
+
|
|
36
|
+
You need a `.zuliprc` file with your bot or user credentials.
|
|
37
|
+
|
|
38
|
+
1. In your Zulip organization, go to **Settings > Personal > API key**
|
|
39
|
+
2. Download the `.zuliprc` file, or create one manually:
|
|
40
|
+
|
|
41
|
+
```ini
|
|
42
|
+
[api]
|
|
43
|
+
email=your-bot@your-org.zulipchat.com
|
|
44
|
+
key=YOUR_ZULIP_API_KEY
|
|
45
|
+
site=https://your-org.zulipchat.com
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
3. Place it in the connectome-host directory:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
cp ~/Downloads/.zuliprc ./.zuliprc
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
4. Install the Zulip MCP server:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
git clone https://github.com/anima-research/zulip_mcp.git ../zulip_mcp
|
|
58
|
+
cd ../zulip_mcp && npm install && npm run build && cd -
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### GitLab
|
|
62
|
+
|
|
63
|
+
Works with both gitlab.com and self-hosted GitLab instances.
|
|
64
|
+
|
|
65
|
+
1. Go to your GitLab instance > **User Settings > Access Tokens**
|
|
66
|
+
2. Create a personal access token with scopes: `read_api`, `read_repository`
|
|
67
|
+
- Add `api` scope if you want write access (creating issues, comments)
|
|
68
|
+
3. Note your token and your GitLab API URL
|
|
69
|
+
|
|
70
|
+
No separate installation needed — the recipe uses `npx` to run `@zereight/mcp-gitlab` on demand.
|
|
71
|
+
|
|
72
|
+
### Notion (optional, via an MCP server)
|
|
73
|
+
|
|
74
|
+
If you want the agent to read your Notion workspace, point the recipe at any MCP server that exposes Notion search and page-read tools. The recipe's template entry is named `syncntn` after the particular Notion MCP adapter it was developed against, but the key is just a label — any Notion MCP server works, as long as its exposed tool names match what the system prompt references (`syncntn--search_pages`, `syncntn--get_page_markdown`, and friends). If your server uses different tool names, either rename the MCP key and update the prompt, or skip Notion entirely by removing the block.
|
|
75
|
+
|
|
76
|
+
Typical setup:
|
|
77
|
+
|
|
78
|
+
1. Install and start your Notion MCP server somewhere the recipe can launch it.
|
|
79
|
+
2. Note any configuration it needs (API credentials, workspace ID, storage URL).
|
|
80
|
+
3. Fill those values into the recipe's `syncntn` env block in Step 3 below.
|
|
81
|
+
|
|
82
|
+
Don't have a Notion MCP server? Remove the `syncntn` entry from the recipe — the agent will adapt and work with whatever sources remain.
|
|
83
|
+
|
|
84
|
+
### DuckDuckGo web search (optional, but enabled by default)
|
|
85
|
+
|
|
86
|
+
The recipe ships with [`nickclyde/duckduckgo-mcp-server`](https://github.com/nickclyde/duckduckgo-mcp-server) wired as `ddg`. It gives the miner one public source — handy when a question has a regulatory, standards-body, or vendor-spec component the internal sources can't answer on their own. The agent emits `[WEB: <url>]` for any claim backed by a web hit, so the citation chain stays auditable.
|
|
87
|
+
|
|
88
|
+
Install once as a sibling of `connectome-host/`:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
cd ..
|
|
92
|
+
git clone https://github.com/nickclyde/duckduckgo-mcp-server.git
|
|
93
|
+
cd duckduckgo-mcp-server
|
|
94
|
+
python3 -m venv .venv
|
|
95
|
+
.venv/bin/pip install -e .
|
|
96
|
+
cd ../connectome-host
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
The recipe expects the entry-point script at `../duckduckgo-mcp-server/.venv/bin/duckduckgo-mcp-server`. No API key needed. Don't want public-web access? Remove the `ddg` block from the recipe.
|
|
100
|
+
|
|
101
|
+
## Step 3: Configure the recipe
|
|
102
|
+
|
|
103
|
+
Copy the template recipe and fill in your credentials:
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
cp recipes/knowledge-miner.json my-recipe.json
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Edit `my-recipe.json` and replace the placeholder values in `mcpServers`:
|
|
110
|
+
|
|
111
|
+
```jsonc
|
|
112
|
+
{
|
|
113
|
+
"mcpServers": {
|
|
114
|
+
"zulip": {
|
|
115
|
+
"command": "node",
|
|
116
|
+
"args": ["../zulip_mcp/build/index.js"],
|
|
117
|
+
"env": {
|
|
118
|
+
"ENABLE_ZULIP": "true",
|
|
119
|
+
"ENABLE_DISCORD": "false",
|
|
120
|
+
"ZULIP_RC_PATH": "./.zuliprc" // path to your .zuliprc
|
|
121
|
+
}
|
|
122
|
+
},
|
|
123
|
+
"syncntn": {
|
|
124
|
+
"command": "../syncntn/services/mcp/start_mcp_local.sh",
|
|
125
|
+
"env": {
|
|
126
|
+
"STORAGE_URL": "http://localhost:8000",
|
|
127
|
+
"WORKSPACE_ID": "YOUR_WORKSPACE_ID" // <-- replace this
|
|
128
|
+
}
|
|
129
|
+
},
|
|
130
|
+
"gitlab": {
|
|
131
|
+
"command": "npx",
|
|
132
|
+
"args": ["-y", "@zereight/mcp-gitlab"],
|
|
133
|
+
"env": {
|
|
134
|
+
"GITLAB_PERSONAL_ACCESS_TOKEN": "YOUR_GITLAB_TOKEN", // <-- replace
|
|
135
|
+
"GITLAB_API_URL": "https://gitlab.example.com/api/v4" // <-- replace
|
|
136
|
+
}
|
|
137
|
+
},
|
|
138
|
+
"ddg": {
|
|
139
|
+
"command": "../duckduckgo-mcp-server/.venv/bin/duckduckgo-mcp-server"
|
|
140
|
+
// no creds; public web. Remove this block to disable web search.
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
**Don't need all three?** Just remove the server entries you don't have. The agent works with any combination.
|
|
147
|
+
|
|
148
|
+
## Step 4: Set your API key
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
export ANTHROPIC_API_KEY=sk-ant-...
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Or add it to a `.env` file in the project directory.
|
|
155
|
+
|
|
156
|
+
## Step 5: Run
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
bun src/index.ts my-recipe.json
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
On subsequent runs, just `bun src/index.ts` — the recipe is remembered.
|
|
163
|
+
|
|
164
|
+
## Using the agent
|
|
165
|
+
|
|
166
|
+
Once running, you'll see a terminal interface. Type natural language requests:
|
|
167
|
+
|
|
168
|
+
```
|
|
169
|
+
> Map out the key architectural decisions made in the last month across Zulip and GitLab
|
|
170
|
+
|
|
171
|
+
> What does the team's Notion say about the deployment process? Cross-reference with
|
|
172
|
+
recent Zulip discussions about deploy failures.
|
|
173
|
+
|
|
174
|
+
> Find all open GitLab issues tagged "tech-debt" and check if any were discussed in Zulip.
|
|
175
|
+
Create a summary report.
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
The agent will:
|
|
179
|
+
1. **Scout** available sources (list Zulip streams, search Notion, browse GitLab)
|
|
180
|
+
2. **Fork** sub-agents to read specific threads, pages, and issues in parallel
|
|
181
|
+
3. **Synthesize** findings and cross-reference across platforms
|
|
182
|
+
4. **Extract** lessons and optionally write reports to `./output/`
|
|
183
|
+
|
|
184
|
+
### Useful commands
|
|
185
|
+
|
|
186
|
+
| Command | What it does |
|
|
187
|
+
|---------|-------------|
|
|
188
|
+
| `Tab` | Toggle fleet view — see sub-agents working in parallel |
|
|
189
|
+
| `/lessons` | Show all extracted knowledge, sorted by confidence |
|
|
190
|
+
| `/status` | Agent state, session info |
|
|
191
|
+
| `/undo` | Roll back the last agent turn |
|
|
192
|
+
| `/mcp list` | Show connected data sources |
|
|
193
|
+
| `/newtopic [context]` | Reset context window for a new topic (compresses old context) |
|
|
194
|
+
| `/session new` | Start a fresh session (lessons persist) |
|
|
195
|
+
| `Esc` | Interrupt the agent mid-turn |
|
|
196
|
+
|
|
197
|
+
### Tips
|
|
198
|
+
|
|
199
|
+
- **Start broad, then narrow.** Ask "what streams/projects exist?" before diving deep.
|
|
200
|
+
- **Let it fork.** The agent is designed to run 2-4 sub-agents in parallel. Don't micromanage.
|
|
201
|
+
- **Check lessons periodically.** `/lessons` shows what's been extracted. You can ask the agent to revise or merge lessons.
|
|
202
|
+
- **Use the workspace.** Ask the agent to "write a report" and it produces files in `./output/`.
|
|
203
|
+
- **Switch topics cleanly.** Use `/newtopic` when changing research direction — it compresses old context and frees up the context window. Cheaper than a new session, and lessons carry over either way.
|
|
204
|
+
|
|
205
|
+
## Customization
|
|
206
|
+
|
|
207
|
+
### Using only some sources
|
|
208
|
+
|
|
209
|
+
Remove MCP server entries from the recipe for sources you don't have. The system prompt automatically adapts — the agent only uses tools that are available.
|
|
210
|
+
|
|
211
|
+
### Overriding servers at runtime
|
|
212
|
+
|
|
213
|
+
Instead of editing the recipe, you can override server config in `mcpl-servers.json`:
|
|
214
|
+
|
|
215
|
+
```bash
|
|
216
|
+
# Add or override a server (persists across restarts)
|
|
217
|
+
/mcp add gitlab npx -y @zereight/mcp-gitlab
|
|
218
|
+
/mcp env gitlab GITLAB_PERSONAL_ACCESS_TOKEN=glpat-xxx GITLAB_API_URL=https://gitlab.myco.com/api/v4
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
Changes require a restart to take effect.
|
|
222
|
+
|
|
223
|
+
### Read-only GitLab
|
|
224
|
+
|
|
225
|
+
If you want the agent to only read from GitLab (no issue creation, no MR comments):
|
|
226
|
+
|
|
227
|
+
```json
|
|
228
|
+
"gitlab": {
|
|
229
|
+
"command": "npx",
|
|
230
|
+
"args": ["-y", "@zereight/mcp-gitlab"],
|
|
231
|
+
"env": {
|
|
232
|
+
"GITLAB_PERSONAL_ACCESS_TOKEN": "YOUR_TOKEN",
|
|
233
|
+
"GITLAB_API_URL": "https://gitlab.example.com/api/v4",
|
|
234
|
+
"GITLAB_READ_ONLY_MODE": "true"
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
### Limiting GitLab tools
|
|
240
|
+
|
|
241
|
+
To only expose certain tool categories (e.g., issues and merge requests, not pipelines or wiki):
|
|
242
|
+
|
|
243
|
+
```json
|
|
244
|
+
"env": {
|
|
245
|
+
"GITLAB_TOOLSETS": "issues,merge_requests,search,projects"
|
|
246
|
+
}
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
## Reviewing knowledge quality
|
|
250
|
+
|
|
251
|
+
After the Knowledge Miner produces documents, run the Reviewer agent for a quality audit.
|
|
252
|
+
|
|
253
|
+
### Step 1: Export lessons
|
|
254
|
+
|
|
255
|
+
In the Knowledge Miner session:
|
|
256
|
+
```
|
|
257
|
+
/export
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
Or just quit — lessons are auto-exported on exit. This creates `./output/lessons-export.json` and `./output/lessons-export.md`.
|
|
261
|
+
|
|
262
|
+
### Step 2: Run the Reviewer
|
|
263
|
+
|
|
264
|
+
```bash
|
|
265
|
+
bun src/index.ts recipes/knowledge-reviewer.json
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
The Reviewer reads the exported lessons and documents from `./output/` (mounted as read-only `input/`). It produces:
|
|
269
|
+
- **Critic findings** per document — internal contradictions, unsupported claims, missing markers
|
|
270
|
+
- **SME checklist** — a focused list of items for domain experts to verify
|
|
271
|
+
|
|
272
|
+
Ask it:
|
|
273
|
+
```
|
|
274
|
+
> Review all documents in input/. Generate the SME checklist.
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
### Step 3: Human review
|
|
278
|
+
|
|
279
|
+
Open `./review-output/sme-checklist.md`. It contains a prioritized list:
|
|
280
|
+
- **High risk** — `[GEN]` claims (general knowledge, no source)
|
|
281
|
+
- **Medium risk** — `[INF]` claims on system boundaries
|
|
282
|
+
- **Knowledge gaps** — `❓` markers needing expert input
|
|
283
|
+
- **Unmarked suspicious claims** — the most dangerous: plausible but unsourced
|
|
284
|
+
|
|
285
|
+
A domain expert can complete this checklist in 10-20 minutes without reading the full document.
|
|
286
|
+
|
|
287
|
+
### The confidence markers
|
|
288
|
+
|
|
289
|
+
The Knowledge Miner tags document claims with `[SRC]`, `[WEB]`, `[INF]`, `[GEN]`, or `❓`. The Reviewer audits these. If the Miner missed markers (unmarked claims that look like general knowledge), the Reviewer flags them.
|
|
290
|
+
|
|
291
|
+
- `[SRC: source]` — direct quote from an **internal** system (Zulip, Notion, GitLab)
|
|
292
|
+
- `[WEB: url]` — quote from a public web page via the DuckDuckGo MCP; the URL is the citation
|
|
293
|
+
- `[INF]` — inferred from multiple sources
|
|
294
|
+
- `[GEN]` — general domain knowledge with no citation (prefer `[WEB]` when checkable)
|
|
295
|
+
- `❓` — knowledge gap; needs a human expert
|
|
296
|
+
|
|
297
|
+
Internal `[SRC]` always wins over `[WEB]` when both speak to the same org-specific term — the miner is instructed to keep the two meanings visibly separate, and the reviewer flags collisions.
|
|
298
|
+
|
|
299
|
+
## Troubleshooting
|
|
300
|
+
|
|
301
|
+
| Problem | Fix |
|
|
302
|
+
|---------|-----|
|
|
303
|
+
| `ANTHROPIC_API_KEY not set` | `export ANTHROPIC_API_KEY=sk-ant-...` |
|
|
304
|
+
| Zulip tools not appearing | Check `.zuliprc` path and that zulip_mcp is built |
|
|
305
|
+
| GitLab 401 errors | Verify your token has the right scopes and hasn't expired |
|
|
306
|
+
| Notion tools not appearing or connection refused | Make sure your Notion MCP server is running and reachable at the command/URL the recipe expects |
|
|
307
|
+
| Agent seems stuck | Press `Esc` to interrupt, then ask it to try a different approach |
|
|
308
|
+
| Sub-agents not returning | Press `Tab` to check fleet view — they may still be working |
|