Mcp Brain — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited Mcp Brain (Agent Skill) and scored it 92/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 2 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 2 flagged
The text {match} tells the agent to skip the normal "ask the user first" gate. Used adversarially it removes the human-in-the-loop check before destructive or sensitive actions, turning a normally-gated agent into a fire-and-forget executor.
The text {match} tells the agent to skip the normal "ask the user first" gate. Used adversarially it removes the human-in-the-loop check before destructive or sensitive actions, turning a normally-gated agent into a fire-and-forget executor.
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
A personal second brain that runs on Cloudflare Workers. Everything is a node in a semantic knowledge graph — thoughts, tasks, people, books, bookmarks, and any custom type you define. Nodes auto-link based on meaning, deduplicate intelligently, and are fully searchable through the Model Context Protocol (MCP).
Built for AI agents. You talk to your AI assistant, and it remembers things for you — no manual note-taking, no app-switching, no friction.
You ←→ AI Assistant ←→ MCP Brain (Cloudflare Worker) ←→ Supabase Postgres + pgvector
↕
Cloudflare Workers AI
(embeddings, dedup, synthesis)You'll need free accounts on two platforms:
git clone https://github.com/YOUR_USERNAME/mcp-brain.git
cd mcp-brain
pnpm install-- Enable pgvector
create extension if not exists vector;
-- Node types (e.g. thought, action, person, bookmark)
create table mb_node_types (
name text primary key,
description text not null,
schema jsonb not null default '{}',
created_at timestamptz not null,
embedding vector(1024)
);
create index mb_node_types_embedding_idx on mb_node_types
using hnsw (embedding vector_cosine_ops);
-- Nodes (the actual knowledge)
create table mb_nodes (
id uuid primary key,
type text not null references mb_node_types(name),
metadata jsonb not null default '{}',
created_at timestamptz not null,
embedding vector(1024),
access_count integer not null default 0,
last_accessed timestamptz
);
create index mb_nodes_type_idx on mb_nodes(type);
create index mb_nodes_created_at_idx on mb_nodes(created_at);
create index mb_nodes_embedding_idx on mb_nodes
using hnsw (embedding vector_cosine_ops);
-- Links between nodes (bidirectional, scored)
create table mb_node_links (
node_a_id uuid not null references mb_nodes(id),
node_b_id uuid not null references mb_nodes(id),
label text,
metadata jsonb not null default '{}',
created_at timestamptz not null,
score real not null default 0.5,
primary key (node_a_id, node_b_id)
);
create index mb_node_links_a_idx on mb_node_links(node_a_id);
create index mb_node_links_b_idx on mb_node_links(node_b_id);
create index mb_node_links_score_idx on mb_node_links(score);
-- Tags
create table mb_tags (
name text primary key,
kind text not null default 'tag',
created_at timestamptz not null,
embedding vector(1024)
);
create index mb_tags_embedding_idx on mb_tags
using hnsw (embedding vector_cosine_ops);
-- Node ↔ Tag junction
create table mb_node_tags (
node_id uuid not null references mb_nodes(id),
tag_name text not null references mb_tags(name),
primary key (node_id, tag_name)
);
-- Key-value settings
create table mb_settings (
key text primary key,
value jsonb not null
);
-- Skills (reusable instruction sets)
create table mb_skills (
name text primary key,
description text not null,
content text not null,
embedding vector(1024),
created_at timestamptz not null,
updated_at timestamptz not null
);
create index mb_skills_embedding_idx on mb_skills
using hnsw (embedding vector_cosine_ops); postgresql://postgres.xxxx:[email protected]:6543/postgrespnpm add -g wranglerwrangler loginwrangler kv namespace create OAUTH_KVid from the output and update wrangler.jsonc:{
"kv_namespaces": [
{
"binding": "OAUTH_KV",
"id": "YOUR_KV_NAMESPACE_ID"
}
]
}# Your Supabase connection string (the pooler URI from step 2)
wrangler secret put SUPABASE_DB_URL
# An API key you choose — this is your password to the brain
wrangler secret put BRAIN_API_KEYPick any strong string for BRAIN_API_KEY — you'll use it to authenticate.
pnpm run deployYour brain is now live at https://mcp-brain.YOUR_SUBDOMAIN.workers.dev.
Create a .dev.vars file at the project root:
SUPABASE_DB_URL=postgresql://postgres.xxxx:[email protected]:6543/postgres
BRAIN_API_KEY=your-secret-keyThen run:
pnpm run devMCP Brain exposes an MCP server. Any MCP-compatible client can connect to it.
Add to your MCP server configuration:
{
"mcpServers": {
"mcp-brain": {
"url": "https://mcp-brain.YOUR_SUBDOMAIN.workers.dev/mcp/oauth",
"type": "streamable-http"
}
}
}When you first connect, your browser will open an authorization page. Enter your BRAIN_API_KEY to authenticate. The key can be saved in your browser's local storage for convenience.
CLI clients can skip OAuth and use Bearer token auth directly:
{
"mcpServers": {
"mcp-brain": {
"url": "https://mcp-brain.YOUR_SUBDOMAIN.workers.dev/mcp",
"type": "streamable-http",
"headers": {
"Authorization": "Bearer YOUR_BRAIN_API_KEY"
}
}
}
}MCP Brain supports two auth methods:
| Method | Endpoint | Use case |
|---|---|---|
| OAuth 2.0 | /mcp/oauth | Browser-based clients (Claude Desktop, claude.ai) |
| Bearer token | /mcp | CLI tools, scripts, API calls |
For Bearer auth, set the header: Authorization: Bearer YOUR_BRAIN_API_KEY
/mcp/oauth/authorize — a simple HTML formBRAIN_API_KEYThe authorize page supports saving your key in browser local storage so you don't re-enter it every time.
Send your BRAIN_API_KEY as a Bearer token:
curl -X POST https://mcp-brain.YOUR_SUBDOMAIN.workers.dev/mcp \
-H "Authorization: Bearer YOUR_BRAIN_API_KEY" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"tools/list","id":1}'MCP Brain exposes 20 tools organized into 5 categories:
| Tool | Description |
|---|---|
create_type | Define a new node type with a metadata schema (e.g. "recipe", "goal") |
list_types | List all node types and their schemas |
update_type | Update a type's description or schema |
delete_type | Delete a type (fails if nodes of that type exist) |
| Tool | Description |
|---|---|
create_node | Save a node — auto-deduplicates, auto-links, resolves tags |
search_nodes | Semantic + temporal search with filters (type, tags, date, sort) |
update_node | Update metadata (merged) or tags (replaced) |
delete_node | Delete a node and all its links/tags |
batch_update | Add/remove tags on up to 50 nodes at once |
| Tool | Description |
|---|---|
link_manager | Manually create or remove links between nodes |
explore_connections | Browse a node's connections, sort by strongest/weakest |
| Tool | Description |
|---|---|
list_tags | List all tags with counts and kinds, filterable by type or kind |
update_tag | Rename a tag or change its kind (e.g. mark as "project") |
forgotten_nodes | Surface least-accessed nodes you may have forgotten |
consolidate_node | AI-powered: extract facts from linked nodes to enrich a sparse profile |
get_stats | Brain overview: node counts by type, total links, total tags |
set_setting | Configure brain settings (currently: timezone) |
| Tool | Description |
|---|---|
list_skills | List all stored skills |
load_skill | Load a skill's instructions for the AI to adopt |
manage_skill | Create, update, or delete skills |
MCP Brain includes system prompts that teach your AI assistant how to use the brain naturally. Choose the one that fits your setup:
| File | Description |
|---|---|
system-prompt-base.md | Full behavioral guide — brain usage, anti-sycophancy, response style. Good default. |
system-prompt-claude-code.md | Lightweight version for dev sessions in Claude Code. Focuses on saving design decisions and architecture insights. |
system-prompt-tiny.md | Minimal version (~50 lines) for local models with small context windows (LM Studio, Ollama, etc.). |
Claude Desktop / claude.ai: Copy the content of your chosen system prompt into the "Custom Instructions" or "System Prompt" field in your client settings.
Claude Code: The system-prompt-claude-code.md content goes into ~/.claude/CLAUDE.md (your global instructions file).
LM Studio / Ollama / local models: Use system-prompt-tiny.md as the system message. It's optimized for small context windows.
API usage: Pass the system prompt content as the system message in your API calls.
All prompts instruct the AI to:
All AI processing runs on Cloudflare's free Workers AI tier:
| Model | Purpose |
|---|---|
@cf/baai/bge-m3 | Embeddings (1024-dim vectors) — multilingual, used for all semantic operations |
@cf/openai/gpt-oss-20b | Dedup decisions — quick LLM to confirm/deny merges in the 0.5–0.85 similarity range |
@cf/qwen/qwq-32b | Synthesis — extracts facts and connections from linked nodes for consolidation |
When you create a node, tag, or type, the system prevents duplicates:
New nodes are compared against all existing nodes. Any pair with cosine similarity between 0.5 and 0.92 gets linked automatically. The link score equals the similarity. Links below 0.92 aren't created (too similar — likely the same thing, handled by dedup). Links are bidirectional.
A cron job runs daily at 3 AM UTC and prunes links with scores below the prune_threshold setting (default: 0.2). This removes weak connections that accumulate over time.
Configure via the set_setting tool:
| Setting | Description | Default |
|---|---|---|
timezone | IANA timezone for date queries (e.g. "Europe/Paris") | None (required for since filter) |
Internal settings (managed automatically):
| Setting | Description | Default |
|---|---|---|
decay_factor | Multiplier applied to link scores during consolidation | 0.7 |
prune_threshold | Links below this score are pruned by the daily cron | 0.2 |
src/
├── index.ts # Entry point: OAuth provider, MCP handler, cron
├── mcp.ts # All 20 MCP tool registrations
├── nodes.ts # Node CRUD, search, auto-linking, consolidation
├── types.ts # Node type management
├── dedup.ts # 3-tier deduplication (types, nodes, tags)
├── ai.ts # Workers AI calls (embeddings, LLM, synthesis)
├── schema.ts # Drizzle ORM schema (7 tables)
├── database.ts # Supabase postgres.js connection
├── settings.ts # KV-cached settings layer
├── validation.ts # Metadata schema validation
├── skills.ts # Skills CRUD
└── env.ts # Environment interface, thresholds
system-prompt-base.md # Full system prompt
system-prompt-claude-code.md # Dev session variant
system-prompt-tiny.md # Minimal for local models
wrangler.jsonc # Cloudflare Workers configAfter deploying, the brain is empty. Start by creating the node types you need:
"Create a 'thought' type for ideas and insights, an 'action' type for tasks, a 'person' type for people I mention, and a 'bookmark' type for links."
The AI will create these with sensible schemas. You can customize later.
You don't need to explicitly tell your AI to "save to brain" — the system prompt handles that. Just talk naturally:
Tags emerge organically. The AI reuses existing tags when possible. To track a project:
"Mark 'mcp-brain' as a project tag."
Then ask "what are my projects?" anytime.
The brain gets more valuable over time. Try:
On free tiers:
For personal use, you're unlikely to hit any limits.
MIT
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.