affine-mcp-server 1.8.0 → 1.10.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/README.md +77 -93
- package/dist/cli.js +361 -25
- package/dist/config.js +47 -1
- package/dist/httpAuth.js +147 -0
- package/dist/httpDiagnostics.js +38 -0
- package/dist/index.js +52 -18
- package/dist/markdown/parse.js +13 -1
- package/dist/markdown/render.js +25 -0
- package/dist/oauth.js +154 -0
- package/dist/sse.js +12 -35
- package/dist/tools/docs.js +1155 -44
- package/package.json +14 -2
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
A Model Context Protocol (MCP) server that integrates with AFFiNE (self‑hosted or cloud). It exposes AFFiNE workspaces and documents to AI assistants over stdio (default) or HTTP (`/mcp`).
|
|
4
4
|
|
|
5
|
-
[](https://github.com/dawncr0w/affine-mcp-server/releases)
|
|
6
6
|
[](https://github.com/modelcontextprotocol/typescript-sdk)
|
|
7
7
|
[](https://github.com/dawncr0w/affine-mcp-server/actions/workflows/ci.yml)
|
|
8
8
|
[](LICENSE)
|
|
@@ -16,16 +16,16 @@ A Model Context Protocol (MCP) server that integrates with AFFiNE (self‑hosted
|
|
|
16
16
|
- Purpose: Manage AFFiNE workspaces and documents through MCP
|
|
17
17
|
- Transport: stdio (default) and optional HTTP (`/mcp`) for remote MCP deployments
|
|
18
18
|
- Auth: Token, Cookie, or Email/Password (priority order)
|
|
19
|
-
- Tools:
|
|
19
|
+
- Tools: 61 focused tools with WebSocket-based document editing
|
|
20
20
|
- Status: Active
|
|
21
21
|
|
|
22
|
-
> New in v1.
|
|
22
|
+
> New in v1.10.0: Added document search/discovery utilities, template and batch document workflows, optional OAuth-protected HTTP mode, richer CLI diagnostics, and an HTTP multi-session email/password auth fix.
|
|
23
23
|
|
|
24
24
|
## Features
|
|
25
25
|
|
|
26
26
|
- Workspace: create (with initial doc), read, update, delete
|
|
27
27
|
- Documents: list/get/read/publish/revoke + create/append/replace/delete + markdown import/export + tags (WebSocket‑based)
|
|
28
|
-
- Database workflows: create database blocks, add columns and rows, and read or update cell values via MCP tools
|
|
28
|
+
- Database workflows: create database blocks, inspect schema, add columns and rows, and read or update cell values via MCP tools
|
|
29
29
|
- Comments: full CRUD and resolve
|
|
30
30
|
- Version History: list
|
|
31
31
|
- Users & Tokens: current user, sign in, profile/settings, and personal access tokens
|
|
@@ -93,7 +93,12 @@ The MCP server will use these credentials automatically.
|
|
|
93
93
|
```
|
|
94
94
|
|
|
95
95
|
Other CLI commands:
|
|
96
|
+
- `affine-mcp --help` / `-h` / `help` — show command help
|
|
96
97
|
- `affine-mcp status` — show current config and test connection
|
|
98
|
+
- `affine-mcp doctor` — run config and connectivity diagnostics
|
|
99
|
+
- `affine-mcp show-config` — print the effective config with secrets redacted
|
|
100
|
+
- `affine-mcp config-path` — print the config file path
|
|
101
|
+
- `affine-mcp snippet <claude|cursor|codex> [--env]` — print ready-to-paste client configuration snippets
|
|
97
102
|
- `affine-mcp logout` — remove stored credentials
|
|
98
103
|
- `affine-mcp --version` / `-v` / `version` — print the installed CLI version and exit
|
|
99
104
|
|
|
@@ -186,6 +191,8 @@ Or with email/password for self-hosted instances (not supported on AFFiNE Cloud
|
|
|
186
191
|
Tips
|
|
187
192
|
- Prefer `affine-mcp login` or `AFFINE_API_TOKEN` for zero‑latency startup.
|
|
188
193
|
- If your password contains `!` (zsh history expansion), wrap it in single quotes in shells or use the JSON config above.
|
|
194
|
+
- `affine-mcp doctor` is the fastest way to confirm that your saved config still works.
|
|
195
|
+
- `affine-mcp snippet claude --env` and `affine-mcp snippet codex --env` can generate ready-to-paste client setup from your current config.
|
|
189
196
|
|
|
190
197
|
### Codex CLI
|
|
191
198
|
|
|
@@ -246,12 +253,16 @@ If you want to host the server remotely (e.g., using Render, Railway, Docker, or
|
|
|
246
253
|
Required:
|
|
247
254
|
- `MCP_TRANSPORT=http`
|
|
248
255
|
- `AFFINE_BASE_URL` (example: `https://app.affine.pro`)
|
|
249
|
-
-
|
|
256
|
+
- `AFFINE_MCP_AUTH_MODE=bearer` (default) or `AFFINE_MCP_AUTH_MODE=oauth`
|
|
257
|
+
|
|
258
|
+
Bearer mode backend auth:
|
|
250
259
|
- `AFFINE_API_TOKEN` (recommended), or `AFFINE_COOKIE`, or `AFFINE_EMAIL` + `AFFINE_PASSWORD`
|
|
251
260
|
|
|
261
|
+
OAuth mode backend auth:
|
|
262
|
+
- `AFFINE_API_TOKEN` (required service credential for AFFiNE backend access)
|
|
263
|
+
|
|
252
264
|
Recommended for remote/public deployments:
|
|
253
265
|
- `AFFINE_MCP_HTTP_HOST=0.0.0.0`
|
|
254
|
-
- `AFFINE_MCP_HTTP_TOKEN=<strong-random-token>` (protects `/mcp`, `/sse`, `/messages`)
|
|
255
266
|
- `AFFINE_MCP_HTTP_ALLOWED_ORIGINS=<comma-separated-origins>` (for browser clients)
|
|
256
267
|
|
|
257
268
|
Optional:
|
|
@@ -260,31 +271,68 @@ Optional:
|
|
|
260
271
|
- `AFFINE_GRAPHQL_PATH` (defaults to `/graphql`)
|
|
261
272
|
- `AFFINE_MCP_HTTP_ALLOW_ALL_ORIGINS=true` (testing only)
|
|
262
273
|
|
|
274
|
+
Bearer-mode only:
|
|
275
|
+
- `AFFINE_MCP_HTTP_TOKEN=<strong-random-token>` (protects `/mcp`, `/sse`, `/messages`)
|
|
276
|
+
|
|
277
|
+
OAuth-mode only:
|
|
278
|
+
- `AFFINE_MCP_PUBLIC_BASE_URL=https://mcp.yourdomain.com`
|
|
279
|
+
- `AFFINE_OAUTH_ISSUER_URL=https://auth.yourdomain.com`
|
|
280
|
+
- `AFFINE_OAUTH_SCOPES=mcp` (defaults to `mcp`)
|
|
281
|
+
|
|
282
|
+
#### HTTP auth modes
|
|
283
|
+
|
|
284
|
+
`AFFINE_MCP_AUTH_MODE=bearer` keeps the current static bearer-token behavior.
|
|
285
|
+
|
|
263
286
|
```bash
|
|
264
|
-
# Export your configuration first
|
|
265
287
|
export MCP_TRANSPORT=http
|
|
288
|
+
export AFFINE_MCP_AUTH_MODE=bearer
|
|
266
289
|
export AFFINE_API_TOKEN="your_token..."
|
|
267
|
-
export AFFINE_MCP_HTTP_HOST="0.0.0.0"
|
|
290
|
+
export AFFINE_MCP_HTTP_HOST="0.0.0.0"
|
|
268
291
|
export AFFINE_MCP_HTTP_TOKEN="your-super-secret-token"
|
|
269
292
|
export PORT=3000
|
|
270
293
|
|
|
271
|
-
# Start in HTTP mode (Streamable HTTP on /mcp)
|
|
272
294
|
npm run start:http
|
|
273
|
-
# OR manually:
|
|
274
|
-
# MCP_TRANSPORT=http node dist/index.js
|
|
275
|
-
# ("sse" is still accepted at /sse)
|
|
276
295
|
```
|
|
277
296
|
|
|
297
|
+
`AFFINE_MCP_AUTH_MODE=oauth` turns the MCP endpoint into an OAuth-protected resource for web MCP clients. In this mode:
|
|
298
|
+
- the server exposes `/.well-known/oauth-protected-resource`
|
|
299
|
+
- unauthenticated `/mcp` requests return `401` with a `WWW-Authenticate` challenge
|
|
300
|
+
- `AFFINE_MCP_HTTP_TOKEN` and `?token=` are disabled
|
|
301
|
+
- `sign_in` is not registered
|
|
302
|
+
- `AFFINE_API_TOKEN` is still required so the server can call AFFiNE as a service credential
|
|
303
|
+
|
|
304
|
+
```bash
|
|
305
|
+
export MCP_TRANSPORT=http
|
|
306
|
+
export AFFINE_MCP_AUTH_MODE=oauth
|
|
307
|
+
export AFFINE_API_TOKEN="your-affine-service-token"
|
|
308
|
+
export AFFINE_MCP_HTTP_HOST="0.0.0.0"
|
|
309
|
+
export AFFINE_MCP_PUBLIC_BASE_URL="https://mcp.yourdomain.com"
|
|
310
|
+
export AFFINE_OAUTH_ISSUER_URL="https://auth.yourdomain.com"
|
|
311
|
+
export AFFINE_OAUTH_SCOPES="mcp"
|
|
312
|
+
export PORT=3000
|
|
313
|
+
|
|
314
|
+
npm run start:http
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
Notes for oauth mode:
|
|
318
|
+
- use HTTPS for non-local deployments
|
|
319
|
+
- `AFFINE_MCP_HTTP_ALLOW_ALL_ORIGINS=true` is rejected in oauth mode
|
|
320
|
+
- tokens are validated against the issuer discovery metadata and JWKS
|
|
321
|
+
- the protected resource metadata is also served at `/.well-known/oauth-protected-resource/mcp` for path-specific discovery
|
|
322
|
+
- `GET /healthz` and `GET /readyz` are available for deployment diagnostics
|
|
323
|
+
|
|
278
324
|
#### Recommended presets
|
|
279
325
|
|
|
280
326
|
Local testing (HTTP mode):
|
|
281
327
|
- `MCP_TRANSPORT=http`
|
|
328
|
+
- `AFFINE_MCP_AUTH_MODE=bearer`
|
|
282
329
|
- `AFFINE_MCP_HTTP_HOST=127.0.0.1`
|
|
283
330
|
- `AFFINE_MCP_HTTP_TOKEN=<token>` (recommended even locally)
|
|
284
331
|
- `AFFINE_MCP_HTTP_ALLOWED_ORIGINS=http://localhost:3000` (if testing from a browser app)
|
|
285
332
|
|
|
286
333
|
Docker / container runtime:
|
|
287
334
|
- `MCP_TRANSPORT=http`
|
|
335
|
+
- `AFFINE_MCP_AUTH_MODE=bearer`
|
|
288
336
|
- `AFFINE_MCP_HTTP_HOST=0.0.0.0`
|
|
289
337
|
- `PORT=3000` (or container/platform port)
|
|
290
338
|
- `AFFINE_MCP_HTTP_TOKEN=<strong-token>`
|
|
@@ -292,14 +340,19 @@ Docker / container runtime:
|
|
|
292
340
|
|
|
293
341
|
Render / Railway / VPS (public endpoint):
|
|
294
342
|
- `MCP_TRANSPORT=http`
|
|
343
|
+
- `AFFINE_MCP_AUTH_MODE=bearer` or `oauth`
|
|
295
344
|
- `AFFINE_MCP_HTTP_HOST=0.0.0.0`
|
|
296
|
-
- `AFFINE_MCP_HTTP_TOKEN=<strong-token>`
|
|
345
|
+
- `AFFINE_MCP_HTTP_TOKEN=<strong-token>` (bearer mode)
|
|
346
|
+
- `AFFINE_MCP_PUBLIC_BASE_URL=<public base URL>` (oauth mode)
|
|
347
|
+
- `AFFINE_OAUTH_ISSUER_URL=<issuer URL>` (oauth mode)
|
|
297
348
|
- `AFFINE_MCP_HTTP_ALLOWED_ORIGINS=<your client origin(s)>`
|
|
298
349
|
|
|
299
350
|
Endpoints currently available:
|
|
300
351
|
- `/mcp` - MCP server (Streamable HTTP)
|
|
301
352
|
- `/sse` - SSE endpoint (old protocol compatible)
|
|
302
353
|
- `/messages` - Messages endpoint (old protocol compatible)
|
|
354
|
+
- `/healthz` - HTTP liveness probe
|
|
355
|
+
- `/readyz` - HTTP readiness probe
|
|
303
356
|
|
|
304
357
|
## Available Tools
|
|
305
358
|
|
|
@@ -313,6 +366,7 @@ Endpoints currently available:
|
|
|
313
366
|
### Documents
|
|
314
367
|
- `list_docs` – list documents with pagination (includes `node.tags`)
|
|
315
368
|
- `list_tags` – list all tags in a workspace
|
|
369
|
+
- `search_docs` – fast title search with substring/prefix/exact matching, optional tag filtering, and updatedAt sorting
|
|
316
370
|
- `list_docs_by_tag` – list documents by tag
|
|
317
371
|
- `get_doc` – get document metadata
|
|
318
372
|
- `read_doc` – read document block content and plain text snapshot (WebSocket)
|
|
@@ -325,9 +379,10 @@ Endpoints currently available:
|
|
|
325
379
|
- `add_tag_to_doc` – attach a tag to a document
|
|
326
380
|
- `remove_tag_from_doc` – detach a tag from a document
|
|
327
381
|
- `append_paragraph` – append a paragraph block (WebSocket)
|
|
328
|
-
- `append_block` – append canonical block types (text/list/code/media/embed/database/edgeless) with strict validation and placement control (`
|
|
382
|
+
- `append_block` – append canonical block types (text/list/code/media/embed/database/edgeless) with strict validation and placement control (`viewMode=kanban` enables preset-backed data views; `data_view` defaults to kanban)
|
|
329
383
|
- `add_database_column` – add a column to a database block (`rich-text`, `select`, `multi-select`, `number`, `checkbox`, `link`, `date`)
|
|
330
384
|
- `add_database_row` – add a row to a database block with values mapped by column name/ID (`title` / `Title` updates the built-in row title)
|
|
385
|
+
- `read_database_columns` – read database schema metadata including column IDs/types, select options, and table view column mappings
|
|
331
386
|
- `read_database_cells` – read row titles plus decoded database cell values with optional row / column filters
|
|
332
387
|
- `update_database_cell` – update a single database cell or the built-in row title (`createOption` defaults to `true` for select fields)
|
|
333
388
|
- `update_database_row` – batch update multiple cells on a database row (`createOption` defaults to `true` for select fields)
|
|
@@ -376,9 +431,10 @@ npm run pack:check
|
|
|
376
431
|
|
|
377
432
|
- `tool-manifest.json` is the source of truth for publicly exposed tool names.
|
|
378
433
|
- CI validates that `registerTool(...)` declarations match the manifest exactly.
|
|
379
|
-
- For full tool-surface verification, run `npm run test:comprehensive
|
|
434
|
+
- For full tool-surface verification, run `npm run test:comprehensive` (self-bootstraps a local Docker AFFiNE stack).
|
|
435
|
+
- For pre-provisioned environments, use `npm run test:comprehensive:raw`.
|
|
380
436
|
- For full environment verification, run `npm run test:e2e` (Docker + MCP + Playwright).
|
|
381
|
-
- Additional focused runners: `npm run test:db-create`, `npm run test:db-cells`, `npm run test:bearer`, `npm run test:cli-version`, `npm run test:playwright`.
|
|
437
|
+
- Additional focused runners: `npm run test:db-create`, `npm run test:db-cells`, `npm run test:db-schema`, `npm run test:supporting-tools`, `npm run test:bearer`, `npm run test:http-email-password`, `npm run test:http-bearer`, `npm run test:oauth-http`, `npm run test:doc-discovery`, `npm run test:cli-version`, `npm run test:cli-commands`, `npm run test:playwright`.
|
|
382
438
|
|
|
383
439
|
## Troubleshooting
|
|
384
440
|
|
|
@@ -411,83 +467,11 @@ Workspace visibility
|
|
|
411
467
|
- Use HTTPS
|
|
412
468
|
- Store credentials in a secrets manager
|
|
413
469
|
|
|
414
|
-
##
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
-
|
|
418
|
-
-
|
|
419
|
-
- Added CLI version commands: `affine-mcp --version`, `affine-mcp -v`, and `affine-mcp version`
|
|
420
|
-
- Added focused regression runners for database cells and CLI version support
|
|
421
|
-
- Verified release gates with `npm run ci`, `npm run test:cli-version`, and live `npm run test:db-cells`
|
|
422
|
-
|
|
423
|
-
### 1.7.2 (2026‑03‑04)
|
|
424
|
-
- Fixed MCP tag persistence to use AFFiNE canonical tag option IDs so tags are visible in Web/App UI
|
|
425
|
-
- Added backward-compatible tag normalization for legacy string tag entries
|
|
426
|
-
- Added tag visibility regression coverage (`tests/test-tag-visibility.mjs`, `tests/playwright/verify-tag-visibility.pw.ts`)
|
|
427
|
-
- Hardened E2E credential bootstrap with configurable health retries, retry attempts, and Docker diagnostics on failure
|
|
428
|
-
- Verified CI gates (`validate`, `e2e`) for PR #46 and local `npm run ci`
|
|
429
|
-
|
|
430
|
-
### 1.7.1 (2026‑03‑03)
|
|
431
|
-
- Fixed MCP-created document structure parity with AFFiNE UI (`sys:parent` handling)
|
|
432
|
-
- Fixed callout text rendering parity in AFFiNE UI for MCP-created blocks
|
|
433
|
-
- Added regression assertions for visibility-sensitive document creation paths
|
|
434
|
-
|
|
435
|
-
### 1.7.0 (2026‑02‑27)
|
|
436
|
-
- Added Streamable HTTP MCP support on `/mcp` for remote hosting while keeping legacy SSE compatibility paths (`/sse`, `/messages`)
|
|
437
|
-
- Added HTTP deployment controls: `AFFINE_MCP_HTTP_HOST`, `AFFINE_MCP_HTTP_TOKEN`, `AFFINE_MCP_HTTP_ALLOWED_ORIGINS`, `AFFINE_MCP_HTTP_ALLOW_ALL_ORIGINS`
|
|
438
|
-
- Added `npm run start:http` for one-command HTTP mode startup
|
|
439
|
-
- Hardened HTTP request handling with explicit 50MB parser application and case-insensitive Bearer auth parsing
|
|
440
|
-
- Expanded docs with remote deployment/security presets (Docker, Render, Railway, VPS)
|
|
441
|
-
- Verified full release checks with `npm run ci`, `npm run test:e2e`, and `npm run test:comprehensive`
|
|
442
|
-
|
|
443
|
-
### 1.6.0 (2026‑02‑24)
|
|
444
|
-
- Added 11 document workflow tools: tags (`list_tags`, `list_docs_by_tag`, `create_tag`, `add_tag_to_doc`, `remove_tag_from_doc`), markdown roundtrip (`export_doc_markdown`, `create_doc_from_markdown`, `append_markdown`, `replace_doc_with_markdown`), and database operations (`add_database_column`, `add_database_row`)
|
|
445
|
-
- Added interactive CLI commands: `affine-mcp login`, `affine-mcp status`, `affine-mcp logout`
|
|
446
|
-
- Added Docker + Playwright E2E pipeline and CI workflow for auth/database regression checks
|
|
447
|
-
- Tool surface increased from 32 to 43 canonical tools
|
|
448
|
-
- Added release test commands (`test:e2e`, `test:db-create`, `test:bearer`, `test:playwright`) and package dependencies for markdown conversion + Playwright
|
|
449
|
-
|
|
450
|
-
### 1.5.0 (2026‑02‑13)
|
|
451
|
-
- Expanded `append_block` from Step1 to Step4 profiles: canonical text/list/code/divider/callout/latex/table/bookmark/media/embed plus `database`, `data_view`, `surface_ref`, `frame`, `edgeless_text`, `note` (`data_view` currently mapped to database for stability)
|
|
452
|
-
- Added strict field validation and canonical parent enforcement for page/note/surface containers
|
|
453
|
-
- Added local integration runner coverage for all 30 append_block cases against a live AFFINE server
|
|
454
|
-
|
|
455
|
-
### 1.4.0 (2026‑02‑13)
|
|
456
|
-
- Added `read_doc` for reading document block snapshot + plain text
|
|
457
|
-
- Added Cursor setup examples and troubleshooting notes for JSON-RPC method usage
|
|
458
|
-
- Added explicit local-storage workspace limitation notes
|
|
459
|
-
|
|
460
|
-
### 1.3.0 (2026‑02‑13)
|
|
461
|
-
- Added `append_block` for slash-command style editing (`heading/list/todo/code/divider/quote`)
|
|
462
|
-
- Tool surface simplified to 31 canonical tools (duplicate aliases removed)
|
|
463
|
-
- Added CI + manifest parity verification (`npm run test:tool-manifest`, `npm run ci`)
|
|
464
|
-
- Added open-source community health docs and issue/PR templates
|
|
465
|
-
|
|
466
|
-
### 1.2.2 (2025‑09‑18)
|
|
467
|
-
- CLI wrapper added to ensure Node runs ESM entry (`bin/affine-mcp`), preventing shell mis-execution
|
|
468
|
-
- Docs cleaned: use env vars via shell/app config; `.env` file no longer recommended
|
|
469
|
-
- MCP startup behavior unchanged from 1.2.1 (async login by default)
|
|
470
|
-
|
|
471
|
-
### 1.2.1 (2025‑09‑17)
|
|
472
|
-
- Default to asynchronous email/password login after MCP stdio handshake
|
|
473
|
-
- `AFFINE_LOGIN_AT_START` supports `sync` when you need blocking startup (default is non-blocking)
|
|
474
|
-
- Expanded docs for Codex/Claude using npm, npx, and local clone
|
|
475
|
-
|
|
476
|
-
### 1.2.0 (2025‑09‑16)
|
|
477
|
-
- WebSocket-based document tools: `create_doc`, `append_paragraph`, `delete_doc` (create/edit/delete now supported)
|
|
478
|
-
- Tool aliases introduced at the time (`affine_*` + non-prefixed names). They were removed later to reduce duplication.
|
|
479
|
-
- ESM resolution: NodeNext; improved build stability
|
|
480
|
-
- CLI binary: `affine-mcp` for easy `npm i -g` usage
|
|
481
|
-
|
|
482
|
-
### 1.1.0 (2025‑08‑12)
|
|
483
|
-
- Fixed workspace creation with initial documents (UI accessible)
|
|
484
|
-
- 30+ tools, simplified tool names
|
|
485
|
-
- Improved error handling and authentication
|
|
486
|
-
|
|
487
|
-
### 1.0.0 (2025‑08‑12)
|
|
488
|
-
- Initial stable release
|
|
489
|
-
- Basic workspace and document operations
|
|
490
|
-
- Full authentication support
|
|
470
|
+
## Release Notes
|
|
471
|
+
|
|
472
|
+
- Changelog: [CHANGELOG.md](CHANGELOG.md)
|
|
473
|
+
- Release notes: [RELEASE_NOTES.md](RELEASE_NOTES.md)
|
|
474
|
+
- GitHub Releases: [Releases](https://github.com/dawncr0w/affine-mcp-server/releases)
|
|
491
475
|
|
|
492
476
|
## Contributing
|
|
493
477
|
|