affine-mcp-server 1.2.0 → 1.2.2

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.
4
4
 
5
- [![Version](https://img.shields.io/badge/version-1.2.0-blue)](https://github.com/dawncr0w/affine-mcp-server/releases)
5
+ [![Version](https://img.shields.io/badge/version-1.2.2-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
  [![License](https://img.shields.io/badge/license-MIT-yellow)](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.0)
16
-
17
- > New in v1.2.0: Document create/edit/delete is now supported via WebSocket sync. Use `create_doc`, `append_paragraph`, and `delete_doc` to manage real AFFiNE docs.
15
+ - Status: Production Ready (v1.2.1)
16
+
17
+ > New in v1.2.2: Fixed CLI binary to always run via Node (no shell mis-execution). Startup remains non-blocking for email/password login by default; set `AFFINE_LOGIN_AT_START=sync` to block at startup.
18
18
 
19
19
  ## Features
20
20
 
@@ -37,35 +37,21 @@ 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-hoc with npx
41
- npx affine-mcp-server
40
+ # Or run adhoc 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.
45
45
 
46
- > Available on npm: install in seconds with `npm i -g affine-mcp-server` and use `affine-mcp` anywhere. No manual build or path setup required.
46
+ Note: From v1.2.2 the CLI wrapper (`bin/affine-mcp`) ensures Node runs the ESM entrypoint, preventing shell from misinterpreting JS.
47
47
 
48
48
  ## Configuration
49
49
 
50
- Create a `.env` file or set environment variables:
51
-
52
- ```env
53
- # AFFiNE server URL (required)
54
- AFFINE_BASE_URL=https://your-affine-instance.com
50
+ Configure via environment variables (shell or app config). `.env` files are no longer recommended.
55
51
 
56
- # Authentication (choose one method):
57
- # 1) Bearer Token (highest priority)
58
- AFFINE_API_TOKEN=your_personal_access_token
59
- # 2) Session Cookie
60
- AFFINE_COOKIE=affine_session=xxx; affine_csrf=yyy
61
- # 3) Email/Password (fallback)
62
- AFFINE_EMAIL=your@email.com
63
- AFFINE_PASSWORD=your_password
64
-
65
- # Optional settings
66
- AFFINE_GRAPHQL_PATH=/graphql # Default: /graphql
67
- AFFINE_WORKSPACE_ID=workspace-uuid # Default workspace for operations
68
- ```
52
+ - Required: `AFFINE_BASE_URL`
53
+ - Auth (choose one): `AFFINE_API_TOKEN` | `AFFINE_COOKIE` | `AFFINE_EMAIL` + `AFFINE_PASSWORD`
54
+ - Optional: `AFFINE_GRAPHQL_PATH` (default `/graphql`), `AFFINE_WORKSPACE_ID`, `AFFINE_LOGIN_AT_START` (`async` default, `sync` to block)
69
55
 
70
56
  Authentication priority:
71
57
  1) `AFFINE_API_TOKEN` → 2) `AFFINE_COOKIE` → 3) `AFFINE_EMAIL` + `AFFINE_PASSWORD`
@@ -87,29 +73,38 @@ Add to your Claude Desktop configuration:
87
73
  "command": "affine-mcp",
88
74
  "env": {
89
75
  "AFFINE_BASE_URL": "https://your-affine-instance.com",
90
- "AFFINE_COOKIE": "affine_session=...; affine_csrf=..."
76
+ "AFFINE_EMAIL": "you@example.com",
77
+ "AFFINE_PASSWORD": "secret!",
78
+ "AFFINE_LOGIN_AT_START": "async"
91
79
  }
92
80
  }
93
81
  }
94
82
  }
95
83
  ```
96
84
 
85
+ Tips
86
+ - Prefer `AFFINE_COOKIE` or `AFFINE_API_TOKEN` for zero‑latency startup.
87
+ - If your password contains `!` (zsh history expansion), wrap it in single quotes in shells or use the JSON config above.
88
+
97
89
  ### Codex CLI
98
90
 
99
- Codex attaches MCP servers by executing commands over stdio. Depending on your Codex version, use one of these patterns:
91
+ Register the MCP server with Codex:
100
92
 
101
- - Direct flag example:
102
- - `codex --mcp affine=affine-mcp --env AFFINE_BASE_URL=https://your-affine-instance.com --env AFFINE_COOKIE='affine_session=...; affine_csrf=...'`
93
+ - Global install path (fastest)
94
+ - `npm i -g affine-mcp-server`
95
+ - `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`
103
96
 
104
- - Profile/config based registration (conceptual):
105
- - name: `affine`, command: `affine-mcp`, env: `AFFINE_*`
97
+ - Use npx (no global install)
98
+ - `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`
106
99
 
107
- General rules:
100
+ - Token or cookie (no startup login)
101
+ - Token: `codex mcp add affine --env AFFINE_BASE_URL=https://... --env AFFINE_API_TOKEN=... -- affine-mcp`
102
+ - Cookie: `codex mcp add affine --env AFFINE_BASE_URL=https://... --env "AFFINE_COOKIE=affine_session=...; affine_csrf=..." -- affine-mcp`
103
+
104
+ Notes
108
105
  - MCP name: `affine`
109
106
  - Command: `affine-mcp`
110
- - Env: `AFFINE_BASE_URL` and one auth method (`AFFINE_COOKIE` or `AFFINE_API_TOKEN` or `AFFINE_EMAIL`/`AFFINE_PASSWORD`)
111
-
112
- Refer to your Codex CLI docs for the exact config keys/paths.
107
+ - Environment: `AFFINE_BASE_URL` + one auth method (`AFFINE_API_TOKEN` | `AFFINE_COOKIE` | `AFFINE_EMAIL`/`AFFINE_PASSWORD`)
113
108
 
114
109
  ## Available Tools
115
110
 
@@ -150,14 +145,19 @@ Refer to your Codex CLI docs for the exact config keys/paths.
150
145
  ### Advanced
151
146
  - `apply_doc_updates` – apply CRDT updates to documents
152
147
 
153
- ## Run locally (dev)
148
+ ## Use Locally (clone)
154
149
 
155
150
  ```bash
156
151
  git clone https://github.com/dawncr0w/affine-mcp-server.git
157
152
  cd affine-mcp-server
158
153
  npm install
159
154
  npm run build
160
- npm start
155
+ # Run directly
156
+ node dist/index.js
157
+
158
+ # Or expose as a global CLI for Codex/Claude without publishing
159
+ npm link
160
+ # Now use `affine-mcp` like a global binary
161
161
  ```
162
162
 
163
163
  ## Troubleshooting
@@ -166,6 +166,7 @@ Authentication
166
166
  - Email/Password: ensure your instance allows password auth and credentials are valid
167
167
  - Cookie: copy cookies (e.g., `affine_session`, `affine_csrf`) from the browser DevTools after login
168
168
  - Token: generate a personal access token; verify it hasn’t expired
169
+ - Startup timeouts: v1.2.2 includes a CLI wrapper fix and the default async login to avoid blocking the MCP handshake. Set `AFFINE_LOGIN_AT_START=sync` only if needed.
169
170
 
170
171
  Connection
171
172
  - Confirm `AFFINE_BASE_URL` is reachable
@@ -182,6 +183,16 @@ Connection
182
183
 
183
184
  ## Version History
184
185
 
186
+ ### 1.2.2 (2025‑09‑18)
187
+ - CLI wrapper added to ensure Node runs ESM entry (`bin/affine-mcp`), preventing shell mis-execution
188
+ - Docs cleaned: use env vars via shell/app config; `.env` file no longer recommended
189
+ - MCP startup behavior unchanged from 1.2.1 (async login by default)
190
+
191
+ ### 1.2.1 (2025‑09‑17)
192
+ - Default to asynchronous email/password login after MCP stdio handshake
193
+ - New `AFFINE_LOGIN_AT_START` env (`async` default, `sync` to block at startup)
194
+ - Expanded docs for Codex/Claude using npm, npx, and local clone
195
+
185
196
  ### 1.2.0 (2025‑09‑16)
186
197
  - WebSocket-based document tools: `create_doc`, `append_paragraph`, `delete_doc` (create/edit/delete now supported)
187
198
  - Tool aliases: both `affine_*` and non‑prefixed names
package/bin/affine-mcp ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env node
2
+ // Lightweight CLI wrapper to ensure Node runs the ESM entry
3
+ // Resolves to the compiled ESM entrypoint in dist
4
+ import '../dist/index.js';
5
+
package/dist/config.js CHANGED
@@ -1,5 +1,3 @@
1
- import dotenv from "dotenv";
2
- dotenv.config();
3
1
  const defaultEndpoints = {
4
2
  listWorkspaces: { method: "GET", path: "/api/workspaces" },
5
3
  listDocs: { method: "GET", path: "/api/workspaces/:workspaceId/docs" },
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.0" });
19
+ const server = new McpServer({ name: "affine-mcp", version: "1.2.2" });
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
- console.error("No token or cookie provided, attempting email/password authentication...");
29
- try {
30
- const { cookieHeader } = await loginWithPassword(config.baseUrl, config.email, config.password);
31
- gql.setCookie(cookieHeader);
32
- console.error("Successfully authenticated with email/password");
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
- catch (e) {
35
- console.error("Failed to authenticate with email/password:", e);
36
- console.error("WARNING: Continuing without authentication - some operations may fail");
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.0",
3
+ "version": "1.2.2",
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",
@@ -20,7 +20,7 @@
20
20
  ],
21
21
  "main": "dist/index.js",
22
22
  "bin": {
23
- "affine-mcp": "dist/index.js"
23
+ "affine-mcp": "bin/affine-mcp"
24
24
  },
25
25
  "scripts": {
26
26
  "build": "tsc -p tsconfig.json",
@@ -29,6 +29,7 @@
29
29
  "prepublishOnly": "npm run build"
30
30
  },
31
31
  "files": [
32
+ "bin",
32
33
  "dist",
33
34
  "README.md",
34
35
  "LICENSE"
@@ -41,7 +42,6 @@
41
42
  },
42
43
  "dependencies": {
43
44
  "@modelcontextprotocol/sdk": "^1.17.2",
44
- "dotenv": "^16.6.1",
45
45
  "form-data": "^4.0.4",
46
46
  "node-fetch": "^3.3.2",
47
47
  "socket.io-client": "^4.8.1",