Skip to main content
Glama
README.md
# hedgedoc-mcp

An [MCP](https://modelcontextprotocol.io) server that lets AI agents — Claude Code, Codex, Cursor, VS Code, OpenCode, Pi, or [any other MCP client](docs/CLIENTS.md) — read and write notes on a **self-hosted HedgeDoc 1.x** instance.

HedgeDoc 1.x has no API token system, so this server handles the real auth model (session cookies from email/password login) and exposes it as a clean, agent-friendly toolset.

---

## Why this exists

[HedgeDoc](https://hedgedoc.org) is a great self-hosted, open-source, collaborative markdown editor. But if you want an AI agent to write notes to it programmatically, you hit a wall immediately: **HedgeDoc 1.x has no API tokens.** Every write endpoint (`POST /new`, etc.) requires an authenticated browser-style session, tracked via the Express session cookie configured by the instance (normally `connect.sid`).

This project does the unglamorous work of handling that correctly — login, cookie storage, automatic re-authentication on expiry — and wraps it in an MCP server so any agent can just call `hedgedoc_create_note` and not think about any of it.

## Features

- 🔐 **Handles HedgeDoc 1.x's real auth model** (session cookies, not tokens)
- 🔁 **Auto re-login on session expiry** — no manual cookie refresh needed
- 🛠️ **5 MCP tools**: create, read, info, whoami, history
- 🐍 **Standalone Python client** (`hedgedoc_mcp.client.HedgeDocClient`) usable outside MCP too
- ✅ **Fully tested** — against an in-process fake HedgeDoc server; no live instance required
- 📦 **Works with any MCP client** — [setup guides for 20+ agents](docs/CLIENTS.md): Claude Code, Codex, Cursor, VS Code, OpenCode, Pi, Gemini CLI, Goose, Zed, and more

## Quick start

### 1. Install uv

Your agent starts the server for you with [`uvx`](https://docs.astral.sh/uv/guides/tools/), which downloads and caches `hedgedoc-mcp` from PyPI on first use. You only need [uv installed](https://docs.astral.sh/uv/getting-started/installation/):

```bash
curl -LsSf https://astral.sh/uv/install.sh | sh     # macOS / Linux
# Windows: powershell -c "irm https://astral.sh/uv/install.ps1 | iex"
```

You don't run `uvx hedgedoc-mcp` yourself: it's a stdio server, so it just waits for an agent to talk to it.

<details>
<summary>Other ways to install</summary>

```bash
uv tool install hedgedoc-mcp     # persistent install; point your agent at the `hedgedoc-mcp` executable
pip install hedgedoc-mcp          # into an existing environment

# Unreleased changes from the main branch:
uvx --from git+https://github.com/mrsunglasses-experiments/hedgedoc-mcp hedgedoc-mcp
```

</details>

### 2. Choose your credentials

The server is configured entirely through environment variables:

| Variable | Required | Description |
|---|---|---|
| `HEDGEDOC_URL` | Yes | Your instance's URL as shown in the browser, e.g. `https://md.example.com` |
| `HEDGEDOC_EMAIL` + `HEDGEDOC_PASSWORD` | One of these two options | Email/password login. The server logs in on first use and again whenever the session expires. |
| `HEDGEDOC_SESSION_COOKIE` | One of these two options | A session cookie from `hedgedoc-mcp-login` (below). Saves a login round-trip; when it expires, the server falls back to email/password if those are set. |
| `HEDGEDOC_SESSION_COOKIE_NAME` | No | Only if your instance uses a session cookie name other than `connect.sid` |

**Recommended:** set `HEDGEDOC_EMAIL` and `HEDGEDOC_PASSWORD`. That's all you need, and you never have to refresh anything. Email login must be enabled on the instance (`CMD_EMAIL=true`, the default).

**Set these in your agent's MCP config (step 3), not just in your shell.** Most agents start MCP servers with a minimal environment, so variables you `export` usually don't reach the server.

<details>
<summary>Optional: get a session cookie with <code>hedgedoc-mcp-login</code></summary>

```bash
uvx --from hedgedoc-mcp hedgedoc-mcp-login --url https://md.example.com --email you@example.com
```

It prompts for your password (or reads `HEDGEDOC_PASSWORD`; avoid `--password`, which lands in your shell history) and prints `HEDGEDOC_SESSION_COOKIE=...` for your agent's config. With `--write-env .env`, it also saves the value to a file readable only by you. The server doesn't read `.env` files itself.

</details>

### 3. Connect your agent

For **Claude Code**:

```bash
claude mcp add hedgedoc --scope user \
  -e HEDGEDOC_URL=https://md.example.com \
  -e HEDGEDOC_EMAIL=you@example.com \
  -e HEDGEDOC_PASSWORD='your-password' \
  -- uvx hedgedoc-mcp
```

Most other agents take the same three pieces of information: command `uvx`, argument `hedgedoc-mcp`, and the environment variables above. Config files and formats differ, though. **[docs/CLIENTS.md](docs/CLIENTS.md)** has a ready-to-paste config for each of these clients:

| | |
|---|---|
| **Terminal agents** | [Claude Code](docs/CLIENTS.md#claude-code) · [Codex CLI](docs/CLIENTS.md#codex-cli) · [Gemini CLI](docs/CLIENTS.md#gemini-cli) · [GitHub Copilot CLI](docs/CLIENTS.md#github-copilot-cli) · [OpenCode](docs/CLIENTS.md#opencode) · [Pi](docs/CLIENTS.md#pi) · [Amp](docs/CLIENTS.md#amp) · [Goose](docs/CLIENTS.md#goose) · [Crush](docs/CLIENTS.md#crush) · [Hermes Agent](docs/CLIENTS.md#hermes-agent) · [Factory Droid](docs/CLIENTS.md#factory-droid) · [Qwen Code](docs/CLIENTS.md#qwen-code) · [Devin CLI](docs/CLIENTS.md#devin-desktop-and-devin-cli) |
| **Editors and IDEs** | [Cursor](docs/CLIENTS.md#cursor) · [VS Code (Copilot)](docs/CLIENTS.md#vs-code-github-copilot) · [Devin Desktop (Windsurf)](docs/CLIENTS.md#devin-desktop-and-devin-cli) · [Zed](docs/CLIENTS.md#zed) · [JetBrains](docs/CLIENTS.md#jetbrains-ides) · [Cline](docs/CLIENTS.md#cline) · [Kilo Code](docs/CLIENTS.md#kilo-code) · [Continue](docs/CLIENTS.md#continue) · [Kiro](docs/CLIENTS.md#kiro) |
| **Desktop apps** | [Claude Desktop](docs/CLIENTS.md#claude-desktop) · [ChatGPT desktop](docs/CLIENTS.md#chatgpt-desktop) · [Warp](docs/CLIENTS.md#warp) · [LM Studio](docs/CLIENTS.md#lm-studio) |

The guide also covers keeping passwords out of config files that get committed, plus [troubleshooting](docs/CLIENTS.md#troubleshooting).

### 4. Try it

Ask your agent something like *"Create a HedgeDoc note summarizing this conversation"* or *"Which HedgeDoc account are you logged in as?"*. If the tools don't show up, check the setup with [MCP Inspector](docs/CLIENTS.md#testing-with-mcp-inspector), which runs the server outside any agent.

## Available tools

| Tool | Description |
|---|---|
| `hedgedoc_create_note` | Create a new note (optionally with a custom URL alias). Returns the note ID and URL. |
| `hedgedoc_read_note` | Fetch a note's raw markdown content by ID or alias. |
| `hedgedoc_note_info` | Get a note's title, description, view count, and timestamps. |
| `hedgedoc_whoami` | Verify the session is valid and show the logged-in user. |
| `hedgedoc_list_history` | List the logged-in user's recently viewed/pinned notes. |

There is no update tool: HedgeDoc 1.x has no HTTP endpoint for editing a note (see [Known limitations](#known-limitations)), so write a note's full content when creating it.

## Using the Python client directly

You don't need MCP to use this — the underlying client is a normal Python class:

```python
from hedgedoc_mcp.client import HedgeDocClient

client = HedgeDocClient("https://md.example.com")
client.login(email="you@example.com", password="your-password")

result = client.create_note("# Research notes\n\nSome findings...")
print(result.url)

content = client.read_note(result.note_id)
info = client.note_info(result.note_id)
```

## Known limitations

HedgeDoc 1.x's HTTP API is genuinely limited compared to newer forks — see [docs/LIMITATIONS.md](docs/LIMITATIONS.md) for the full rundown, including:

- No API tokens (session-cookie auth only)
- No HTTP note-update endpoint
- No delete endpoint over HTTP

These are constraints of the HedgeDoc 1.x server itself, not this client — the docs explain the workarounds this project uses and what genuinely isn't possible.

## Development

```bash
git clone https://github.com/mrsunglasses-experiments/hedgedoc-mcp.git
cd hedgedoc-mcp
uv venv && source .venv/bin/activate
uv pip install -e ".[dev]"

pytest                 # run tests (against an in-process fake HedgeDoc; no live server needed)
ruff check .            # lint
ruff format --check .   # formatting
```

See [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) for how the auth flow and MCP layer fit together, and [CONTRIBUTING.md](CONTRIBUTING.md) for contribution guidelines.

## License

MIT — see [LICENSE](LICENSE).

TDQS

A4.4/5.0

Scored across 6 tools

Disambiguation5/5

Each tool performs a distinct function: create, read, update, metadata, session validation, and history. Even read_note and note_info are clearly separated by raw content vs. metadata.

Naming Consistency5/5

All tools use the 'hedgedoc_' prefix with clear verb_noun or noun_info naming in consistent snake_case. The pattern is uniform and predictable.

Tool Count5/5

Six tools is a well-scoped set for a HedgeDoc server, covering core note operations plus session and history. No unnecessary duplication or bloat.

Completeness4/5

Core lifecycle (create, read, update) is present, along with metadata and history. Missing delete is a notable gap, and update's alias-only limitation creates a dead end for non-alias notes, but the overall surface is reasonably complete.

Maintenance

ActivityMaintained
ResponsivenessNo issues