An MCP server that lets an AI agent read, write, and organize your HackMD notes, and keep them in sync with Markdown files on your own disk.
HackMD is where meeting notes, lecture handouts, and team specs end up. Working on them with an agent usually means copying a note into a chat, copying the answer back, and hoping nobody edited the note in between. This server removes that loop and the risks that come with it:
- Ask in plain language. "Summarize this week's meeting notes in the
opsteam", "fix the broken links in https://hackmd.io/@me/syllabus", or "move the action items into a new note underProjects". The agent finds notes by ID or by the URL you paste, across your personal and team workspaces. - Body edits touch only the lines they mean to. The agent changes a note with a context-checked patch, not by rewriting the whole body, so a typo fix stays a typo fix, and it can pass along the hash it read to refuse the write if the note changed in between. See patch editing.
- Notes become local files. Pull a note into a
.mdfile, then edit it with your editor, grep it, diff it, or commit it to git. Push sends it back, and if the note also changed on HackMD the push stops and hands you both versions instead of overwriting either. See sync. - Edits are confirmed, not assumed. HackMD may show a write only after a delay, so body edits and folder changes are read back before they are reported as done. A write whose outcome is unknown is reported as such and never retried blindly, so you do not get duplicate notes.
- Local file access can be fenced in. Set a workspace root and every local path stays inside it; without one, a pull still refuses to write the files agents load as instructions. Your API token never appears in any output. See configuration.
The server runs on your machine as a child process of your agent and talks to it over stdio. Nothing listens on a network port.
Every push to main that passes CI replaces a rolling latest
release.
Pick the archive for your platform:
| Platform | Archive |
|---|---|
| Linux x86_64, glibc 2.17 or newer | hackmd-mcp-x86_64-unknown-linux-gnu.tar.gz |
| macOS Apple silicon | hackmd-mcp-aarch64-apple-darwin.tar.gz |
| Windows x86_64 | hackmd-mcp-x86_64-pc-windows-msvc.zip |
On Linux or macOS, set asset to the archive from the table above (where
sha256sum is missing, as on older macOS, use shasum -a 256 in its place):
asset=hackmd-mcp-x86_64-unknown-linux-gnu.tar.gz
base=https://github.com/sysprog21/hackmd-mcp/releases/download/latest
curl -sSfLO "$base/$asset" -O "$base/SHA256SUMS"
grep " $asset\$" SHA256SUMS | sha256sum -c - &&
tar xzf "$asset" &&
mkdir -p ~/.local/bin &&
install -m 755 hackmd-mcp ~/.local/bin/The checksum catches a corrupt download. To also confirm the archive was built
by this repository's CI from a commit on main, run:
gh attestation verify "$asset" --repo sysprog21/hackmd-mcp \
--source-ref refs/heads/main \
--signer-workflow sysprog21/hackmd-mcp/.github/workflows/ci.ymlOn Windows, download the zip from the release page and extract
hackmd-mcp.exe. Other platforms build from source with Rust 1.88 or newer:
cargo install --git https://github.com/sysprog21/hackmd-mcp --lockedCreate an API token under HackMD's Settings, API, and pick a directory for notes you pull to disk. Put both in the environment your agent is launched from, such as your shell profile:
export HACKMD_API_TOKEN=...
export HACKMD_MCP_WORKSPACE_ROOT=$HOME/notes
mkdir -p "$HACKMD_MCP_WORKSPACE_ROOT"The workspace root is optional but recommended: it confines every local file operation and enables image upload. The server reads both at startup, so restart your agent after changing them. Keep the token out of chat, logs, and shared config files; docs/configuration.md has the details.
~/.local/bin/hackmd-mcp --self-check --probe-apiIt prints a JSON report and exits nonzero if anything is wrong, without ever
printing the token. Its commit field, also shown by --version, names the
commit the binary was built from, with -dirty when that checkout had
uncommitted edits to its sources (so two dirty builds of one commit look
alike); it is absent for a build made outside a git checkout. If it is not the
commit you expect, the installed binary is stale: install the new one and
restart your agent, since a running agent keeps the server it started.
Claude Code:
claude mcp add --scope user hackmd -- ~/.local/bin/hackmd-mcpClaude Desktop, Codex, and other clients need a few more lines, mostly to pass the environment through; see docs/clients.md. Then ask your agent something like "list my recent HackMD notes".
Fourteen tools, kept few on purpose so they cost the agent little context:
| Area | Tools |
|---|---|
| Account | hackmd_get_me (profile and teams) |
| Notes | hackmd_list_notes, hackmd_get_note, hackmd_create_note, hackmd_update_note, hackmd_delete_note, hackmd_upload_note_image |
| Folders | hackmd_list_folders, hackmd_create_folder, hackmd_update_folder, hackmd_delete_folder |
| Local sync | hackmd_pull_note, hackmd_push_note, hackmd_untrack_note |
docs/tools.md walks through the editing and sync workflows.
- docs/configuration.md: environment variables, token handling, state directory, workspace root, self-check, logging.
- docs/clients.md: wiring the server into Claude Code, Claude Desktop, Codex, and other MCP clients.
- docs/tools.md: the tools, patch editing, and the pull/edit/push cycle with conflict handling.
- docs/development.md: building, testing, the live API suites, and why the server is stdio only.
MIT. See LICENSE.