AFFiNE MCP Server
A Model Context Protocol (MCP) server for AFFiNE. It exposes AFFiNE workspaces and documents to AI assistants over stdio (default) or HTTP (/mcp) and supports both AFFiNE Cloud and self-hosted deployments.
Table of Contents
- Overview
- Choose Your Path
- Quick Start
- Compatibility Matrix
- Tool Surface
- Documentation Map
- Verify Your Setup
- Security and Scope
- Development
- Release Notes
- License
- Support
Overview
AFFiNE MCP Server is designed for three common scenarios:
- Run a local stdio MCP server for Claude Code, Codex CLI, Cursor, or Claude Desktop
- Expose a remote HTTP MCP endpoint for hosted or browser-connected clients
- Automate AFFiNE workspace, document, database, organization, and comment workflows through a stable MCP tool surface
Highlights:
- Supports AFFiNE Cloud and self-hosted AFFiNE instances
- Supports stdio and HTTP transports
- Supports session-cookie and email/password authentication, plus compatible bearer tokens for older deployments
- Exposes 92 canonical MCP tools backed by AFFiNE GraphQL and WebSocket APIs
- Includes semantic page composition, native template instantiation, database intent composition, capability and fidelity reporting, and workspace blueprint helpers
- Includes Docker images, health probes, and end-to-end test coverage
Scope boundaries:
- This server can access only server-backed AFFiNE workspaces
- Browser-local workspaces stored only in local storage are not available through AFFiNE server APIs
- AFFiNE 0.27+ removed the legacy personal-access-token GraphQL API; this server no longer exposes token-management tools
- AFFiNE Cloud requires browser-session authentication for this external GraphQL integration; programmatic email/password sign-in is blocked by Cloudflare
New in v3.0.1: Markdown import/export now preserves AFFiNE inline LinkedPage references for safe round-tripping.
Choose Your Path
| Goal | Start here |
|---|---|
| Set up a local stdio server with the least friction | docs/getting-started.md |
| Run the server in Docker or another OCI runtime | docs/getting-started.md#path-c-run-from-the-docker-image |
| Configure Claude Code, Claude Desktop, Codex CLI, or Cursor | docs/client-setup.md |
| Run the server remotely over HTTP or behind OAuth | docs/configuration-and-deployment.md |
| Lock down tool exposure for least-privilege deployments | docs/configuration-and-deployment.md#least-privilege-tool-exposure |
| Learn common AFFiNE workflows and tool sequences | docs/workflow-recipes.md |
| Browse the tool catalog by domain | docs/tool-reference.md |
Quick Start
1. Install the CLI
npm i -g affine-mcp-server
affine-mcp --version
You can also run the package ad hoc:
npx -y -p affine-mcp-server affine-mcp -- --version
2. Or run the server in Docker
docker run -d \
-p 3000:3000 \
-e MCP_TRANSPORT=http \
-e AFFINE_BASE_URL=https://your-affine-instance.com \
-e [email protected] \
-e AFFINE_PASSWORD=your-password \
-e AFFINE_MCP_AUTH_MODE=bearer \
-e AFFINE_MCP_HTTP_TOKEN=your-strong-secret \
ghcr.io/dawncr0w/affine-mcp-server:latest
Then point your client at:
{
"mcpServers": {
"affine": {
"type": "http",
"url": "http://localhost:3000/mcp",
"headers": {
"Authorization": "Bearer your-strong-secret"
}
}
}
}
For Docker, health checks, and remote deployment details, see docs/configuration-and-deployment.md#docker.
3. Save credentials with interactive login
affine-mcp login
This stores credentials in $XDG_CONFIG_HOME/affine-mcp/config when XDG_CONFIG_HOME is set, otherwise in ~/.config/affine-mcp/config, with mode 600.
- For AFFiNE Cloud, paste the Cookie request header from a signed-in browser session
- For self-hosted AFFiNE, use email/password (recommended) or a signed-in session cookie
AFFINE_API_TOKENremains available only for deployments that still accept a compatible GraphQL bearer token
4. Register the server with your client
Claude Code project config:
{
"mcpServers": {
"affine": {
"command": "affine-mcp"
}
}
}
Codex CLI:
codex mcp add affine -- affine-mcp
More client-specific setup is in docs/client-setup.md.
5. Verify the connection
affine-mcp status
affine-mcp doctor
If you want to expose the server remotely over HTTP instead of stdio, start with docs/configuration-and-deployment.md.
Compatibility Matrix
Node.js 20 is the minimum supported runtime. CI validates the minimum runtime and the current Node.js release used by the npm publish workflow.
| Target | Transport | Recommended auth | Recommended path |
|---|---|---|---|
| Claude Code | stdio | Saved config | docs/client-setup.md#claude-code |
| Claude Desktop | stdio | Saved config or session cookie | docs/client-setup.md#claude-desktop |
| Codex CLI | stdio | Saved config or self-hosted email/password | docs/client-setup.md#codex-cli |
| Cursor | stdio | Saved config or session cookie | docs/client-setup.md#cursor |
| Containerized remote deployment | HTTP | Bearer token or OAuth | docs/getting-started.md#path-c-run-from-the-docker-image |
| Remote MCP clients | HTTP | Bearer token or OAuth | docs/configuration-and-deployment.md#http-mode |
| AFFiNE Cloud | stdio or HTTP | Signed-in browser session cookie | docs/configuration-and-deployment.md#auth-strategy-matrix |
| Self-hosted AFFiNE | stdio or HTTP | Email/password or session cookie | docs/configuration-and-deployment.md#auth-strategy-matrix |
Tool Surface
tool-manifest.json is the source of truth for canonical tool names. The MCP server exposes those tools through tools/list and tools/call; tool definitions returned by tools/list include MCP annotations that mark read-only, destructive, idempotent, and external-world behavior for client-side tool selection.
Domains:
- Workspace: create, inspect, update, delete, and traverse workspaces
- Organization: collections, collection-rule sync, workspace blueprints, and experimental organize or folder helpers
- Documents: search, read, create, publish, move, tag, custom properties, import/export, semantic composition, template inspection and native instantiation, capability and fidelity reporting, and block-level mutation
- Databases: create columns, add rows, update rows, inspect schema, and compose database structures from intent
- Comments: list, create, update, delete, and resolve
- History: version history listing
- Users and authentication: current user, sign-in, and profile/settings
- Notifications: list and mark notifications as read
- Blob storage: upload, delete, and cleanup blobs
Use AFFINE_TOOL_PROFILE=read_only, core, or authoring when a deployment should expose a smaller surface than the complete full default. This is the recommended path for hosted, browser-connected, or least-privilege deployments because it reduces agent choice overload while keeping the full tool catalog available as an opt-in surface. You can also combine profiles with AFFINE_DISABLED_GROUPS such as docs.database, destructive, or admin for finer control.
For the grouped catalog, notes, and operational caveats, see docs/tool-reference.md.
Documentation Map
| Document | Purpose |
|---|---|
| docs/getting-started.md | First-run setup paths and verification |
| docs/client-setup.md | Client-specific configuration snippets and tips |
| docs/configuration-and-deployment.md | Environment variables, auth modes, Docker, HTTP mode, and deployment guidance |
| docs/workflow-recipes.md | End-to-end workflows and example tool sequences |
| docs/tool-reference.md | Tool catalog grouped by domain |
| docs/edgeless-canvas-cookbook.md | Edgeless canvas layout helpers and surface elements, worked end-to-end |
| CONTRIBUTING.md | Contributor workflow |
| SECURITY.md | Security reporting |
Verify Your Setup
Useful CLI commands:
affine-mcp status- test the effective configurationaffine-mcp status --json- machine-readable status outputaffine-mcp doctor- diagnose config and connectivity issuesaffine-mcp show-config- print the effective config with secrets redactedaffine-mcp config-path- print the config file pathaffine-mcp snippet <claude|cursor|codex|all> [--env]- generate ready-to-paste client configaffine-mcp logout- remove stored credentials
status, doctor, and the server runtime use the same environment > saved config > defaults resolution. For a self-hosted deployment with a non-standard GraphQL route, use affine-mcp login --graphql-path /your/graphql/path or set AFFINE_GRAPHQL_PATH; show-config --json prints the exact resolved graphqlEndpoint without exposing secrets.
For common failures, see:
- docs/getting-started.md#common-first-run-failures
- docs/configuration-and-deployment.md#deployment-checklist
Security and Scope
- Never commit passwords, session cookies, or compatible bearer tokens
- Use a dedicated least-privilege AFFiNE account for unattended deployments
- Email/password HTTP sessions share one login and never fall back to anonymous backend requests after authentication failure
- Use HTTPS for non-local deployments
- Keep remote HTTP MCP listeners authenticated; bearer mode refuses a non-loopback bind without
AFFINE_MCP_HTTP_TOKEN - Send MCP bearer tokens in the
Authorizationheader, never in the URL - Re-run
affine-mcp loginwhen a saved browser session expires - Restrict exposed tools with
AFFINE_DISABLED_GROUPSandAFFINE_DISABLED_TOOLSfor least-privilege setups - Treat OAuth mode as a shared AFFiNE service-account deployment: it defaults to
read_only, and write-capable profiles requireAFFINE_OAUTH_ALLOW_SERVICE_WRITES=true - Use
/healthzand/readyzwhen running the HTTP server behind a container platform or load balancer - Set HTTP body, session, idle, and shutdown limits explicitly for high-volume deployments
Development
Run the main quality gates before opening a PR:
npm run ci
Additional validation:
npm testverifies tool metadata, test-suite coverage, and the fast regression suite without requiring a live AFFiNE instancenpm run test:comprehensiveboots a local Docker AFFiNE stack and validates the tool surfacenpm run test:e2eruns Docker, MCP, and Playwright togethernpm run test:playwrightruns the Playwright suite only- Focused runners for the new high-level tool surface include
npm run test:create-placement,npm run test:capabilities-fidelity,npm run test:native-template,npm run test:mutation-ack,node tests/test-database-intent.mjs,node tests/test-semantic-page-composer.mjs,node tests/test-structured-receipts.mjs,node tests/test-organize-tools.mjs, andnode tests/test-supporting-tools.mjs
Live tests can mutate or delete AFFiNE data. They allow loopback targets by
default and refuse non-loopback targets unless the disposable target is
explicitly enabled and confirmed as documented in CONTRIBUTING.md. Never run
them against production.
Local clone flow:
git clone https://github.com/dawncr0w/affine-mcp-server.git
cd affine-mcp-server
npm install
npm run build
node dist/index.js
Release Notes
License
MIT License - see LICENSE.
Support
- Open an issue on GitHub
- Review AFFiNE product documentation at docs.affine.pro
Acknowledgments
- Built for the AFFiNE knowledge base platform
- Uses the Model Context Protocol specification
- Powered by @modelcontextprotocol/sdk
No comments yet
Be the first to share your take.