v11.0.0 — Everywhere
Every client, every endpoint — plus a maintenance pass that fixes the brain itself.
Every client, every endpoint
Legacy SSE transport. Streamable HTTP replaced SSE as the MCP transport in the 2025-03-26 spec revision, but a long tail of clients still speaks nothing else — older Cursor builds, Continue, and anyone pinned to a pre-streamable Python SDK. BrainLLM now serves the full legacy wire contract natively: GET /sse opens the stream (first event names the POST endpoint with the session id), POST /messages ingests one JSON-RPC message per request. Implemented over Bun's web-standard request/response pair — the SDK's own SSE transport is Express-shaped and unusable here — with 30-second keepalive pings for proxies that time out silent connections. It sits behind the same authentication gate, the same CORS policy, and the same idle eviction as /mcp: an older transport must never mean a weaker door.
RFC 7591 dynamic client registration. The OAuth server previously spoke only Client ID Metadata Documents — which Claude selects, and which almost nothing else implements. opencode (MCP TS SDK ≤ 1.29) refuses to authenticate at all without a registration_endpoint. /register now mints opaque reg_* client ids, validated against the same redirect rules CIMD applies, stored in the persisted OAuth state under a 200-registration ceiling. The consent screen learned to identify non-URL clients honestly: a registered client is shown by its self-declared name, labelled as self-reported, while CIMD clients keep the DNS-and-TLS-vouched host. Both mechanisms coexist; Claude's flow is untouched.
Path-suffixed authorization-server metadata. /.well-known/oauth-authorization-server/mcp now exists alongside the root variant, per RFC 8414's path-insertion rule — some discovery implementations derive the AS metadata location from the resource path rather than the issuer, and refusing the variant reads as "no OAuth here".
A landing page at the root. A human or probing client landing on the origin now gets a page naming the server, the endpoint to point a client at, and what authentication expects — with the consent screen's no-external-request policy, for the same reasons. A bare 404 read as "nothing is here".
The brain maintains itself
Four defects and gaps, all confirmed in daily production use, all fixed in the maintenance engine:
- The pending-addendum counter lied.
session()reportedpending.addendums: 6whileaddendum()found 0 — three times, across two days. The counter matched the bare word "Addendum", which prose mentions of the tool match freely; the search required the structural marker (an h2–h4 "Addendum —" heading). Both now share one marker, so the one field added to stop the close protocol reciting empty steps can no longer manufacture one. - The entity-corruption detector stopped flagging documentation. A note that describes the double-escape trap necessarily stores its signature — inside a code element, deliberately. Five consecutive flags across two days were all this class. Classification now strips code/pre spans and re-tests: only matches outside them are corruption,
repairnever unwinds inside a span, and a documenting note stays silent unless repair was explicitly requested. revise(section=)catches typos. A section miss within edit distance of a real heading now returnsdidYouMean— andstrict=truerefuses the write entirely instead of appending a typo'd heading. The failure this prevents was real: a markdown-backticked section name wrote a new section instead of replacing the one intended, caught only because the receipt was honest.- Claims track their sources. A claim verified against a note is only as fresh as that note.
maintain(deep)now flagsclaim source-changed— a claim whose~derivedFromsource was revised after the claim's last verification. Nobody predicts at write time which assertions will age; staleness now arrives as "the fact's home moved" instead of a lucky catch.
Housekeeping
- The local OAuth secret store is no longer tracked in git (it was committed before
.gitignoretook effect; the historical secret should be treated as public — production mints its own on the volume). - A cross-user audit of
src/found zero person-specific runtime assumptions: the only hits are comments, test fixtures, and the project's own branding URLs. - Trilium fork synced with upstream (99 commits).
Upgrade notes: no configuration changes. New endpoints appear automatically; BRAINLLM_OWNER_PASSWORD still gates the entire OAuth surface, and MCP_AUTH_TOKEN still works exactly as before.