md-annotate
A local-first markdown review tool with MCP integration, enabling AI and humans to collaboratively annotate documents inline and generate revision prompts.
README
md-annotate
A shared markdown review surface between Claude (via MCP) and humans (via browser). Push markdown documents, annotate them inline like a GitHub PR review, and generate structured revision prompts — all in a local-first workflow.
How it works
┌────────────────┐ ┌────────────────┐ ┌────────────────┐
│ Claude │ MCP tools │ md-annotate │ Browser UI │ Human │
│ (or any AI) │ ══════════════>│ daemon │<══════════════ │ (reviewer) │
│ │ <══════════════│ │ ══════════════>│ │
└────────────────┘ push / read └────────────────┘ annotate/view └────────────────┘
- Claude pushes a markdown document via the
md_pushMCP tool - Human reviews in the browser — select text, add inline annotations (like PR review comments)
- Claude reads annotations via
md_get_annotationsand revises the document - Repeat until done
Quick start
# Clone and install
git clone https://github.com/alaeddineG/md-annotate.git
cd md-annotate
npm install
# Build the UI
npm run build
# Start the daemon
npm start
# → http://localhost:4242
Or use the setup script which handles everything including the MCP bridge:
# macOS / Linux
chmod +x setup.sh
./setup.sh
# Windows (PowerShell)
.\setup.ps1
MCP integration
md-annotate exposes four tools to Claude via the Model Context Protocol:
| Tool | Description |
|---|---|
md_push |
Push a markdown document for review |
md_get_annotations |
Read all human annotations on a document |
md_list_documents |
List all documents in the review queue |
md_clear_annotations |
Clear annotations after incorporating feedback |
Claude Desktop (stdio transport)
Add to your Claude Desktop MCP config:
{
"mcpServers": {
"md-annotate": {
"command": "npx",
"args": ["md-annotate", "mcp"]
}
}
}
Standalone MCP bridge
For environments where the MCP bridge needs to live outside the project directory (e.g. macOS sandbox restrictions with Claude Desktop):
# Build the self-contained bridge
npm run build:mcp
# Copy it somewhere accessible
mkdir -p ~/.mcp_servers/md-annotate
cp mcp-bridge.js ~/.mcp_servers/md-annotate/
Then configure Claude Desktop:
{
"mcpServers": {
"md-annotate": {
"command": "node",
"args": [
"/Users/you/.mcp_servers/md-annotate/mcp-bridge.js",
"--daemon-url", "http://localhost:4242"
]
}
}
}
Remote daemon
If the daemon runs on a different machine:
{
"mcpServers": {
"md-annotate": {
"command": "npx",
"args": ["md-annotate", "mcp", "--daemon-url", "http://192.168.1.100:4242"]
}
}
}
CLI
md-annotate start [--port 4242] [--host 0.0.0.0] Start the daemon
md-annotate stop Stop the daemon
md-annotate status Show daemon status
md-annotate open Open UI in browser
md-annotate push <file.md> [--id ID] [--context ""] Push a file for review
md-annotate mcp [--daemon-url <url>] Run MCP stdio bridge
Architecture
md-annotate/
├── bin/cli.js # CLI entry point
├── server/
│ ├── daemon.js # Express server (REST API + SSE + static files)
│ ├── mcp.js # MCP server (stdio + HTTP transports)
│ └── store.js # File-based document/annotation storage
├── src/ # React frontend (Vite + @primer/react)
│ ├── App.jsx # Main app with SSE real-time updates
│ └── components/
│ ├── RawView.jsx # Raw markdown with inline review threads
│ ├── MarkdownPreview.jsx # Rendered markdown preview
│ ├── SelectionPopover.jsx # Text selection → annotation popover
│ ├── DocumentList.jsx # Sidebar document list
│ ├── ModeToggle.jsx # Raw/Preview toggle
│ └── PromptGenerator.jsx # Generate revision prompt from annotations
├── mcp-standalone.js # Entry point for standalone MCP bridge
├── setup.sh # Setup script (macOS/Linux)
└── setup.ps1 # Setup script (Windows)
Storage: Documents and annotations are persisted as JSON files under ~/.md-annotate/documents/.
Real-time: The browser connects via Server-Sent Events (SSE) so annotations and document updates appear instantly — whether created from the UI or pushed via MCP.
Development
# Start Vite dev server (hot reload) + proxy to daemon
npm run dev
# In another terminal, start the daemon
node server/daemon.js
Platform support
Works on macOS, Linux, and Windows. The daemon, CLI, and MCP bridge are pure Node.js with no native dependencies. The setup.sh script is bash-only (macOS/Linux) — on Windows, run the steps manually or use WSL.
Requirements
- Node.js >= 18
- A browser
- Claude Desktop or any MCP-compatible client (for the AI side)
License
MIT
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.