n2n-nexus 0.4.2 → 0.6.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.
Files changed (39) hide show
  1. package/CHANGELOG.md +87 -0
  2. package/README.md +74 -117
  3. package/assets/n2n-nexus-banner.jpg +0 -0
  4. package/assets/n2n-nexus-icon.png +0 -0
  5. package/assets/n2n-nexus-logo.png +0 -0
  6. package/build/client/nexus-client.js +30 -14
  7. package/build/config/cli.js +0 -3
  8. package/build/config/index.js +0 -10
  9. package/build/constants.js +7 -11
  10. package/build/daemon/index.js +35 -19
  11. package/build/daemon/rate-limit.js +62 -0
  12. package/build/daemon/server.js +349 -542
  13. package/build/daemon/tool-outputs.js +155 -0
  14. package/build/daemon/tools.js +271 -0
  15. package/build/index.js +1 -1
  16. package/build/server/instance-id.js +19 -0
  17. package/build/server/nexus.js +152 -43
  18. package/build/storage/docs.js +14 -7
  19. package/build/storage/events.js +31 -0
  20. package/build/storage/fs-utils.js +42 -0
  21. package/build/storage/global-messages.js +44 -0
  22. package/build/storage/index.js +44 -41
  23. package/build/storage/migrations.js +79 -0
  24. package/build/storage/paths.js +0 -3
  25. package/build/storage/projects.js +4 -5
  26. package/build/storage/registry.js +67 -25
  27. package/build/storage/sqlite-meeting.js +35 -23
  28. package/build/storage/sqlite.js +41 -24
  29. package/build/storage/tasks.js +29 -103
  30. package/build/types.js +1 -1
  31. package/docs/ARCHITECTURE.md +29 -20
  32. package/docs/ARCHITECTURE_zh.md +29 -20
  33. package/docs/ASSISTANT_GUIDE.md +70 -67
  34. package/docs/README_zh.md +25 -15
  35. package/llms.txt +11 -1
  36. package/package.json +24 -14
  37. package/build/storage/logs.js +0 -60
  38. package/build/storage/meetings.js +0 -276
  39. package/build/storage/store.js +0 -153
@@ -28,7 +28,7 @@ Stateless protocol adapter, one per IDE
28
28
  1. **Daemon is the single source of truth** — all reads/writes, business logic, and tool definitions live in the daemon.
29
29
  2. **MCP is a stateless protocol adapter** — no tool definitions, no hardcoded names, no local data.
30
30
  3. **Daemon decides tool capability** — MCP fetches `GET /api/tools` at startup; any daemon upgrade is immediately visible to all connected MCPs.
31
- 4. **No local fallback** — if the daemon is unreachable, the MCP reports an error and retries every 3 s. No split-brain degradation.
31
+ 4. **No local fallback** — if the daemon is unreachable, the MCP reports an error and retries every 3 s. No split-brain degradation. A tool call the daemon rejects (validation, not found, permission) is returned to the IDE as an error result (`isError: true`) and does not affect the connection; an unknown tool name is a JSON-RPC `-32602` error.
32
32
  5. **Plain HTTP between MCP and daemon** — no SSE; AI is request-driven and doesn't need push.
33
33
 
34
34
  ### MCP Startup Flow
@@ -36,20 +36,21 @@ Stateless protocol adapter, one per IDE
36
36
  ```
37
37
  Read NEXUS_ENDPOINT (default: http://127.0.0.1:5688)
38
38
  │
39
- ├─ Connect stdio transport → IDE sees MCP as ready
39
+ ├─ Serve stdio (MCP TypeScript SDK v2, serveStdio) and GET /api/tools once;
40
+ │ the first tools/list waits up to 1 s for that fetch
41
+ │ ├─ 2026-07-28 clients: server/discover, per-request _meta envelope,
42
+ │ │ list_changed delivered on subscriptions/listen
43
+ │ └─ 2025-era clients: initialize handshake, unsolicited list_changed
40
44
  │
41
- └─ Background retry loop (every 3 s)
42
- │
43
- ├─ GET /api/tools fails
44
- │ → log "[n2n-nexus] Waiting for daemon..."
45
- │ → keep retrying, do not exit
46
- │
47
- └─ GET /api/tools succeeds
48
- → cache tool list
49
- → send notifications/tools/list_changed
50
- → IDE re-fetches: tools appear
45
+ ├─ If the daemon was down: retry loop (every 3 s)
46
+ │ └─ GET /api/tools succeeds → cache tool list
47
+ │ → notifications/tools/list_changed → IDE re-fetches
48
+ │
49
+ └─ stdin closes → stop retrying, close, exit
51
50
  ```
52
51
 
52
+ The adapter's instance ID (read cursors, meeting permissions) uses the first client name seen on the connection, from the request's `io.modelcontextprotocol/clientInfo` (2026-07-28) or from `initialize` (2025 era), unless `NEXUS_INSTANCE_ID` / `--id` pins it.
53
+
53
54
  ---
54
55
 
55
56
  ## 💾 Data Persistence
@@ -60,7 +61,6 @@ All data lives under the daemon's storage root (default `~/.n2n-nexus`):
60
61
  ~/.n2n-nexus/
61
62
  ├── global/
62
63
  │ ├── blueprint.md # Master strategy document
63
- │ ├── discussion.json # Global chat (JSON fallback)
64
64
  │ ├── docs_index.json # Global docs index
65
65
  │ └── docs/ # Shared markdown documents
66
66
  ├── projects/
@@ -68,14 +68,17 @@ All data lives under the daemon's storage root (default `~/.n2n-nexus`):
68
68
  │ ├── manifest.json # Project metadata
69
69
  │ ├── internal_blueprint.md # Internal technical docs
70
70
  │ └── assets/ # Binary assets (images, PDFs)
71
- ├── meetings/ # Meeting files (JSON fallback mode)
72
71
  ├── registry.json # Global project index
73
- └── nexus.db # SQLite database (meetings, tasks, cursors)
72
+ └── nexus.db # SQLite database (meetings, global chat, events, tasks, cursors)
74
73
  ```
75
74
 
76
- **SQLite WAL mode**: Only the daemon process writes to SQLite directly. MCP processes never touch the DB — they go through HTTP, which serializes all writes naturally.
75
+ **SQLite WAL mode**: Only the daemon process opens the database. MCP adapters never touch it — they go through HTTP.
76
+
77
+ **File-store writes**: HTTP requests are handled concurrently, so every mutation of `registry.json`, manifests and the docs index is queued behind one daemon-wide lock and written atomically (temp file + rename).
77
78
 
78
- **Self-healing**: Core JSON files (`registry.json`, `discussion.json`) are auto-repaired if corrupted or missing.
79
+ **Activity log**: state changes made through the daemon (project sync/rename/delete, meeting start/end, doc sync, ...) are recorded as structured events in SQLite and read with `list_events` / `GET /api/events`; they are not mixed into chat streams.
80
+
81
+ **Self-healing**: `registry.json` is auto-repaired if corrupted or missing.
79
82
 
80
83
  ---
81
84
 
@@ -148,32 +151,34 @@ POST /api/tools/call Execute tool call { tool, args, instanceId }
148
151
  ### System
149
152
  ```
150
153
  GET /health Health status + version
151
- GET /api/storage/info Storage mode and stats
152
154
  ```
153
155
 
154
- ### Session & Projects
156
+ ### Projects
155
157
  ```
156
- POST /api/session/register
157
158
  POST /api/projects/sync
158
159
  POST /api/projects/update
159
160
  POST /api/projects/rename
160
161
  POST /api/projects/delete
161
162
  GET /api/projects/search
162
163
  GET /api/projects/topology
164
+ GET /api/projects/:projectId
163
165
  ```
164
166
 
165
167
  ### Messages & Global
166
168
  ```
167
169
  POST /api/messages/send
168
170
  GET /api/messages/unread
171
+ GET /api/events
169
172
  GET /api/global/docs
170
173
  GET /api/global/docs/:docId
171
174
  POST /api/global/docs/:docId
175
+ GET /api/global/strategy
172
176
  POST /api/global/strategy
173
177
  ```
174
178
 
175
179
  ### Meetings
176
180
  ```
181
+ GET /api/meetings
177
182
  POST /api/meetings/start
178
183
  POST /api/meetings/end
179
184
  POST /api/meetings/archive
@@ -197,6 +202,10 @@ POST /api/maintenance/logs
197
202
 
198
203
  ---
199
204
 
205
+ ### Request guards
206
+
207
+ The daemon rejects browser-originated requests (`Origin` header or cross-site `Sec-Fetch-Site`: 403), `Host` names that are neither IP literals nor local/allow-listed names (403, prevents DNS rebinding), non-JSON POST bodies (415) and bodies above 16 MB (413). Tool calls are rate limited per instance and per client address (429 with `Retry-After`). See `SECURITY.md`.
208
+
200
209
  ## Scope Boundaries
201
210
 
202
211
  - No cloud bridge by default.
@@ -28,7 +28,7 @@ MCP-A MCP-B MCP-C
28
28
  1. **Daemon 是唯一的真相来源** — 所有读写、业务逻辑和工具定义都在 daemon 侧。
29
29
  2. **MCP 是无状态协议适配器** — 不含工具定义、不含 hardcode 工具名、不存本地数据。
30
30
  3. **Daemon 决定工具能力** — MCP 启动时拉取 `GET /api/tools`;daemon 升级新工具后,所有已连接 MCP 立即获得新能力,无需更新。
31
- 4. **无本地降级** — daemon 不可达时,MCP 每 3 秒重试并报告错误,不做本地 fallback(避免数据分裂)。
31
+ 4. **无本地降级** — daemon 不可达时,MCP 每 3 秒重试并报告错误,不做本地 fallback(避免数据分裂)。daemon 拒绝的工具调用(校验失败、不存在、无权限)作为错误结果(`isError: true`)返回给 IDE,不影响连接;未知工具名返回 JSON-RPC `-32602` 错误。
32
32
  5. **MCP ↔ Daemon 全部走普通 HTTP** — 不使用 SSE;AI 是请求驱动模型,不需要推送。
33
33
 
34
34
  ### MCP 启动流程
@@ -36,20 +36,21 @@ MCP-A MCP-B MCP-C
36
36
  ```
37
37
  读取 NEXUS_ENDPOINT(默认 http://127.0.0.1:5688)
38
38
  │
39
- ├─ 连接 stdio transport → IDE 认为 MCP 已就绪
39
+ ├─ 开始 stdio 服务(MCP TypeScript SDK v2,serveStdio),同时拉一次 GET /api/tools;
40
+ │ 第一次 tools/list 最多等这次拉取 1 秒
41
+ │ ├─ 2026-07-28 客户端:server/discover、每请求 _meta 信封,
42
+ │ │ list_changed 经 subscriptions/listen 下发
43
+ │ └─ 2025 代客户端:initialize 握手,主动下发 list_changed
40
44
  │
41
- └─ 后台重试循环(每 3 秒)
42
- │
43
- ├─ GET /api/tools 失败
44
- │ → 打印 "[n2n-nexus] Waiting for daemon..."
45
- │ → 继续等待,不退出
46
- │
47
- └─ GET /api/tools 成功
48
- → 缓存工具列表
49
- → 发送 notifications/tools/list_changed
50
- → IDE 重新拉取,工具出现
45
+ ├─ 若 daemon 不在线:重试循环(每 3 秒)
46
+ │ └─ GET /api/tools 成功 → 缓存工具列表
47
+ │ → notifications/tools/list_changed → IDE 重新拉取
48
+ │
49
+ └─ stdin 关闭 → 停止重试、关闭、退出
51
50
  ```
52
51
 
52
+ 适配器的实例 ID(未读游标、会议权限以它为键)取自该连接上第一次见到的客户端名,来源是请求 `_meta` 中的 `io.modelcontextprotocol/clientInfo`(2026-07-28)或 `initialize`(2025 代),`NEXUS_INSTANCE_ID` / `--id` 可固定。
53
+
53
54
  ---
54
55
 
55
56
  ## 💾 数据持久化
@@ -60,7 +61,6 @@ MCP-A MCP-B MCP-C
60
61
  ~/.n2n-nexus/
61
62
  ├── global/
62
63
  │ ├── blueprint.md # 主战略文档
63
- │ ├── discussion.json # 全局聊天(JSON 回退)
64
64
  │ ├── docs_index.json # 全局文档索引
65
65
  │ └── docs/ # 共享 Markdown 文档
66
66
  ├── projects/
@@ -68,14 +68,17 @@ MCP-A MCP-B MCP-C
68
68
  │ ├── manifest.json # 项目元数据
69
69
  │ ├── internal_blueprint.md # 内部技术文档
70
70
  │ └── assets/ # 二进制资产(图片、PDF)
71
- ├── meetings/ # 会议文件(JSON 回退模式)
72
71
  ├── registry.json # 全局项目索引
73
- └── nexus.db # SQLite 数据库(会议、任务、游标)
72
+ └── nexus.db # SQLite 数据库(会议、全局聊天、事件、任务、游标)
74
73
  ```
75
74
 
76
- **SQLite WAL 模式**:只有 daemon 进程直接写入 SQLite。MCP 进程通过 HTTP 间接访问,天然串行,无并发冲突。
75
+ **SQLite WAL 模式**:只有 daemon 进程打开数据库。MCP 适配器不直接访问,全部经由 HTTP。
76
+
77
+ **文件存储写入**:HTTP 请求是并发处理的,因此对 `registry.json`、manifest 和文档索引的每次修改都排在一把 daemon 级写锁后面,并以原子方式写入(临时文件 + rename)。
77
78
 
78
- **自我修复**:核心 JSON 文件(`registry.json`、`discussion.json`)在损坏或丢失时自动重建初始状态。
79
+ **活动日志**:经由 daemon 发生的状态变更(项目同步/重命名/删除、会议开始/结束、文档同步等)以结构化事件记录在 SQLite 中,通过 `list_events` / `GET /api/events` 读取,不混入聊天流。
80
+
81
+ **自我修复**:`registry.json` 在损坏或丢失时自动重建初始状态。
79
82
 
80
83
  ---
81
84
 
@@ -148,32 +151,34 @@ POST /api/tools/call 执行工具调用 { tool, args, instanceId }
148
151
  ### 系统
149
152
  ```
150
153
  GET /health 健康状态 + 版本信息
151
- GET /api/storage/info 存储模式和统计
152
154
  ```
153
155
 
154
- ### 会话与项目
156
+ ### 项目
155
157
  ```
156
- POST /api/session/register
157
158
  POST /api/projects/sync
158
159
  POST /api/projects/update
159
160
  POST /api/projects/rename
160
161
  POST /api/projects/delete
161
162
  GET /api/projects/search
162
163
  GET /api/projects/topology
164
+ GET /api/projects/:projectId
163
165
  ```
164
166
 
165
167
  ### 消息与全局协作
166
168
  ```
167
169
  POST /api/messages/send
168
170
  GET /api/messages/unread
171
+ GET /api/events
169
172
  GET /api/global/docs
170
173
  GET /api/global/docs/:docId
171
174
  POST /api/global/docs/:docId
175
+ GET /api/global/strategy
172
176
  POST /api/global/strategy
173
177
  ```
174
178
 
175
179
  ### 会议
176
180
  ```
181
+ GET /api/meetings
177
182
  POST /api/meetings/start
178
183
  POST /api/meetings/end
179
184
  POST /api/meetings/archive
@@ -197,6 +202,10 @@ POST /api/maintenance/logs
197
202
 
198
203
  ---
199
204
 
205
+ ### 请求防护
206
+
207
+ daemon 拒绝来自浏览器的请求(带 `Origin` 头或跨站 `Sec-Fetch-Site`:403)、既非 IP 也不在本地/允许列表中的 `Host`(403,防 DNS rebinding)、非 JSON 的 POST 请求体(415)以及超过 16 MB 的请求体(413)。工具调用按实例和客户端地址限流(429,带 `Retry-After`)。详见 `SECURITY.md`。
208
+
200
209
  ## 边界说明
201
210
 
202
211
  - 不默认提供云端桥接。
@@ -1,120 +1,123 @@
1
1
  # Nexus Assistant Guide
2
2
 
3
- 你现在是 **n2ns Nexus** 协作网络的一员。Nexus 由一个独立运行的 **daemon** 提供所有能力——你所使用的工具均由 daemon 定义和执行,MCP 只是透明的转发层。
3
+ You are now part of the **n2ns Nexus** coordination network. All capabilities are provided by a standalone **daemon** — every tool you use is defined and executed by the daemon. The MCP adapter is a transparent forwarding layer only.
4
4
 
5
- > **前提**:在使用任何工具之前,确认 daemon 已启动(`n2n-nexus daemon --port 5688`),你的 MCP 已连接(工具列表非空即为已连接)。
5
+ > **Prerequisite**: Before calling any tool, confirm that the daemon is running (`n2n-nexus daemon --port 5688`) and that your MCP is connected (a non-empty tool list means you are connected).
6
6
 
7
7
  ---
8
8
 
9
- ## 🚦 核心原则:先发现,再操作
9
+ ## Core principle: discover first, then act
10
10
 
11
- ### 1. 了解系统全局状态
11
+ ### 1. Understand the global system state
12
12
 
13
- 在任何任务开始前,先用以下工具了解环境:
13
+ Before starting any task, use these tools to orient yourself:
14
14
 
15
15
  ```
16
- get_global_topology() → 获取所有项目的摘要列表 + 依赖统计
17
- get_global_topology(projectId) → 获取特定项目的详细依赖子图
18
- search_projects(query) → 按名称或描述搜索项目
19
- read_messages(count) → 获取你尚未读取的消息(增量,自动游标)
16
+ get_global_topology() → summary list of all projects + dependency stats
17
+ get_global_topology(projectId) → detailed dependency sub-graph for one project
18
+ search_projects(query) → search projects by name or description
19
+ get_project(projectId) → full manifest + internal docs of one project
20
+ read_messages(count) → fetch messages you have not yet read (incremental, auto-cursor)
20
21
  ```
21
22
 
22
- ### 2. 声明工作上下文
23
+ ### 2. Project IDs
23
24
 
24
- 在写入任何项目数据前,必须先声明活跃项目:
25
+ There is no session to set up: every project tool takes the `projectId` it acts on.
26
+ Project IDs must follow `[prefix]_[name]` format, for example: `web_my-site`, `api_user-auth`, `mcp_nexus`.
25
27
 
26
- ```
27
- register_session_context(projectId) → 绑定当前会话到指定项目
28
- ```
29
-
30
- 项目 ID 格式必须为 `[prefix]_[name]`,例如:`web_datafrog.io`、`api_user-auth`、`mcp_nexus`。
31
-
32
- ### 3. 项目数据写入
28
+ ### 3. Write project data
33
29
 
34
30
  ```
35
- sync_project_assets(manifest, internalDocs) → [ASYNC] 同步项目全量数据,返回 taskId
36
- update_project(projectId, patch) → 部分更新 Manifest 字段
37
- rename_project(oldId, newId) → [ASYNC] 重命名并级联更新所有引用
38
- upload_project_asset(fileName, base64Content) → 上传二进制文件到项目库
31
+ sync_project_assets(manifest, internalDocs) → sync full project data
32
+ update_project(projectId, patch) → partial update of manifest fields
33
+ rename_project(oldId, newId) → rename and cascade-update all references
34
+ upload_project_asset(projectId, fileName, base64Content) → upload a binary file to the project store
39
35
  ```
40
36
 
41
- 异步操作返回 `taskId`,通过 `get_task(taskId)` 轮询进度(`progress` 0.0→1.0)。
37
+ All write tools run synchronously and return their result directly.
42
38
 
43
- ### 4. 消息与协作
39
+ ### 4. Messages and collaboration
44
40
 
45
41
  ```
46
- send_message(message, category?) → 发消息到活跃会议或全局聊天
47
- read_messages(count?, meetingId?) → 读取你的未读消息(增量)
48
- update_global_strategy(content) → 覆盖写入主战略文档
49
- sync_global_doc(docId, title, content) → 创建/更新跨项目共享文档
42
+ send_message(message, category?, meetingId?) → post to meetingId, else the active meeting, else global chat
43
+ read_messages(count?, meetingId?) → read your unread messages (incremental)
44
+ list_events(limit?, action?) → structured activity log (project.sync, meeting.end, ...)
45
+ get_global_strategy() → read the master strategy document
46
+ update_global_strategy(content) → overwrite the master strategy document
47
+ list_global_docs() → list cross-project shared documents
48
+ get_global_doc(docId) → read a shared document
49
+ sync_global_doc(docId, title, content) → create or update a cross-project shared document
50
50
  ```
51
51
 
52
- 消息分类(`category`):
53
- - `CHAT` — 普通讨论(默认)
54
- - `PROPOSAL` — 提案
55
- - `DECISION` — 决策/共识
56
- - `UPDATE` — 进度更新
57
- - `MEETING_START` — 系统用,无需手动设置
52
+ Message categories (`category`):
58
53
 
59
- ### 5. 战术会议
54
+ - `CHAT` — general discussion (default)
55
+ - `PROPOSAL` — a proposal for others to review
56
+ - `DECISION` — a locked consensus or decision
57
+ - `UPDATE` — a progress update
58
+ - `MEETING_START` — set by the system; do not set manually
59
+
60
+ ### 5. Tactical meetings
60
61
 
61
62
  ```
62
- start_meeting(topic) → 开启新会议,返回 meetingId
63
- send_message("...", "PROPOSAL") → 在会议中发言
64
- send_message("...", "DECISION") → 记录决策
65
- end_meeting(meetingId?, summary?) → 关闭并锁定会议
66
- archive_meeting(meetingId) → 存档(只读)
67
- reopen_meeting(meetingId) → 重新开启
63
+ list_meetings(status?, limit?) → list meetings with status, participants, counts, summary
64
+ start_meeting(topic) → open a meeting, returns meetingId
65
+ send_message("...", "PROPOSAL") → post a proposal inside the meeting
66
+ send_message("...", "DECISION") → record a decision
67
+ end_meeting(meetingId?, summary?) → close and lock the meeting
68
+ archive_meeting(meetingId) → move to archive (read-only)
69
+ reopen_meeting(meetingId) → reactivate a closed or archived meeting
68
70
  ```
69
71
 
70
- ### 6. 后台任务管理
72
+ ### 6. Task tracking
71
73
 
72
74
  ```
73
- create_task(source_meeting_id?, metadata?) → 创建任务,返回 taskId
74
- get_task(taskId) → 查询状态和进度
75
- list_tasks(status?) → 列出所有任务
76
- cancel_task(taskId) → 取消任务
75
+ create_task(source_meeting_id?, metadata?) → create a task you manage yourself, returns taskId
76
+ get_task(taskId) → query status and progress
77
+ list_tasks(status?) → list all tasks
78
+ cancel_task(taskId) → cancel a pending or running task
77
79
  ```
78
80
 
79
- ### 7. 维护工具
81
+ ### 7. Maintenance
80
82
 
81
83
  ```
82
- host_maintenance(action, count) → prune 最旧 N 条日志 / clear 全部
83
- host_delete_project(projectId) → [ASYNC] 永久删除项目(不可逆)
84
+ host_maintenance(action, count) → prune the oldest N global messages / clear all
85
+ host_delete_project(projectId) → permanently delete a project (irreversible)
84
86
  ```
85
87
 
86
88
  ---
87
89
 
88
- ## 📋 典型工作流
90
+ ## Typical workflows
91
+
92
+ ### First connection to the system
89
93
 
90
- ### 首次接入系统
91
94
  ```
92
- 1. get_global_topology() ← 了解有哪些项目
93
- 2. read_messages(20) ← 了解最近的讨论
94
- 3. register_session_context(id) ← 声明我在哪个项目工作
95
+ 1. get_global_topology() ← learn what projects exist
96
+ 2. read_messages(20) ← catch up on recent discussion
97
+ 3. get_project(projectId) ← read the manifest and docs of the project you work on
95
98
  ```
96
99
 
97
- ### 同步项目数据
100
+ ### Sync project data
101
+
98
102
  ```
99
- 1. register_session_context(projectId)
100
- 2. sync_project_assets(manifest, internalDocs) ← 返回 taskId
101
- 3. get_task(taskId) ← 轮询直到 completed
103
+ 1. sync_project_assets(manifest, internalDocs) ← returns { ok, projectId }
102
104
  ```
103
105
 
104
- ### 发起协作讨论
106
+ ### Start a collaborative discussion
107
+
105
108
  ```
106
109
  1. start_meeting("Topic")
107
- 2. send_message("我的提案...", "PROPOSAL")
108
- 3. read_messages() ← 读取其他实例的回复
109
- 4. send_message("已达成共识", "DECISION")
110
+ 2. send_message("My proposal...", "PROPOSAL")
111
+ 3. read_messages() ← read replies from other instances
112
+ 4. send_message("Consensus reached", "DECISION")
110
113
  5. end_meeting(meetingId, "summary")
111
114
  ```
112
115
 
113
116
  ---
114
117
 
115
- ## ⚠️ 注意事项
118
+ ## Notes
116
119
 
117
- - `read_messages` 是**增量的**:每次调用只返回自上次读取后的新消息,游标由 daemon 自动管理,不需要传 `afterId`。
118
- - 异步操作(`sync_project_assets`、`rename_project`、`host_delete_project`)立即返回 `taskId`,不阻塞。如需等待完成,轮询 `get_task`。
119
- - 项目 ID 一旦被其他项目引用(`relations`),重命名会自动级联更新所有引用,不需要手动处理。
120
- - daemon 重启后,你的 MCP 会自动重连并恢复工具列表,无需重启 IDE。
120
+ - `read_messages` is **incremental**: each call returns only messages received since the last read. The cursor is managed automatically by the daemon — do not pass `afterId`.
121
+ - Write tools (`sync_project_assets`, `update_project`, `rename_project`, `host_delete_project`) complete before they return; there is nothing to poll.
122
+ - When a project ID is referenced by other projects via `relations`, renaming it automatically cascades to all references — no manual cleanup needed.
123
+ - After a daemon restart, your MCP reconnects automatically and restores the tool list. You do not need to restart the IDE.
package/docs/README_zh.md CHANGED
@@ -37,12 +37,12 @@ n2n-nexus 面向这些场景设计:共享 daemon 状态、无状态 MCP 适配
37
37
 
38
38
  n2n-nexus 为 AI 助手提供共享协作空间。不同助手不再只依赖自己的聊天上下文,而是可以通过 MCP 读取和更新同一个本地 daemon 中的项目状态。
39
39
 
40
- **TL;DR**
40
+ **Quick summary**
41
41
 
42
42
  - **安装**:`npx n2n-nexus daemon --port 5688`
43
43
  - **协议**:Model Context Protocol (MCP),适配器通过 HTTP 连接 daemon
44
44
  - **存储**:默认在 `~/.n2n-nexus` 下使用本地文件和 SQLite
45
- - **适合**:多助手编码会话、项目交接、共享决策、会议记录、异步任务、项目 Manifest
45
+ - **适合**:多助手编码会话、项目交接、共享决策、会议记录、任务跟踪、项目 Manifest
46
46
  - **不适合**:云端团队聊天、公开项目管理 SaaS、源码索引、向量搜索或远程数据库托管
47
47
 
48
48
  ## 为什么使用它?
@@ -75,6 +75,8 @@ n2n-nexus 为 AI 助手提供共享协作空间。不同助手不再只依赖自
75
75
 
76
76
  ## 快速开始
77
77
 
78
+ 运行环境要求 Node.js 22.x 中的 22.14.0 或更高版本,或 Node.js 23.6.0 及以上版本。
79
+
78
80
  ### 1. 启动 daemon
79
81
 
80
82
  ```bash
@@ -110,43 +112,45 @@ npx n2n-nexus daemon --port 5688
110
112
 
111
113
  ## 工具集
112
114
 
113
- ### 会话和上下文
114
-
115
- - `register_session_context`:声明当前活跃项目 ID。
116
-
117
115
  ### 项目资产管理
118
116
 
119
117
  - `sync_project_assets`:提交项目 Manifest 和内部文档。
120
118
  - `update_project`:局部更新项目 Manifest。
121
119
  - `rename_project`:重命名项目 ID 并更新关联关系。
122
- - `upload_project_asset`:上传二进制或文本资产。
120
+ - `upload_project_asset`:向指定项目上传二进制或文本资产。
123
121
  - `search_projects`:搜索项目注册表。
124
122
  - `get_global_topology`:查看项目拓扑和依赖关系。
123
+ - `get_project`:读取项目完整 Manifest 和内部文档。
125
124
 
126
125
  ### 消息和协作
127
126
 
128
127
  - `send_message`:发送会议消息或全局消息。
129
- - `read_messages`:增量读取未读消息。
128
+ - `read_messages`:增量读取未读消息(全局或指定会议)。
129
+ - `list_events`:读取结构化活动日志(项目同步、重命名、会议结束等)。
130
+ - `get_global_strategy`:读取主策略文档。
130
131
  - `update_global_strategy`:更新主策略文档。
132
+ - `list_global_docs`:列出共享文档。
133
+ - `get_global_doc`:读取共享文档。
131
134
  - `sync_global_doc`:创建或更新共享文档。
132
135
 
133
136
  ### 会议管理
134
137
 
138
+ - `list_meetings`:列出会议(状态、参与者、消息与决策数、摘要)。
135
139
  - `start_meeting`:开启会议会话。
136
140
  - `end_meeting`:关闭并锁定会议。
137
141
  - `archive_meeting`:归档已关闭会议。
138
142
  - `reopen_meeting`:重新打开已关闭或已归档会议。
139
143
 
140
- ### 异步任务管理
144
+ ### 任务管理
141
145
 
142
- - `create_task`:创建后台任务。
146
+ - `create_task`:创建由助手自行管理的任务。
143
147
  - `get_task`:查询任务状态和结果。
144
148
  - `list_tasks`:按状态列出任务。
145
149
  - `cancel_task`:取消等待中或运行中的任务。
146
150
 
147
151
  ### 维护
148
152
 
149
- - `host_maintenance`:清理或清空系统日志。
153
+ - `host_maintenance`:清理或清空全局聊天流。
150
154
  - `host_delete_project`:删除项目和资产。
151
155
 
152
156
  ## 数据存储
@@ -209,7 +213,11 @@ NEXUS_ENDPOINT=http://127.0.0.1:5688 n2n-nexus mcp
209
213
  | `NEXUS_ENDPOINT` | MCP 适配器连接的 daemon 地址 | `http://127.0.0.1:5688` |
210
214
  | `NEXUS_ROOT` | daemon 存储根目录 | `~/.n2n-nexus` |
211
215
  | `NEXUS_HOST` | daemon 监听地址 | `127.0.0.1` |
212
- | `NEXUS_INSTANCE_ID` | 覆盖 MCP 实例 ID | 自动生成 |
216
+ | `NEXUS_DAEMON_PORT` | daemon 端口(`--port` 优先) | `5688` |
217
+ | `NEXUS_RATE_LIMIT` | 每个实例每秒工具调用数,每个客户端地址为其 5 倍;`0` 关闭限流 | `20` |
218
+ | `NEXUS_RATE_BURST` | 每个实例可一次性突发的调用数(最小为 1) | `60` |
219
+ | `NEXUS_ALLOWED_HOSTS` | `Host` 头额外允许的域名,逗号分隔(IP、`localhost`、`host.docker.internal` 始终允许) | 空 |
220
+ | `NEXUS_INSTANCE_ID` | 覆盖 MCP 实例 ID(未读游标、会议权限都以它为键) | `mcp-<主机名>-<工作目录哈希>-<IDE 名>` |
213
221
 
214
222
  ## 安全和治理说明
215
223
 
@@ -226,10 +234,12 @@ NEXUS_ENDPOINT=http://127.0.0.1:5688 n2n-nexus mcp
226
234
  | 文件 | 说明 |
227
235
  | --- | --- |
228
236
  | [会议纪要](./MEETING_MINUTES_2025-12-29.md) | 结构化决策和测试记录 |
229
- | [讨论日志](./discussion_2025-12-29_en.md) | 可读的讨论记录 |
237
+ | [讨论日志](./discussion_2025-12-29.md) | 可读的讨论记录 |
230
238
 
231
239
  ## 本地开发
232
240
 
241
+ 开发请使用 Node.js 24,与 CI 和 lint 工具链保持一致。
242
+
233
243
  ```bash
234
244
  git clone https://github.com/n2ns/n2n-nexus.git
235
245
  cd n2n-nexus
@@ -272,7 +282,7 @@ NEXUS_ENDPOINT=http://127.0.0.1:5688 node build/index.js mcp
272
282
  ## 相关文档
273
283
 
274
284
  - [架构文档](./ARCHITECTURE_zh.md)
275
- - [AI 助手指南](./ASSISTANT_GUIDE.md)
285
+ - [AI 助手指南](./ASSISTANT_GUIDE_zh.md)
276
286
  - [英文 README](../README.md)
277
287
  - [llms.txt](../llms.txt)
278
288
 
@@ -282,4 +292,4 @@ NEXUS_ENDPOINT=http://127.0.0.1:5688 node build/index.js mcp
282
292
 
283
293
  ---
284
294
 
285
- Built by N2NS Lab, short for Next-to-Native Systems Lab, Datafrog's open-source lab for practical AI developer tools.
295
+ Built by N2NS Lab, Datafrog's open-source lab for practical AI developer tools.
package/llms.txt CHANGED
@@ -2,6 +2,16 @@
2
2
 
3
3
  n2n-nexus is a local-first Model Context Protocol (MCP) coordination hub from N2NS Lab for multi-AI assistant collaboration. It uses a long-running local daemon as the source of truth and stateless MCP adapters for IDEs and AI coding assistants.
4
4
 
5
+ ## Search intent coverage
6
+
7
+ - multi-agent MCP coordination
8
+ - multi-AI assistant collaboration
9
+ - local MCP coordination hub
10
+ - shared project context for AI coding agents
11
+ - cross-IDE MCP collaboration server
12
+ - local-first project registry for AI assistants
13
+ - meeting and task coordination for coding agents
14
+
5
15
  ## Core positioning
6
16
 
7
17
  - Local MCP coordination hub for multi-AI assistant collaboration.
@@ -43,4 +53,4 @@ Default storage root is `~/.n2n-nexus`, containing global docs, project manifest
43
53
 
44
54
  ## Brand
45
55
 
46
- Built by N2NS Lab, short for Next-to-Native Systems Lab, Datafrog's open-source lab for practical AI developer tools.
56
+ Built by N2NS Lab, Datafrog's open-source lab for practical AI developer tools.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n2n-nexus",
3
- "version": "0.4.2",
3
+ "version": "0.6.0",
4
4
  "description": "Local-first MCP coordination hub from N2NS Lab for multi-AI assistant collaboration.",
5
5
  "main": "build/index.js",
6
6
  "type": "module",
@@ -9,6 +9,7 @@
9
9
  },
10
10
  "files": [
11
11
  "build",
12
+ "assets",
12
13
  "README.md",
13
14
  "llms.txt",
14
15
  "CHANGELOG.md",
@@ -49,6 +50,10 @@
49
50
  "ai-developer-tools"
50
51
  ],
51
52
  "author": "N2NS Lab",
53
+ "funding": {
54
+ "type": "github",
55
+ "url": "https://github.com/sponsors/n2ns"
56
+ },
52
57
  "license": "Apache-2.0",
53
58
  "repository": {
54
59
  "type": "git",
@@ -59,32 +64,37 @@
59
64
  "url": "https://github.com/n2ns/n2n-nexus/issues"
60
65
  },
61
66
  "engines": {
62
- "node": ">=18.0.0"
67
+ "node": "^22.14.0 || >=23.6.0"
63
68
  },
64
69
  "scripts": {
65
- "build": "tsc",
70
+ "build": "node -e \"fs.rmSync('build', { recursive: true, force: true })\" && tsc",
66
71
  "start": "node build/index.js",
67
72
  "daemon": "node build/index.js daemon",
68
73
  "dev": "tsc -w",
69
74
  "test": "vitest run",
75
+ "audit": "npm audit",
76
+ "audit:prod": "npm audit --omit=dev",
77
+ "pack:dry-run": "npm pack --dry-run",
78
+ "check": "npm run lint && npm test && npm run build && npm run audit && npm run pack:dry-run",
70
79
  "test:publish": "npm run build && npm test && npm pack --dry-run",
71
80
  "test:integration": "vitest run tests/daemon_projects.test.ts tests/daemon_messages.test.ts tests/message_cursor.test.ts",
72
- "lint": "eslint src/**",
73
- "prepublishOnly": "npm run build && npm test"
81
+ "lint": "eslint src tests",
82
+ "prepublishOnly": "npm run check"
74
83
  },
75
84
  "dependencies": {
76
- "@modelcontextprotocol/sdk": "^1.29.0",
77
- "better-sqlite3": "^12.10.1",
78
- "zod": "^4.4.3"
85
+ "@modelcontextprotocol/server": "^2.3.1",
86
+ "better-sqlite3": "^13.0.3",
87
+ "zod": "^4.6.6"
79
88
  },
80
89
  "devDependencies": {
81
90
  "@eslint/js": "^10.0.1",
82
- "@types/better-sqlite3": "^7.6.13",
83
- "@types/node": "^25.9.3",
84
- "eslint": "^10.5.0",
85
- "lefthook": "^2.1.9",
91
+ "@modelcontextprotocol/client": "^2.3.1",
92
+ "@types/better-sqlite3": "^9.6.0",
93
+ "@types/node": "^26.6.5",
94
+ "eslint": "^10.12.0",
95
+ "lefthook": "^2.2.1",
86
96
  "typescript": "^6.0.3",
87
- "typescript-eslint": "^8.61.0",
88
- "vitest": "^4.1.8"
97
+ "typescript-eslint": "^8.71.1",
98
+ "vitest": "^5.0.3"
89
99
  }
90
100
  }