affine-mcp-server 1.12.0 → 2.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/README.md +155 -502
- package/dist/edgeless/layout.js +222 -0
- package/dist/index.js +34 -62
- package/dist/markdown/parse.js +51 -10
- package/dist/toolSurface.js +322 -0
- package/dist/tools/comments.js +25 -5
- package/dist/tools/docs.js +3220 -583
- package/dist/tools/organize.js +419 -42
- package/dist/tools/workspaces.js +25 -6
- package/dist/util/mcp.js +26 -2
- package/docs/assets/edgeless-canvas-demo-advanced-dark.png +0 -0
- package/docs/assets/edgeless-canvas-demo-advanced-light.png +0 -0
- package/docs/client-setup.md +174 -0
- package/docs/configuration-and-deployment.md +265 -0
- package/docs/edgeless-canvas-cookbook.md +226 -0
- package/docs/getting-started.md +229 -0
- package/docs/tool-reference.md +186 -0
- package/docs/workflow-recipes.md +147 -0
- package/package.json +11 -2
- package/tool-manifest.json +89 -0
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# AFFiNE MCP Server
|
|
2
2
|
|
|
3
|
-
A Model Context Protocol (MCP) server
|
|
3
|
+
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.
|
|
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)
|
|
@@ -11,604 +11,257 @@ A Model Context Protocol (MCP) server that integrates with AFFiNE (self‑hosted
|
|
|
11
11
|
<img width="380" height="200" src="https://glama.ai/mcp/servers/@DAWNCR0W/affine-mcp-server/badge" alt="AFFiNE Server MCP server" />
|
|
12
12
|
</a>
|
|
13
13
|
|
|
14
|
-
##
|
|
15
|
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
-
|
|
20
|
-
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
14
|
+
## Table of Contents
|
|
15
|
+
|
|
16
|
+
- [Overview](#overview)
|
|
17
|
+
- [Choose Your Path](#choose-your-path)
|
|
18
|
+
- [Quick Start](#quick-start)
|
|
19
|
+
- [Compatibility Matrix](#compatibility-matrix)
|
|
20
|
+
- [Tool Surface](#tool-surface)
|
|
21
|
+
- [Documentation Map](#documentation-map)
|
|
22
|
+
- [Verify Your Setup](#verify-your-setup)
|
|
23
|
+
- [Security and Scope](#security-and-scope)
|
|
24
|
+
- [Development](#development)
|
|
25
|
+
- [Release Notes](#release-notes)
|
|
26
|
+
- [License](#license)
|
|
27
|
+
- [Support](#support)
|
|
25
28
|
|
|
26
|
-
|
|
27
|
-
- Documents: list/get/read/publish/revoke + create/append/replace/delete + markdown import/export + tags (WebSocket‑based)
|
|
28
|
-
- Sidebar data: collections, folders, and organize links for AFFiNE workspace trees
|
|
29
|
-
- Database workflows: create database blocks, inspect schema, add/update/delete rows, and read or update cell values via MCP tools
|
|
30
|
-
- Comments: full CRUD and resolve
|
|
31
|
-
- Version History: list
|
|
32
|
-
- Users & Tokens: current user, sign in, profile/settings, and personal access tokens
|
|
33
|
-
- Notifications: list and mark as read
|
|
34
|
-
- Blob storage: upload/delete/cleanup
|
|
35
|
-
|
|
36
|
-
## Requirements
|
|
29
|
+
## Overview
|
|
37
30
|
|
|
38
|
-
|
|
39
|
-
-
|
|
40
|
-
-
|
|
31
|
+
AFFiNE MCP Server is designed for three common scenarios:
|
|
32
|
+
- Run a local stdio MCP server for Claude Code, Codex CLI, Cursor, or Claude Desktop
|
|
33
|
+
- Expose a remote HTTP MCP endpoint for hosted or browser-connected clients
|
|
34
|
+
- Automate AFFiNE workspace, document, database, organization, and comment workflows through a stable MCP tool surface
|
|
41
35
|
|
|
42
|
-
|
|
36
|
+
Highlights:
|
|
43
37
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
38
|
+
- Supports AFFiNE Cloud and self-hosted AFFiNE instances
|
|
39
|
+
- Supports stdio and HTTP transports
|
|
40
|
+
- Supports token, cookie, and email/password authentication
|
|
41
|
+
- Exposes 84 canonical MCP tools backed by AFFiNE GraphQL and WebSocket APIs
|
|
42
|
+
- Includes semantic page composition, native template instantiation, database intent composition, capability and fidelity reporting, and workspace blueprint helpers
|
|
43
|
+
- Includes Docker images, health probes, and end-to-end test coverage
|
|
47
44
|
|
|
48
|
-
|
|
49
|
-
npx -y -p affine-mcp-server affine-mcp -- --version
|
|
50
|
-
```
|
|
45
|
+
Scope boundaries:
|
|
51
46
|
|
|
52
|
-
|
|
47
|
+
- This server can access only server-backed AFFiNE workspaces
|
|
48
|
+
- Browser-local workspaces stored only in local storage are not available through AFFiNE server APIs
|
|
49
|
+
- AFFiNE Cloud requires API-token-based access for MCP usage; programmatic email/password sign-in is blocked by Cloudflare
|
|
53
50
|
|
|
54
|
-
|
|
51
|
+
> New in v2.0.0: Added native edgeless canvas tools and shipped a slimmer 84-tool public surface with least-privilege profiles for read-only, core, and authoring deployments.
|
|
55
52
|
|
|
56
|
-
##
|
|
53
|
+
## Choose Your Path
|
|
54
|
+
| Goal | Start here |
|
|
55
|
+
| --- | --- |
|
|
56
|
+
| Set up a local stdio server with the least friction | [docs/getting-started.md](docs/getting-started.md) |
|
|
57
|
+
| Run the server in Docker or another OCI runtime | [docs/getting-started.md#path-c-run-from-the-docker-image](docs/getting-started.md#path-c-run-from-the-docker-image) |
|
|
58
|
+
| Configure Claude Code, Claude Desktop, Codex CLI, or Cursor | [docs/client-setup.md](docs/client-setup.md) |
|
|
59
|
+
| Run the server remotely over HTTP or behind OAuth | [docs/configuration-and-deployment.md](docs/configuration-and-deployment.md) |
|
|
60
|
+
| Lock down tool exposure for least-privilege deployments | [docs/configuration-and-deployment.md#least-privilege-tool-exposure](docs/configuration-and-deployment.md#least-privilege-tool-exposure) |
|
|
61
|
+
| Learn common AFFiNE workflows and tool sequences | [docs/workflow-recipes.md](docs/workflow-recipes.md) |
|
|
62
|
+
| Browse the tool catalog by domain | [docs/tool-reference.md](docs/tool-reference.md) |
|
|
57
63
|
|
|
58
|
-
|
|
64
|
+
## Quick Start
|
|
59
65
|
|
|
60
|
-
|
|
66
|
+
### 1. Install the CLI
|
|
61
67
|
|
|
62
68
|
```bash
|
|
63
69
|
npm i -g affine-mcp-server
|
|
64
|
-
affine-mcp
|
|
70
|
+
affine-mcp --version
|
|
65
71
|
```
|
|
66
72
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
**AFFiNE Cloud** (`app.affine.pro`): you'll be prompted to paste an API token from Settings → Integrations → MCP Server.
|
|
70
|
-
|
|
71
|
-
**Self-hosted instances**: you can choose between email/password (recommended — auto-generates an API token) or pasting a token manually.
|
|
72
|
-
|
|
73
|
-
```
|
|
74
|
-
$ affine-mcp login
|
|
75
|
-
Affine MCP Server — Login
|
|
76
|
-
|
|
77
|
-
Affine URL [https://app.affine.pro]: https://my-affine.example.com
|
|
78
|
-
|
|
79
|
-
Auth method — [1] Email/password (recommended) [2] Paste API token: 1
|
|
80
|
-
Email: user@example.com
|
|
81
|
-
Password: ****
|
|
82
|
-
Signing in...
|
|
83
|
-
✓ Signed in as: User Name <user@example.com>
|
|
84
|
-
|
|
85
|
-
Generating API token...
|
|
86
|
-
✓ Created token: ut_abc123... (name: affine-mcp-2026-02-18)
|
|
87
|
-
|
|
88
|
-
Detecting workspaces...
|
|
89
|
-
Found 1 workspace: abc-def-123 (by User Name, 1 member, 2/10/2026)
|
|
90
|
-
Auto-selected.
|
|
73
|
+
You can also run the package ad hoc:
|
|
91
74
|
|
|
92
|
-
|
|
93
|
-
|
|
75
|
+
```bash
|
|
76
|
+
npx -y -p affine-mcp-server affine-mcp -- --version
|
|
94
77
|
```
|
|
95
78
|
|
|
96
|
-
|
|
97
|
-
- `affine-mcp --help` / `-h` / `help` — show command help
|
|
98
|
-
- `affine-mcp status` — show current config and test connection
|
|
99
|
-
- `affine-mcp status --json` — machine-readable status output
|
|
100
|
-
- `affine-mcp doctor` — run config and connectivity diagnostics
|
|
101
|
-
- `affine-mcp show-config` — print the effective config with secrets redacted
|
|
102
|
-
- `affine-mcp config-path` — print the config file path
|
|
103
|
-
- `affine-mcp snippet <claude|cursor|codex|all> [--env]` — print ready-to-paste client configuration snippets
|
|
104
|
-
- `affine-mcp logout` — remove stored credentials
|
|
105
|
-
- `affine-mcp --version` / `-v` / `version` — print the installed CLI version and exit
|
|
106
|
-
|
|
107
|
-
Non-interactive login helpers:
|
|
108
|
-
- `affine-mcp login --url <url> --token <token> --workspace-id <id> --force`
|
|
109
|
-
|
|
110
|
-
### Environment variables
|
|
111
|
-
|
|
112
|
-
You can also configure via environment variables (they override the config file):
|
|
113
|
-
|
|
114
|
-
- Required: `AFFINE_BASE_URL`
|
|
115
|
-
- Auth (choose one): `AFFINE_API_TOKEN` | `AFFINE_COOKIE` | `AFFINE_EMAIL` + `AFFINE_PASSWORD`
|
|
116
|
-
- Optional: `AFFINE_GRAPHQL_PATH` (default `/graphql`), `AFFINE_WORKSPACE_ID`, `AFFINE_LOGIN_AT_START` (set `sync` only when you must block startup)
|
|
117
|
-
- Tool filtering: `AFFINE_DISABLED_GROUPS`, `AFFINE_DISABLED_TOOLS` (see [Filtering Exposed Tools](#filtering-exposed-tools))
|
|
118
|
-
|
|
119
|
-
Authentication priority:
|
|
120
|
-
1) `AFFINE_API_TOKEN` → 2) `AFFINE_COOKIE` → 3) `AFFINE_EMAIL` + `AFFINE_PASSWORD`
|
|
121
|
-
|
|
122
|
-
> **Cloudflare note**: `AFFINE_EMAIL`/`AFFINE_PASSWORD` auth requires programmatic access to `/api/auth/sign-in`. AFFiNE Cloud (`app.affine.pro`) is behind Cloudflare, which blocks these requests. Use `AFFINE_API_TOKEN` for cloud, or use `affine-mcp login` which handles this automatically. Email/password works for self-hosted instances without Cloudflare.
|
|
123
|
-
|
|
124
|
-
## Quick Start
|
|
125
|
-
|
|
126
|
-
### Claude Code
|
|
127
|
-
|
|
128
|
-
After running `affine-mcp login`, add to your project's `.mcp.json`:
|
|
79
|
+
### 2. Or run the server in Docker
|
|
129
80
|
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
81
|
+
```bash
|
|
82
|
+
docker run -d \
|
|
83
|
+
-p 3000:3000 \
|
|
84
|
+
-e MCP_TRANSPORT=http \
|
|
85
|
+
-e AFFINE_BASE_URL=https://your-affine-instance.com \
|
|
86
|
+
-e AFFINE_API_TOKEN=ut_your_token \
|
|
87
|
+
-e AFFINE_MCP_AUTH_MODE=bearer \
|
|
88
|
+
-e AFFINE_MCP_HTTP_TOKEN=your-strong-secret \
|
|
89
|
+
ghcr.io/dawncr0w/affine-mcp-server:latest
|
|
138
90
|
```
|
|
139
91
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
If you prefer explicit env vars instead of the config file:
|
|
92
|
+
Then point your client at:
|
|
143
93
|
|
|
144
94
|
```json
|
|
145
95
|
{
|
|
146
96
|
"mcpServers": {
|
|
147
97
|
"affine": {
|
|
148
|
-
"
|
|
149
|
-
"
|
|
150
|
-
|
|
151
|
-
"
|
|
98
|
+
"type": "http",
|
|
99
|
+
"url": "http://localhost:3000/mcp",
|
|
100
|
+
"headers": {
|
|
101
|
+
"Authorization": "Bearer your-strong-secret"
|
|
152
102
|
}
|
|
153
103
|
}
|
|
154
104
|
}
|
|
155
105
|
}
|
|
156
106
|
```
|
|
157
107
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
Add to your Claude Desktop configuration:
|
|
161
|
-
|
|
162
|
-
- macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
163
|
-
- Windows: `%APPDATA%\Claude\claude_desktop_config.json`
|
|
164
|
-
- Linux: `~/.config/Claude/claude_desktop_config.json`
|
|
165
|
-
|
|
166
|
-
```json
|
|
167
|
-
{
|
|
168
|
-
"mcpServers": {
|
|
169
|
-
"affine": {
|
|
170
|
-
"command": "affine-mcp",
|
|
171
|
-
"env": {
|
|
172
|
-
"AFFINE_BASE_URL": "https://app.affine.pro",
|
|
173
|
-
"AFFINE_API_TOKEN": "ut_xxx"
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
```
|
|
108
|
+
For Docker, health checks, and remote deployment details, see [docs/configuration-and-deployment.md#docker](docs/configuration-and-deployment.md#docker).
|
|
179
109
|
|
|
180
|
-
|
|
110
|
+
### 3. Save credentials with interactive login
|
|
181
111
|
|
|
182
|
-
```
|
|
183
|
-
|
|
184
|
-
"mcpServers": {
|
|
185
|
-
"affine": {
|
|
186
|
-
"command": "affine-mcp",
|
|
187
|
-
"env": {
|
|
188
|
-
"AFFINE_BASE_URL": "https://your-self-hosted-affine.com",
|
|
189
|
-
"AFFINE_EMAIL": "you@example.com",
|
|
190
|
-
"AFFINE_PASSWORD": "secret!"
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
}
|
|
112
|
+
```bash
|
|
113
|
+
affine-mcp login
|
|
195
114
|
```
|
|
196
115
|
|
|
197
|
-
|
|
198
|
-
- Prefer `affine-mcp login` or `AFFINE_API_TOKEN` for zero‑latency startup.
|
|
199
|
-
- If your password contains `!` (zsh history expansion), wrap it in single quotes in shells or use the JSON config above.
|
|
200
|
-
- `affine-mcp doctor` is the fastest way to confirm that your saved config still works.
|
|
201
|
-
- `affine-mcp snippet claude --env` and `affine-mcp snippet codex --env` can generate ready-to-paste client setup from your current config.
|
|
202
|
-
- `affine-mcp snippet all --env` prints Claude, Cursor, and Codex setup in one shot.
|
|
203
|
-
|
|
204
|
-
### Codex CLI
|
|
205
|
-
|
|
206
|
-
Register the MCP server with Codex:
|
|
116
|
+
This stores credentials in `~/.config/affine-mcp/config` with mode `600`.
|
|
207
117
|
|
|
208
|
-
-
|
|
209
|
-
|
|
118
|
+
- For AFFiNE Cloud, use an API token from `Settings -> Integrations -> MCP Server`
|
|
119
|
+
- For self-hosted AFFiNE, you can use either an API token or email/password
|
|
210
120
|
|
|
211
|
-
|
|
212
|
-
- `codex mcp add affine --env AFFINE_BASE_URL=https://app.affine.pro --env AFFINE_API_TOKEN=ut_xxx -- affine-mcp`
|
|
121
|
+
### 4. Register the server with your client
|
|
213
122
|
|
|
214
|
-
|
|
215
|
-
- `codex mcp add affine --env AFFINE_BASE_URL=https://your-self-hosted-affine.com --env 'AFFINE_EMAIL=you@example.com' --env 'AFFINE_PASSWORD=secret!' -- affine-mcp`
|
|
216
|
-
|
|
217
|
-
### Cursor
|
|
218
|
-
|
|
219
|
-
Cursor also supports MCP over stdio with `mcp.json`.
|
|
220
|
-
|
|
221
|
-
Project-local (`.cursor/mcp.json`) example:
|
|
123
|
+
Claude Code project config:
|
|
222
124
|
|
|
223
125
|
```json
|
|
224
126
|
{
|
|
225
127
|
"mcpServers": {
|
|
226
128
|
"affine": {
|
|
227
|
-
"command": "affine-mcp"
|
|
228
|
-
"env": {
|
|
229
|
-
"AFFINE_BASE_URL": "https://app.affine.pro",
|
|
230
|
-
"AFFINE_API_TOKEN": "ut_xxx"
|
|
231
|
-
}
|
|
129
|
+
"command": "affine-mcp"
|
|
232
130
|
}
|
|
233
131
|
}
|
|
234
132
|
}
|
|
235
133
|
```
|
|
236
134
|
|
|
237
|
-
|
|
135
|
+
Codex CLI:
|
|
238
136
|
|
|
239
|
-
```
|
|
240
|
-
|
|
241
|
-
"mcpServers": {
|
|
242
|
-
"affine": {
|
|
243
|
-
"command": "npx",
|
|
244
|
-
"args": ["-y", "-p", "affine-mcp-server", "affine-mcp"],
|
|
245
|
-
"env": {
|
|
246
|
-
"AFFINE_BASE_URL": "https://app.affine.pro",
|
|
247
|
-
"AFFINE_API_TOKEN": "ut_xxx"
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
}
|
|
137
|
+
```bash
|
|
138
|
+
codex mcp add affine -- affine-mcp
|
|
252
139
|
```
|
|
253
140
|
|
|
254
|
-
|
|
141
|
+
More client-specific setup is in [docs/client-setup.md](docs/client-setup.md).
|
|
255
142
|
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
```
|
|
259
|
-
ghcr.io/dawncr0w/affine-mcp-server:latest # latest release
|
|
260
|
-
ghcr.io/dawncr0w/affine-mcp-server:1.12.0 # specific version
|
|
261
|
-
```
|
|
262
|
-
|
|
263
|
-
Quick start:
|
|
143
|
+
### 5. Verify the connection
|
|
264
144
|
|
|
265
145
|
```bash
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
-e AFFINE_BASE_URL=https://your-affine-instance.com \
|
|
269
|
-
-e AFFINE_API_TOKEN=ut_your_token \
|
|
270
|
-
-e AFFINE_MCP_HTTP_TOKEN=your-strong-secret \
|
|
271
|
-
ghcr.io/dawncr0w/affine-mcp-server:latest
|
|
146
|
+
affine-mcp status
|
|
147
|
+
affine-mcp doctor
|
|
272
148
|
```
|
|
273
149
|
|
|
274
|
-
|
|
150
|
+
If you want to expose the server remotely over HTTP instead of stdio, start with [docs/configuration-and-deployment.md](docs/configuration-and-deployment.md).
|
|
275
151
|
|
|
276
|
-
|
|
277
|
-
{
|
|
278
|
-
"mcpServers": {
|
|
279
|
-
"affine": {
|
|
280
|
-
"type": "http",
|
|
281
|
-
"url": "http://localhost:3000/mcp",
|
|
282
|
-
"headers": { "Authorization": "Bearer your-strong-secret" }
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
```
|
|
152
|
+
## Compatibility Matrix
|
|
287
153
|
|
|
288
|
-
|
|
154
|
+
| Target | Transport | Recommended auth | Recommended path |
|
|
155
|
+
| --- | --- | --- | --- |
|
|
156
|
+
| Claude Code | stdio | Saved config or API token | [docs/client-setup.md#claude-code](docs/client-setup.md#claude-code) |
|
|
157
|
+
| Claude Desktop | stdio | Saved config or API token | [docs/client-setup.md#claude-desktop](docs/client-setup.md#claude-desktop) |
|
|
158
|
+
| Codex CLI | stdio | Saved config or API token | [docs/client-setup.md#codex-cli](docs/client-setup.md#codex-cli) |
|
|
159
|
+
| Cursor | stdio | Saved config or API token | [docs/client-setup.md#cursor](docs/client-setup.md#cursor) |
|
|
160
|
+
| Containerized remote deployment | HTTP | Bearer token or OAuth | [docs/getting-started.md#path-c-run-from-the-docker-image](docs/getting-started.md#path-c-run-from-the-docker-image) |
|
|
161
|
+
| Remote MCP clients | HTTP | Bearer token or OAuth | [docs/configuration-and-deployment.md#http-mode](docs/configuration-and-deployment.md#http-mode) |
|
|
162
|
+
| AFFiNE Cloud | stdio or HTTP | API token | [docs/configuration-and-deployment.md#auth-strategy-matrix](docs/configuration-and-deployment.md#auth-strategy-matrix) |
|
|
163
|
+
| Self-hosted AFFiNE | stdio or HTTP | API token, cookie, or email/password | [docs/configuration-and-deployment.md#auth-strategy-matrix](docs/configuration-and-deployment.md#auth-strategy-matrix) |
|
|
289
164
|
|
|
290
|
-
|
|
165
|
+
## Tool Surface
|
|
291
166
|
|
|
292
|
-
|
|
167
|
+
`tool-manifest.json` is the source of truth for canonical tool names. The MCP server exposes those tools through `tools/list` and `tools/call`.
|
|
293
168
|
|
|
294
|
-
|
|
169
|
+
Domains:
|
|
295
170
|
|
|
296
|
-
|
|
297
|
-
-
|
|
298
|
-
-
|
|
299
|
-
-
|
|
171
|
+
- Workspace: create, inspect, update, delete, and traverse workspaces
|
|
172
|
+
- Organization: collections, collection-rule sync, workspace blueprints, and experimental organize or folder helpers
|
|
173
|
+
- Documents: search, read, create, publish, move, tag, import/export, semantic composition, template inspection and native instantiation, capability and fidelity reporting, and block-level mutation
|
|
174
|
+
- Databases: create columns, add rows, update rows, inspect schema, and compose database structures from intent
|
|
175
|
+
- Comments: list, create, update, delete, and resolve
|
|
176
|
+
- History: version history listing
|
|
177
|
+
- Users and tokens: current user, sign-in, profile/settings, personal access tokens
|
|
178
|
+
- Notifications: list and mark notifications as read
|
|
179
|
+
- Blob storage: upload, delete, and cleanup blobs
|
|
300
180
|
|
|
301
|
-
|
|
302
|
-
- `AFFINE_API_TOKEN` (recommended), or `AFFINE_COOKIE`, or `AFFINE_EMAIL` + `AFFINE_PASSWORD`
|
|
181
|
+
Use `AFFINE_TOOL_PROFILE=read_only`, `core`, or `authoring` when a deployment should expose a smaller surface than the complete `full` default. You can also combine profiles with `AFFINE_DISABLED_GROUPS` such as `docs.database`, `destructive`, or `admin` for finer control.
|
|
303
182
|
|
|
304
|
-
|
|
305
|
-
- `AFFINE_API_TOKEN` (required service credential for AFFiNE backend access)
|
|
183
|
+
For the grouped catalog, notes, and operational caveats, see [docs/tool-reference.md](docs/tool-reference.md).
|
|
306
184
|
|
|
307
|
-
|
|
308
|
-
- `AFFINE_MCP_HTTP_HOST=0.0.0.0`
|
|
309
|
-
- `AFFINE_MCP_HTTP_ALLOWED_ORIGINS=<comma-separated-origins>` (for browser clients)
|
|
185
|
+
## Documentation Map
|
|
310
186
|
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
-
|
|
314
|
-
-
|
|
315
|
-
-
|
|
187
|
+
| Document | Purpose |
|
|
188
|
+
| --- | --- |
|
|
189
|
+
| [docs/getting-started.md](docs/getting-started.md) | First-run setup paths and verification |
|
|
190
|
+
| [docs/client-setup.md](docs/client-setup.md) | Client-specific configuration snippets and tips |
|
|
191
|
+
| [docs/configuration-and-deployment.md](docs/configuration-and-deployment.md) | Environment variables, auth modes, Docker, HTTP mode, and deployment guidance |
|
|
192
|
+
| [docs/workflow-recipes.md](docs/workflow-recipes.md) | End-to-end workflows and example tool sequences |
|
|
193
|
+
| [docs/tool-reference.md](docs/tool-reference.md) | Tool catalog grouped by domain |
|
|
194
|
+
| [docs/edgeless-canvas-cookbook.md](docs/edgeless-canvas-cookbook.md) | Edgeless canvas layout helpers and surface elements, worked end-to-end |
|
|
195
|
+
| [CONTRIBUTING.md](CONTRIBUTING.md) | Contributor workflow |
|
|
196
|
+
| [SECURITY.md](SECURITY.md) | Security reporting |
|
|
316
197
|
|
|
317
|
-
|
|
318
|
-
- `AFFINE_MCP_HTTP_TOKEN=<strong-random-token>` (protects `/mcp`, `/sse`, `/messages`)
|
|
198
|
+
## Verify Your Setup
|
|
319
199
|
|
|
320
|
-
|
|
321
|
-
- `AFFINE_MCP_PUBLIC_BASE_URL=https://mcp.yourdomain.com`
|
|
322
|
-
- `AFFINE_OAUTH_ISSUER_URL=https://auth.yourdomain.com`
|
|
323
|
-
- `AFFINE_OAUTH_SCOPES=mcp` (defaults to `mcp`)
|
|
200
|
+
Useful CLI commands:
|
|
324
201
|
|
|
325
|
-
|
|
202
|
+
- `affine-mcp status` - test the effective configuration
|
|
203
|
+
- `affine-mcp status --json` - machine-readable status output
|
|
204
|
+
- `affine-mcp doctor` - diagnose config and connectivity issues
|
|
205
|
+
- `affine-mcp show-config` - print the effective config with secrets redacted
|
|
206
|
+
- `affine-mcp config-path` - print the config file path
|
|
207
|
+
- `affine-mcp snippet <claude|cursor|codex|all> [--env]` - generate ready-to-paste client config
|
|
208
|
+
- `affine-mcp logout` - remove stored credentials
|
|
326
209
|
|
|
327
|
-
|
|
210
|
+
For common failures, see:
|
|
328
211
|
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
export AFFINE_MCP_AUTH_MODE=bearer
|
|
332
|
-
export AFFINE_API_TOKEN="your_token..."
|
|
333
|
-
export AFFINE_MCP_HTTP_HOST="0.0.0.0"
|
|
334
|
-
export AFFINE_MCP_HTTP_TOKEN="your-super-secret-token"
|
|
335
|
-
export PORT=3000
|
|
336
|
-
|
|
337
|
-
npm run start:http
|
|
338
|
-
```
|
|
212
|
+
- [docs/getting-started.md#common-first-run-failures](docs/getting-started.md#common-first-run-failures)
|
|
213
|
+
- [docs/configuration-and-deployment.md#deployment-checklist](docs/configuration-and-deployment.md#deployment-checklist)
|
|
339
214
|
|
|
340
|
-
|
|
341
|
-
- the server exposes `/.well-known/oauth-protected-resource`
|
|
342
|
-
- unauthenticated `/mcp` requests return `401` with a `WWW-Authenticate` challenge
|
|
343
|
-
- `AFFINE_MCP_HTTP_TOKEN` and `?token=` are disabled
|
|
344
|
-
- `sign_in` is not registered
|
|
345
|
-
- `AFFINE_API_TOKEN` is still required so the server can call AFFiNE as a service credential
|
|
215
|
+
## Security and Scope
|
|
346
216
|
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
export AFFINE_OAUTH_ISSUER_URL="https://auth.yourdomain.com"
|
|
354
|
-
export AFFINE_OAUTH_SCOPES="mcp"
|
|
355
|
-
export PORT=3000
|
|
356
|
-
|
|
357
|
-
npm run start:http
|
|
358
|
-
```
|
|
217
|
+
- Never commit secrets or long-lived tokens
|
|
218
|
+
- Prefer API tokens over cookies or passwords in production
|
|
219
|
+
- Use HTTPS for non-local deployments
|
|
220
|
+
- Rotate access tokens regularly
|
|
221
|
+
- Restrict exposed tools with `AFFINE_DISABLED_GROUPS` and `AFFINE_DISABLED_TOOLS` for least-privilege setups
|
|
222
|
+
- Use `/healthz` and `/readyz` when running the HTTP server behind a container platform or load balancer
|
|
359
223
|
|
|
360
|
-
|
|
361
|
-
- use HTTPS for non-local deployments
|
|
362
|
-
- `AFFINE_MCP_HTTP_ALLOW_ALL_ORIGINS=true` is rejected in OAuth mode
|
|
363
|
-
- tokens are validated against the issuer discovery metadata and JWKS
|
|
364
|
-
- the protected resource metadata is also served at `/.well-known/oauth-protected-resource/mcp` for path-specific discovery
|
|
365
|
-
- `GET /healthz` and `GET /readyz` are available for deployment diagnostics
|
|
366
|
-
|
|
367
|
-
#### Recommended presets
|
|
368
|
-
|
|
369
|
-
Local testing (HTTP mode):
|
|
370
|
-
- `MCP_TRANSPORT=http`
|
|
371
|
-
- `AFFINE_MCP_AUTH_MODE=bearer`
|
|
372
|
-
- `AFFINE_MCP_HTTP_HOST=127.0.0.1`
|
|
373
|
-
- `AFFINE_MCP_HTTP_TOKEN=<token>` (recommended even locally)
|
|
374
|
-
- `AFFINE_MCP_HTTP_ALLOWED_ORIGINS=http://localhost:3000` (if testing from a browser app)
|
|
375
|
-
|
|
376
|
-
Docker / container runtime:
|
|
377
|
-
- `MCP_TRANSPORT=http`
|
|
378
|
-
- `AFFINE_MCP_AUTH_MODE=bearer`
|
|
379
|
-
- `AFFINE_MCP_HTTP_HOST=0.0.0.0`
|
|
380
|
-
- `PORT=3000` (or container/platform port)
|
|
381
|
-
- `AFFINE_MCP_HTTP_TOKEN=<strong-token>`
|
|
382
|
-
- `AFFINE_MCP_HTTP_ALLOWED_ORIGINS=<your app origin(s)>`
|
|
383
|
-
|
|
384
|
-
Render / Railway / VPS (public endpoint):
|
|
385
|
-
- `MCP_TRANSPORT=http`
|
|
386
|
-
- `AFFINE_MCP_AUTH_MODE=bearer` or `oauth`
|
|
387
|
-
- `AFFINE_MCP_HTTP_HOST=0.0.0.0`
|
|
388
|
-
- `AFFINE_MCP_HTTP_TOKEN=<strong-token>` (bearer mode)
|
|
389
|
-
- `AFFINE_MCP_PUBLIC_BASE_URL=<public base URL>` (OAuth mode)
|
|
390
|
-
- `AFFINE_OAUTH_ISSUER_URL=<issuer URL>` (OAuth mode)
|
|
391
|
-
- `AFFINE_MCP_HTTP_ALLOWED_ORIGINS=<your client origin(s)>`
|
|
392
|
-
|
|
393
|
-
Endpoints currently available:
|
|
394
|
-
- `/mcp` - MCP server (Streamable HTTP)
|
|
395
|
-
- `/sse` - SSE endpoint (old protocol compatible)
|
|
396
|
-
- `/messages` - Messages endpoint (old protocol compatible)
|
|
397
|
-
- `/healthz` - HTTP liveness probe
|
|
398
|
-
- `/readyz` - HTTP readiness probe
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
## Available Tools
|
|
402
|
-
|
|
403
|
-
### Workspace
|
|
404
|
-
- `list_workspaces` – list all workspaces
|
|
405
|
-
- `get_workspace` – get workspace details
|
|
406
|
-
- `create_workspace` – create workspace with initial document
|
|
407
|
-
- `update_workspace` – update workspace settings
|
|
408
|
-
- `delete_workspace` – delete workspace permanently
|
|
409
|
-
- `list_workspace_tree` – return the workspace document hierarchy as a tree
|
|
410
|
-
- `get_orphan_docs` – find documents that are not linked from any parent doc in the sidebar tree
|
|
411
|
-
|
|
412
|
-
### Organization
|
|
413
|
-
- `list_collections` – list workspace collections
|
|
414
|
-
- `get_collection` – get a collection by id
|
|
415
|
-
- `create_collection` – create a collection
|
|
416
|
-
- `update_collection` – rename a collection
|
|
417
|
-
- `delete_collection` – delete a collection
|
|
418
|
-
- `add_doc_to_collection` – add a document to a collection allow-list
|
|
419
|
-
- `remove_doc_from_collection` – remove a document from a collection allow-list
|
|
420
|
-
- `list_organize_nodes` – experimental organize/folder tree dump
|
|
421
|
-
- `create_folder` – experimental root or nested folder creation
|
|
422
|
-
- `rename_folder` – experimental folder rename
|
|
423
|
-
- `delete_folder` – experimental recursive folder delete
|
|
424
|
-
- `move_organize_node` – experimental folder/link move
|
|
425
|
-
- `add_organize_link` – experimental doc/tag/collection link under a folder
|
|
426
|
-
- `delete_organize_link` – experimental doc/tag/collection link delete
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
### Documents
|
|
430
|
-
- `list_docs` – list documents with pagination (includes `node.tags`)
|
|
431
|
-
- `list_tags` – list all tags in a workspace
|
|
432
|
-
- `search_docs` – fast title search with substring/prefix/exact matching, optional tag filtering, and updatedAt sorting
|
|
433
|
-
- `list_docs_by_tag` – list documents that contain the requested tag
|
|
434
|
-
- `get_docs_by_tag` – discover documents by case-insensitive tag substring and return `availableTags` when nothing matches
|
|
435
|
-
- `get_doc` – get document metadata
|
|
436
|
-
- `get_doc_by_title` – find a document by title and return its Markdown content
|
|
437
|
-
- `read_doc` – read document block content and plain text snapshot (WebSocket)
|
|
438
|
-
- `export_doc_markdown` – export document content as markdown
|
|
439
|
-
- `publish_doc` – make document public
|
|
440
|
-
- `revoke_doc` – revoke public access
|
|
441
|
-
- `create_doc` – create a new document (WebSocket)
|
|
442
|
-
- `create_doc_from_markdown` – create a document from markdown content
|
|
443
|
-
- `create_doc_from_template` – clone a template doc, substitute `{{variables}}`, and optionally link it under a parent doc
|
|
444
|
-
- `duplicate_doc` – clone a document into a new doc, optionally under a parent doc
|
|
445
|
-
- `create_tag` – create a reusable workspace-level tag
|
|
446
|
-
- `add_tag_to_doc` – attach a tag to a document
|
|
447
|
-
- `remove_tag_from_doc` – detach a tag from a document
|
|
448
|
-
- `update_doc_title` – rename a document in both workspace metadata and the internal page block
|
|
449
|
-
- `append_paragraph` – append a paragraph block (WebSocket)
|
|
450
|
-
- `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)
|
|
451
|
-
- `move_doc` – move a document in the sidebar by relinking it under a different parent
|
|
452
|
-
- `batch_create_docs` – create up to 20 documents in a single call
|
|
453
|
-
- `add_database_column` – add a column to a database block (`rich-text`, `select`, `multi-select`, `number`, `checkbox`, `link`, `date`)
|
|
454
|
-
- `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)
|
|
455
|
-
- `delete_database_row` – delete a row from a database block by row block id
|
|
456
|
-
- `read_database_columns` – read database schema metadata including column IDs/types, select options, and table view column mappings
|
|
457
|
-
- `read_database_cells` – read row titles plus decoded database cell values with optional row / column filters
|
|
458
|
-
- `update_database_cell` – update a single database cell or the built-in row title (`createOption` defaults to `true` for select fields)
|
|
459
|
-
- `update_database_row` – batch update multiple cells on a database row (`createOption` defaults to `true` for select fields)
|
|
460
|
-
- `append_markdown` – append markdown content to an existing document
|
|
461
|
-
- `replace_doc_with_markdown` – replace the main note content with markdown content
|
|
462
|
-
- `list_children` – list the direct child docs linked from a document
|
|
463
|
-
- `list_backlinks` – list the parent/reference docs that link to a document
|
|
464
|
-
- `cleanup_orphan_embeds` – remove linked-doc embeds that point to missing docs
|
|
465
|
-
- `find_and_replace` – preview or apply text replacement across a document
|
|
466
|
-
- `delete_doc` – delete a document (WebSocket)
|
|
467
|
-
|
|
468
|
-
### Comments
|
|
469
|
-
- `list_comments`, `create_comment`, `update_comment`, `delete_comment`, `resolve_comment`
|
|
470
|
-
|
|
471
|
-
### Version History
|
|
472
|
-
- `list_histories`
|
|
473
|
-
|
|
474
|
-
### Users & Tokens
|
|
475
|
-
- `current_user`, `sign_in`, `update_profile`, `update_settings`
|
|
476
|
-
- `list_access_tokens`, `generate_access_token`, `revoke_access_token`
|
|
477
|
-
|
|
478
|
-
### Notifications
|
|
479
|
-
- `list_notifications`, `read_all_notifications`
|
|
480
|
-
|
|
481
|
-
### Blob Storage
|
|
482
|
-
- `upload_blob`, `delete_blob`, `cleanup_blobs`
|
|
483
|
-
|
|
484
|
-
## Filtering Exposed Tools
|
|
485
|
-
|
|
486
|
-
Optional environment variables to narrow the exposed surface.
|
|
487
|
-
|
|
488
|
-
### Group-level — `AFFINE_DISABLED_GROUPS`
|
|
489
|
-
|
|
490
|
-
| Group name | Tools included |
|
|
491
|
-
|---|---|
|
|
492
|
-
| `workspaces` | `list_workspaces`, `get_workspace`, `create_workspace`, `update_workspace`, `delete_workspace` |
|
|
493
|
-
| `docs` | `list_docs`, `read_doc`, `search_docs`, `create_doc`, `create_doc_from_markdown`, `create_doc_from_template`, `duplicate_doc`, `append_paragraph`, `append_block`, `append_markdown`, `replace_doc_with_markdown`, `delete_doc`, `publish_doc`, `revoke_doc`, `list_tags`, `list_docs_by_tag`, `create_tag`, `add_tag_to_doc`, `remove_tag_from_doc`, `list_workspace_tree`, `get_orphan_docs`, `list_children`, `update_doc_title`, `get_doc_by_title`, `get_docs_by_tag`, `list_backlinks`, `move_doc`, `batch_create_docs`, `cleanup_orphan_embeds`, `find_and_replace`, `add_database_column`, `add_database_row`, `delete_database_row`, `read_database_columns`, `read_database_cells`, `update_database_cell`, `update_database_row` |
|
|
494
|
-
| `comments` | `list_comments`, `create_comment`, `update_comment`, `delete_comment`, `resolve_comment` |
|
|
495
|
-
| `history` | `list_histories` |
|
|
496
|
-
| `organize` | `list_collections`, `get_collection`, `create_collection`, `update_collection`, `delete_collection`, `add_doc_to_collection`, `remove_doc_from_collection`, `list_organize_nodes`, `create_folder`, `rename_folder`, `delete_folder`, `move_organize_node`, `add_organize_link`, `delete_organize_link` |
|
|
497
|
-
| `users` | `current_user`, `sign_in`, `update_profile`, `update_settings` |
|
|
498
|
-
| `access_tokens` | `list_access_tokens`, `generate_access_token`, `revoke_access_token` |
|
|
499
|
-
| `blobs` | `upload_blob`, `delete_blob`, `cleanup_blobs` |
|
|
500
|
-
| `notifications` | `list_notifications`, `read_all_notifications` |
|
|
224
|
+
## Development
|
|
501
225
|
|
|
502
|
-
|
|
503
|
-
"env": {
|
|
504
|
-
"AFFINE_DISABLED_GROUPS": "comments,history,blobs,users"
|
|
505
|
-
}
|
|
506
|
-
```
|
|
226
|
+
Run the main quality gates before opening a PR:
|
|
507
227
|
|
|
508
|
-
|
|
228
|
+
```bash
|
|
229
|
+
npm run build
|
|
230
|
+
npm run test:tool-manifest
|
|
231
|
+
npm run pack:check
|
|
232
|
+
```
|
|
509
233
|
|
|
510
|
-
|
|
234
|
+
Additional validation:
|
|
511
235
|
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
```
|
|
236
|
+
- `npm run test:comprehensive` boots a local Docker AFFiNE stack and validates the tool surface
|
|
237
|
+
- `npm run test:e2e` runs Docker, MCP, and Playwright together
|
|
238
|
+
- `npm run test:playwright` runs the Playwright suite only
|
|
239
|
+
- 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`, `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`, and `node tests/test-supporting-tools.mjs`
|
|
517
240
|
|
|
518
|
-
|
|
241
|
+
Local clone flow:
|
|
519
242
|
|
|
520
243
|
```bash
|
|
521
244
|
git clone https://github.com/dawncr0w/affine-mcp-server.git
|
|
522
245
|
cd affine-mcp-server
|
|
523
246
|
npm install
|
|
524
247
|
npm run build
|
|
525
|
-
# Run directly
|
|
526
248
|
node dist/index.js
|
|
527
|
-
|
|
528
|
-
# Or expose as a global CLI for Codex/Claude without publishing
|
|
529
|
-
npm link
|
|
530
|
-
# Now use `affine-mcp` like a global binary
|
|
531
|
-
```
|
|
532
|
-
|
|
533
|
-
## Quality Gates
|
|
534
|
-
|
|
535
|
-
```bash
|
|
536
|
-
npm run build
|
|
537
|
-
npm run test:tool-manifest
|
|
538
|
-
npm run pack:check
|
|
539
249
|
```
|
|
540
250
|
|
|
541
|
-
- `tool-manifest.json` is the source of truth for publicly exposed tool names.
|
|
542
|
-
- CI validates that `registerTool(...)` declarations match the manifest exactly.
|
|
543
|
-
- For full tool-surface verification, run `npm run test:comprehensive` (self-bootstraps a local Docker AFFiNE stack).
|
|
544
|
-
- For pre-provisioned environments, use `npm run test:comprehensive:raw`.
|
|
545
|
-
- For full environment verification, run `npm run test:e2e` (Docker + MCP + Playwright).
|
|
546
|
-
- 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:organize`, `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:cli-live`, `npm run test:tool-filtering`, `npm run test:markdown-rich-text-import`, `npm run test:playwright`.
|
|
547
|
-
|
|
548
|
-
## Troubleshooting
|
|
549
|
-
|
|
550
|
-
Authentication
|
|
551
|
-
- **Cloudflare (403 "Just a moment...")**: AFFiNE Cloud (`app.affine.pro`) uses Cloudflare protection, which blocks programmatic sign-in via `/api/auth/sign-in`. Use `AFFINE_API_TOKEN` instead, or run `affine-mcp login` which guides you through the right method automatically. Email/password auth only works for self-hosted instances.
|
|
552
|
-
- Email/Password: only works on self-hosted instances without Cloudflare. Ensure your instance allows password auth and credentials are valid.
|
|
553
|
-
- Cookie: copy cookies (e.g., `affine_session`, `affine_csrf`) from the browser DevTools after login
|
|
554
|
-
- Token: generate a personal access token; verify it hasn't expired. Run `affine-mcp status` to test.
|
|
555
|
-
- Startup timeouts: v1.2.2+ includes a CLI wrapper fix and default async login to avoid blocking the MCP handshake. Set `AFFINE_LOGIN_AT_START=sync` only if needed.
|
|
556
|
-
|
|
557
|
-
Connection
|
|
558
|
-
- Confirm `AFFINE_BASE_URL` is reachable
|
|
559
|
-
- GraphQL endpoint default is `/graphql`
|
|
560
|
-
- Check firewall/proxy rules; verify CORS if self‑hosted
|
|
561
|
-
|
|
562
|
-
Method not found
|
|
563
|
-
- MCP tool names (for example `list_workspaces`) are not JSON-RPC top-level method names.
|
|
564
|
-
- Use an MCP client (`tools/list`, `tools/call`) instead of sending direct JSON-RPC calls like `{\"method\":\"list_workspaces\"}`.
|
|
565
|
-
- From v1.3.0, only canonical tool names are exposed (legacy `affine_*` aliases were removed).
|
|
566
|
-
|
|
567
|
-
Workspace visibility
|
|
568
|
-
- This MCP server can access server-backed workspaces only (AFFiNE cloud/self-hosted).
|
|
569
|
-
- Browser local-storage workspaces are client-side data, so they are not visible via server GraphQL/WebSocket APIs.
|
|
570
|
-
|
|
571
|
-
## Security Considerations
|
|
572
|
-
|
|
573
|
-
- Never commit `.env` with secrets
|
|
574
|
-
- Prefer environment variables in production
|
|
575
|
-
- Rotate access tokens regularly
|
|
576
|
-
- Use HTTPS
|
|
577
|
-
- Store credentials in a secrets manager
|
|
578
|
-
|
|
579
251
|
## Release Notes
|
|
580
252
|
|
|
581
|
-
-
|
|
582
|
-
-
|
|
583
|
-
- GitHub Releases
|
|
584
|
-
|
|
585
|
-
## Contributing
|
|
586
|
-
|
|
587
|
-
Contributions are welcome!
|
|
588
|
-
1. Read `CONTRIBUTING.md`
|
|
589
|
-
2. Run `npm run ci` locally before opening PR
|
|
590
|
-
3. Keep tool changes synced with `tool-manifest.json`
|
|
591
|
-
4. Use issue/PR templates in `.github/`
|
|
592
|
-
|
|
593
|
-
## Community Health
|
|
594
|
-
|
|
595
|
-
- Code of Conduct: `CODE_OF_CONDUCT.md`
|
|
596
|
-
- Security policy: `SECURITY.md`
|
|
597
|
-
- Contributing guide: `CONTRIBUTING.md`
|
|
253
|
+
- [CHANGELOG.md](CHANGELOG.md)
|
|
254
|
+
- [RELEASE_NOTES.md](RELEASE_NOTES.md)
|
|
255
|
+
- [GitHub Releases](https://github.com/dawncr0w/affine-mcp-server/releases)
|
|
598
256
|
|
|
599
257
|
## License
|
|
600
258
|
|
|
601
|
-
MIT License - see LICENSE
|
|
259
|
+
MIT License - see [LICENSE](LICENSE).
|
|
602
260
|
|
|
603
261
|
## Support
|
|
604
262
|
|
|
605
|
-
For issues and questions:
|
|
606
263
|
- Open an issue on [GitHub](https://github.com/dawncr0w/affine-mcp-server/issues)
|
|
607
|
-
-
|
|
608
|
-
|
|
609
|
-
## Author
|
|
610
|
-
|
|
611
|
-
**dawncr0w** - [GitHub](https://github.com/dawncr0w)
|
|
264
|
+
- Review AFFiNE product documentation at [docs.affine.pro](https://docs.affine.pro)
|
|
612
265
|
|
|
613
266
|
## Acknowledgments
|
|
614
267
|
|