Wiki Reader MCP
Live · v0.1I build a lot of projects, and they don't stay independent: a decision in one turns out to matter in another. Each keeps its reasoning in a committed .wiki/, but that memory is trapped on whatever machine holds the repo. This server lifts it out: read another project's wiki remotely, without cloning the whole thing down.
.wiki/, and pushes the change back. Git is the only store, and the project never lands on your machine.Why I built it
Every project I build already keeps its own memory: a committed .wiki/ directory holding the architecture, the active rules, the decisions (ADR-style), and the gotchas we hit once and never want to hit again. On its own project, that works great. The wiki isn't the problem I'm solving.
The problem shows up once you have many projects. They stop being independent, a decision I made in one starts to matter in another, and the reason I did something over there is exactly what I need to rediscover while I'm working over here. But that reasoning lives in another repo, maybe on another machine, and the last thing I want is to clone an entire unrelated project onto this box just to read a few pages of its wiki.
So I wrote a server that reads the wiki where it already lives. It holds the clone remotely and hands back just the structured pages you ask for. The knowledge travels; the project doesn't have to.
What it does
It's a Model Context Protocol server. It operates on remote wiki repos: hand it a git URL, it clones into a cache on whatever host runs the server (not your machine), reads or writes under .wiki/, and pushes the change back. Every write is a single atomic commit and push, so the git history is the audit log.
- Read tools pull structure out, not just text:
wiki_get_ruleby ID,wiki_list_decisions/wiki_read_decision,wiki_list_specs/wiki_read_spec, plus a plainwiki_read_page. - Write tools are structured, never free-form overwrite:
wiki_add_rule,wiki_create_adr(with correct numbering),wiki_append_gotcha,wiki_create_spec, andwiki_set_spec_status(mark a spec implemented or abandoned). - A graph tool.
wiki_relatedwalks the wiki's citation graph, theSource:fields, relative links, andR-NNN/ADR/specid tokens, and bundles up the docs related to a target: both what it references and what references it (backlinks).
Every tool takes a repoUrl, but it's optional once a default is set: explicit argument wins, then a session default (wiki_use_repo), then an environment variable.
Auth, without a database
GitHub access uses the OAuth device flow: call github_login, get a code and a URL, authorize in the browser, then call github_login_poll. The token is stored as a single credentials.json inside the cache root. That's the whole design philosophy: there is no database. Credentials are treated as disposable cache, so clearing the cache logs you out and drops the clones together.
One server, three ways to host it
The default transport is stdio, which is exactly what local Claude Code wants. To host it for remote agents or a web backend, a flag switches on a Streamable HTTP transport, which comes in three shapes:
- Single-tenant: one shared bearer token, one GitHub identity. It fails closed, with no token set in HTTP mode, the server refuses to start.
- Multi-tenant: one endpoint where each user signs in as themselves, with per-session in-memory tokens and isolated clones. Nothing touches disk, so one session can never see another's working tree.
- OAuth connector: the server becomes its own GitHub-backed OAuth 2.1 authorization server, so a Claude custom connector shows a real "Sign in with GitHub" button and the login survives reconnects. Claude never sees the GitHub token.
You need a GitHub OAuth App client ID with the device flow enabled, passed as WIKI_READER_MCP_GITHUB_CLIENT_ID. Until that's set, the login tools have nothing to authorize against.
The bigger idea
A project's best documentation is the reasoning it already wrote down while it was being built. The waste is that this reasoning stays locked to one repo on one machine, so the moment you're working somewhere else it may as well not exist. Make it readable from anywhere, cheaply and remotely, and a pile of separate projects starts to behave like one connected body of knowledge you can query across.
The reasoning behind a project is worth the most when you're standing in a different one. It should be readable from there, without carrying the whole project along.
Juggling a dozen repos?
If your projects have started leaning on each other and you're tired of digging through old repos to remember why you did something, or you just want the code, get in touch. This is the kind of plumbing I like thinking about.