{%hackmd BJOT7rhoyl %} {%hackmd rJ_1SdPkxx %} # HackMD MCP Server Setup HackMD provides a remote [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server at `https://mcp.hackmd.io`. It lets AI assistants like Claude, Cursor, and Windsurf read and write your HackMD notes directly within the conversation — no copy-pasting required. ## Table of Contents - [Prerequisites](#prerequisites) - [Get an API Token](#get-an-api-token) - [Client Setup](#client-setup) - [Claude Desktop](#claude-desktop) - [Cursor](#cursor) - [Windsurf](#windsurf) - [Claude Code (CLI)](#claude-code-cli) - [Other MCP Clients](#other-mcp-clients) - [Available Tools](#available-tools) - [Available Resources](#available-resources) - [Troubleshooting](#troubleshooting) --- ## Prerequisites - A HackMD account (free or paid) - An MCP-compatible AI client (Claude Desktop, Cursor, Windsurf, etc.) - A HackMD API token (see below) --- ## Get an API Token 1. Sign in to [HackMD](https://hackmd.io). 2. Go to **Settings** → **API** (or visit `https://hackmd.io/settings#api`). 3. Click **Generate API Token**, give it a name, and copy the token. > Keep your token secret. Anyone who has it can read and modify your notes. --- ## Client Setup All clients connect using the same server URL and authentication header: | Field | Value | |-------|-------| | **Server URL** | `https://mcp.hackmd.io` | | **Transport** | Streamable HTTP | | **Auth header** | `Authorization: Bearer YOUR_API_TOKEN` | --- ### Claude Desktop 1. Open Claude Desktop. 2. Go to **Settings** → **Developer** → **Edit Config**. This opens `claude_desktop_config.json`: - macOS: `~/Library/Application Support/Claude/claude_desktop_config.json` - Windows: `%APPDATA%\Claude\claude_desktop_config.json` 3. Add the HackMD server: ```json { "mcpServers": { "hackmd": { "url": "https://mcp.hackmd.io", "headers": { "Authorization": "Bearer YOUR_API_TOKEN" } } } } ``` 4. Save the file and **fully restart Claude Desktop**. 5. Look for the tools icon in the chat input — clicking it should list HackMD tools. --- ### Cursor > **Coming soon — zero-config install:** The official HackMD plugin for Cursor is pending marketplace approval. Once published, installing it will automatically wire up the MCP server and skill without any manual steps below. Until the plugin is available, set up via `mcp-remote`. Cursor's MCP config supports `${env:VAR}` interpolation, so your API token stays out of config files. #### Step 1 — Set the environment variable Add your HackMD API token to your shell profile (`~/.zshrc`, `~/.bash_profile`, etc.): ```bash export HMD_API_ACCESS_TOKEN=YOUR_API_TOKEN ``` Then reload your shell or source the file: ```bash source ~/.zshrc ``` > Cursor inherits environment variables from the shell it was launched from. Set the variable in your profile **and fully restart Cursor** (not just reload the window) for it to take effect. #### Step 2 — Add to Cursor MCP config Create or edit `~/.cursor/mcp.json`: ```json { "mcpServers": { "hackmd-mcp": { "command": "npx", "args": [ "mcp-remote@0.1.38", "https://mcp.hackmd.io/", "--header", "Authorization:Bearer ${env:HMD_API_ACCESS_TOKEN}" ] } } } ``` Fully restart Cursor. The `hackmd-mcp` server will appear in the Composer tool list. #### Verify from terminal (optional) ```bash export HMD_API_ACCESS_TOKEN=YOUR_API_TOKEN npx mcp-remote@0.1.38 https://mcp.hackmd.io/ --header "Authorization:Bearer $HMD_API_ACCESS_TOKEN" ``` A successful connection prints the server's capabilities and exits cleanly. --- ### Windsurf 1. Go to **Windsurf Settings** → **Cascade** → **Model Context Protocol (MCP)**. 2. Click **Add Server**, or edit `~/.codeium/windsurf/mcp_config.json` directly: ```json { "mcpServers": { "hackmd": { "serverUrl": "https://mcp.hackmd.io", "headers": { "Authorization": "Bearer YOUR_API_TOKEN" } } } } ``` 3. Click **Refresh** in the MCP panel and confirm `hackmd` shows as connected. --- ### Claude Code (CLI) Run this command in your terminal: ```bash claude mcp add --transport http hackmd https://mcp.hackmd.io \ --header "Authorization: Bearer YOUR_API_TOKEN" ``` Confirm the server is registered: ```bash claude mcp list ``` You should see `hackmd` in the list. The tools are available in any `claude` session from that point on. --- ### Other MCP Clients Any client that supports the [Streamable HTTP transport](https://modelcontextprotocol.io/docs/concepts/transports#streamable-http) can connect. Use this generic config: ```json { "mcpServers": { "hackmd": { "url": "https://mcp.hackmd.io", "headers": { "Authorization": "Bearer YOUR_API_TOKEN" } } } } ``` No local process or Docker container is required — the server is fully hosted. --- ## Available Tools ### Note Tools | Tool | Description | Parameters | |------|-------------|------------| | `list-notes` | List all notes accessible to you. Returns metadata only — use `get-note` for content. | `page` (default: 1), `limit` (default: 20, max: 50) | | `get-note` | Retrieve the full content of a note. | `noteId` (note ID or short ID) | | `create-note` | Create a new markdown note. | `content` (required), `title` (optional) | | `update-note` | Overwrite the content of an existing note. | `noteId`, `content` | | `delete-note` | Move a note to trash. | `noteId` | | `get-history` | Get recently accessed notes. Returns metadata only. | `limit` (default: 20, max: 200) | ### Team Tools | Tool | Description | Parameters | |------|-------------|------------| | `list-teams` | List all teams you belong to. | — | | `get-team` | Get details about a specific team. | `teamPath` | | `list-team-notes` | List notes in a team. Returns metadata only. | `teamPath`, `page` (default: 1), `limit` (default: 20, max: 50) | | `create-team-note` | Create a note inside a team workspace. | `teamPath`, `content` (required), `title` (optional) | | `update-team-note` | Update a note that belongs to a team. | `teamPath`, `noteId`, `content` | | `delete-team-note` | Move a team note to trash. | `teamPath`, `noteId` | ### Search Tools | Tool | Description | Parameters | |------|-------------|------------| | `search-notes` | Search notes by title across your personal and team notes. | `query`, `limit` (default: 20, max: 50) | ### User Tools | Tool | Description | Parameters | |------|-------------|------------| | `get-me` | Get your profile information, including team membership and plan status. | — | --- ## Available Resources Resources provide direct read access to HackMD data using URI references. Clients that support MCP resources can load these without calling a tool explicitly. | URI | Description | MIME Type | |-----|-------------|-----------| | `hackmd://notes/{noteId}` | Raw markdown content of a note | `text/markdown` | | `hackmd://me` | Your profile as a JSON object | `application/json` | | `hackmd://teams/{teamPath}` | Team details as a JSON object | `application/json` | --- ## Troubleshooting **Server not connecting** - Verify your API token is correct and still active (Settings → API in HackMD). - Make sure the `Authorization` header value starts with `Bearer ` (note the space). - Confirm your client supports the Streamable HTTP transport. - Try restarting your client completely after changing config files. **"Authentication required" on every tool call** - Your token may have been revoked or expired. Generate a new one in HackMD settings and update the config. **Tools not appearing after configuration** - In Claude Desktop: fully quit and reopen the app (menu bar → Quit, then relaunch). - In Cursor: fully quit and reopen Cursor — a window reload is not enough for `mcp-remote` to pick up changes. Also confirm `HMD_API_ACCESS_TOKEN` is exported in your shell profile and that you restarted Cursor after setting it. - In Windsurf: click Refresh in the MCP panel. **`search-notes` returns no results** - The search matches note titles only, not note body content. - Try a shorter or more general query term. **`get-history` returns "No notes in history"** - History is populated when you view notes in the HackMD web interface or API. Open a few notes in HackMD first, then try again. **Permission denied on a team note** - Make sure you are a member of the team and that your API token belongs to the correct account. - Use `list-teams` to confirm which teams your token has access to. --- For more information, see the [HackMD Developer Portal](https://hackmd.io/@hackmd-api/developer-portal) and the [MCP specification](https://modelcontextprotocol.io/specification). # Was this tutorial helpful? <iframe src="https://tally.so/embed/warqZW?feature=mcp&hideTitle=1&dynamicHeight=1" loading="lazy" width="100%" height="200" frameborder="0" marginheight="0" marginwidth="0" title="Tutorial Book Feedback"></iframe><script>var d=document,w="https://tally.so/widgets/embed.js",v=function(){"undefined"!=typeof Tally?Tally.loadEmbeds():d.querySelectorAll("iframe\[data-tally-src\]:not(\[src\])").forEach((function(e){e.src=e.dataset.tallySrc}))};if("undefined"!=typeof Tally)v();else if(d.querySelector('script\[src="'+w+'"\]')==null){var s=d.createElement("script");s.src=w,s.onload=v,s.onerror=v,d.body.appendChild(s);}</script>