affine-mcp-server 1.2.0 → 1.2.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 +43 -19
- package/dist/index.js +28 -10
- package/package.json +2 -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.
|
|
4
4
|
|
|
5
|
-
[](https://github.com/dawncr0w/affine-mcp-server/releases)
|
|
6
6
|
[](https://github.com/modelcontextprotocol/typescript-sdk)
|
|
7
7
|
[](LICENSE)
|
|
8
8
|
|
|
@@ -12,9 +12,9 @@ A Model Context Protocol (MCP) server that integrates with AFFiNE (self‑hosted
|
|
|
12
12
|
- Transport: stdio only (Claude Desktop / Codex compatible)
|
|
13
13
|
- Auth: Token, Cookie, or Email/Password (priority order)
|
|
14
14
|
- Tools: 30+ tools plus WebSocket-based document editing
|
|
15
|
-
- Status: Production Ready (v1.2.
|
|
16
|
-
|
|
17
|
-
> New in v1.2.
|
|
15
|
+
- Status: Production Ready (v1.2.1)
|
|
16
|
+
|
|
17
|
+
> New in v1.2.1: Email/Password login no longer blocks MCP startup. The server connects over stdio immediately and performs login asynchronously by default. Use `AFFINE_LOGIN_AT_START=sync` to restore the previous blocking behavior.
|
|
18
18
|
|
|
19
19
|
## Features
|
|
20
20
|
|
|
@@ -37,8 +37,8 @@ A Model Context Protocol (MCP) server that integrates with AFFiNE (self‑hosted
|
|
|
37
37
|
# Global install (recommended)
|
|
38
38
|
npm i -g affine-mcp-server
|
|
39
39
|
|
|
40
|
-
# Or run ad
|
|
41
|
-
npx affine-mcp-server
|
|
40
|
+
# Or run ad‑hoc via npx (no install)
|
|
41
|
+
npx -y -p affine-mcp-server affine-mcp -- --version
|
|
42
42
|
```
|
|
43
43
|
|
|
44
44
|
The package installs a CLI named `affine-mcp` that runs the MCP server over stdio.
|
|
@@ -47,7 +47,7 @@ The package installs a CLI named `affine-mcp` that runs the MCP server over stdi
|
|
|
47
47
|
|
|
48
48
|
## Configuration
|
|
49
49
|
|
|
50
|
-
|
|
50
|
+
Set environment variables (recommended) or create a `.env` file:
|
|
51
51
|
|
|
52
52
|
```env
|
|
53
53
|
# AFFiNE server URL (required)
|
|
@@ -65,6 +65,10 @@ AFFINE_PASSWORD=your_password
|
|
|
65
65
|
# Optional settings
|
|
66
66
|
AFFINE_GRAPHQL_PATH=/graphql # Default: /graphql
|
|
67
67
|
AFFINE_WORKSPACE_ID=workspace-uuid # Default workspace for operations
|
|
68
|
+
|
|
69
|
+
# Startup auth behavior (optional)
|
|
70
|
+
# AFFINE_LOGIN_AT_START=async # Default: async (don't block MCP handshake)
|
|
71
|
+
# AFFINE_LOGIN_AT_START=sync # Block at startup to sign in with email/password
|
|
68
72
|
```
|
|
69
73
|
|
|
70
74
|
Authentication priority:
|
|
@@ -87,29 +91,38 @@ Add to your Claude Desktop configuration:
|
|
|
87
91
|
"command": "affine-mcp",
|
|
88
92
|
"env": {
|
|
89
93
|
"AFFINE_BASE_URL": "https://your-affine-instance.com",
|
|
90
|
-
"
|
|
94
|
+
"AFFINE_EMAIL": "you@example.com",
|
|
95
|
+
"AFFINE_PASSWORD": "secret!",
|
|
96
|
+
"AFFINE_LOGIN_AT_START": "async"
|
|
91
97
|
}
|
|
92
98
|
}
|
|
93
99
|
}
|
|
94
100
|
}
|
|
95
101
|
```
|
|
96
102
|
|
|
103
|
+
Tips
|
|
104
|
+
- Prefer `AFFINE_COOKIE` or `AFFINE_API_TOKEN` for zero‑latency startup.
|
|
105
|
+
- If your password contains `!` (zsh history expansion), wrap it in single quotes in shells or use the JSON config above.
|
|
106
|
+
|
|
97
107
|
### Codex CLI
|
|
98
108
|
|
|
99
|
-
|
|
109
|
+
Register the MCP server with Codex:
|
|
110
|
+
|
|
111
|
+
- Global install path (fastest)
|
|
112
|
+
- `npm i -g affine-mcp-server`
|
|
113
|
+
- `codex mcp add affine --env AFFINE_BASE_URL=https://your-affine-instance.com --env 'AFFINE_EMAIL=you@example.com' --env 'AFFINE_PASSWORD=secret!' --env AFFINE_LOGIN_AT_START=async -- affine-mcp`
|
|
100
114
|
|
|
101
|
-
-
|
|
102
|
-
- `codex
|
|
115
|
+
- Use npx (no global install)
|
|
116
|
+
- `codex mcp add affine --env AFFINE_BASE_URL=https://your-affine-instance.com --env 'AFFINE_EMAIL=you@example.com' --env 'AFFINE_PASSWORD=secret!' --env AFFINE_LOGIN_AT_START=async -- npx -y -p affine-mcp-server affine-mcp`
|
|
103
117
|
|
|
104
|
-
-
|
|
105
|
-
-
|
|
118
|
+
- Token or cookie (no startup login)
|
|
119
|
+
- Token: `codex mcp add affine --env AFFINE_BASE_URL=https://... --env AFFINE_API_TOKEN=... -- affine-mcp`
|
|
120
|
+
- Cookie: `codex mcp add affine --env AFFINE_BASE_URL=https://... --env "AFFINE_COOKIE=affine_session=...; affine_csrf=..." -- affine-mcp`
|
|
106
121
|
|
|
107
|
-
|
|
122
|
+
Notes
|
|
108
123
|
- MCP name: `affine`
|
|
109
124
|
- Command: `affine-mcp`
|
|
110
|
-
-
|
|
111
|
-
|
|
112
|
-
Refer to your Codex CLI docs for the exact config keys/paths.
|
|
125
|
+
- Environment: `AFFINE_BASE_URL` + one auth method (`AFFINE_API_TOKEN` | `AFFINE_COOKIE` | `AFFINE_EMAIL`/`AFFINE_PASSWORD`)
|
|
113
126
|
|
|
114
127
|
## Available Tools
|
|
115
128
|
|
|
@@ -150,14 +163,19 @@ Refer to your Codex CLI docs for the exact config keys/paths.
|
|
|
150
163
|
### Advanced
|
|
151
164
|
- `apply_doc_updates` – apply CRDT updates to documents
|
|
152
165
|
|
|
153
|
-
##
|
|
166
|
+
## Use Locally (clone)
|
|
154
167
|
|
|
155
168
|
```bash
|
|
156
169
|
git clone https://github.com/dawncr0w/affine-mcp-server.git
|
|
157
170
|
cd affine-mcp-server
|
|
158
171
|
npm install
|
|
159
172
|
npm run build
|
|
160
|
-
|
|
173
|
+
# Run directly
|
|
174
|
+
node dist/index.js
|
|
175
|
+
|
|
176
|
+
# Or expose as a global CLI for Codex/Claude without publishing
|
|
177
|
+
npm link
|
|
178
|
+
# Now use `affine-mcp` like a global binary
|
|
161
179
|
```
|
|
162
180
|
|
|
163
181
|
## Troubleshooting
|
|
@@ -166,6 +184,7 @@ Authentication
|
|
|
166
184
|
- Email/Password: ensure your instance allows password auth and credentials are valid
|
|
167
185
|
- Cookie: copy cookies (e.g., `affine_session`, `affine_csrf`) from the browser DevTools after login
|
|
168
186
|
- Token: generate a personal access token; verify it hasn’t expired
|
|
187
|
+
- If using Email/Password and your MCP client shows a startup timeout, ensure `AFFINE_LOGIN_AT_START=async` (default) so login happens after the stdio handshake.
|
|
169
188
|
|
|
170
189
|
Connection
|
|
171
190
|
- Confirm `AFFINE_BASE_URL` is reachable
|
|
@@ -182,6 +201,11 @@ Connection
|
|
|
182
201
|
|
|
183
202
|
## Version History
|
|
184
203
|
|
|
204
|
+
### 1.2.1 (2025‑09‑17)
|
|
205
|
+
- Default to asynchronous email/password login after MCP stdio handshake
|
|
206
|
+
- New `AFFINE_LOGIN_AT_START` env (`async` default, `sync` to block at startup)
|
|
207
|
+
- Expanded docs for Codex/Claude using npm, npx, and local clone
|
|
208
|
+
|
|
185
209
|
### 1.2.0 (2025‑09‑16)
|
|
186
210
|
- WebSocket-based document tools: `create_doc`, `append_paragraph`, `delete_doc` (create/edit/delete now supported)
|
|
187
211
|
- Tool aliases: both `affine_*` and non‑prefixed names
|
package/dist/index.js
CHANGED
|
@@ -16,24 +16,42 @@ import { loginWithPassword } from "./auth.js";
|
|
|
16
16
|
import { registerAuthTools } from "./tools/auth.js";
|
|
17
17
|
const config = loadConfig();
|
|
18
18
|
async function buildServer() {
|
|
19
|
-
const server = new McpServer({ name: "affine-mcp", version: "1.1
|
|
19
|
+
const server = new McpServer({ name: "affine-mcp", version: "1.2.1" });
|
|
20
20
|
// Initialize GraphQL client with authentication
|
|
21
21
|
const gql = new GraphQLClient({
|
|
22
22
|
endpoint: `${config.baseUrl}${config.graphqlPath}`,
|
|
23
23
|
headers: config.headers,
|
|
24
24
|
bearer: config.apiToken
|
|
25
25
|
});
|
|
26
|
-
// Try email/password authentication if no other auth method is configured
|
|
26
|
+
// Try email/password authentication if no other auth method is configured.
|
|
27
|
+
// To avoid startup timeouts in MCP clients, default to async login after the stdio handshake.
|
|
27
28
|
if (!gql.isAuthenticated() && config.email && config.password) {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
29
|
+
const mode = (process.env.AFFINE_LOGIN_AT_START || "async").toLowerCase();
|
|
30
|
+
if (mode === "sync") {
|
|
31
|
+
console.error("No token/cookie; performing synchronous email/password authentication at startup...");
|
|
32
|
+
try {
|
|
33
|
+
const { cookieHeader } = await loginWithPassword(config.baseUrl, config.email, config.password);
|
|
34
|
+
gql.setCookie(cookieHeader);
|
|
35
|
+
console.error("Successfully authenticated with email/password");
|
|
36
|
+
}
|
|
37
|
+
catch (e) {
|
|
38
|
+
console.error("Failed to authenticate with email/password:", e);
|
|
39
|
+
console.error("WARNING: Continuing without authentication - some operations may fail");
|
|
40
|
+
}
|
|
33
41
|
}
|
|
34
|
-
|
|
35
|
-
console.error("
|
|
36
|
-
|
|
42
|
+
else {
|
|
43
|
+
console.error("No token/cookie; deferring email/password authentication (async after connect)...");
|
|
44
|
+
// Fire-and-forget async login so stdio handshake is not delayed.
|
|
45
|
+
(async () => {
|
|
46
|
+
try {
|
|
47
|
+
const { cookieHeader } = await loginWithPassword(config.baseUrl, config.email, config.password);
|
|
48
|
+
gql.setCookie(cookieHeader);
|
|
49
|
+
console.error("Successfully authenticated with email/password (async)");
|
|
50
|
+
}
|
|
51
|
+
catch (e) {
|
|
52
|
+
console.error("Failed to authenticate with email/password (async):", e);
|
|
53
|
+
}
|
|
54
|
+
})();
|
|
37
55
|
}
|
|
38
56
|
}
|
|
39
57
|
// Log authentication status
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "affine-mcp-server",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Model Context Protocol server for AFFiNE - enables AI assistants to interact with AFFiNE workspaces, documents, and collaboration features.",
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"license": "MIT",
|
|
9
9
|
"repository": {
|
|
10
10
|
"type": "git",
|
|
11
|
-
"url": "https://github.com/dawncr0w/affine-mcp-server.git"
|
|
11
|
+
"url": "git+https://github.com/dawncr0w/affine-mcp-server.git"
|
|
12
12
|
},
|
|
13
13
|
"keywords": [
|
|
14
14
|
"mcp",
|