Upload base64 files to a page with MIME type auto-detection (magic bytes,
then extension). Images are inserted as image blocks and other files as
attachments at the end of the page via realtime collaboration. Request
body limit raised to 50MB (MCP_MAX_BODY_MB).
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Markdown checklist items (`- [ ]` / `- [x]`) were rendered as plain
bullet points instead of checkboxes. The client-side conversion pipeline
(marked -> generateJSON) dropped the checkbox because:
- tiptapExtensions did not register TaskList/TaskItem.
- marked emits `<ul><li><input type="checkbox">`, but TipTap's parseHTML
rules only match `ul[data-type="taskList"]` / `li[data-type="taskItem"]`
with the checked state in `data-checked`.
Register TaskList/TaskItem and add normalizeTaskLists() to rewrite marked's
checkbox markup into the format TipTap expects before generateJSON runs.
collaboration.ts now reuses markdownToTiptapJson() so update_page and
comments share the same conversion.
- Remove workerBusy promise chain (mutex) in src/index.ts: each
StreamableHTTPServerTransport is stateless and per-request, so
concurrent handling within a worker is safe. Eliminates request
starvation when long page writes are in flight.
- Raise the Hocuspocus safety timeout in collaboration.ts from 25 s
to 120 s, giving large documents enough time to complete the Yjs
sync phase before the hard abort fires.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Integrates StreamableHTTP natively into the MCP server instead of
using StdioServerTransport. Adds Node.js cluster support so multiple
workers can handle concurrent MCP clients simultaneously.
Changes:
- src/index.ts: replace StdioServerTransport with StreamableHTTPServerTransport
+ Node.js cluster (primary forks N workers, each worker handles HTTP
requests on :8080/mcp with a serializing mutex)
- Dockerfile: multi-stage build (node:22-slim builder + runtime)
- .gitea/workflows/docker-build.yml: CI/CD pipeline — on push to main,
builds and pushes Docker image to gitea.p-lao.com registry
Environment variables:
- MCP_WORKERS (default: 4) — number of cluster workers
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds 6 new MCP tools for managing Docmost page comments:
- list_comments: list all comments on a page (content as Markdown)
- get_comment: retrieve a single comment by ID
- create_comment: create page-level or inline comment (Markdown input)
- update_comment: update comment content (creator only)
- delete_comment: delete a comment (creator or space admin)
- check_new_comments: poll for new comments since a timestamp
Implementation details:
- New markdownToTiptapJson() utility in src/lib/markdown-to-json.ts
- New filterComment() in src/lib/filters.ts
- Supports inline comments, threaded replies via parentCommentId
- README updated with comment tools documentation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Closes#1Closes#8
Docmost changed the search API response format in v0.25.0:
- Before: response.data.data was a direct array
- After: response.data.data is { items: [...], meta: {...} }
The old code assumed the array format and crashed with
"items.map is not a function" on Docmost 0.25+.
Fix normalizes both formats for backwards compatibility.
Closes#2
GFM tables were corrupted when using update_page because the
Markdown → HTML (marked) → ProseMirror JSON (generateJSON) flow did not
recognize <table>, <tr>, <th>, <td> elements. Adding TableKit from
@tiptap/extension-table registers the required schema so tables round-trip
correctly in both create and update flows.
Tested on Docmost 0.70.1. Fixes PR #6 from the original repo.
Closes#4
When update_page contained images, they were silently dropped because
the Image extension was configured with inline: true, but Docmost's
editor uses inline: false, group: "block". The Yjs merge discarded
mismatched inline image nodes.
Fixes PR #5 from the original repo.