使用说明
brain-mcp-server
A generic MCP server that serves Markdown-based AI Brain files to any MCP-compatible client.
What It Does
Gives MCP clients persistent, context-aware access to a collection of Markdown files (an "AI Brain") via the Model Context Protocol. Supports reading, writing, searching, git-backed versioning, local stdio transport, and hosted HTTP transport with GitHub OAuth.
Tools
| Tool | Description |
|---|---|
brain_list_brains |
List the Brains the caller can reach, with metadata |
brain_describe |
Describe a single Brain (id, type, integration mode, role, metadata) |
brain_semantic_index |
Build/refresh the vector index over the sources/ archive |
brain_semantic_search |
Vector search across indexed sources |
brain_sync_status |
Hosted sync health — provider, hosted file count, open conflicts, latest cursor |
brain_list_conflicts |
List open sync conflicts |
brain_resolve_conflict |
Resolve a sync conflict |
brain_capture_item |
Capture a transient triage item into TASKS.md (brain_report_item is a compatibility alias) |
brain_load_context |
Entry point — returns the loader + NOW.md, plus nudges: stale lint, stale/oversized capture queue, open maintenance issues, and pending inbox files (inbox nudge is filesystem-backed Brains only) |
brain_read_file |
Read a specific file. Accepts scope = brain (default) or sources to read from the sources/ archive |
brain_update_file |
Update a Brain file (replace, append, or patch) |
brain_commit |
Git commit changes, optionally push |
brain_list_files |
List all Brain files with staleness metadata |
brain_list_sources |
List files in the sources/ archive, with optional category filter |
brain_search |
Structured ranked search with scores and mechanism codes. Accepts scope = brain (default), sources, or all; operational/history paths are excluded unless include_operational=true |
brain_log |
Append an entry to the Brain change log |
brain_read_log |
Read recent change log entries |
brain_lint |
Read-only health check by default: bloat, staleness, legacy/graph-shadow reachability, 2,500-token bootstrap budget, drift, and maintenance signals. fix=true can only relocate/date-stamp/archive ordinary task content; structural files are never auto-fixed. See Applying Brain lint fixes |
brain_prepare_ingest |
Read-only backend/category/capability preflight; call before any ingestion-related write |
brain_ingest |
Filesystem-backed source analysis/save; Postgres Brains use their operator source workflow |
brain_ingest_complete |
Complete filesystem provenance/inbox cleanup after preflight; hosted revision logging remains available through brain_log |
brain_scan_inbox |
List a filesystem-backed inbox; hosted Postgres output reports that operator-side inbox state is not observable |
The scope parameter on brain_read_file and brain_search separates the Brain vault (curated summaries, default) from the sources/ archive (original ingested documents: bios, assessments, meeting notes, writing samples, analysis, correspondence, etc.). brain_search returns deterministic ranked matches; normalized fallback makes queries like cnet id match CNetID. Its default knowledge scope excludes LOG.md, JOURNAL.md, archive/**, and working/**; set include_operational=true only when those paths are intended.
Requirements
- Node.js 22.x
- npm 10.9.8, pinned in
package.jsonviapackageManager - A directory of Markdown files (your "Brain") with at least
00_loader.mdandNOW.md - Git initialised in the Brain directory (for commit/push features)
See docs/TOOLING.md for the runtime/package-manager contract, system dependencies, hosted/local state boundaries, and script safety taxonomy.
Quick Start
# 1. Clone and build
git clone <your-fork-or-clone-url> ~/Projects/brain-mcp-server
cd ~/Projects/brain-mcp-server
npm ci
npm run build
# 2. Verify the build produced dist/index.js
ls dist/index.js
# 3. Test with MCP Inspector (optional but recommended)
npx @modelcontextprotocol/inspector node dist/index.js
Configuration
| Variable | Description | Default |
|---|---|---|
BRAIN_DIR |
Absolute path to your Brain markdown files directory | ~/Projects/ai-brain-jem/brain |
BRAIN_SOURCES_DIR |
Absolute path to your source archive directory | sibling sources/ next to BRAIN_DIR |
TRANSPORT |
stdio by default, or http for hosted/HTTP mode |
unset / stdio |
HOST or MCP_HTTP_HOST |
HTTP bind host when TRANSPORT=http |
127.0.0.1 |
PORT |
HTTP bind port and local OAuth base fallback | 3000 |
MCP_OAUTH_PUBLIC_BASE |
Public HTTPS base URL for hosted OAuth and MCP metadata | http://127.0.0.1:$PORT |
MCP_ALLOWED_ORIGINS |
Additional exact HTTP(S) origins allowed on /mcp, comma-separated. No wildcards, paths, credentials or trailing slash. Missing Origin remains allowed with bearer authentication; malformed/untrusted/duplicate Origin is rejected with 403 |
Resource URI's own origin only |
MCP_OAUTH_DOCUMENTATION_URL |
Deployment documentation URL advertised by OAuth discovery metadata | required in HTTP mode |
MCP_OAUTH_SIGNING_SECRET |
Required in HTTP mode. HS256 access-token signing secret | unset |
GITHUB_OAUTH_CLIENT_ID |
Required in HTTP mode. GitHub OAuth app client ID | unset |
GITHUB_OAUTH_CLIENT_SECRET |
Required in HTTP mode. GitHub OAuth app client secret | unset |
GITHUB_ALLOWED_LOGINS |
Comma-separated GitHub login allowlist for fallback owner access | unset |
GITHUB_ALLOWED_EMAILS |
Comma-separated email allowlist for fallback owner access | unset |
BRAIN_PLATFORM_CONFIG |
Registry JSON path for hosted/multi-Brain mode | ~/.config/brain-platform/registry.json |
BRAIN_LINT_MODE_OVERRIDES |
Validated per-Brain JSON mode map, e.g. {"ai-brain-jem":"graph_shadow"}. Malformed JSON, unknown Brains, and unknown modes fail startup |
unset; registry/default legacy |
BRAIN_PLATFORM_STATE_ROOT |
File-backed OAuth state root for local/dev fallback | ~/.config/brain-platform/state |
BRAIN_OAUTH_STATE_STORE |
OAuth client/session state store: file or postgres. Hosted should use postgres so connector enrollment survives Fly machine replacement |
file |
MCP_OAUTH_REFRESH_REUSE_GRACE_SEC |
Optional short refresh-token reuse window for cloud-synced client refresh races. Hosted uses 15; local/dev defaults to strict one-time rotation |
0 |
BRAIN_AUTO_SYNC |
Filesystem/git mode only. When true, successful mutating Brain tools automatically commit changes. Do not enable for Supabase-backed hosted runtime | unset / false |
BRAIN_AUTO_PUSH |
Filesystem/git mode only. When auto-sync is enabled, push commits to origin unless set false. Do not enable for Supabase-backed hosted runtime | true |
BRAIN_DATE_TIME_ZONE |
IANA timezone used for Brain log/source dates | TZ or UTC |
Lint rollout and structural-file authorisation
Each registry Brain may define a typed lint block with reachability_mode, optional graph_roots, relative_parent_scope, SharePoint URL mappings, and exemption globs. The default remains legacy; use graph_shadow to report graph/legacy deltas without changing enforced orphan results. Promote a Brain to graph only after its shadow findings have been adjudicated.
Hosted revision-store writes to 00_loader.md and NOW.md require an exact owner or admin role. Registry roles are validated fail-closed, while reader remains able to run detection-only lint. This gate intentionally does not cover direct local filesystem or SharePoint edits, sync ingestion, direct database administration, or the current stdio/system owner bypass. Those paths remain deployment/sync hardening work; the hosted gate must not be treated as universal enforcement. See docs/specs/013-brain-context-architecture.md.
Hosted HTTP Deployment
Remote-only clients need a public HTTPS MCP endpoint; 127.0.0.1 only works for clients running on the same laptop. The current hosted rebuild targets a Node runtime that serves OAuth and MCP over HTTPS while storing Brain revisions in Supabase Postgres and source artifacts in private Supabase Storage. The local Markdown Brain remains the baseline and is mirrored through the sync contract rather than by a hosted git checkout.
This repo includes:
Dockerfilefor the hosted Node runtimefly.tomlfor the first Supabase-backed Fly.io target,jem-brain-mcpdocs/deploy-fly.mdfor the deployment runbookdocs/hosted-client-cutover.mdfor the JEM hosted client shadow rehearsal and promotion gatedocs/ROADMAP.mdfor the staged hosted-client and multi-tenant roadmap
Hosted endpoint shape (substitute your own Fly.io app name):
https://<your-fly-app>.fly.dev/mcp
For hosted client cutover, add the HTTP endpoint as a separate brain-hosted connector first and keep the local stdio brain connector available as fallback.
After full Codex cutover, hosted may be the default brain connector and local stdio should be retained as brain-local. ChatGPT uses the same hosted endpoint as a custom MCP app: turn on Developer mode (Settings -> Security and login), then add the app from ChatGPT's plugins; in a Business or Enterprise workspace an admin creates it under Workspace settings -> Apps -> Create. See OpenAI's developer-mode guide.
Each hosted deployment should use a private registry. A deployment may serve one or more Brain IDs, but different owners should be isolated at the deployment and credential boundary. This public repo does not contain private deployment registries; clients using multiple deployments should install a connector for each and pass brain_id explicitly.
For local operator visibility, run npm run hosted:cockpit. It opens on 127.0.0.1:8787 by default and automatically tries the next local port if that port is already occupied. For a user-launchable local operator surface, generate the reviewable macOS LaunchAgent with npm run hosted:cockpit:launchd:plist; see docs/hosted-cockpit.md.
For rendered Brain and source-companion reading, use the separate JEM-only
npm run brain:library pilot. It keeps Markdown canonical, resolves ordinary
relative and HTTPS links, exposes exact source trace data, and leaves local
artifact opening disabled by default. See docs/brain-library.md.
Hosted deployments can also raise reason-aware authentication alerts to Slack (anonymous-activity review → channel; credential warning → channel, credential failure → operator DM), gated on BRAIN_SLACK_BOT_TOKEN (no-op without it). The cockpit doctor's hosted_mcp_auth_failures check surfaces the same condition in the Checks tab. See docs/hosted-cockpit.md for thresholds, routing, and env vars.
Applying Brain lint fixes
brain_lint detection is read-only for every read-authorised role. Its remaining mechanical fixes relocate completed [x] tasks to Done, date-stamp them, and archive Done items older than 30 days into archive/tasks-done.md. Orphans, graph ambiguity, bootstrap budget excess, 00_loader.md, and NOW.md are review items and are never auto-fixed. The ordinary-content fixes can be applied from three surfaces, all sharing one implementation:
- Cockpit Fixes tab (primary) — lists each fix with a checkbox plus "Approve all", applies only what you approve. Backed by a loopback-only write endpoint (Host allowlist + per-process nonce + JSON-only).
- Brain Monitor menu-bar app — Controls → "Apply Lint Fixes..." (confirm-gated dry-run → apply).
- CLI —
npm run brain:lint:fix(dry run) /npm run brain:lint:fix -- --apply.
Archiving moves items (nothing is deleted) and dates are stamped forward. Full operator detail, the security posture, and the design rationale are in docs/hosted-cockpit.md and docs/specs/010-cockpit-fixes-tab.md.
Client Setup
Claude Code
Add to ~/.claude/settings.json (user-level) or .claude/settings.json (project-level):
{
"mcpServers": {
"brain": {
"command": "node",
"args": ["/absolute/path/to/brain-mcp-server/dist/index.js"],
"env": {
"BRAIN_DIR": "/absolute/path/to/your/brain/files"
}
}
}
}
Claude Desktop
Add to claude_desktop_config.json (same format as above).
Claude Cowork
Add via the MCP server configuration in Cowork settings (same command, args, and env values).
Post-Install Configuration
After the MCP server is connected, three additional steps make it fully automatic.
Step 1: Pre-authorise tool calls (Claude Code)
Add mcp__brain to your permissions allow-list so Claude doesn't prompt for approval on every Brain tool call.
In ~/.claude/settings.json, add to the permissions.allow array:
{
"permissions": {
"allow": [
"mcp__brain"
]
}
}
The mcp__brain prefix matches all Brain tools (25 total). You can verify with /permissions in Claude Code.
Step 2: Conditional auto-load directive (Claude Code / Cowork)
Add the following to ~/.claude/CLAUDE.md so Claude loads Brain context when relevant — not on every conversation:
## AI Brain (Conditional Auto-Load)
An AI Brain (personal knowledge system) is connected via MCP. Load it when the conversation
benefits from personal context — skip it for generic tasks.
Load Brain context proactively (don't wait to be asked) when:
- Writing on the user's behalf, career/professional tasks, work context, personal projects,
strategy/advice requiring background, anything needing voice/preferences/expertise,
user references "my Brain" / "my context", or user attaches a document or asks to ingest.
Skip when:
- Generic technical questions, general knowledge/research, pure coding help,
or user explicitly says not to load.
Load sequence (when loading):
1. Fetch tools (if deferred): ToolSearch(query="select:mcp__brain__brain_load_context,mcp__brain__brain_read_file,mcp__brain__brain_search,mcp__brain__brain_list_files,mcp__brain__brain_list_sources,mcp__brain__brain_update_file,mcp__brain__brain_commit,mcp__brain__brain_log,mcp__brain__brain_read_log,mcp__brain__brain_lint,mcp__brain__brain_prepare_ingest,mcp__brain__brain_ingest,mcp__brain__brain_ingest_complete,mcp__brain__brain_scan_inbox")
2. Call brain_load_context — returns the loader navigation table, current priorities, and nudges (lint overdue, capture queue stale, maintenance issues open, inbox pending). The loader contains the full ingestion protocol, source categories, and file-editing rules; follow it.
3. Call brain_read_file for task-relevant files per the navigation table.
4. If brain_load_context flags a lint nudge, run brain_lint before accuracy-sensitive work.
Reading source archives:
- brain_read_file and brain_search accept scope = "brain" (default, vault only), "sources", or "all" (search only). brain_search prefers exact keyword matches, then uses normalized fallback for spacing, punctuation, camel-case, and common lookup wording. Escalate scope automatically when a query implicates original ingested material rather than a Brain summary.
- Use brain_list_sources (optional category filter) to discover source files.
Ingestion: call `brain_prepare_ingest` before any source or Brain-content write. A filesystem-backed Brain can use `brain_scan_inbox`, `brain_ingest`, and `brain_ingest_complete` directly. A hosted Postgres Brain has no Fly-local inbox or source tree: preserve source bytes, provenance and inbox cleanup through its local Monitor/operator workflow, then use hosted revision tools only for reviewed Brain writes and `brain_log` receipts.
This works for both Claude Code and Cowork (both read ~/.claude/CLAUDE.md).
Step 3: User preferences (Claude Desktop / claude.ai — manual)
Claude Desktop and claude.ai do not read CLAUDE.md. For these clients, add the conditional auto-load directive to your user preferences (Settings → Profile → User preferences).
See MANUAL_SETUP.md for the exact text to paste, verification tests, and a troubleshooting checklist.
Note: This step requires manual entry in each client's preferences UI. It cannot be automated.
How It Works
- Claude calls
brain_load_contextat session start (automatically, if configured per above) - The response includes the loader, NOW.md, and nudges (lint overdue, capture queue stale or oversized, open maintenance issues, pending inbox files)
- Claude reads the navigation table and requests specific files via
brain_read_file - Edits are written via
brain_update_file, then committed viabrain_commit - New information is processed via
brain_ingest(dry-run analysis, then guided updates) - Changes are tracked via
brain_log; health is checked viabrain_lint
The routing logic lives in the loader (a Markdown file you maintain), not in code. The server is content-agnostic — it knows nothing about your specific Brain content, only how to serve Markdown files.
Brain files may cross-reference each other with [[wikilinks]], relative Markdown links, backtick file/directory references, and configured SharePoint mappings. Legacy lint remains the default; graph_shadow computes convention-aware reachability from 00_loader.md, NOW.md, and configured roots without changing enforcement. The Brain directory can be opened as an Obsidian vault for graph view and backlink navigation.
Brain Routing Evals
The repo includes a read-only deterministic eval lane for loader and routing regressions:
npm run eval:brain:routing -- --jem-dir "/path/to/ai-brain-jem/brain" --ers-dir "/path/to/ers-brain/brain"
The golden set lives in evals/brain-routing/golden.json. The evaluator uses the production ranking code, reports policy markers separately from retargetable signposts, and records bootstrap/follow-up-read/latency metrics. Run the frozen server fixture with npm run eval:brain:routing -- --fixtures evals/brain-routing/fixtures/server-foundation.json. See docs/specs/008-brain-routing-evals.md.
Recommended Workflow
The MCP server works from any Claude client, but different tasks suit different clients:
| Activity | Best client | Why |
|---|---|---|
| Using Brain in conversation | Chat (any client with MCP) | All read/write tools work over stdio — no uploads needed |
| Small updates (NOW.md, tasks, journal) | Chat | brain_update_file + brain_commit handle it directly |
| Large document ingestion | Cowork or Code | Multi-step workflow needs filesystem access to sources/ |
| Drop-folder ingestion | Any (via scheduled task) | Drop files into inbox/, daily task processes them automatically |
| Server code maintenance | Code | Iterative build-test-commit cycle |
| Brain repo git operations | Code | Shell access for rebasing, conflict resolution, pushing |
| Graph view & knowledge mapping | Obsidian | Open brain/ as a vault for graph visualization, backlink navigation, and orphan detection |
Chat is the primary interface for day-to-day Brain usage — loading context, searching, editing files, committing. Cowork or Code are needed when the workflow requires direct filesystem access (e.g., saving source documents) or agentic multi-step operations. Code is the right tool for maintaining the server codebase itself.
For the full methodology, see the AI Brain Primer.
Related Projects
- ai-brain-primer — Framework and methodology for building an AI Brain
- ai-brain-jem — Example private Brain implementation (private repo)
License
MIT