brainllm 12.2.0 → 12.4.0
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 +10 -2
- package/README.md +42 -21
- package/SECURITY.md +33 -0
- package/dist/index.js +2556 -6071
- package/manifest.json +14 -9
- package/package.json +9 -5
- package/server.json +22 -3
- package/skills/brainllm/SKILL.md +23 -13
- package/skills/brainllm/references/domains.md +6 -0
- package/skills/brainllm/references/fullmode.md +12 -12
- package/skills/brainllm/references/taxonomy.md +3 -2
- package/skills/brainllm/references/troubleshooting.md +1 -1
package/.env.example
CHANGED
|
@@ -8,7 +8,7 @@ TRILIUM_BASE_URL=http://localhost:8080
|
|
|
8
8
|
# TRILIUM_BASE_URL=https://trilium.yourdomain.com
|
|
9
9
|
|
|
10
10
|
# ETAPI token — create in Trilium (Options → ETAPI → Create token), or set
|
|
11
|
-
# TRILIUM_PASSWORD instead and `bun run init` will mint one for you
|
|
11
|
+
# TRILIUM_PASSWORD instead and `bun run init` will mint and cache one for you.
|
|
12
12
|
TRILIUM_ETAPI_TOKEN=
|
|
13
13
|
|
|
14
14
|
# Alternative to the token: when TRILIUM_ETAPI_TOKEN is empty, BrainLLM mints one on
|
|
@@ -17,7 +17,7 @@ TRILIUM_ETAPI_TOKEN=
|
|
|
17
17
|
TRILIUM_PASSWORD=
|
|
18
18
|
|
|
19
19
|
# ── Tool surface ───────────────────────────────────────────────────────────────
|
|
20
|
-
# core (default): the
|
|
20
|
+
# core (default): the 44 brain-aware tools. full: adds the 33 raw ETAPI tools.
|
|
21
21
|
# BRAINLLM_MODE=full
|
|
22
22
|
|
|
23
23
|
# ── Timezone ───────────────────────────────────────────────────────────────────
|
|
@@ -33,6 +33,11 @@ TRILIUM_PASSWORD=
|
|
|
33
33
|
# Bearer token that all MCP clients must send as Authorization: Bearer <token>.
|
|
34
34
|
# Generate with: openssl rand -hex 32
|
|
35
35
|
# MCP_AUTH_TOKEN=
|
|
36
|
+
# HTTP mode fails closed when neither MCP_AUTH_TOKEN nor BRAINLLM_OWNER_PASSWORD is set.
|
|
37
|
+
# Only use this explicit escape hatch on an isolated, trusted network:
|
|
38
|
+
# BRAINLLM_ALLOW_UNAUTHENTICATED_HTTP=true
|
|
39
|
+
# Set true only when a trusted reverse proxy supplies x-forwarded-host/proto.
|
|
40
|
+
# BRAINLLM_TRUST_PROXY=true
|
|
36
41
|
|
|
37
42
|
# ── Config persistence (Railway / persistent-volume deploys) ──────────────────
|
|
38
43
|
# Absolute path where brainllm.json should be read/written.
|
|
@@ -47,6 +52,9 @@ TRILIUM_PASSWORD=
|
|
|
47
52
|
# you type on the consent screen when authorizing a client. Leave unset and the
|
|
48
53
|
# OAuth surface is disabled entirely; MCP_AUTH_TOKEN still works for Claude Code.
|
|
49
54
|
# BRAINLLM_OWNER_PASSWORD=
|
|
55
|
+
# Optional deployment secret used to sign OAuth access/refresh tokens. Set a
|
|
56
|
+
# new random value (32+ chars) when rotating OAuth; it overrides the local store.
|
|
57
|
+
# BRAINLLM_OAUTH_SECRET=
|
|
50
58
|
|
|
51
59
|
# Only needed if a proxy rewrites Host so the server cannot derive its own
|
|
52
60
|
# public URL. Must match the URL you type into the client, exactly.
|
package/README.md
CHANGED
|
@@ -6,11 +6,11 @@
|
|
|
6
6
|
|
|
7
7
|
**Give Claude a memory that survives the session.**
|
|
8
8
|
|
|
9
|
-
A persistent, graph-structured second brain for Claude and any MCP client — built on [TriliumNext Notes](https://github.com/TriliumNext/
|
|
9
|
+
A persistent, graph-structured second brain for Claude and any MCP client — built on [TriliumNext Notes](https://github.com/TriliumNext/Trilium), served over the [Model Context Protocol](https://modelcontextprotocol.io).
|
|
10
10
|
|
|
11
11
|
[**brainllm site**](https://miisodev.github.io/BrainLLM/) · [How it works](https://miisodev.github.io/BrainLLM/how-it-works.html) · [Use cases](https://miisodev.github.io/BrainLLM/use-cases.html) · [Docs](https://miisodev.github.io/BrainLLM/docs.html)
|
|
12
12
|
|
|
13
|
-
[](https://github.com/miisodev/BrainLLM/releases)
|
|
14
14
|
[](https://github.com/miisodev/BrainLLM/actions/workflows/ci.yml)
|
|
15
15
|
[](./LICENSE)
|
|
16
16
|
[](https://bun.sh)
|
|
@@ -25,7 +25,7 @@ A persistent, graph-structured second brain for Claude and any MCP client — bu
|
|
|
25
25
|
|
|
26
26
|
LLMs forget. Every session starts from zero: who you are, what you're working on, what was decided yesterday, what went wrong last week. BrainLLM fixes that.
|
|
27
27
|
|
|
28
|
-
**BrainLLM is an MCP server that gives an LLM a real, persistent memory** — stored in [TriliumNext Notes](https://github.com/TriliumNext/
|
|
28
|
+
**BrainLLM is an MCP server that gives an LLM a real, persistent memory** — stored in [TriliumNext Notes](https://github.com/TriliumNext/Trilium), a mature open-source knowledge base you self-host and own. The model opens each session by loading who you are and what's live, writes durable facts the moment they surface, wires knowledge together as a typed graph, and closes each session with a log, a diary entry, and a database backup. The next session picks up exactly where the last one ended.
|
|
29
29
|
|
|
30
30
|
It's a single Bun/TypeScript service with two dependencies (the MCP SDK and Zod), speaking to Trilium exclusively through its public ETAPI. Your memory lives in *your* Trilium instance — inspectable, editable, and portable, never locked inside a vendor's black box.
|
|
31
31
|
|
|
@@ -48,9 +48,11 @@ Placement, naming, labels, deduplication, relation bookkeeping, lifecycle aging,
|
|
|
48
48
|
- **Structure is enforced, not requested** — every content kind has a canonical structure, served by `template()` and held on write: a new thread requires its goal, thread/diary/session entries open with an identification line (which LLM, which environment, which session type), threads carry exactly one Resolution (owned by `resolve()`), duplicate section headings are detected, and `Last updated` stamps are server-maintained.
|
|
49
49
|
- **Domains born complete** — creating a knowledge domain creates its book *and* its canonical Sources note (marker legend, stamp, grouped source list, revision table), so every claim has a sourcing home from the first write.
|
|
50
50
|
- **A visible graph** — `graph()` renders the whole relation graph (or any note's neighborhood) as a Mermaid flowchart, maintained as a native Trilium note.
|
|
51
|
+
- **Byte-preserving artifacts** — text is UTF-8, while binary content uses strict standard base64 in the tool contract and raw bytes on the wire; binary reads return an explicit MIME/base64 envelope instead of replacement characters.
|
|
51
52
|
- **One-call day orientation** — `day()` serves the previous session, its change log, everything touched since, and the month's deliverables in a single call.
|
|
52
|
-
- **Resilient plumbing** — every backend call is timeout-bounded with retry on idempotent reads;
|
|
53
|
-
- **Multi-agent by default** — all write-classified tools serialize behind a process-wide FIFO lock, so two agents (an interactive session and an automated run, say) writing through one hosted instance queue in arrival order instead of racing; reads stay fully parallel. Deletion catch-up in the daily log keeps a note deleted after its day's close from vanishing without a trace.
|
|
53
|
+
- **Resilient plumbing** — every backend call is timeout-bounded with retry on idempotent reads; routine core writes are idempotent or duplicate-guarded, while full-mode raw overwrites remain explicit; content surgery survives the editor's own HTML rewriting; renaming a domain cascades to everything inside it; the maintenance sweep heals drift it finds.
|
|
54
|
+
- **Multi-agent by default** — all write-classified tools serialize behind a process-wide FIFO lock, so two agents (an interactive session and an automated run, say) writing through one hosted instance queue in arrival order instead of racing; reads stay fully parallel. Deletion catch-up in the daily log keeps a note deleted after its day's close from vanishing without a trace — and its window is configurable (`deletionCatchupDays` in the lifecycle policy), defaulting to Trilium's 7-day retention.
|
|
55
|
+
- **Ask in prose, split on a seam** — `consistency(subject="…")` finds every note asserting about a fact however it is phrased, no regex guessing; `consistency(pattern, staleAfterDays=N)` surfaces figures held in exactly one untouched note, the ones that rot silently because nothing disagrees with them; `read(ids=[…])` batches a multi-note orientation into one round trip; and `split(noteId, sections=[…], into="…")` is the write half of the oversized-note problem — it lifts whole sections into a new note and leaves a pointer back. Information notes can carry a `#mandate` marker so a scoped session finds the one note it must obey without reading every note's prose.
|
|
54
56
|
|
|
55
57
|
---
|
|
56
58
|
|
|
@@ -64,7 +66,7 @@ BrainLLM (#brainLlmRoot)
|
|
|
64
66
|
├── 🤖 LLM Responsibilities · Protocols · Self-correction · Diary/ (the assistant's self-model + daily diary)
|
|
65
67
|
├── 🗂️ Memory Sessions/ · Threads/ (daily session logs + multi-session work)
|
|
66
68
|
├── 📚 Knowledge Master/ · Domains/<domain>/{ Sources, info } (learned facts beyond/contra training)
|
|
67
|
-
└── 💡 Insights Logs/ · Graph
|
|
69
|
+
└── 💡 Insights Logs/ · Graph · Claims (the brain's record of itself)
|
|
68
70
|
```
|
|
69
71
|
|
|
70
72
|
| Note class | Kinds | Behavior |
|
|
@@ -86,7 +88,7 @@ Knowledge is a **typed graph**: a closed vocabulary of 16 relations (`extends`,
|
|
|
86
88
|
### Prerequisites
|
|
87
89
|
|
|
88
90
|
- [Bun](https://bun.sh) v1.0+
|
|
89
|
-
- A running [TriliumNext](https://github.com/TriliumNext/
|
|
91
|
+
- A running [TriliumNext](https://github.com/TriliumNext/Trilium) instance (desktop app or server)
|
|
90
92
|
|
|
91
93
|
### 1. Install and build
|
|
92
94
|
|
|
@@ -107,7 +109,7 @@ To do it explicitly instead, either let `init` mint one:
|
|
|
107
109
|
TRILIUM_BASE_URL=http://localhost:8080 TRILIUM_PASSWORD=your-trilium-password bun run init
|
|
108
110
|
```
|
|
109
111
|
|
|
110
|
-
It
|
|
112
|
+
It caches the token beside `brainllm.json` with owner-only permissions and does **not** print the secret. If you explicitly need a copy, run `bun run init -- --show-token`; the CLI is idempotent and adopts an existing `#brainLlmRoot` instead of creating a duplicate tree. Or create one by hand in Trilium: **Options → ETAPI → Create token**.
|
|
111
113
|
|
|
112
114
|
### 3. Configure your MCP client
|
|
113
115
|
|
|
@@ -134,7 +136,7 @@ For **Claude Desktop**, add to `claude_desktop_config.json` (see `config.example
|
|
|
134
136
|
}
|
|
135
137
|
```
|
|
136
138
|
|
|
137
|
-
For **Claude Code**, the same server block works in `.mcp.json`. A
|
|
139
|
+
For **Claude Code**, the same server block works in `.mcp.json`. A schema-valid MCPB manifest (`manifest.json`) is included for hosts that support custom Bun commands, but BrainLLM still requires Bun and this repository does not yet publish a `.mcpb` one-click artifact.
|
|
138
140
|
|
|
139
141
|
### 4. Bootstrap the brain
|
|
140
142
|
|
|
@@ -149,10 +151,16 @@ TRILIUM_BASE_URL=http://localhost:8080 TRILIUM_ETAPI_TOKEN=your-token bun run in
|
|
|
149
151
|
Install the **operational skill** — the document that teaches Claude to treat BrainLLM as its own mind rather than a filing cabinet:
|
|
150
152
|
|
|
151
153
|
```bash
|
|
152
|
-
# Claude Code / Cowork skills directory
|
|
154
|
+
# Claude Code / Cowork skills directory (macOS/Linux)
|
|
153
155
|
cp -r skills/brainllm ~/.claude/skills/brainllm
|
|
154
156
|
```
|
|
155
157
|
|
|
158
|
+
```powershell
|
|
159
|
+
# Windows PowerShell
|
|
160
|
+
New-Item -ItemType Directory -Force "$env:USERPROFILE\.agents\skills" | Out-Null
|
|
161
|
+
Copy-Item skills\brainllm "$env:USERPROFILE\.agents\skills\brainllm" -Recurse -Force
|
|
162
|
+
```
|
|
163
|
+
|
|
156
164
|
Then start a session. The model calls `start()`, orients, and operates the brain natively from there.
|
|
157
165
|
|
|
158
166
|
---
|
|
@@ -189,17 +197,17 @@ The **full mode** tools deliberately break this convention — they are named af
|
|
|
189
197
|
|
|
190
198
|
### Tool permissions
|
|
191
199
|
|
|
192
|
-
Every tool declares whether it reads, writes, or destroys, so your client can group them and you can grant permission per group instead of per call. The current split is **
|
|
200
|
+
Every tool declares whether it reads, writes, or destroys, so your client can group them and you can grant permission per group instead of per call. The current full-mode split is **33 read-only · 38 write · 6 destructive** (core mode is **22 read-only · 20 write · 2 destructive**), which lets reads run unattended while anything that touches your brain still asks.
|
|
193
201
|
|
|
194
202
|
The classification lives in one reviewable table ([`src/annotations.ts`](./src/annotations.ts)) rather than scattered across registrations, and its default is deliberately unsafe-side: a tool missing from the table is treated as a **write**, never a read, and says so at startup. Three are worth knowing because they look like reads and aren't — `start()` creates today's diary and session stubs, `session()` runs the maintenance sweep, and `graph()` writes the rendered graph note.
|
|
195
203
|
|
|
196
|
-
### Core — universal verbs (
|
|
204
|
+
### Core — universal verbs (34)
|
|
197
205
|
|
|
198
206
|
| Group | Tools |
|
|
199
207
|
|---|---|
|
|
200
208
|
| Session lifecycle | `start` · `day` · `session` · `remarks` · `close` · `backup` |
|
|
201
|
-
| Writing | `remember` · `diary` · `revise` · `resolve` · `withdraw` · `recover` |
|
|
202
|
-
| Reading & search | `recall` · `domain` · `brain` · `assembly` · `outline` · `inspect` · `diff` · `template` · `consistency` |
|
|
209
|
+
| Writing | `remember` · `diary` · `revise` · `split` · `resolve` · `withdraw` · `recover` |
|
|
210
|
+
| Reading & search | `read` · `recall` · `domain` · `brain` · `assembly` · `outline` · `inspect` · `diff` · `template` · `consistency` |
|
|
203
211
|
| Graph | `connect` · `explore` · `graph` |
|
|
204
212
|
| Attachments & labels | `attach` · `detach` · `label` |
|
|
205
213
|
| Maintenance & system | `addendum` · `maintain` · `claim` · `forget` · `bootstrap` |
|
|
@@ -225,7 +233,7 @@ The complete operational reference is [`skills/brainllm/SKILL.md`](./skills/brai
|
|
|
225
233
|
| **stdio** | Local — Claude Desktop / Claude Code spawns BrainLLM as a child process | `PORT` unset (default) |
|
|
226
234
|
| **HTTP connector** | Remote — clients reach BrainLLM over the network | `PORT` set (Railway injects it) |
|
|
227
235
|
|
|
228
|
-
The HTTP connector serves a streamable-HTTP MCP endpoint at `/mcp` (one session per `mcp-session-id`, DELETE terminates, CORS-enabled with `mcp-session-id` exposed for browser clients), a **legacy SSE endpoint** at `/sse` (with `POST /messages`) for clients that predate streamable HTTP — older Cursor builds, Continue, and Python-SDK clients — and `GET /health`. The server root serves a plain page naming the endpoints, so a human or probing client landing on the origin sees what lives there. The server itself speaks plain HTTP — TLS is expected to terminate in front of it (Railway's edge does this automatically for you; on a bare VPS or your own Docker host, put it behind a reverse proxy such as Caddy, nginx, or a Cloudflare Tunnel). **
|
|
236
|
+
The HTTP connector serves a streamable-HTTP MCP endpoint at `/mcp` (one session per `mcp-session-id`, DELETE terminates, CORS-enabled with `mcp-session-id` exposed for browser clients), a **legacy SSE endpoint** at `/sse` (with `POST /messages`) for clients that predate streamable HTTP — older Cursor builds, Continue, and Python-SDK clients — and `GET /health`. The server root serves a plain page naming the endpoints, so a human or probing client landing on the origin sees what lives there. The server itself speaks plain HTTP — TLS is expected to terminate in front of it (Railway's edge does this automatically for you; on a bare VPS or your own Docker host, put it behind a reverse proxy such as Caddy, nginx, or a Cloudflare Tunnel). **HTTP mode now fails closed unless `MCP_AUTH_TOKEN` or `BRAINLLM_OWNER_PASSWORD` is configured**; `BRAINLLM_ALLOW_UNAUTHENTICATED_HTTP=true` is an explicit escape hatch for an isolated trusted network only. CORS defaults to `*`, so a reachable deployment must have a real authentication gate. Idle sessions are evicted after 1 hour; MCP request bodies are capped at 50 MiB by both the server and SDK transport. Both transports sit behind the same authentication gate.
|
|
229
237
|
|
|
230
238
|
### Docker / Railway
|
|
231
239
|
|
|
@@ -289,6 +297,9 @@ Without a volume, leave `BRAINLLM_CONFIG` unset — auto-discovery re-finds the
|
|
|
289
297
|
| `PORT` | — | Presence switches to HTTP-connector mode |
|
|
290
298
|
| `MCP_AUTH_TOKEN` | — | Static bearer token accepted on `/mcp` — what Claude Code and `mcp-remote` send |
|
|
291
299
|
| `BRAINLLM_OWNER_PASSWORD` | — | Enables the OAuth 2.1 / CIMD endpoints, required for claude.ai. The password you type on the consent screen |
|
|
300
|
+
| `BRAINLLM_OAUTH_SECRET` | — | Optional 32+ character deployment signing secret; rotate it to invalidate old OAuth tokens |
|
|
301
|
+
| `BRAINLLM_ALLOW_UNAUTHENTICATED_HTTP` | `false` | Explicit trusted-network-only escape hatch when no HTTP credential is configured; never use on a public interface |
|
|
302
|
+
| `BRAINLLM_TRUST_PROXY` | `false` | Trust `x-forwarded-host`/`x-forwarded-proto` for OAuth discovery only when a trusted reverse proxy sets them; prefer `BRAINLLM_PUBLIC_URL` |
|
|
292
303
|
| `BRAINLLM_PUBLIC_URL` | — | Override the derived public origin when a proxy rewrites `Host`. Must match the URL you enter in the client exactly |
|
|
293
304
|
| `BRAINLLM_CONFIG` | — | Absolute file path for `brainllm.json` on persistent-volume deploys |
|
|
294
305
|
|
|
@@ -326,23 +337,27 @@ index.ts ─→ tools.ts ─┬→ trilium.ts ETAPI client: bounded/retrying
|
|
|
326
337
|
├→ lifecycle.ts protection, sweep, aging, the start digest
|
|
327
338
|
├→ journal.ts daily Insights log generation (regenerate-in-place)
|
|
328
339
|
├→ time.ts timezone-correct now/today (BRAINLLM_TZ)
|
|
340
|
+
├→ rate-limit.ts bounded public HTTP budgets
|
|
341
|
+
├→ network-security.ts CIMD public-network and redirect checks
|
|
329
342
|
├→ bootstrap.ts five-area tree builder
|
|
330
343
|
└→ tools-*.ts per-area surface reads · full-mode raw ETAPI
|
|
331
344
|
```
|
|
332
345
|
|
|
333
|
-
Key properties: every write is sanitized for Trilium/CKEditor 5 compatibility (mutations reported back as `sanitized[]`); a revision snapshot precedes
|
|
346
|
+
Key properties: every write is sanitized for Trilium/CKEditor 5 compatibility (mutations reported back as `sanitized[]`); a revision snapshot precedes routine content mutation; every request carries the user's local time so Trilium stamps dates in the right day; core writes are idempotent or duplicate-guarded, while raw full-mode overwrites are explicit.
|
|
334
347
|
|
|
335
348
|
## Development
|
|
336
349
|
|
|
337
350
|
```bash
|
|
338
351
|
bun run dev # hot-reload dev server
|
|
339
352
|
bun run build # bundle to dist/index.js
|
|
340
|
-
bun
|
|
341
|
-
bun run test #
|
|
353
|
+
bun run test:unit # all unit tests (Bun discovery; works on Windows and CI)
|
|
354
|
+
bun run test:http # local auth/header smoke (no Trilium required)
|
|
355
|
+
bun run test # integration tests (requires a live Trilium instance)
|
|
356
|
+
bun run validate:manifest # MCPB schema/icon validation
|
|
342
357
|
bun run init # CLI bootstrap
|
|
343
358
|
```
|
|
344
359
|
|
|
345
|
-
Repo layout: runtime source in `src/`, the operational skill in `skills/brainllm/`, developer scripts in `scripts/`,
|
|
360
|
+
Repo layout: runtime source in `src/`, the operational skill in `skills/brainllm/`, developer scripts in `scripts/`, schema-valid MCPB manifest in `manifest.json`, container build in `Dockerfile`.
|
|
346
361
|
|
|
347
362
|
## Contributing
|
|
348
363
|
|
|
@@ -364,12 +379,18 @@ BrainLLM started as one person's daily-driver tool, so the code and docs still c
|
|
|
364
379
|
|
|
365
380
|
1. **Open an issue first** for anything non-trivial — bugs with reproduction steps, or proposals with the use case spelled out.
|
|
366
381
|
2. **Fork and branch**, keep changes focused, and match the existing code style.
|
|
367
|
-
3. **`bun run build` must pass clean** and unit tests must stay green (`bun
|
|
382
|
+
3. **`bun run build` must pass clean** and unit tests must stay green (`bun run test:unit` — CI runs the same checks on every push and PR); add tests for new normalize/lifecycle logic.
|
|
368
383
|
4. **Use conventional commits** (`fix:`, `feat:`, `docs:`, `refactor:`).
|
|
369
384
|
5. **Update the docs that your change touches** — `README.md`, the skill package under `skills/brainllm/`, and `config.example.json`/`.env.example` where relevant. The skill is part of the product: a tool change without its skill update is half a change.
|
|
370
385
|
|
|
371
386
|
Not sure where to start? Issues labeled `good first issue`, doc gaps, and the troubleshooting reference are all friendly entry points.
|
|
372
387
|
|
|
388
|
+
## Security
|
|
389
|
+
|
|
390
|
+
Please do not report suspected vulnerabilities in a public issue. Follow the private reporting process in [`SECURITY.md`](./SECURITY.md); never include ETAPI tokens, OAuth credentials, or private brain content in a report.
|
|
391
|
+
|
|
392
|
+
---
|
|
393
|
+
|
|
373
394
|
## Support the project
|
|
374
395
|
|
|
375
396
|
BrainLLM is built and maintained by one person. If it's useful to you, sponsorship directly funds its continued development:
|
|
@@ -391,5 +412,5 @@ Starring the repo, reporting bugs, and spreading the word help too.
|
|
|
391
412
|
|
|
392
413
|
## Credits
|
|
393
414
|
|
|
394
|
-
- [TriliumNext Notes](https://github.com/TriliumNext/
|
|
415
|
+
- [TriliumNext Notes](https://github.com/TriliumNext/Trilium) — the open-source, self-hosted knowledge base that powers this server's backend. BrainLLM would not exist without the TriliumNext team's work.
|
|
395
416
|
- [Model Context Protocol](https://modelcontextprotocol.io) — the open standard that lets one memory serve every MCP-capable client.
|
package/SECURITY.md
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Security Policy
|
|
2
|
+
|
|
3
|
+
## Supported versions
|
|
4
|
+
|
|
5
|
+
Security fixes ship on the latest release line. Older versions may remain useful for compatibility, but upgrade before relying on them for an internet-facing deployment.
|
|
6
|
+
|
|
7
|
+
| Version | Supported |
|
|
8
|
+
|---|---|
|
|
9
|
+
| 12.4.x | ✅ |
|
|
10
|
+
| 12.3.x and earlier | ❌ |
|
|
11
|
+
|
|
12
|
+
## Reporting a vulnerability
|
|
13
|
+
|
|
14
|
+
Do not open a public issue for a suspected vulnerability, and do not include credentials, ETAPI tokens, OAuth tokens, or private brain content in a report.
|
|
15
|
+
|
|
16
|
+
Use GitHub's private **Report a vulnerability** form for this repository, or email **miisodev@gmail.com** with:
|
|
17
|
+
|
|
18
|
+
- affected BrainLLM version and deployment mode (stdio, HTTP, Docker, or Railway);
|
|
19
|
+
- the request or sequence that reproduces the issue;
|
|
20
|
+
- the expected and observed behaviour;
|
|
21
|
+
- impact and any evidence already collected.
|
|
22
|
+
|
|
23
|
+
Please use a private channel until a fix and coordinated disclosure path are agreed. Do not test against data or accounts you do not own.
|
|
24
|
+
|
|
25
|
+
## Deployment guidance
|
|
26
|
+
|
|
27
|
+
Run the latest tagged release rather than an unreleased branch or a mutable dependency lock. For an HTTP deployment reachable outside a trusted network, set `MCP_AUTH_TOKEN`; configure `BRAINLLM_OWNER_PASSWORD` only when hosted OAuth clients require it. Keep the Trilium instance, ETAPI token, OAuth store, and `brainllm.json` on protected storage, and restrict network access at the platform edge.
|
|
28
|
+
|
|
29
|
+
For credential rotation, replace `MCP_AUTH_TOKEN` and the ETAPI token in the provider/Trilium, set a fresh `BRAINLLM_OAUTH_SECRET` (32+ characters) to invalidate existing OAuth tokens, and remove obsolete local `*.oauth.json` / `*.token` files. Never put recovered credentials in a repository, shared context note, Docker context, or release artifact.
|
|
30
|
+
|
|
31
|
+
## Scope
|
|
32
|
+
|
|
33
|
+
BrainLLM is an MCP server over TriliumNext's ETAPI boundary. Vulnerabilities in Trilium itself should be reported to the TriliumNext project unless the issue is caused by BrainLLM's use of that boundary.
|