affine-mcp-server 1.9.0 → 1.10.1

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 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
- [![Version](https://img.shields.io/badge/version-1.9.0-blue)](https://github.com/dawncr0w/affine-mcp-server/releases)
5
+ [![Version](https://img.shields.io/badge/version-1.10.1-blue)](https://github.com/dawncr0w/affine-mcp-server/releases)
6
6
  [![MCP SDK](https://img.shields.io/badge/MCP%20SDK-1.17.2-green)](https://github.com/modelcontextprotocol/typescript-sdk)
7
7
  [![CI](https://github.com/dawncr0w/affine-mcp-server/actions/workflows/ci.yml/badge.svg)](https://github.com/dawncr0w/affine-mcp-server/actions/workflows/ci.yml)
8
8
  [![License](https://img.shields.io/badge/license-MIT-yellow)](LICENSE)
@@ -16,10 +16,10 @@ 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: 47 focused tools with WebSocket-based document editing
19
+ - Tools: 61 focused tools with WebSocket-based document editing
20
20
  - Status: Active
21
21
 
22
- > New in v1.9.0: Added database schema discovery, preset-backed data views, self-bootstrapping comprehensive regression, focused supporting-tools coverage, and markdown callout round-trips.
22
+ > New in v1.10.1: Refreshed packaged docs and release metadata for the v1.10.x toolset, and tightened tag-publish validation with E2E coverage. No runtime or tool-behavior changes.
23
23
 
24
24
  ## Features
25
25
 
@@ -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
- - One auth method:
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" # Default: 127.0.0.1
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
 
@@ -309,23 +362,33 @@ Endpoints currently available:
309
362
  - `create_workspace` – create workspace with initial document
310
363
  - `update_workspace` – update workspace settings
311
364
  - `delete_workspace` – delete workspace permanently
365
+ - `list_workspace_tree` – return the workspace document hierarchy as a tree
366
+ - `get_orphan_docs` – find documents that are not linked from any parent doc in the sidebar tree
312
367
 
313
368
  ### Documents
314
369
  - `list_docs` – list documents with pagination (includes `node.tags`)
315
370
  - `list_tags` – list all tags in a workspace
316
- - `list_docs_by_tag` – list documents by tag
371
+ - `search_docs` – fast title search with substring/prefix/exact matching, optional tag filtering, and updatedAt sorting
372
+ - `list_docs_by_tag` – list documents that contain the requested tag
373
+ - `get_docs_by_tag` – discover documents by case-insensitive tag substring and return `availableTags` when nothing matches
317
374
  - `get_doc` – get document metadata
375
+ - `get_doc_by_title` – find a document by title and return its Markdown content
318
376
  - `read_doc` – read document block content and plain text snapshot (WebSocket)
319
377
  - `export_doc_markdown` – export document content as markdown
320
378
  - `publish_doc` – make document public
321
379
  - `revoke_doc` – revoke public access
322
380
  - `create_doc` – create a new document (WebSocket)
323
381
  - `create_doc_from_markdown` – create a document from markdown content
382
+ - `create_doc_from_template` – clone a template doc, substitute `{{variables}}`, and optionally link it under a parent doc
383
+ - `duplicate_doc` – clone a document into a new doc, optionally under a parent doc
324
384
  - `create_tag` – create a reusable workspace-level tag
325
385
  - `add_tag_to_doc` – attach a tag to a document
326
386
  - `remove_tag_from_doc` – detach a tag from a document
387
+ - `update_doc_title` – rename a document in both workspace metadata and the internal page block
327
388
  - `append_paragraph` – append a paragraph block (WebSocket)
328
389
  - `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)
390
+ - `move_doc` – move a document in the sidebar by relinking it under a different parent
391
+ - `batch_create_docs` – create up to 20 documents in a single call
329
392
  - `add_database_column` – add a column to a database block (`rich-text`, `select`, `multi-select`, `number`, `checkbox`, `link`, `date`)
330
393
  - `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)
331
394
  - `read_database_columns` – read database schema metadata including column IDs/types, select options, and table view column mappings
@@ -334,6 +397,10 @@ Endpoints currently available:
334
397
  - `update_database_row` – batch update multiple cells on a database row (`createOption` defaults to `true` for select fields)
335
398
  - `append_markdown` – append markdown content to an existing document
336
399
  - `replace_doc_with_markdown` – replace the main note content with markdown content
400
+ - `list_children` – list the direct child docs linked from a document
401
+ - `list_backlinks` – list the parent/reference docs that link to a document
402
+ - `cleanup_orphan_embeds` – remove linked-doc embeds that point to missing docs
403
+ - `find_and_replace` – preview or apply text replacement across a document
337
404
  - `delete_doc` – delete a document (WebSocket)
338
405
 
339
406
  ### Comments
@@ -380,7 +447,7 @@ npm run pack:check
380
447
  - For full tool-surface verification, run `npm run test:comprehensive` (self-bootstraps a local Docker AFFiNE stack).
381
448
  - For pre-provisioned environments, use `npm run test:comprehensive:raw`.
382
449
  - For full environment verification, run `npm run test:e2e` (Docker + MCP + Playwright).
383
- - 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:cli-version`, `npm run test:playwright`.
450
+ - 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`.
384
451
 
385
452
  ## Troubleshooting
386
453