HedgeDoc MCP Multitenant Proxy Server
This repository contains a Model Context Protocol (MCP) server that actsas a secure, multi-tenant proxy between an AI Assistant and the HedgeDocbackend API. It exposes 27 MCP tools covering 5 resource domainswith full CRUD and permission management.
โจ Features
- ๐ Identity Passthrough โ Extracts the
Authorization: Bearer <token>header from incoming HTTP requests and forwards it to the HedgeDoc APIwithout server-side authentication. - ๐ฅ Multi-Tenancy โ Uses Python
contextvarsto maintain thread-safeuser identity isolation, ensuring all AI-driven actions are scoped tothe authenticated user's permissions. - ๐ Full HedgeDoc Coverage โ 27 tools mapped to HedgeDoc API endpointsacross 5 resource domains.
- โก TOON Optimization โ Bulk list responses are automatically compressedusing TOON (Token-Optimized Object Notation) to reduce token consumptionand maximize context window efficiency.
- ๐ Efficient Gets โ GET responses return only commonly used fields bydefault. Full objects are available via an
include_all_fieldsflag. - ๐งช Comprehensive Testing โ 38 automated tests covering all tooldomains, run via the test runner pipeline.
๐ง Environment Variables
| Variable | Required | Description |
|---|---|---|
HEDGEDOC_BASE_URL |
Yes | Docker-internal URL of the HedgeDoc API (e.g. http://hedgedoc-backend:3000). |
MCP_SERVER_PORT |
Yes | Port number the MCP server listens on. |
ALLOW_ALL_AGGREGATE |
No | When true, aggregate listing tools honor the include_all_fields parameter. When false (default), the parameter is silently forced to False for aggregate list operations. |
IS_STATEFUL |
No | When true, uses stateful Streamable HTTP with session tracking. When false (default), uses stateless mode. |
HEDGEDOC_PUBLIC_URL |
No | Public-facing URL for note_url in responses. Defaults to HEDGEDOC_BASE_URL if not set. |
๐ฆ Installation & Local Development
- Ensure you have Python 3.12+ installed.
- Install dependencies:
pip install fastmcp httpx pydantic uvicorn toon-mcp-server - Run the server:
export HEDGEDOC_BASE_URL=http://localhost:7462 export HEDGEDOC_PUBLIC_URL=https://hedgedoc.example.com export MCP_SERVER_PORT=80 python -m src.main
๐ณ Docker Deployment
Build and run the server using Docker:
docker build -t hedgedoc-mcp:latest .
docker run -d --name hedgedoc-mcp \
-e HEDGEDOC_BASE_URL="http://hedgedoc-backend:3000" \
-e HEDGEDOC_PUBLIC_URL="https://hedgedoc.example.com" \
-e MCP_SERVER_PORT=80 \
-e IS_STATEFUL=false \
hedgedoc-mcp:latest
The MCP server serves at `http://hedgedoc-mcp:80/mcp` (Streamable HTTP).
โ ๏ธ Important Notes
- ๐
include_all_fieldsโ Theinclude_all_fieldsparameter (availableon allget_*andlist_*tools) controls whether all available fieldsare included in responses. Defaults toFalsefor performance; set toTrueonly when additional fields are needed. - โก TOON Compression โ All bulk list responses are automaticallycompressed using TOON to reduce token consumption by 30โ60%.
- ๐ Required Fields & Defaults โ Each
create_*tool requires specifickey fields. All other fields default to empty strings or reasonable values.The owner field is automatically set to the authenticated user for mostresources.
๐ ๏ธ API Tool Mapping
The server implements 27 MCP tools organized into the following categories:
๐ Notes Core (6 tools)
create_noteโ Create a new note from markdown contentget_note_by_idโ Get a single note by ID or aliasupdate_noteโ Update an existing note's contentdelete_note_by_idโ Delete a note by ID or aliasget_note_contentโ Get raw markdown content of a noteget_note_metadataโ Get a note's metadata (title, tags, etc.)
๐ Notes Advanced (7 tools)
list_note_mediaโ List all media files attached to a notelist_note_revisionsโ List all revisions of a noteget_note_revision_by_idโ Get a specific revision by UUIDrevert_to_revisionโ Revert a note to a previous revisionadd_aliasโ Add an alias to a notemake_alias_primaryโ Set an alias as primary or non-primaryremove_aliasโ Remove an alias from a note
๐ Notes Permissions (6 tools)
get_note_permissionsโ Get a note's permission settingsset_note_user_permissionโ Set a user's permission on a noteremove_note_user_permissionโ Remove a user's permission from a noteset_note_group_permissionโ Set a group's permission on a noteremove_note_group_permissionโ Remove a group's permission from a notechange_note_ownerโ Change the owner of a note
๐ Notes Listing (4 tools)
list_all_my_notesโ List notes owned by the current userlist_all_shared_notesโ List notes shared with the current userlist_all_public_notesโ List public notes visible to the current userlist_all_pinned_notesโ List notes pinned by the current user
๐ค Profile & Media (4 tools)
get_my_profileโ Get the current user's profile informationlist_all_my_mediaโ List all media files owned by the current userget_media_by_idโ Get a single media file by UUIDdelete_media_by_idโ Delete a media file by UUID