@ulyxie/n8n-nodes-docmost (0.0.3-dev.4)

Published 2026-08-23 00:06:18 +02:00 by ulysia in ulysia/n8n-nodes-docmost

Installation

@ulyxie:registry=
npm install @ulyxie/n8n-nodes-docmost@0.0.3-dev.4
"@ulyxie/n8n-nodes-docmost": "0.0.3-dev.4"

About this package

@ulyxie/n8n-nodes-docmost

n8n community node for Docmost, the open-source wiki and documentation platform. Create and update pages, embed images with size and alignment control, and read or write rows on a Docmost base — all from an n8n workflow.

n8n is a fair-code licensed workflow automation platform.

Installation · Credentials · Resource: Page · Resource: Base · Behaviour notes · Development

Installation

Follow the community nodes installation guide. In your n8n instance go to Settings → Community Nodes → Install and enter:

@ulyxie/n8n-nodes-docmost

Or install manually:

npm install @ulyxie/n8n-nodes-docmost

This package has no runtime dependencies — every request goes through n8n's own HTTP helpers — so it's eligible for n8n Cloud as well as self-hosted instances.

The package ships one node and one credential type.

Credentials

The Docmost API credential (docmostApi) has two fields:

Field Required Notes
Base URL yes Your Docmost workspace URL, e.g. https://docmost.example.com. Trailing slashes are stripped before use.
API Token yes An API key created in Docmost under Settings → API Keys. Sent as Authorization: Bearer <token> on every request.

The credential's Test button calls POST {baseUrl}/api/users/me, which returns 200 with the user and workspace on a valid token and 401 on an invalid or expired one.

Node: Docmost

Internal name docmost. Marked usableAsTool, so it can be attached to an AI Agent node. Operations are grouped under two resources; the node subtitle shows <operation>: <resource>.

Resource: Page

Operation Calls Returns
Create POST /api/pages/create The created page
Update POST /api/pages/update The updated page
Get POST /api/pages/info The page (optionally with space and content)
Get Children POST /api/pages/sidebar-pages One output item per direct subpage
Add Image POST /api/files/upload then POST /api/pages/update The updated page plus the uploaded attachment

Create takes a Space, a Title, an optional Parent Page (to create a subpage), and optional Additional Fields: Icon, and Content with a Content Format of Markdown, HTML, or a raw Prosemirror JSON document.

Update takes a Page, an Update Mode (Append, Prepend, or Replace), a Content Format, and Content.

Get takes a Page and optional Additional Fields: Include Space, Include Content, and the Content Format the content comes back in.

Get Children takes a Page and lists its direct subpages — one output item each, with Return All / Limit to bound the result. It's one level deep, not a recursive tree walk; each item carries a hasChildren flag so you can recurse yourself if you need to. Rows of a base are pages too, so pointing this at a base page returns that base's row pages.

Add Image is the operation built for image-heavy workflows (e.g. downloading a comic page and adding it to a Docmost page): it takes a Page, an Input Binary Field, and Additional Fields for Width, Height, Align, Alt Text, and Insert Mode (Append/Prepend). It uploads the binary input as an attachment on the page, then appends (or prepends) an image node pointing at it. Width and Height are the same pixel values the resize handles write when you drag an image's corner in the Docmost editor — set Width alone to scale proportionally, or set both for an exact size. Leaving both at 0 keeps the image at its natural size.

Run Add Image once per input item — the usual shape is one workflow item per image, each call appending to the same Page so the images land on the page in order.

Space, Parent Page, and Page are all pickers: click into the field to search and select from your workspace, or switch the field to ID mode to type (or expression-drive) a raw ID directly. Page pickers search by title across the whole workspace once you type, and show the current space's most recently updated pages before you do — scoped to the chosen Space where one is already selected on the same field.

Resource: Base

A Docmost base is a database-like page: it has properties (columns — text, select, date, a link to another page, etc.) and rows. Every base operation needs a Space and a Base, both pickers backed by your workspace the same way as the Page resource's — search-and-select, or type an ID directly.

Operation Calls Returns
Get POST /api/bases/info The base, including its property and view definitions
Get Rows POST /api/bases/rows One output item per row
Get Row POST /api/bases/rows/info A single row
Find Rows POST /api/bases/rows One output item per matching row (none if nothing matches)
Row Exists POST /api/bases/rows Exactly one item: { exists, matchCount, row }
Create Row POST /api/bases/rows/create The created row
Update Row POST /api/bases/rows/update The updated row

Get Rows paginates on Docmost's cursor. With Return All off it fetches one page sized to Limit; with it on, it walks pages of 100 until the API stops returning a next cursor.

Rows come back with readable cell values. Docmost stores cells keyed by opaque property ID, with select and page values as opaque IDs of their own, which makes the raw cells object awkward to read in a workflow. Get Rows, Get Row, Find Rows and Row Exists therefore add a cellsByName companion object — same cells, but keyed by property name and resolved to display values (choice names, linked page titles, user names). The raw cells object is still there untouched, so {{$json.cellsByName.Comic}} gives you "test comic" while {{$json.cells.prp4n10foppe}} still gives you "optznnp7r0ls".

Find Rows and Row Exists both take a Property Name or ID and a Value, and match the way you'd expect to type it: an option's name or its raw ID, a linked page's title or its ID, or plain case-insensitive text for everything else. A multi-valued cell matches when any one of its values does.

Use Row Exists to branch — it always emits exactly one item, so {{$json.exists}} feeds straight into an n8n If node, with row carrying the first match (or null) so the true branch already has the data. Use Find Rows when you want the matches themselves as items; zero matches means zero items, which an If can't branch on but a downstream node simply won't run for.

Note

Docmost's row-listing API has no server-side filter yet (its filter parameter is accepted and ignored), so Find Rows and Row Exists page through the base and match client-side. That's fine for bases of a few thousand rows; it is not a substitute for a real indexed query on a very large base.

Create Row and Update Row take a Cells list: each entry picks a Property Name or ID (loaded from the selected base once it's chosen) and a raw Value. The value format depends on the property's type — a date property expects an ISO 8601 string, and a page property another page's ID (this is how you link a base row to the subpage you just created with Page → Add Image). Update Row only touches the cells you list; every other cell on the row is left as-is.

Select, status and multi-select cells accept a name, not just an ID. Docmost stores these as opaque choice IDs internally, but the node matches your Value against the property's existing choices by ID or by name (case-insensitive) — so "The Dragoness Says Sit" finds the right option even though the API itself only understands opt1bs7hc0jz. Multi-select takes a comma-separated list of names/IDs. When nothing matches, a new choice is created automatically (mirroring Docmost's own random ID and color-rotation scheme) unless you turn off Create Missing Options in Additional Fields — with it off, an unmatched value is sent through as-is and Docmost will silently store it without it resolving to any real option (this is Docmost's native behavior for an unrecognized choice ID, not something this node adds).

Behaviour notes

Docmost wraps most responses. Every JSON endpoint under /api/pages, /api/bases, and /api/spaces returns { data, success, status }; this node unwraps data for you, so node output is just the resource itself. The two upload endpoints are the exception — they return the created attachment object directly, which is why Add Image's output merges the (unwrapped) page update response with an attachment field.

Uploads go straight from memory. The binary input is read into a buffer and sent as multipart/form-data, with no temporary file on disk.

Per-item error handling. Every operation runs once per input item. With Continue On Fail enabled a failing item emits { "error": "<message>" } and the run continues; otherwise the error is thrown with the offending item index attached. All output items — including error items — carry pairedItem references back to their input.

Resource and operation are checked together. Execution dispatches on the pair, so driving either field by expression into a combination that doesn't exist raises Unsupported operation "<op>" for resource "<resource>" rather than quietly running the wrong branch.

Compatibility

  • n8n: nodes API version 1; the node is at node version 1.
  • Node.js: 20 or newer, matching n8n's own requirement.
  • Docmost: the REST API documented at <your workspace>/docs-json, specifically the Page, Base, Space, and Attachment endpoints.

Development

npm install
npm run dev     # starts n8n with this node loaded, hot reload enabled
Script Does
npm run build Compiles TypeScript into dist/ and copies static files (icons, .node.json)
npm run lint Runs the n8n community-node linter
npm run lint:fix Autofixes what it can

Layout

credentials/DocmostApi.credentials.ts   credential type + connection test
nodes/Docmost/                          the node
nodes/shared/transport.ts               the only place that talks HTTP
icons/                                  light + dark SVGs

nodes/shared/transport.ts is the single place requests are built: docmostApiRequest calls the standard JSON endpoints and unwraps their { data } envelope, docmostUploadRequest handles the two multipart upload endpoints. Neither depends on anything beyond n8n-workflow's own HTTP helpers.

Releasing

Two channels, both automated:

Channel Trigger Target Secret
Release push a v* tag npmjs.com, lateststaged, pending approval NPM_TOKEN
Dev push to main Forgejo registry, dev dist-tag CI

The release version comes from the tag, so package.json is never hand-edited:

git tag v0.0.1 && git push origin v0.0.1

A tag push does not make the version live. CI runs npm stage publish, which uploads the tarball to npm's staging area without needing 2FA. A maintainer then approves it:

npm stage list @ulyxie/n8n-nodes-docmost
npm stage view <stage-id>
npm stage approve <stage-id>

npm stage approve prompts for 2FA; that is the point of the design. Staging cannot create a package that doesn't exist yet on the registry — the very first version has to be published by hand, interactively, by a maintainer with npm publish --access public.

Dev builds are versioned <version>-dev.<run number> and never move latest:

npm install @ulyxie/n8n-nodes-docmost@dev --registry https://git.derg.cz/api/packages/ulysia/npm/

Note

This scaffolding (workflows, lint/build config, release process) is carried over from n8n-nodes-otex-cs — the npm scope and secret names above assume the same npmjs account.

Resources

License

MIT

Dependencies

Development dependencies

ID Version
@n8n/node-cli *
eslint 9.29.0
prettier 3.8.3
release-it 20.2.0
typescript 5.9.3

Peer dependencies

ID Version
n8n-workflow *

Keywords

n8n-community-node-package docmost wiki documentation
Details
npm
2026-08-23 00:06:18 +02:00
0
ulysia
MIT
23 KiB
Assets (1)
Versions (4) View all
0.0.4-dev.6 2026-08-23
0.0.3-dev.4 2026-08-23
0.0.1-dev.2 2026-08-19
0.0.0-dev.1 2026-08-19