Discover MCPs & agents
Loading MCPs and agents…
Loading MCPs and agents…
Self-improving, AI-native markdown vault you hand to an AI agent. GitHub-style file tree + Notion editing, exposed to Claude/Cursor via a built-in MCP server (24 tools): semantic & hybrid search, RAG, cited answers. Learns your voice from your edits; human-approved review queue. Local-first .md.
From the repo.
Own the context. Rent the memory.
Your notes stay plain .md files you own — bring any AI model and swap it whenever you like.
A local-first markdown vault you can hand to an AI agent — and it gets better the more you use it. Browse it like a GitHub file tree, edit it like Notion, and plug it into Claude, Cursor, or any MCP host as 27 agent tools — semantic & hybrid search, RAG context, and cited answers. The vault self-improves: it learns your writing voice from your draft→final edits and self-tidies broken links, orphans, and duplicates — every change lands in a human-in-the-loop review queue where agents propose and you decide. Plain
.mdfiles, runs offline, no API key required.
If you’ve ever wanted your markdown content to be:
this project is for you.
Most note/documentation tools force a tradeoff:
This repo bridges both worlds:
etag / lastModified)CONTENT_ROOT (the "vault")[[wikilinks]], browse backlinks, and explore an
interactive knowledge graphThis isn't just a file browser — the vault is built to double as an AI agent's brain, with a human always in control. Everything below runs locally and offline by default (no API key needed), and anything an agent wants to change in your notes goes through a review queue you approve.
semantic search ranks by relevance and hybrid search fuses keyword +
semantic results. Great for "I know I wrote this somewhere…". Runs offline
on a built-in TF-IDF ranker by default; flip on real embeddings (below)
when you want stronger synonym/paraphrase matching.think). Ask a question and get a cited answer
assembled from your own notes — plus an honest list of gaps when the vault
can't fully answer, so you know what's missing.type: (person,
meeting, project, idea…) and the graph colours it by what it is, agents
learn the canonical types to author well-formed notes, and the maintenance scan
flags notes that break the vocabulary — all from plain frontmatter, no database.FSBRAIN_EMBEDDINGS=on with an API key and the same
search routes rank by dense vector similarity instead, so paraphrases and
synonyms that share no keywords still match. It's a drop-in swap: nothing
downstream (semantic/hybrid search, think, RAG context) changes, only the
scoring improves. Vectors are cached to .fsbrain/embeddings.json so a
restart re-embeds only changed notes, and the engine falls back to TF-IDF
on any provider outage — "off" is always a working search. See the
FSBRAIN_EMBEDDINGS env vars below.The throughline: agents propose, you decide. Risky or outward-facing changes are never applied automatically — they become reviewable proposals attributed to a named actor (e.g.
agent:maintenance,agent:feedback-loop), so you always see who suggested what.
The feedback loop in 30 seconds:
social/x/drafts/launch.md.social/x/old-posts/launch.md.type: feedback,
channel: x, draftPath, finalPath, and an optional reviewReason).run_feedback agent tool (or POST /api/feedback/scan). It compares
the two, distills the lesson into a channel playbook, and files it as a
proposal you approve in the Review tab.apps/web (React + Vite)
├─ File tree + editor / preview / graph / activity UI
└─ Calls the API over HTTP/JSON (live updates over SSE)
apps/api (Node HTTP server)
├─ Validates and resolves logical paths (sandboxed to CONTENT_ROOT)
├─ Markdown-focused file CRUD + optimistic concurrency
└─ Search (text/semantic/hybrid), backlinks, graph, think, audit, proposals
apps/mcp (MCP stdio server)
├─ Exposes the vault to AI agents as 27 tools
└─ Embeds the API in-process — one self-contained command for an MCP host
packages/shared
└─ Shared TypeScript contracts + pure helpers (markdown, search, graph, …)
Repository structure:
apps/
api/ # Backend HTTP server + filesystem storage (CONTENT_ROOT)
web/ # Frontend UI (React + Vite)
mcp/ # MCP stdio server — the vault as agent tools (embeds the API)
packages/
shared/ # Shared types/contracts + pure helpers
docs/
implementation.md # Source of truth for project state
CONNECT.md # Connect an MCP host (OpenClaw / Claude / Cursor)
integration-test-plan.md # Manual integration checks
AGENTS.md # Start here if you are an AI agent working in this repo
npm install
Terminal A:
npm run dev:api
Terminal B:
npm run dev:web
http://localhost:5173http://localhost:3001/healthSkip the web UI and hand the vault to an MCP-aware agent (OpenClaw, Claude Desktop, Claude Code, Cursor, …):
git clone https://github.com/andylow92/file-system-like-github.git
cd file-system-like-github
npm install
npm run build # produces apps/mcp/dist/server.js
npm run start:agent # launches the self-contained fsbrain-mcp on stdio
fsbrain-mcp embeds the storage API in-process and auto-creates the vault
at ~/.fsbrain/vault (override with CONTENT_ROOT=...). It exposes 27
vault tools (list_notes, read_note, create_note, patch_note,
semantic_search, hybrid_search, think, get_graph, propose_edit,
run_maintenance, list_skills, curate_skills, run_feedback, proposal_stats, …) and records every agent write to
<vault>/.fsbrain/audit.jsonl so you can always see what the agent did.
Copy-paste config snippets for OpenClaw / Claude Desktop / Claude Code
/ Cursor are in docs/CONNECT.md.
Heads-up if you have an older clone. The default
CONTENT_ROOTis now~/.fsbrain/vault(previously<cwd>/content). Existing./contentnotes aren't deleted, butnpm run dev:api/npm run dev:web/npm run start:agentwithoutCONTENT_ROOTset will now read the new path. SetCONTENT_ROOT=./content(inapps/api/.envor your shell) to keep the old location.
An opt-in integration that lets connected agents run structured, auditable prospect research. It is disabled by default — vaults that do no prospect research never see the tools or get asked to configure anything.
<vault>/.fsbrain/integrations.json (owner-only, never in
a note, never committed) and is never shown again once saved.npm run start:agent) and reconnect your
agent. The server decides which tools to register at startup, so the
rocketreach_* tools do not appear in an already-running session. Turning the
integration off needs no restart — calls fail closed immediately.rocketreach_get_account_status,
rocketreach_start_intake (standardized intake questions to ask before
spending credits), rocketreach_search_contacts (search-only — no paid
lookups), and rocketreach_lookup_contacts (paid enrichment, which requires
an explicit maxLookups cap and never exceeds it).prospects/… notes with full provenance (actor, timestamp,
normalized parameters, credit deltas).For apps/api:
CONTENT_ROOT
~/.fsbrain/vault (auto-created on first run).CONTENT_ROOT=./content to keep an older clone's location.PORT
3001).FSBRAIN_EMBEDDINGS
1/true/on/yes turns it on); when off, semantic search uses the
fully-offline TF-IDF engine — no network, no key, exactly as before.EMBEDDINGS_API_KEY (falls back to
OPENROUTER_API_KEY). If the provider is unreachable or misconfigured,
retrieval automatically falls back to TF-IDF, so "off" is always a working
search — flip the flag off and restart to revert entirely.EMBEDDINGS_MODEL (default
openai/text-embedding-3-small), EMBEDDINGS_URL (any OpenAI-compatible
/v1/embeddings endpoint; default OpenRouter), EMBEDDINGS_BATCH_SIZE
(default 96).<CONTENT_ROOT>/.fsbrain/embeddings.json so a restart
re-embeds only changed notes. The file is safe to delete (it rebuilds on
demand) and is tagged with the model, so switching EMBEDDINGS_MODEL
invalidates it automatically.Example:
CONTENT_ROOT=/absolute/path/to/vault PORT=3001 npm run dev:api
# Opt into embedding-based semantic search:
FSBRAIN_EMBEDDINGS=on EMBEDDINGS_API_KEY=sk-... npm run dev:api
Files & tree
GET /healthGET /api/tree?path=...GET /api/file?path=... (or ?id=...)POST /api/file · PUT /api/file · PATCH /api/file (granular ops)POST /api/dirPATCH /api/path (move/rename) · DELETE /api/path?path=...&recursive=true|falseLinks, graph & blocks
GET /api/backlinks · GET /api/graphGET /api/block · GET /api/block-anchorsSearch & retrieval
GET /api/search · GET /api/semantic-search · GET /api/hybrid-searchGET /api/context (RAG bundle) · GET /api/think (cited answer kit)Provenance, review & maintenance
GET /api/auditGET /api/proposals · POST /api/proposals · POST /api/proposals/resolve (human-only)GET /api/proposals/stats (review-queue approval rates + threshold nudges)GET /api/maintenance · POST /api/maintenance/scanGET /api/skills/curator (report-only skill-library curator)GET /api/feedback · POST /api/feedback/scanLive
GET /api/events (Server-Sent Events)For endpoint details and request/response examples, see apps/api/README.md.
Agents typically reach these via the MCP tools — see apps/mcp/README.md.
npm test
npm run lint
npm run format
.md).CONTENT_ROOT.This helps protect the host filesystem while still enabling file-based workflows.
For persistent content in production, mount a host volume and point CONTENT_ROOT to it.
See the full deployment examples in this README’s history and backend docs.
think) and dream-cycle maintenancetype:s, graph colouring, validation```mermaid blocks render as SVG in the previewPRs are welcome. If you want to contribute:
AGENTS.md — repo entry point + a
tool/endpoint quick-referencedocs/implementation.mdapps/api/README.mdapps/mcp/README.mddocs/CONNECT.mddocs/integration-test-plan.mdAI-native: MCP server, Model Context Protocol, AI agent tools, agent memory, self-improving knowledge base, learns-from-edits feedback loop, self-healing maintenance, agentic RAG, retrieval-augmented generation, semantic search, hybrid search (RRF), vector-ready knowledge base, Claude / Cursor / OpenClaw integration, second brain for LLMs, human-in-the-loop, agent proposals & audit log, cited answers.
Markdown workspace: github-like file tree, notion-style markdown editor, local-first markdown vault, filesystem CMS, markdown knowledge base, wikilinks & backlinks, knowledge graph, react markdown editor, node filesystem api, PKM.
Replace {MCP_ENDPOINT_URL} with this MCP’s endpoint URL (from its repo or docs above). No API key — you connect directly.
Tool
OS
Config file: ~/.cursor/mcp.json
{
"mcpServers": {
"mcp-server": {
"url": "{MCP_ENDPOINT_URL}"
}
}
}Paste into mcpServers in the config file. Restart Cursor after saving.
If this MCP is also published on mcpchannel.ai, you can subscribe from Browse and use the gateway config there instead.