Skip to main content

docmost-mcp-oss

CI PyPI License: MIT Python 3.10+

An MCP server built with FastMCP that exposes the REST API of Docmost as tools for AI assistants (Claude Desktop, Claude Code, Cursor, VS Code…).

Managed with uv.

📄 Full API research: docs/DOCMOST-API.md. Verified against a real Docmost instance (not just the documentation).

Why a custom MCP?

Docmost ships with an official MCP, but it requires a Business/Enterprise license and is enabled from Settings → AI settings → MCP. This project uses the internal API (the same one the web UI consumes), which is also available in the self-hosted OSS edition.

About the name: the -oss suffix distinguishes this package from the unrelated docmost-mcp already on PyPI. They are different projects by different authors, and they would collide if installed side by side (both used to ship the same import package). This one targets self-hosted Docmost and can edit page bodies; install it as docmost-mcp-oss.

Exposed tools (20)

Category Tools
Pages search_pages, get_page, create_page, update_page, update_page_content, delete_page, restore_page, move_page, list_recent_pages, list_child_pages, get_page_breadcrumbs, get_page_history
Spaces list_spaces, get_space, create_space
Comments get_comments, create_comment, update_comment
User get_current_user, list_workspace_members

Two tools stand out:

  • get_page returns metadata and content in Markdown (it combines /pages/info with /pages/export, because the former does not return the body).
  • update_page_content replaces the body of an existing page. The REST API can't do this: it writes directly to the Yjs document over the collaboration WebSocket. Requires the yjs extra and takes ~13 s (Docmost persists with a 10 s debounce).

Editing the body of an existing page

Docmost's REST API ignores the content field in /pages/create and /pages/update (they respond 200 but save nothing): the body lives in the Yjs collaboration server.

That's why there are two distinct paths:

Operation How
Read content get_page
Create pagewith content create_page (uses /pages/import)
Replace the body of an existing page update_page_content (Yjs WebSocket)
Rename update_page
Delete / restore / move

update_page_content opens the wss://<host>/collab WebSocket, syncs the document, replaces the content and waits for it to persist. Markdown is converted using Docmost's own converter, so it supports the full schema (tables, lists, code, quotes, images…).

uv sync --extra yjs     # enables update_page_content

Technical details of the protocol: docs/YJS-EDITING.md.

Installation

As a tool, from PyPI (no clone needed)

uvx docmost-mcp-oss            # stdio, for MCP clients
uvx docmost-mcp-oss --check    # verify the connection to your instance

Add --with pycrdt --with websockets (or install docmost-mcp-oss[yjs]) to enable update_page_content, the tool that edits existing page bodies.

From source (for development)

uv creates the virtual environment and installs the dependencies (pinned in uv.lock):

uv sync

No need to activate the environment: use uv run ….

Configuration

cp .env.example .env   # then edit the values
DOCMOST_URL=https://docmost.example.com

# Option A — API Key
DOCMOST_API_KEY=dm_xxx

# Option B — login (works on OSS)
DOCMOST_EMAIL=you@example.com
DOCMOST_PASSWORD=your-password

Verify the connection:

uv run docmost-mcp-oss --check
# -> OK: authenticated as you@example.com (https://docmost.example.com)

Usage

uv run docmost-mcp-oss

HTTP (for remote access)

uv run docmost-mcp-oss --http --port 8000
# MCP endpoint: http://127.0.0.1:8000/mcp

Connecting to MCP clients

Every client below launches the same stdio command. The examples install from PyPI with uvx; to run from a clone instead, replace uvx docmost-mcp-oss with uv --directory /path/to/docmost-mcp-oss run docmost-mcp-oss.

To enable update_page_content (editing existing page bodies), use the yjs extra — replace docmost-mcp-oss with --from "docmost-mcp-oss[yjs]" docmost-mcp-oss, or see the note at the end of this section.

Claude Code

claude mcp add docmost \
  -e DOCMOST_URL=https://docmost.example.com \
  -e DOCMOST_EMAIL=you@example.com \
  -e DOCMOST_PASSWORD=your-password \
  -- uvx docmost-mcp-oss

Equivalent JSON, in .mcp.json at the root of your project (or under mcpServers in ~/.claude.json for a user-wide server):

{
  "mcpServers": {
    "docmost": {
      "type": "stdio",
      "command": "uvx",
      "args": ["docmost-mcp-oss"],
      "env": {
        "DOCMOST_URL": "https://docmost.example.com",
        "DOCMOST_EMAIL": "you@example.com",
        "DOCMOST_PASSWORD": "your-password"
      }
    }
  }
}

Codex

⚠️ Codex configures MCP servers in TOML, not JSON. Add this to ~/.codex/config.toml:

[mcp_servers.docmost]
command = "uvx"
args = ["docmost-mcp-oss"]

[mcp_servers.docmost.env]
DOCMOST_URL = "https://docmost.example.com"
DOCMOST_EMAIL = "you@example.com"
DOCMOST_PASSWORD = "your-password"

Or let the CLI write it for you:

codex mcp add docmost \
  --env DOCMOST_URL=https://docmost.example.com \
  --env DOCMOST_EMAIL=you@example.com \
  --env DOCMOST_PASSWORD=your-password \
  -- uvx docmost-mcp-oss

phoson-cli

phoson reads JSON from the file named by mcp_config_file in ~/.phoson/config.toml (defaults to ~/.phoson/mcps.json). Entries need an explicit "enabled": true:

{
  "mcpServers": {
    "docmost": {
      "command": "uvx",
      "args": ["docmost-mcp-oss"],
      "env": {
        "DOCMOST_URL": "https://docmost.example.com",
        "DOCMOST_EMAIL": "you@example.com",
        "DOCMOST_PASSWORD": "your-password"
      },
      "enabled": true
    }
  }
}

Claude Desktop (claude_desktop_config.json)

{
  "mcpServers": {
    "docmost": {
      "command": "uvx",
      "args": ["docmost-mcp-oss"],
      "env": {
        "DOCMOST_URL": "https://docmost.example.com",
        "DOCMOST_EMAIL": "you@example.com",
        "DOCMOST_PASSWORD": "your-password"
      }
    }
  }
}

Cursor (.cursor/mcp.json)

Same shape as Claude Desktop, inside the mcpServers key.

Enabling body editing

update_page_content needs the yjs extra, which is optional to keep the base install small. Point the client at the extra instead of the bare package:

Client Launcher to use
uvx uvx --from "docmost-mcp-oss[yjs]" docmost-mcp-oss
Any command/args JSON "command": "uvx", "args": ["--from", "docmost-mcp-oss[yjs]", "docmost-mcp-oss"]

For example, in Claude Code:

claude mcp add docmost \
  -e DOCMOST_URL=https://docmost.example.com \
  -e DOCMOST_EMAIL=you@example.com \
  -e DOCMOST_PASSWORD=your-password \
  -- uvx --from "docmost-mcp-oss[yjs]" docmost-mcp-oss

Tests

Command What it validates Needs instance
uv run python tests/test_client.py Client against a mocked Docmost (12 cases) No
uv run python tests/test_tools.py MCP tool registry No
uv run python tests/smoke_live.py Read-only against a real instance Yes
uv run python tests/smoke_mcp_live.py Tools through the MCP layer Yes
uv run --extra yjs python tests/smoke_yjs_live.py Body editing via Yjs (7 checks) Yes
uv run ruff check . Lint No

The live tests read credentials from .docmost-creds.json (ignored by git):

{
  "url": "https://docmost.example.com",
  "email": "you@example.com",
  "password": "your-password"
}

--write adds a create → update → get → delete cycle over a test page (use --write keep to keep it).

Implementation notes

Things that are not obvious and that the client already handles:

  • All endpoints are POST and respond with {data, success, status}; the client unwraps data.
  • Content does not come from /pages/info: it is fetched via /pages/export (markdown|html), which responds with the raw file, no wrapper.
  • Only /pages/import persists content over REST; /pages/create and /pages/update ignore content. To edit the body of an already-created page you must write to the Yjs document (see above).
  • Authentication: both real variants are supported — the authToken cookie (httpOnly) and data.tokens.accessToken forwarded as Bearer.
  • /search requires query and spaceId; if you don't provide a space, it fans out across all accessible spaces and merges by rank.
  • /pages/sidebar-pages requires spaceId; if you only provide a page, its space is resolved first.
  • Lexical search (PostgreSQL FTS): stopwords ("a", "de", "the") return 0 results.
  • Heterogeneous response shapes: some builds return {items, meta} and others raw lists; the client normalizes both.
  • Permissions: the MCP acts as the authenticated user; it can never do more than the user can.

Structure

docmost-mcp-oss/
├── docmost_mcp_oss/
│   ├── __init__.py
│   ├── client.py       # async HTTP client for the Docmost REST API
│   ├── collab.py       # Yjs WebSocket: read/write page bodies
│   └── server.py       # FastMCP server + tools
├── docs/
│   ├── DOCMOST-API.md  # API research (OSS + real instance)
│   └── YJS-EDITING.md  # collaboration WebSocket protocol
├── tests/
│   ├── test_client.py      # mocked, no network
│   ├── test_tools.py       # MCP tool registry, no network
│   ├── smoke_live.py       # real instance, read-only
│   ├── smoke_mcp_live.py   # MCP layer against a real instance
│   └── smoke_yjs_live.py   # body editing via Yjs
├── .github/workflows/ci.yml  # lint, tests and packaging
├── CONTRIBUTING.md
├── LICENSE                   # MIT
├── pyproject.toml            # metadata, dependencies and ruff config
├── uv.lock                   # reproducible resolution (it is versioned)
└── .env.example

License

MIT © 2026 Abel Santillan Rodriguez

Release files for docmost-mcp-oss 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for docmost-mcp-oss 0.1.1
File Size Uploaded
docmost_mcp_oss-0.1.1.tar.gz 160.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for docmost-mcp-oss 0.1.1
File Interpreter ABI Platform
docmost_mcp_oss-0.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 183.0 kB

Release files / docmost_mcp_oss-0.1.1.tar.gz

Download URL docmost_mcp_oss-0.1.1.tar.gz
Size 160.6 kB
Tags Source
SHA-256 checksum
How to use checksums
8be53bea0a030154dbaf187fde52e1cdd0166d20745dd2982c2cbdd70897b9ba
BLAKE2b-256 checksum
How to use checksums
543b5061bc150b3af06c6c93a4e3b4ebc310ab885ee6fa457801333bf01b528b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 21, 2026.

Transparency log

Release files / docmost_mcp_oss-0.1.1-py3-none-any.whl

Download URL docmost_mcp_oss-0.1.1-py3-none-any.whl
Size 22.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
5113246e6d9edcd73dc06125eda2cb6150fe543d2480e24f0e3fc1111b0705f3
BLAKE2b-256 checksum
How to use checksums
6240c649d43d6ee07b88f2c8601eb736d9c2e50e84c43d05291870436fedf744
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 21, 2026.

Transparency log

Release history Release notifications | RSS feed

0.6.0

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.0

2 release files

This release

0.1.1 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page