@geminilight/mindos 0.1.6 → 0.1.8

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
@@ -65,42 +65,45 @@ Static documents are hard to synchronize and weak as execution systems in real h
65
65
 
66
66
  ## ✨ Features
67
67
 
68
- ### For Humans
68
+ **For Humans**
69
69
 
70
70
  - **GUI Collaboration Workbench**: use one command entry to browse, edit, and search efficiently (`⌘K` / `⌘/`).
71
71
  - **Built-in Agent Assistant**: converse in context while edits are captured into managed knowledge.
72
72
  - **Plugin Views**: use scenario-focused views like TODO, Kanban, and Timeline.
73
73
 
74
- ### For Agents
74
+ **For Agents**
75
75
 
76
76
  - **MCP Server + Skills**: connect any compatible agent to read, write, search, and run workflows.
77
77
  - **Structured Templates**: start quickly with Profile, Workflows, and Configurations scaffolds.
78
78
  - **Experience Auto-Distillation**: automatically distill daily work into reusable, executable SOP experience.
79
79
 
80
- ### Infrastructure
80
+ **Infrastructure**
81
81
 
82
82
  - **Reference Sync**: keep cross-file status and context aligned via links/backlinks.
83
83
  - **Knowledge Graph**: visualize relationships and dependencies across notes.
84
84
  - **Git Time Machine**: track every edit, audit history, and roll back safely.
85
85
 
86
- **Coming Soon:**
86
+ <details>
87
+ <summary><strong>Coming Soon</strong></summary>
87
88
 
88
89
  - [ ] ACP (Agent Communication Protocol): connect external Agents (e.g., Claude Code, Cursor) and turn the knowledge base into a multi-Agent collaboration hub
89
90
  - [ ] Deep RAG integration: retrieval-augmented generation grounded in your knowledge base for more accurate, context-aware AI responses
90
91
  - [ ] Backlinks View: display all files that reference the current file, helping you understand how a note fits into the knowledge network
91
92
  - [ ] Agent Inspector: render Agent operation logs as a filterable timeline to audit every tool call in detail
92
93
 
94
+ </details>
95
+
93
96
  ---
94
97
 
95
98
  ## 🚀 Getting Started
96
99
 
97
100
  > [!IMPORTANT]
98
- > **Quick Start with Agent:** Paste this prompt into any MCP-capable Agent (Claude Code, Cursor, etc.) to install automatically, then skip to [Step 4](#4-inject-your-personal-mind-with-mindos-agent):
101
+ > **Quick Start with Agent:** Paste this prompt into any MCP-capable Agent (Claude Code, Cursor, etc.) to install automatically, then skip to [Step 3](#3-inject-your-personal-mind-with-mindos-agent):
99
102
  > ```
100
103
  > Help me install MindOS from https://github.com/GeminiLight/MindOS with MCP and Skills. Use English template.
101
104
  > ```
102
105
 
103
- > Already have a knowledge base? Skip to [Step 5](#5-make-any-agent-ready-mcp--skills) to configure MCP + Skills.
106
+ > Already have a knowledge base? Skip to [Step 4](#4-make-any-agent-ready-mcp--skills) to configure MCP + Skills.
104
107
 
105
108
  ### 1. Install
106
109
 
@@ -129,10 +132,13 @@ mindos onboard --install-daemon
129
132
 
130
133
  The setup wizard will guide you through:
131
134
  1. Knowledge base path → default `~/.mindos/my-mind`
132
- 2. Choose template language (en / zh)
133
- 3. Optional Auth token to protect your API
134
- 4. Configure AI Provider (Anthropic / OpenAI) + API Key — or choose **skip** to configure later via `mindos config set`
135
- 5. Config saved to `~/.mindos/config.json` automatically
135
+ 2. Choose template (en / zh / empty / custom)
136
+ 3. Ports (Web UI + MCP)
137
+ 4. Auth token (auto-generated or passphrase-seeded)
138
+ 5. Web UI password (optional)
139
+ 6. AI Provider (Anthropic / OpenAI) + API Key — or **skip** to configure later via `mindos config set`
140
+
141
+ Config is saved to `~/.mindos/config.json` automatically.
136
142
 
137
143
  <!-- For Agents: Before running setup, if the user has not provided LLM configuration, ask them:
138
144
  1. AI Provider — `anthropic` or `openai` (compatible)?
@@ -183,24 +189,10 @@ Multiple providers can be configured simultaneously — switch between them by c
183
189
  > [!NOTE]
184
190
  > If you want the MindOS GUI to be reachable from other devices, make sure the port is open in firewall/security-group settings and bound to an accessible host/network interface.
185
191
 
186
- ### 3. Run
187
-
188
- ```bash
189
- mindos start # start app + MCP server (production, auto-rebuilds when a new version is detected)
190
- ```
191
-
192
- On startup, MindOS prints your Web UI URL, MCP config snippet, and auth token — ready to copy into your Agent.
193
-
194
192
  > [!TIP]
195
- > **Upgrading?** Run `mindos update` to install the latest version.
193
+ > With `--install-daemon`, MindOS is installed as a background OS service and starts automatically — no need to run `mindos start` manually. If you skipped the flag, run `mindos start` to start manually, or `mindos update` to upgrade to the latest version.
196
194
 
197
- > [!TIP]
198
- > If the port is already in use, set a different port during `mindos onboard` or update `~/.mindos/config.json`:
199
- > ```bash
200
- > MINDOS_WEB_PORT=3002 mindos
201
- > ```
202
-
203
- ### 4. Inject Your Personal Mind with MindOS Agent
195
+ ### 3. Inject Your Personal Mind with MindOS Agent
204
196
 
205
197
  1. Open the built-in MindOS Agent chat panel in the GUI.
206
198
  2. Upload your resume or any personal/project material.
@@ -210,24 +202,51 @@ On startup, MindOS prints your Web UI URL, MCP config snippet, and auth token
210
202
  <img src="assets/images/gui-sync-cv.png" alt="Sync CV Example" width="800" />
211
203
  </p>
212
204
 
213
- ### 5. Make Any Agent Ready (MCP + Skills)
205
+ ### 4. Make Any Agent Ready (MCP + Skills)
214
206
 
215
- #### 5.1 Configure MindOS MCP
207
+ #### 4.1 Configure MindOS MCP
216
208
 
217
209
  <!-- For Agents: Register MindOS MCP as global (user-level) config by default, so all projects share the same knowledge base. -->
218
210
 
219
- > [!TIP]
220
- > Each Agent stores MCP config in a different file — see the **MCP Config Path** column in the [Supported Agents](#-supported-agents) table below for exact paths.
211
+ Run one command to auto-install MCP config into your Agent:
221
212
 
222
- Register the MindOS MCP Server in your Agent client:
213
+ ```bash
214
+ mindos mcp install
215
+ ```
216
+
217
+ Supports Claude Code, Cursor, Windsurf, Cline, Trae, Gemini CLI, and more — interactively guides you through agent, scope, transport, and token.
223
218
 
224
- The MCP server starts automatically when you run `mindos start` or `mindos dev`. The MCP URL, auth token, and a ready-to-paste config snippet are printed on every startup.
219
+ **Local (Agent and MindOS on the same machine)**
225
220
 
226
- > The MCP port defaults to `8787`. To use a different port, set `mcpPort` in `~/.mindos/config.json` via `mindos onboard`.
221
+ Use `stdio` transport no server process needed, most reliable:
227
222
 
228
- **Option A: Local (same machine)**
223
+ ```bash
224
+ # Interactive
225
+ mindos mcp install
229
226
 
230
- Via stdio no server process needed:
227
+ # One-shot, global scope (shared across all projects)
228
+ mindos mcp install claude-code -g -y
229
+ ```
230
+
231
+ **Remote (Agent on a different machine)**
232
+
233
+ Use `http` transport — MindOS must be running (`mindos start`) on the remote machine:
234
+
235
+ ```bash
236
+ mindos mcp install codex --transport http --url http://<server-ip>:8787/mcp --token your-token -g
237
+ ```
238
+
239
+ > [!NOTE]
240
+ > For remote access, ensure port `8787` is open in your firewall/security-group.
241
+
242
+ > Add `-g` to install globally — MCP config is shared across all projects instead of the current directory only.
243
+
244
+ > The MCP port defaults to `8787`. To use a different port, run `mindos onboard` and set `mcpPort`.
245
+
246
+ <details>
247
+ <summary>Manual config (JSON snippets)</summary>
248
+
249
+ **Local via stdio** (no server process needed):
231
250
 
232
251
  ```json
233
252
  {
@@ -242,7 +261,7 @@ Via stdio — no server process needed:
242
261
  }
243
262
  ```
244
263
 
245
- Or via URL:
264
+ **Local via URL:**
246
265
 
247
266
  ```json
248
267
  {
@@ -255,10 +274,7 @@ Or via URL:
255
274
  }
256
275
  ```
257
276
 
258
- **Option B: Remote URL (another device)**
259
-
260
- > [!NOTE]
261
- > Ensure port `8787` is open in your firewall/security-group so remote clients can reach the server.
277
+ **Remote:**
262
278
 
263
279
  ```json
264
280
  {
@@ -271,7 +287,11 @@ Or via URL:
271
287
  }
272
288
  ```
273
289
 
274
- #### 5.2 Install MindOS Skills
290
+ Each Agent stores config in a different file — see the **MCP Config Path** column in the [Supported Agents](#-supported-agents) table for exact paths.
291
+
292
+ </details>
293
+
294
+ #### 4.2 Install MindOS Skills
275
295
 
276
296
  | Skill | Description |
277
297
  |-------|-------------|
@@ -290,7 +310,7 @@ npx skills add https://github.com/GeminiLight/MindOS --skill mindos-zh -g -y
290
310
 
291
311
  MCP = connection capability, Skills = workflow capability. Enabling both gives the complete MindOS agent experience.
292
312
 
293
- #### 5.3 Common Pitfalls
313
+ #### 4.3 Common Pitfalls
294
314
 
295
315
  - Only MCP, no Skills: tools are callable, but best-practice workflows are missing.
296
316
  - Only Skills, no MCP: workflow guidance exists, but the Agent cannot operate your local knowledge base.
package/README_zh.md CHANGED
@@ -65,42 +65,45 @@ MindOS 是一个**人机协同心智系统**——基于本地优先的协作知
65
65
 
66
66
  ## ✨ 功能特性
67
67
 
68
- ### 人类侧
68
+ **人类侧**
69
69
 
70
70
  - **GUI 协作工作台**:以统一入口高效浏览、编辑与搜索(`⌘K` / `⌘/`)。
71
71
  - **内置 Agent 助手**:在上下文中对话,编辑内容可持续沉淀为可管理知识。
72
72
  - **插件视图**:按场景使用 TODO、看板、时间线等视图。
73
73
 
74
- ### Agent
74
+ **Agent 侧**
75
75
 
76
76
  - **MCP Server + Skills**:让兼容 Agent 统一接入读写、搜索与工作流执行。
77
77
  - **结构化模板**:通过 Profile、Workflows、Configurations 快速冷启动。
78
78
  - **经验自动沉淀**:将日常记录自动化沉淀为可执行 SOP 经验。
79
79
 
80
- ### 基础设施
80
+ **基础设施**
81
81
 
82
82
  - **引用同步**:通过引用与反向链接保持跨文件状态一致。
83
83
  - **知识图谱**:可视化笔记间关系与依赖。
84
84
  - **Git 时光机**:记录修改历史,支持审计与安全回滚。
85
85
 
86
- **即将到来:**
86
+ <details>
87
+ <summary><strong>即将到来</strong></summary>
87
88
 
88
89
  - [ ] ACP(Agent Communication Protocol):连接外部 Agent(如 Claude Code、Cursor),让知识库成为多 Agent 协作的中枢
89
90
  - [ ] RAG 深度集成:基于知识库内容的检索增强生成,让 AI 回答更精准、更有上下文
90
91
  - [ ] 反向链接视图(Backlinks):展示所有引用当前文件的反向链接,理解笔记在知识网络中的位置
91
92
  - [ ] Agent 审计面板(Agent Inspector):将 Agent 操作日志渲染为可筛选的时间线,审查每次工具调用的详情
92
93
 
94
+ </details>
95
+
93
96
  ---
94
97
 
95
98
  ## 🚀 快速开始
96
99
 
97
100
  > [!IMPORTANT]
98
- > **用 Agent 一键安装:** 将以下指令粘贴到任意支持 MCP 的 Agent(Claude Code、Cursor 等),即可自动完成安装,然后跳到[第 4 步](#4-通过-mindos-agent-注入你的个人心智):
101
+ > **用 Agent 一键安装:** 将以下指令粘贴到任意支持 MCP 的 Agent(Claude Code、Cursor 等),即可自动完成安装,然后跳到[第 3 步](#3-通过-mindos-agent-注入你的个人心智):
99
102
  > ```
100
103
  > 帮我从 https://github.com/GeminiLight/MindOS 安装 MindOS,包含 MCP 和 Skills,使用中文模板。
101
104
  > ```
102
105
 
103
- > 已有知识库?直接跳到[第 5 步](#5-让任意-agent-可用mcp--skills)配置 MCP + Skills。
106
+ > 已有知识库?直接跳到[第 4 步](#4-让任意-agent-可用mcp--skills)配置 MCP + Skills。
104
107
 
105
108
  ### 1. 安装
106
109
 
@@ -129,10 +132,13 @@ mindos onboard --install-daemon
129
132
 
130
133
  配置向导将引导你完成:
131
134
  1. 知识库路径 → 默认 `~/.mindos/my-mind`
132
- 2. 选择模板语言(en / zh / empty)
133
- 3. 可选 Auth token,保护你的 API
134
- 4. 配置 AI Provider(Anthropic / OpenAI)+ API Key — 或选择 **skip**,稍后通过 `mindos config set` 补填
135
- 5. 配置自动保存到 `~/.mindos/config.json`
135
+ 2. 选择模板(en / zh / empty / custom
136
+ 3. 端口配置(Web UI + MCP)
137
+ 4. Auth token(自动生成或口令派生)
138
+ 5. Web UI 访问密码(可选)
139
+ 6. 配置 AI Provider(Anthropic / OpenAI)+ API Key — 或选择 **skip**,稍后通过 `mindos config set` 补填
140
+
141
+ 配置自动保存到 `~/.mindos/config.json`。
136
142
 
137
143
  <!-- For Agents: 运行 onboard 前,如果用户未提供 LLM 配置,请询问:
138
144
  1. AI Provider — `anthropic` 还是 `openai`(兼容)?
@@ -183,24 +189,10 @@ mindos onboard --install-daemon
183
189
  > [!NOTE]
184
190
  > 如果你希望其他设备也能访问 MindOS GUI,请确保端口已在防火墙/安全组中放行,并绑定到可访问的主机地址/网卡。
185
191
 
186
- ### 3. 启动
187
-
188
- ```bash
189
- mindos start # 启动 app + MCP 服务(生产模式,检测到新版本时自动重新构建)
190
- ```
191
-
192
- 启动后,MindOS 会自动打印 Web UI 地址、MCP 配置片段和 Auth token,直接复制到你的 Agent 即可。
193
-
194
192
  > [!TIP]
195
- > **升级?** 运行 `mindos update` 安装最新版本。
193
+ > 使用 `--install-daemon` 时,MindOS 会作为后台 OS 服务安装并自动启动,无需手动执行 `mindos start`。如果跳过了该参数,运行 `mindos start` 手动启动,或运行 `mindos update` 升级到最新版本。
196
194
 
197
- > [!TIP]
198
- > 如果端口被占用,在 `mindos onboard` 时指定其他端口,或更新 `~/.mindos/config.json`,也可通过环境变量临时覆盖:
199
- > ```bash
200
- > MINDOS_WEB_PORT=3002 mindos
201
- > ```
202
-
203
- ### 4. 通过 MindOS Agent 注入你的个人心智
195
+ ### 3. 通过 MindOS Agent 注入你的个人心智
204
196
 
205
197
  1. 打开 MindOS GUI 中内置的 Agent 对话面板。
206
198
  2. 上传你的简历或任意个人/项目资料。
@@ -210,24 +202,54 @@ mindos start # 启动 app + MCP 服务(生产模式,检测到新版本时
210
202
  <img src="assets/images/gui-sync-cv.png" alt="同步简历示例" width="800" />
211
203
  </p>
212
204
 
213
- ### 5. 让任意 Agent 可用(MCP + Skills)
205
+ ### 4. 让任意 Agent 可用(MCP + Skills)
214
206
 
215
- #### 5.1 配置 MindOS MCP
207
+ #### 4.1 配置 MindOS MCP
216
208
 
217
209
  <!-- For Agents: MindOS MCP 默认注册为全局(user-level)配置,使所有项目共享同一知识库。-->
218
210
 
219
- > [!TIP]
220
- > 每个 Agent 的 MCP 配置文件路径不同——详见下方 [支持的 Agent](#-支持的-agent) 表格中的 **MCP 配置文件路径** 列。
211
+ 一条命令自动将 MCP 配置写入 Agent:
212
+
213
+ ```bash
214
+ mindos mcp install
215
+ ```
216
+
217
+ 支持 Claude Code、Cursor、Windsurf、Cline、Trae、Gemini CLI 等主流 Agent,交互式引导完成 agent、scope、transport 和 token 的配置。
218
+
219
+ **本机访问(Agent 和 MindOS 在同一台机器)**
221
220
 
222
- MindOS MCP Server 注册到你的 Agent 客户端:
221
+ 使用 `stdio` transport 无需启动服务进程,最稳定:
223
222
 
224
- 运行 `mindos start` 或 `mindos dev` 时,MCP 服务自动随之启动。每次启动都会打印 MCP URL、Auth token 及可直接粘贴的配置片段。
223
+ ```bash
224
+ # 交互式
225
+ mindos mcp install claude-code
226
+
227
+ # 一键安装,无需交互(stdio + 项目级)
228
+ mindos mcp install claude-code -y
229
+
230
+ # 一键安装,全局(所有项目共享)
231
+ mindos mcp install claude-code -g -y
232
+ ```
233
+
234
+ **远程访问(Agent 在另一台机器)**
235
+
236
+ 使用 `http` transport — 远程机器上需先运行 `mindos start`:
237
+
238
+ ```bash
239
+ mindos mcp install claude-code --transport http --url http://<服务器IP>:8787/mcp --token your-token
240
+ ```
225
241
 
226
- > MCP 端口默认为 `8787`。如需修改,通过 `mindos onboard` 设置 `~/.mindos/config.json` 中的 `mcpPort`。
242
+ > [!NOTE]
243
+ > 远程访问时,请确保端口 `8787` 已在防火墙/安全组中放行。
244
+
245
+ > 加 `-g` 表示全局安装 — MCP 配置写入用户级配置文件,所有项目共享,而非仅当前目录。
227
246
 
228
- **方式 A:本机(同一台机器)**
247
+ > MCP 端口默认为 `8787`。如需修改,运行 `mindos onboard` 设置 `mcpPort`。
229
248
 
230
- 通过 stdio — 无需启动服务进程:
249
+ <details>
250
+ <summary>手动配置(JSON 片段)</summary>
251
+
252
+ **本机 stdio**(无需启动服务进程):
231
253
 
232
254
  ```json
233
255
  {
@@ -242,7 +264,7 @@ mindos start # 启动 app + MCP 服务(生产模式,检测到新版本时
242
264
  }
243
265
  ```
244
266
 
245
- 或通过 URL
267
+ **本机 URL:**
246
268
 
247
269
  ```json
248
270
  {
@@ -255,10 +277,7 @@ mindos start # 启动 app + MCP 服务(生产模式,检测到新版本时
255
277
  }
256
278
  ```
257
279
 
258
- **方式 B:远程 URL(其他设备)**
259
-
260
- > [!NOTE]
261
- > 请确保端口 `8787` 已在防火墙/安全组中放行,远程客户端才能连接。
280
+ **远程:**
262
281
 
263
282
  ```json
264
283
  {
@@ -271,7 +290,11 @@ mindos start # 启动 app + MCP 服务(生产模式,检测到新版本时
271
290
  }
272
291
  ```
273
292
 
274
- #### 5.2 安装 MindOS Skills
293
+ Agent 的配置文件路径不同,详见下方 [支持的 Agent](#-支持的-agent) 表格中的 **MCP 配置文件路径** 列。
294
+
295
+ </details>
296
+
297
+ #### 4.2 安装 MindOS Skills
275
298
 
276
299
  | Skill | 说明 |
277
300
  |-------|------|
@@ -290,7 +313,7 @@ npx skills add https://github.com/GeminiLight/MindOS --skill mindos-zh -g -y
290
313
 
291
314
  MCP = 连接能力,Skills = 工作流能力;两者都开启后体验完整。
292
315
 
293
- #### 5.3 常见误区
316
+ #### 4.3 常见误区
294
317
 
295
318
  - 只配 MCP,不装 Skills:能调用工具,但缺少最佳实践指引。
296
319
  - 只装 Skills,不配 MCP:有流程提示,但无法操作本地知识库。
package/bin/cli.js CHANGED
@@ -539,6 +539,158 @@ function spawnMcp(verbose = false) {
539
539
  return child;
540
540
  }
541
541
 
542
+ // ── mcp install ───────────────────────────────────────────────────────────────
543
+
544
+ const MCP_AGENTS = {
545
+ 'claude-code': { name: 'Claude Code', project: '.mcp.json', global: '~/.claude.json', key: 'mcpServers' },
546
+ 'claude-desktop': { name: 'Claude Desktop', project: null, global: process.platform === 'darwin' ? '~/Library/Application Support/Claude/claude_desktop_config.json' : '~/.config/Claude/claude_desktop_config.json', key: 'mcpServers' },
547
+ 'cursor': { name: 'Cursor', project: '.cursor/mcp.json', global: '~/.cursor/mcp.json', key: 'mcpServers' },
548
+ 'windsurf': { name: 'Windsurf', project: null, global: '~/.codeium/windsurf/mcp_config.json', key: 'mcpServers' },
549
+ 'cline': { name: 'Cline', project: null, global: process.platform === 'darwin' ? '~/Library/Application Support/Code/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json' : '~/.config/Code/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json', key: 'mcpServers' },
550
+ 'trae': { name: 'Trae', project: '.trae/mcp.json', global: '~/.trae/mcp.json', key: 'mcpServers' },
551
+ 'gemini-cli': { name: 'Gemini CLI', project: '.gemini/settings.json', global: '~/.gemini/settings.json', key: 'mcpServers' },
552
+ 'openclaw': { name: 'OpenClaw', project: null, global: '~/.openclaw/mcp.json', key: 'mcpServers' },
553
+ 'codebuddy': { name: 'CodeBuddy', project: null, global: '~/.claude-internal/.claude.json', key: 'mcpServers' },
554
+ };
555
+
556
+ function expandHome(p) {
557
+ return p.startsWith('~/') ? resolve(homedir(), p.slice(2)) : p;
558
+ }
559
+
560
+ async function mcpInstall() {
561
+ const args = process.argv.slice(4);
562
+
563
+ // parse flags
564
+ const hasGlobalFlag = args.includes('-g') || args.includes('--global');
565
+ const hasYesFlag = args.includes('-y') || args.includes('--yes');
566
+ const transportIdx = args.findIndex(a => a === '--transport');
567
+ const urlIdx = args.findIndex(a => a === '--url');
568
+ const tokenIdx = args.findIndex(a => a === '--token');
569
+ const transportArg = transportIdx >= 0 ? args[transportIdx + 1] : null;
570
+ const urlArg = urlIdx >= 0 ? args[urlIdx + 1] : null;
571
+ const tokenArg = tokenIdx >= 0 ? args[tokenIdx + 1] : null;
572
+
573
+ // agent positional arg: first non-flag arg after "mcp install"
574
+ const agentArg = args.find(a => !a.startsWith('-')) ?? null;
575
+
576
+ const readline = await import('node:readline');
577
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
578
+ const ask = (q) => new Promise(r => rl.question(q, r));
579
+ const choose = async (prompt, options, defaultIdx = 0) => {
580
+ if (hasYesFlag) return options[defaultIdx];
581
+ console.log(`\n${bold(prompt)}\n`);
582
+ options.forEach((o, i) => console.log(` ${dim(`${i + 1}.`)} ${o.label} ${o.hint ? dim(`(${o.hint})`) : ''}`));
583
+ const ans = await ask(`\n${bold(`Enter number`)} ${dim(`[${defaultIdx + 1}]:`)} `);
584
+ const idx = ans.trim() === '' ? defaultIdx : parseInt(ans.trim(), 10) - 1;
585
+ return options[idx >= 0 && idx < options.length ? idx : defaultIdx];
586
+ };
587
+
588
+ console.log(`\n${bold('🔌 MindOS MCP Install')}\n`);
589
+
590
+ // ── 1. agent ────────────────────────────────────────────────────────────────
591
+ let agentKey = agentArg;
592
+ if (!agentKey) {
593
+ const keys = Object.keys(MCP_AGENTS);
594
+ const picked = await choose('Which Agent would you like to configure?',
595
+ keys.map(k => ({ label: MCP_AGENTS[k].name, hint: k, value: k })));
596
+ agentKey = picked.value;
597
+ }
598
+
599
+ const agent = MCP_AGENTS[agentKey];
600
+ if (!agent) {
601
+ rl.close();
602
+ console.error(red(`\nUnknown agent: ${agentKey}`));
603
+ console.error(dim(`Supported: ${Object.keys(MCP_AGENTS).join(', ')}`));
604
+ process.exit(1);
605
+ }
606
+
607
+ // ── 2. scope (only ask if agent supports both) ───────────────────────────────
608
+ let isGlobal = hasGlobalFlag;
609
+ if (!hasGlobalFlag) {
610
+ if (agent.project && agent.global) {
611
+ const picked = await choose('Install scope?', [
612
+ { label: 'Project', hint: agent.project, value: 'project' },
613
+ { label: 'Global', hint: agent.global, value: 'global' },
614
+ ]);
615
+ isGlobal = picked.value === 'global';
616
+ } else {
617
+ // agent only supports one scope, no need to ask
618
+ isGlobal = !agent.project;
619
+ }
620
+ }
621
+
622
+ const configPath = isGlobal ? agent.global : agent.project;
623
+ if (!configPath) {
624
+ rl.close();
625
+ console.error(red(`${agent.name} does not support ${isGlobal ? 'global' : 'project'} scope.`));
626
+ process.exit(1);
627
+ }
628
+
629
+ // ── 3. transport ─────────────────────────────────────────────────────────────
630
+ let transport = transportArg;
631
+ if (!transport) {
632
+ const picked = await choose('Transport type?', [
633
+ { label: 'stdio', hint: 'local, no server process needed (recommended)' },
634
+ { label: 'http', hint: 'URL-based, use when server is running separately or remotely' },
635
+ ]);
636
+ transport = picked.label;
637
+ }
638
+
639
+ // ── 4. url + token (only for http) ───────────────────────────────────────────
640
+ let url = urlArg;
641
+ let token = tokenArg;
642
+
643
+ if (transport === 'http') {
644
+ if (!url) {
645
+ url = hasYesFlag ? 'http://localhost:8787/mcp' : (await ask(`${bold('MCP URL')} ${dim('[http://localhost:8787/mcp]:')} `)).trim() || 'http://localhost:8787/mcp';
646
+ }
647
+
648
+ if (!token) {
649
+ // try reading from config.json first
650
+ try { token = JSON.parse(readFileSync(CONFIG_PATH, 'utf-8')).authToken || ''; } catch {}
651
+ if (!token && !hasYesFlag) {
652
+ token = (await ask(`${bold('Auth token')} ${dim('(leave blank to skip):')} `)).trim();
653
+ } else if (token) {
654
+ console.log(dim(` Using auth token from ~/.mindos/config.json`));
655
+ }
656
+ }
657
+ }
658
+
659
+ rl.close();
660
+
661
+ // ── build entry ──────────────────────────────────────────────────────────────
662
+ const entry = transport === 'stdio'
663
+ ? { type: 'stdio', command: 'mindos', args: ['mcp'], env: { MCP_TRANSPORT: 'stdio' } }
664
+ : token
665
+ ? { url, headers: { Authorization: `Bearer ${token}` } }
666
+ : { url };
667
+
668
+ // ── read + merge existing config ─────────────────────────────────────────────
669
+ const absPath = expandHome(configPath);
670
+ let config = {};
671
+ if (existsSync(absPath)) {
672
+ try { config = JSON.parse(readFileSync(absPath, 'utf-8')); } catch {
673
+ console.error(red(`\nFailed to parse existing config: ${absPath}`));
674
+ process.exit(1);
675
+ }
676
+ }
677
+
678
+ if (!config[agent.key]) config[agent.key] = {};
679
+ const existed = !!config[agent.key].mindos;
680
+ config[agent.key].mindos = entry;
681
+
682
+ // ── preview + write ──────────────────────────────────────────────────────────
683
+ console.log(`\n${bold('Preview:')} ${dim(absPath)}\n`);
684
+ console.log(dim(JSON.stringify({ [agent.key]: { mindos: entry } }, null, 2)));
685
+
686
+ const dir = resolve(absPath, '..');
687
+ if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
688
+ writeFileSync(absPath, JSON.stringify(config, null, 2) + '\n', 'utf-8');
689
+
690
+ console.log(`\n${green('✔')} ${existed ? 'Updated' : 'Installed'} MindOS MCP for ${bold(agent.name)}`);
691
+ console.log(dim(` Config: ${absPath}\n`));
692
+ }
693
+
542
694
  // ── Commands ──────────────────────────────────────────────────────────────────
543
695
 
544
696
  const cmd = process.argv[2];
@@ -644,7 +796,12 @@ const commands = {
644
796
  writeBuildStamp();
645
797
  },
646
798
 
647
- mcp: () => { loadConfig(); run(`npx tsx src/index.ts`, resolve(ROOT, 'mcp')); },
799
+ mcp: async () => {
800
+ const sub = process.argv[3];
801
+ if (sub === 'install') { await mcpInstall(); return; }
802
+ loadConfig();
803
+ run(`npx tsx src/index.ts`, resolve(ROOT, 'mcp'));
804
+ },
648
805
 
649
806
  // ── stop / restart ─────────────────────────────────────────────────────────
650
807
  stop: () => stopMindos(),
@@ -1018,6 +1175,7 @@ ${row('mindos stop', 'Stop running MindOS processes')}
1018
1175
  ${row('mindos restart', 'Stop then start again')}
1019
1176
  ${row('mindos build', 'Build the app for production')}
1020
1177
  ${row('mindos mcp', 'Start MCP server only')}
1178
+ ${row('mindos mcp install [agent]', 'Install MindOS MCP config into Agent (claude-code/cursor/windsurf/…) [-g]')}
1021
1179
  ${row('mindos token', 'Show current auth token and MCP config snippet')}
1022
1180
  ${row('mindos gateway <subcommand>', 'Manage background service (install/uninstall/start/stop/status/logs)')}
1023
1181
  ${row('mindos doctor', 'Health check (config, ports, build, daemon)')}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@geminilight/mindos",
3
- "version": "0.1.6",
3
+ "version": "0.1.8",
4
4
  "description": "MindOS — Human-Agent Collaborative Mind System. Local-first knowledge base that syncs your mind to all AI Agents via MCP.",
5
5
  "keywords": [
6
6
  "mindos",
package/scripts/setup.js CHANGED
@@ -490,6 +490,42 @@ async function applyTemplate(tpl, mindDir) {
490
490
  async function main() {
491
491
  console.log(`\n${c.bold(t('title'))}\n\n${c.dim(t('langHint'))}\n`);
492
492
 
493
+ // ── Early overwrite check ─────────────────────────────────────────────────
494
+ if (existsSync(CONFIG_PATH)) {
495
+ let existing = {};
496
+ try { existing = JSON.parse(readFileSync(CONFIG_PATH, 'utf-8')); } catch {}
497
+
498
+ const mask = (s) => s ? s.slice(0, 4) + '••••••••' + s.slice(-2) : c.dim('(not set)');
499
+ const row = (label, val) => ` ${c.dim(label.padEnd(18))} ${val}`;
500
+ const providers = existing.ai?.providers;
501
+ const anthropicKey = providers?.anthropic?.apiKey || existing.ai?.anthropicApiKey || '';
502
+ const openaiKey = providers?.openai?.apiKey || existing.ai?.openaiApiKey || '';
503
+
504
+ console.log(c.bold('\nExisting config:'));
505
+ console.log(row('Knowledge base:', c.cyan(existing.mindRoot || '(not set)')));
506
+ console.log(row('Web port:', c.cyan(String(existing.port || '3000'))));
507
+ console.log(row('MCP port:', c.cyan(String(existing.mcpPort || '8787'))));
508
+ console.log(row('Auth token:', existing.authToken ? mask(existing.authToken) : c.dim('(not set)')));
509
+ console.log(row('Web password:', existing.webPassword ? '••••••••' : c.dim('(none)')));
510
+ console.log(row('AI provider:', c.cyan(existing.ai?.provider || '(not set)')));
511
+ if (anthropicKey) console.log(row('Anthropic key:', mask(anthropicKey)));
512
+ if (openaiKey) console.log(row('OpenAI key:', mask(openaiKey)));
513
+ write('\n');
514
+
515
+ const overwrite = await askYesNo('cfgExists', CONFIG_PATH);
516
+ if (!overwrite) {
517
+ const existingMode = existing.startMode || 'start';
518
+ const existingMcpPort = existing.mcpPort || 8787;
519
+ const existingAuth = existing.authToken || '';
520
+ const existingMindRoot = existing.mindRoot || resolve(MINDOS_DIR, 'my-mind');
521
+ console.log(`\n${c.green(t('cfgKept'))} ${c.dim(CONFIG_PATH)}`);
522
+ write(c.dim(t('cfgKeptNote') + '\n'));
523
+ const installDaemon = process.argv.includes('--install-daemon');
524
+ finish(existingMindRoot, existingMode, existingMcpPort, existingAuth, installDaemon);
525
+ return;
526
+ }
527
+ }
528
+
493
529
  // ── Step 1: Knowledge base path ───────────────────────────────────────────
494
530
  stepHeader(1);
495
531
 
@@ -559,28 +595,6 @@ async function main() {
559
595
  write('\n');
560
596
  stepHeader(6);
561
597
 
562
- // if config exists, ask about overwrite first
563
- if (existsSync(CONFIG_PATH)) {
564
- const overwrite = await askYesNo('cfgExists', CONFIG_PATH);
565
- if (!overwrite) {
566
- let existingMode = 'start';
567
- let existingMcpPort = 8787;
568
- let existingAuth = '';
569
- let existingMindRoot = mindDir;
570
- try {
571
- const existing = JSON.parse(readFileSync(CONFIG_PATH, 'utf-8'));
572
- existingMode = existing.startMode || 'start';
573
- existingMcpPort = existing.mcpPort || 8787;
574
- existingAuth = existing.authToken || '';
575
- existingMindRoot = existing.mindRoot || mindDir;
576
- } catch { /* ignore */ }
577
- console.log(`\n${c.green(t('cfgKept'))} ${c.dim(CONFIG_PATH)}`);
578
- write(c.dim(t('cfgKeptNote') + '\n'));
579
- finish(existingMindRoot, existingMode, existingMcpPort, existingAuth);
580
- return;
581
- }
582
- }
583
-
584
598
  const provider = await select('providerPrompt', 'providerOpts', 'providerVals');
585
599
  const isSkip = provider === 'skip';
586
600
  const isAnthropic = provider === 'anthropic';