docmost-community-mcp 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Docmost Community MCP contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,116 @@
1
+ # docmost-community-mcp
2
+
3
+ Model Context Protocol server for self-hosted [Docmost](https://docmost.com) **Community / Open Source Edition**.
4
+
5
+ Source: [github.com/dilruwanm/docmost-community-mcp](https://github.com/dilruwanm/docmost-community-mcp)
6
+
7
+ Official Docmost MCP and API keys are Enterprise-only. This server talks to the same internal HTTP API the Docmost web app uses, so you can search, read, write, and organize a CE wiki from Cursor, Claude, or any MCP client.
8
+
9
+ Requires **Docmost v0.71+** for Markdown body writes. Latest verified target is **v0.95.0**.
10
+
11
+ ## Install
12
+
13
+ ```bash
14
+ npx -y docmost-community-mcp
15
+ ```
16
+
17
+ From source:
18
+
19
+ ```bash
20
+ git clone https://github.com/dilruwanm/docmost-community-mcp.git
21
+ cd docmost-community-mcp
22
+ npm install
23
+ npm run build
24
+ ```
25
+
26
+ ## What you get
27
+
28
+ Official Enterprise MCP tool names, plus Community extras those docs omit.
29
+
30
+ **Pages:** `search_pages`, `get_page`, `create_page`, `update_page`, `list_pages`, `list_child_pages`, `duplicate_page`, `copy_page_to_space`, `move_page`, `move_page_to_space`, `delete_page`, `restore_page`, `list_trash`, `get_page_history`, `get_history_version`, `get_breadcrumbs`, `get_backlinks`, `export_page`
31
+
32
+ **Spaces:** `list_spaces`, `get_space`, `create_space`, `update_space`, `delete_space`, `export_space`
33
+
34
+ **Comments:** `get_comments`, `create_comment`, `update_comment`, `delete_comment`
35
+
36
+ **Search / people:** `search_attachments`, `search_suggest`, `list_workspace_members`, `get_current_user`
37
+
38
+ **Files / labels / access:** `upload_attachment`, `get_attachment_info`, `list_page_labels`, `add_page_labels`, `remove_page_label`, `list_space_members`, `add_space_members`, `remove_space_member`, `update_space_member_role`
39
+
40
+ Page and comment bodies are **Markdown**. Updates go through `POST /api/pages/update` with `format: "markdown"` so Docmost converts and applies the change in place. The server does not open a Yjs socket or invent its own TipTap schema.
41
+
42
+ ## Environment
43
+
44
+ | Variable | Required | Purpose |
45
+ |---|---|---|
46
+ | `DOCMOST_URL` | yes | Instance URL, e.g. `https://docs.example.com` |
47
+ | `DOCMOST_EMAIL` + `DOCMOST_PASSWORD` | one auth method | Community login |
48
+ | `DOCMOST_AUTH_TOKEN` | one auth method | `authToken` cookie from the browser |
49
+ | `DOCMOST_SESSION_PATH` | no | Session cache file |
50
+ | `DOCMOST_READ_ONLY` | no | `true` / `1` / `yes` — search and read only; mutating tools are refused |
51
+
52
+ Email/password is preferred. The JWT is cached under `~/.docmost-community-mcp/session.json` and refreshed on 401. MFA accounts cannot complete login here — use `DOCMOST_AUTH_TOKEN` instead.
53
+
54
+ Use a dedicated Docmost user. Do not commit credentials.
55
+
56
+ ## Cursor
57
+
58
+ Add to `.cursor/mcp.json` or `~/.cursor/mcp.json`:
59
+
60
+ ```json
61
+ {
62
+ "mcpServers": {
63
+ "docmost": {
64
+ "command": "npx",
65
+ "args": ["-y", "docmost-community-mcp"],
66
+ "env": {
67
+ "DOCMOST_URL": "https://docs.example.com",
68
+ "DOCMOST_EMAIL": "you@example.com",
69
+ "DOCMOST_PASSWORD": "your-password"
70
+ }
71
+ }
72
+ }
73
+ }
74
+ ```
75
+
76
+ From a local clone:
77
+
78
+ ```json
79
+ {
80
+ "mcpServers": {
81
+ "docmost": {
82
+ "command": "node",
83
+ "args": ["/absolute/path/to/docmost-community-mcp/dist/index.js"],
84
+ "env": {
85
+ "DOCMOST_URL": "https://docs.example.com",
86
+ "DOCMOST_EMAIL": "you@example.com",
87
+ "DOCMOST_PASSWORD": "your-password"
88
+ }
89
+ }
90
+ }
91
+ }
92
+ ```
93
+
94
+ ## Claude Desktop / Claude Code
95
+
96
+ Same `mcpServers` block as above. Claude Code:
97
+
98
+ ```bash
99
+ claude mcp add docmost --env DOCMOST_URL=https://docs.example.com --env DOCMOST_EMAIL=you@example.com --env DOCMOST_PASSWORD=secret -- npx -y docmost-community-mcp
100
+ ```
101
+
102
+ ## Design notes
103
+
104
+ - **stdio only** in this release. Streamable HTTP can be added later.
105
+ - **No Enterprise license, no Docmost database access, no Docmost fork.**
106
+ - Space slugs are accepted anywhere a space id is required.
107
+ - `move_page` computes the required fractional `position` key (`first`, `last`, or after a sibling).
108
+ - `create_page` / `update_page` fail clearly on servers older than v0.71 instead of silently dropping the body. `get_current_user` reports `docmostVersion` from Docmost's `currentVersion` field.
109
+ - `delete_space` requires `confirm: true`. Mutating tools honor `DOCMOST_READ_ONLY`.
110
+ - `list_pages` defaults to recently updated pages. Pass `view=tree` for sidebar-root pages.
111
+ - `search_attachments` is Enterprise-only; Community hosts get a clear 403 message.
112
+ - Export tools write a zip or a single `.md`/`.html` file to `output_path` or a temp file and return the path.
113
+
114
+ ## License
115
+
116
+ MIT. This package does not include Docmost AGPL or Enterprise source.
@@ -0,0 +1,57 @@
1
+ import type { DocmostConfig } from "./config.js";
2
+ export declare const MIN_WRITE_VERSION = "0.71.0";
3
+ export type Pagination = {
4
+ limit?: number;
5
+ cursor?: string;
6
+ };
7
+ export declare class DocmostClient {
8
+ private readonly config;
9
+ private token;
10
+ private versionProbe;
11
+ private writeChecked;
12
+ constructor(config: DocmostConfig);
13
+ apiUrl(path: string): string;
14
+ ensureSession(): Promise<void>;
15
+ login(): Promise<void>;
16
+ request<T = unknown>(path: string, body?: unknown, options?: {
17
+ retry?: boolean;
18
+ raw?: boolean;
19
+ }): Promise<T>;
20
+ multipart<T = unknown>(path: string, form: FormData, options?: {
21
+ retry?: boolean;
22
+ }): Promise<T>;
23
+ get readOnly(): boolean;
24
+ assertMutable(): void;
25
+ getVersion(): Promise<string | undefined>;
26
+ probeVersion(): Promise<{
27
+ version?: string;
28
+ error?: string;
29
+ }>;
30
+ sessionInfo(): Promise<{
31
+ docmostVersion: string | null;
32
+ versionProbeError: string | null;
33
+ readOnly: boolean;
34
+ markdownWritesSupported: boolean | null;
35
+ }>;
36
+ assertWritable(): Promise<string | undefined>;
37
+ confirmMarkdownWrite(page: unknown, sentMarkdown: string): Promise<void>;
38
+ resolveSpaceId(spaceIdOrSlug: string): Promise<string>;
39
+ computeMovePosition(input: {
40
+ pageId: string;
41
+ parentPageId?: string | null;
42
+ position?: "first" | "last" | string;
43
+ afterPageId?: string;
44
+ }): Promise<string>;
45
+ commentContent(markdown: string): string;
46
+ uploadFile(pageId: string, filePath: string): Promise<unknown>;
47
+ importPage(input: {
48
+ spaceId: string;
49
+ title: string;
50
+ markdown: string;
51
+ parentPageId?: string;
52
+ }): Promise<unknown>;
53
+ private extractCookie;
54
+ private extractToken;
55
+ private parseBody;
56
+ private toError;
57
+ }
package/dist/client.js ADDED
@@ -0,0 +1,317 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { basename } from "node:path";
3
+ import { ConfigError, DocmostError, VersionError } from "./errors.js";
4
+ import { asItems, compareSemver, decodeJwtExpiry, generatePosition, markdownToProseMirror, parseVersion, readSession, unwrap, writeSession, } from "./util.js";
5
+ export const MIN_WRITE_VERSION = "0.71.0";
6
+ const USER_AGENT = "docmost-community-mcp/1.0.0";
7
+ export class DocmostClient {
8
+ config;
9
+ token;
10
+ versionProbe = { probed: false };
11
+ writeChecked = false;
12
+ constructor(config) {
13
+ this.config = config;
14
+ this.token = config.authToken;
15
+ }
16
+ apiUrl(path) {
17
+ const suffix = path.startsWith("/") ? path : `/${path}`;
18
+ return `${this.config.baseUrl}/api${suffix}`;
19
+ }
20
+ async ensureSession() {
21
+ if (!this.token) {
22
+ this.token = await readSession(this.config.sessionPath, this.config.baseUrl);
23
+ }
24
+ if (this.token) {
25
+ return;
26
+ }
27
+ await this.login();
28
+ }
29
+ async login() {
30
+ if (!this.config.email || !this.config.password) {
31
+ throw new ConfigError("Saved session is missing or expired. Set DOCMOST_EMAIL and DOCMOST_PASSWORD, or a fresh DOCMOST_AUTH_TOKEN");
32
+ }
33
+ const response = await fetch(this.apiUrl("/auth/login"), {
34
+ method: "POST",
35
+ headers: {
36
+ "content-type": "application/json",
37
+ accept: "application/json",
38
+ "user-agent": USER_AGENT,
39
+ },
40
+ body: JSON.stringify({
41
+ email: this.config.email,
42
+ password: this.config.password,
43
+ }),
44
+ });
45
+ const body = await this.parseBody(response);
46
+ if (!response.ok) {
47
+ throw this.toError("Login failed", response.status, body);
48
+ }
49
+ const payload = unwrap(body);
50
+ if (payload && (payload.userHasMfa || payload.requiresMfaSetup)) {
51
+ throw new ConfigError("This account requires MFA. Community MCP cannot complete that flow. Sign in via the Docmost UI, copy the authToken cookie, and set DOCMOST_AUTH_TOKEN");
52
+ }
53
+ const token = this.extractCookie(response, "authToken") ?? this.extractToken(body);
54
+ if (!token) {
55
+ throw new ConfigError("Login succeeded but no authToken cookie was returned");
56
+ }
57
+ this.token = token;
58
+ await writeSession(this.config.sessionPath, {
59
+ baseUrl: this.config.baseUrl,
60
+ token,
61
+ expiresAt: decodeJwtExpiry(token),
62
+ });
63
+ }
64
+ async request(path, body, options = {}) {
65
+ await this.ensureSession();
66
+ const response = await fetch(this.apiUrl(path), {
67
+ method: "POST",
68
+ headers: {
69
+ "content-type": "application/json",
70
+ accept: "application/json",
71
+ "user-agent": USER_AGENT,
72
+ cookie: `authToken=${this.token}`,
73
+ },
74
+ body: JSON.stringify(body ?? {}),
75
+ });
76
+ if (response.status === 401 && options.retry !== false) {
77
+ this.token = undefined;
78
+ await this.login();
79
+ return this.request(path, body, { ...options, retry: false });
80
+ }
81
+ if (options.raw) {
82
+ if (!response.ok) {
83
+ const errorBody = await this.parseBody(response);
84
+ throw this.toError(`POST ${path} failed`, response.status, errorBody);
85
+ }
86
+ return response;
87
+ }
88
+ const payload = await this.parseBody(response);
89
+ if (!response.ok) {
90
+ throw this.toError(`POST ${path} failed`, response.status, payload);
91
+ }
92
+ return unwrap(payload);
93
+ }
94
+ async multipart(path, form, options = {}) {
95
+ await this.ensureSession();
96
+ const response = await fetch(this.apiUrl(path), {
97
+ method: "POST",
98
+ headers: {
99
+ accept: "application/json",
100
+ "user-agent": USER_AGENT,
101
+ cookie: `authToken=${this.token}`,
102
+ },
103
+ body: form,
104
+ });
105
+ if (response.status === 401 && options.retry !== false) {
106
+ this.token = undefined;
107
+ await this.login();
108
+ return this.multipart(path, form, { retry: false });
109
+ }
110
+ const payload = await this.parseBody(response);
111
+ if (!response.ok) {
112
+ throw this.toError(`POST ${path} failed`, response.status, payload);
113
+ }
114
+ return unwrap(payload);
115
+ }
116
+ get readOnly() {
117
+ return this.config.readOnly;
118
+ }
119
+ assertMutable() {
120
+ if (this.config.readOnly) {
121
+ throw new ConfigError("DOCMOST_READ_ONLY is enabled. This MCP session can search and read, but cannot create, update, move, or delete wiki content.");
122
+ }
123
+ }
124
+ async getVersion() {
125
+ const probe = await this.probeVersion();
126
+ return probe.version;
127
+ }
128
+ async probeVersion() {
129
+ if (this.versionProbe.probed) {
130
+ return this.versionProbe;
131
+ }
132
+ try {
133
+ const response = await this.request("/version", {}, { raw: true });
134
+ const payload = await this.parseBody(response);
135
+ const version = parseVersion(unwrap(payload)) ??
136
+ parseVersion(payload) ??
137
+ parseVersionFromHeaders(response.headers);
138
+ if (!version) {
139
+ const preview = typeof payload === "string" ? payload.slice(0, 180) : JSON.stringify(payload)?.slice(0, 180);
140
+ this.versionProbe = {
141
+ probed: true,
142
+ error: `POST /api/version returned no currentVersion (${preview || "empty body"})`,
143
+ };
144
+ }
145
+ else {
146
+ this.versionProbe = { probed: true, version };
147
+ }
148
+ }
149
+ catch (error) {
150
+ this.versionProbe = {
151
+ probed: true,
152
+ error: error instanceof Error ? error.message : String(error),
153
+ };
154
+ }
155
+ return this.versionProbe;
156
+ }
157
+ async sessionInfo() {
158
+ const probe = await this.probeVersion();
159
+ return {
160
+ docmostVersion: probe.version ?? null,
161
+ versionProbeError: probe.error ?? null,
162
+ readOnly: this.config.readOnly,
163
+ markdownWritesSupported: probe.version
164
+ ? compareSemver(probe.version, MIN_WRITE_VERSION) >= 0
165
+ : null,
166
+ };
167
+ }
168
+ async assertWritable() {
169
+ this.assertMutable();
170
+ if (this.writeChecked) {
171
+ return this.versionProbe.probed ? this.versionProbe.version : undefined;
172
+ }
173
+ const probe = await this.probeVersion();
174
+ this.writeChecked = true;
175
+ if (probe.version && compareSemver(probe.version, MIN_WRITE_VERSION) < 0) {
176
+ throw new VersionError(`Docmost ${probe.version} cannot persist page bodies over REST. Upgrade to v${MIN_WRITE_VERSION} or later. Title-only updates still work.`);
177
+ }
178
+ return probe.version;
179
+ }
180
+ async confirmMarkdownWrite(page, sentMarkdown) {
181
+ if (!page || typeof page !== "object") {
182
+ return;
183
+ }
184
+ const content = page.content;
185
+ if (content && typeof content === "object") {
186
+ throw new VersionError("The server ignored format=markdown and returned ProseMirror JSON. This Docmost build is too old for in-place Markdown writes. Upgrade to v0.71+");
187
+ }
188
+ if (typeof content === "string" && sentMarkdown.trim() && !content.trim()) {
189
+ throw new DocmostError("Page update returned empty Markdown content");
190
+ }
191
+ }
192
+ async resolveSpaceId(spaceIdOrSlug) {
193
+ if (isUuid(spaceIdOrSlug)) {
194
+ return spaceIdOrSlug;
195
+ }
196
+ const listed = asItems(await this.request("/spaces", { limit: 100 }));
197
+ const match = listed.items.find((item) => {
198
+ const space = item;
199
+ return space.slug === spaceIdOrSlug || space.id === spaceIdOrSlug;
200
+ });
201
+ if (!match) {
202
+ throw new DocmostError(`Space not found: ${spaceIdOrSlug}`);
203
+ }
204
+ return String(match.id);
205
+ }
206
+ async computeMovePosition(input) {
207
+ if (input.position && input.position !== "first" && input.position !== "last") {
208
+ if (input.position.length < 5 || input.position.length > 12) {
209
+ throw new DocmostError("position must be 5-12 characters, or first/last");
210
+ }
211
+ return input.position;
212
+ }
213
+ const siblings = asItems(await this.request("/pages/sidebar-pages", {
214
+ pageId: input.parentPageId ?? undefined,
215
+ spaceId: input.parentPageId ? undefined : (await this.request("/pages/info", { pageId: input.pageId })).spaceId,
216
+ limit: 100,
217
+ })).items;
218
+ const others = siblings.filter((page) => page.id !== input.pageId);
219
+ if (input.afterPageId) {
220
+ const index = others.findIndex((page) => page.id === input.afterPageId);
221
+ const before = index >= 0 ? String(others[index]?.position ?? "") : undefined;
222
+ const after = index >= 0 ? String(others[index + 1]?.position ?? "") : undefined;
223
+ return generatePosition(before || null, after || null);
224
+ }
225
+ if (input.position === "first") {
226
+ return generatePosition(null, others[0] ? String(others[0].position) : null);
227
+ }
228
+ const last = others[others.length - 1];
229
+ return generatePosition(last ? String(last.position) : null, null);
230
+ }
231
+ commentContent(markdown) {
232
+ return JSON.stringify(markdownToProseMirror(markdown));
233
+ }
234
+ async uploadFile(pageId, filePath) {
235
+ const bytes = await readFile(filePath);
236
+ const fileName = basename(filePath);
237
+ const form = new FormData();
238
+ form.append("pageId", pageId);
239
+ form.append("file", new Blob([bytes]), fileName);
240
+ return this.multipart("/files/upload", form);
241
+ }
242
+ async importPage(input) {
243
+ const form = new FormData();
244
+ form.append("spaceId", input.spaceId);
245
+ if (input.parentPageId) {
246
+ form.append("parentPageId", input.parentPageId);
247
+ }
248
+ const body = input.markdown.startsWith("#")
249
+ ? input.markdown
250
+ : `# ${input.title}\n\n${input.markdown}`;
251
+ form.append("file", new Blob([body], { type: "text/markdown" }), "import.md");
252
+ return this.multipart("/pages/import", form);
253
+ }
254
+ extractCookie(response, name) {
255
+ const headers = typeof response.headers.getSetCookie === "function"
256
+ ? response.headers.getSetCookie()
257
+ : [response.headers.get("set-cookie") ?? ""];
258
+ for (const header of headers) {
259
+ const match = header.match(new RegExp(`${name}=([^;]+)`));
260
+ if (match?.[1]) {
261
+ return match[1];
262
+ }
263
+ }
264
+ return undefined;
265
+ }
266
+ extractToken(body) {
267
+ const data = unwrap(body);
268
+ if (!data || typeof data !== "object") {
269
+ return undefined;
270
+ }
271
+ const record = data;
272
+ if (typeof record.authToken === "string") {
273
+ return record.authToken;
274
+ }
275
+ if (typeof record.token === "string") {
276
+ return record.token;
277
+ }
278
+ return undefined;
279
+ }
280
+ async parseBody(response) {
281
+ const text = await response.text();
282
+ if (!text) {
283
+ return undefined;
284
+ }
285
+ try {
286
+ return JSON.parse(text);
287
+ }
288
+ catch {
289
+ return text;
290
+ }
291
+ }
292
+ toError(prefix, status, body) {
293
+ const data = unwrap(body);
294
+ const message = (data && typeof data === "object" && typeof data.message === "string"
295
+ ? data.message
296
+ : typeof data === "string"
297
+ ? data
298
+ : JSON.stringify(data ?? {})) ?? "";
299
+ return new DocmostError(`${prefix} (${status})${message ? `: ${message}` : ""}`, status, body);
300
+ }
301
+ }
302
+ function parseVersionFromHeaders(headers) {
303
+ for (const name of ["x-docmost-version", "x-app-version"]) {
304
+ const value = headers.get(name)?.trim();
305
+ if (value) {
306
+ const parsed = parseVersion(value);
307
+ if (parsed) {
308
+ return parsed;
309
+ }
310
+ }
311
+ }
312
+ return undefined;
313
+ }
314
+ function isUuid(value) {
315
+ return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(value);
316
+ }
317
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ export type DocmostConfig = {
2
+ baseUrl: string;
3
+ email?: string;
4
+ password?: string;
5
+ authToken?: string;
6
+ sessionPath: string;
7
+ readOnly: boolean;
8
+ };
9
+ export declare function loadConfig(): DocmostConfig;
package/dist/config.js ADDED
@@ -0,0 +1,38 @@
1
+ import { homedir } from "node:os";
2
+ import { join } from "node:path";
3
+ import { ConfigError } from "./errors.js";
4
+ function required(name) {
5
+ const value = process.env[name]?.trim();
6
+ if (!value) {
7
+ throw new ConfigError(`Missing required environment variable ${name}`);
8
+ }
9
+ return value;
10
+ }
11
+ function optional(name) {
12
+ const value = process.env[name]?.trim();
13
+ return value ? value : undefined;
14
+ }
15
+ function optionalFlag(name) {
16
+ const value = process.env[name]?.trim().toLowerCase();
17
+ return value === "1" || value === "true" || value === "yes";
18
+ }
19
+ export function loadConfig() {
20
+ const rawUrl = required("DOCMOST_URL").replace(/\/+$/, "");
21
+ const baseUrl = rawUrl.replace(/\/api$/i, "");
22
+ const email = optional("DOCMOST_EMAIL");
23
+ const password = optional("DOCMOST_PASSWORD");
24
+ const authToken = optional("DOCMOST_AUTH_TOKEN");
25
+ if (!authToken && (!email || !password)) {
26
+ throw new ConfigError("Set DOCMOST_EMAIL and DOCMOST_PASSWORD, or DOCMOST_AUTH_TOKEN");
27
+ }
28
+ return {
29
+ baseUrl,
30
+ email,
31
+ password,
32
+ authToken,
33
+ sessionPath: optional("DOCMOST_SESSION_PATH") ??
34
+ join(homedir(), ".docmost-community-mcp", "session.json"),
35
+ readOnly: optionalFlag("DOCMOST_READ_ONLY"),
36
+ };
37
+ }
38
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAW1C,SAAS,QAAQ,CAAC,IAAY;IAC5B,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC;IACxC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,WAAW,CAAC,yCAAyC,IAAI,EAAE,CAAC,CAAC;IACzE,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,QAAQ,CAAC,IAAY;IAC5B,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC;IACxC,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;AACnC,CAAC;AAED,SAAS,YAAY,CAAC,IAAY;IAChC,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACtD,OAAO,KAAK,KAAK,GAAG,IAAI,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,KAAK,CAAC;AAC9D,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC3D,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;IAC9C,MAAM,KAAK,GAAG,QAAQ,CAAC,eAAe,CAAC,CAAC;IACxC,MAAM,QAAQ,GAAG,QAAQ,CAAC,kBAAkB,CAAC,CAAC;IAC9C,MAAM,SAAS,GAAG,QAAQ,CAAC,oBAAoB,CAAC,CAAC;IAEjD,IAAI,CAAC,SAAS,IAAI,CAAC,CAAC,KAAK,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QACxC,MAAM,IAAI,WAAW,CACnB,+DAA+D,CAChE,CAAC;IACJ,CAAC;IAED,OAAO;QACL,OAAO;QACP,KAAK;QACL,QAAQ;QACR,SAAS;QACT,WAAW,EACT,QAAQ,CAAC,sBAAsB,CAAC;YAChC,IAAI,CAAC,OAAO,EAAE,EAAE,wBAAwB,EAAE,cAAc,CAAC;QAC3D,QAAQ,EAAE,YAAY,CAAC,mBAAmB,CAAC;KAC5C,CAAC;AACJ,CAAC"}
@@ -0,0 +1,11 @@
1
+ export declare class DocmostError extends Error {
2
+ readonly status?: number | undefined;
3
+ readonly body?: unknown | undefined;
4
+ constructor(message: string, status?: number | undefined, body?: unknown | undefined);
5
+ }
6
+ export declare class ConfigError extends Error {
7
+ constructor(message: string);
8
+ }
9
+ export declare class VersionError extends Error {
10
+ constructor(message: string);
11
+ }
package/dist/errors.js ADDED
@@ -0,0 +1,23 @@
1
+ export class DocmostError extends Error {
2
+ status;
3
+ body;
4
+ constructor(message, status, body) {
5
+ super(message);
6
+ this.status = status;
7
+ this.body = body;
8
+ this.name = "DocmostError";
9
+ }
10
+ }
11
+ export class ConfigError extends Error {
12
+ constructor(message) {
13
+ super(message);
14
+ this.name = "ConfigError";
15
+ }
16
+ }
17
+ export class VersionError extends Error {
18
+ constructor(message) {
19
+ super(message);
20
+ this.name = "VersionError";
21
+ }
22
+ }
23
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,YAAa,SAAQ,KAAK;IAG1B;IACA;IAHX,YACE,OAAe,EACN,MAAe,EACf,IAAc;QAEvB,KAAK,CAAC,OAAO,CAAC,CAAC;QAHN,WAAM,GAAN,MAAM,CAAS;QACf,SAAI,GAAJ,IAAI,CAAU;QAGvB,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;IAC7B,CAAC;CACF;AAED,MAAM,OAAO,WAAY,SAAQ,KAAK;IACpC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,aAAa,CAAC;IAC5B,CAAC;CACF;AAED,MAAM,OAAO,YAAa,SAAQ,KAAK;IACrC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;IAC7B,CAAC;CACF"}
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,31 @@
1
+ #!/usr/bin/env node
2
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
+ import { DocmostClient } from "./client.js";
5
+ import { loadConfig } from "./config.js";
6
+ import { ConfigError } from "./errors.js";
7
+ import { registerTools } from "./tools.js";
8
+ const PACKAGE_VERSION = "1.0.0";
9
+ function createServer() {
10
+ const config = loadConfig();
11
+ const client = new DocmostClient(config);
12
+ const server = new McpServer({
13
+ name: "docmost-community-mcp",
14
+ version: PACKAGE_VERSION,
15
+ });
16
+ registerTools(server, client);
17
+ return server;
18
+ }
19
+ async function main() {
20
+ const server = createServer();
21
+ const transport = new StdioServerTransport();
22
+ await server.connect(transport);
23
+ }
24
+ main().catch((error) => {
25
+ const message = error instanceof ConfigError || error instanceof Error
26
+ ? error.message
27
+ : String(error);
28
+ console.error(message);
29
+ process.exit(1);
30
+ });
31
+ //# sourceMappingURL=index.js.map