@kaneo/mcp 0.1.1 → 0.1.3

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.
@@ -148,19 +148,21 @@ export async function runInstall(argv) {
148
148
  process.exitCode = 1;
149
149
  return;
150
150
  }
151
- let targetId = parsed.target;
152
- const needsInteractive = input.isTTY && output.isTTY && !parsed.yes && targetId === undefined;
151
+ let targetIds = parsed.target
152
+ ? [parsed.target]
153
+ : undefined;
154
+ const needsInteractive = input.isTTY && output.isTTY && !parsed.yes && targetIds === undefined;
153
155
  if (needsInteractive) {
154
- targetId = await promptTargetSelect();
156
+ targetIds = await promptTargetSelect();
155
157
  }
156
- else if (targetId === undefined) {
158
+ else if (targetIds === undefined) {
157
159
  console.error("Non-interactive mode: specify --target (e.g. --target cursor-user) and use -y to confirm.");
158
160
  printInstallHelp();
159
161
  process.exitCode = 1;
160
162
  return;
161
163
  }
162
164
  let customPath = parsed.output;
163
- if (targetId === "custom") {
165
+ if (targetIds.includes("custom")) {
164
166
  if (!customPath) {
165
167
  if (input.isTTY && output.isTTY) {
166
168
  customPath = await promptCustomConfigPath();
@@ -172,10 +174,6 @@ export async function runInstall(argv) {
172
174
  }
173
175
  }
174
176
  }
175
- const configPath = resolveTargetConfigPath(targetId, {
176
- cwd: parsed.projectDir,
177
- customPath,
178
- });
179
177
  const entryPath = resolvePackageEntryPath();
180
178
  const env = parsed.apiUrl !== undefined && parsed.apiUrl.length > 0
181
179
  ? { KANEO_API_URL: parsed.apiUrl }
@@ -185,40 +183,55 @@ export async function runInstall(argv) {
185
183
  args: [entryPath],
186
184
  ...(env ? { env } : {}),
187
185
  };
188
- let existingText = null;
189
- try {
190
- existingText = await readFile(configPath, "utf8");
191
- }
192
- catch {
193
- existingText = null;
194
- }
195
- const already = hasExistingServerEntry(existingText, parsed.name);
196
- if (already && !parsed.yes) {
197
- if (input.isTTY && output.isTTY) {
198
- const ok = await promptConfirmOverwrite(parsed.name);
199
- if (!ok) {
200
- console.log("Aborted.");
186
+ const writtenPaths = [];
187
+ for (const targetId of targetIds) {
188
+ const configPath = resolveTargetConfigPath(targetId, {
189
+ cwd: parsed.projectDir,
190
+ customPath,
191
+ });
192
+ let existingText = null;
193
+ try {
194
+ existingText = await readFile(configPath, "utf8");
195
+ }
196
+ catch {
197
+ existingText = null;
198
+ }
199
+ const already = hasExistingServerEntry(existingText, parsed.name);
200
+ if (already && !parsed.yes) {
201
+ if (input.isTTY && output.isTTY) {
202
+ const ok = await promptConfirmOverwrite(parsed.name);
203
+ if (!ok) {
204
+ console.log(`Skipped:\n ${configPath}`);
205
+ continue;
206
+ }
207
+ }
208
+ else {
209
+ console.error(`Entry "${parsed.name}" already exists. Pass -y to overwrite.`);
210
+ process.exitCode = 1;
201
211
  return;
202
212
  }
203
213
  }
204
- else {
205
- console.error(`Entry "${parsed.name}" already exists. Pass -y to overwrite.`);
214
+ let merged;
215
+ try {
216
+ merged = mergeMcpServerEntry(existingText, parsed.name, serverConfig);
217
+ }
218
+ catch {
219
+ console.error(`Cannot update config (invalid JSON or merge error): ${configPath}`);
206
220
  process.exitCode = 1;
207
221
  return;
208
222
  }
223
+ await mkdir(dirname(configPath), { recursive: true });
224
+ await writeFile(configPath, merged, { encoding: "utf8", mode: 0o600 });
225
+ writtenPaths.push(configPath);
209
226
  }
210
- let merged;
211
- try {
212
- merged = mergeMcpServerEntry(existingText, parsed.name, serverConfig);
213
- }
214
- catch {
215
- console.error(`Cannot update config (invalid JSON or merge error): ${configPath}`);
216
- process.exitCode = 1;
227
+ if (writtenPaths.length === 0) {
228
+ console.log("No config files were updated.");
217
229
  return;
218
230
  }
219
- await mkdir(dirname(configPath), { recursive: true });
220
- await writeFile(configPath, merged, { encoding: "utf8", mode: 0o600 });
221
- console.log(`Wrote MCP server "${parsed.name}" to:\n ${configPath}`);
231
+ console.log(`Wrote MCP server "${parsed.name}" to:`);
232
+ for (const configPath of writtenPaths) {
233
+ console.log(` ${configPath}`);
234
+ }
222
235
  console.log("\nRestart your MCP client (or reload the window) if needed.");
223
236
  }
224
237
  function printInstallHelp() {
@@ -4,32 +4,26 @@ function onCancel() {
4
4
  console.log("\nCancelled.");
5
5
  process.exit(0);
6
6
  }
7
- function printIntro() {
8
- console.log(`
9
- ────────────────────────────────────────
10
- Kaneo MCP · editor setup
11
- ────────────────────────────────────────
12
- Use ↑ / ↓ to move, Enter to select.
13
- ────────────────────────────────────────
14
- `);
15
- }
16
7
  export async function promptTargetSelect() {
17
- printIntro();
18
8
  const answer = await prompts({
19
- type: "select",
20
- name: "target",
9
+ type: "multiselect",
10
+ name: "targets",
21
11
  message: "Where should Kaneo register this MCP server?",
22
12
  choices: INSTALL_TARGETS.map((t) => ({
23
13
  title: t.label,
24
14
  description: t.description,
25
15
  value: t.id,
26
16
  })),
27
- initial: 0,
17
+ hint: "- Space to select. Enter to confirm.",
18
+ min: 1,
19
+ instructions: false,
28
20
  }, { onCancel });
29
- if (answer.target === undefined) {
21
+ if (answer.targets === undefined ||
22
+ !Array.isArray(answer.targets) ||
23
+ answer.targets.length === 0) {
30
24
  onCancel();
31
25
  }
32
- return answer.target;
26
+ return answer.targets;
33
27
  }
34
28
  export async function promptCustomConfigPath() {
35
29
  const answer = await prompts({
package/package.json CHANGED
@@ -1,8 +1,13 @@
1
1
  {
2
2
  "name": "@kaneo/mcp",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "Model Context Protocol (stdio) server for Kaneo — tasks, projects, labels, and device authorization",
5
5
  "license": "MIT",
6
+ "homepage": "https://github.com/usekaneo/kaneo/",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/usekaneo/kaneo/"
10
+ },
6
11
  "type": "module",
7
12
  "bin": {
8
13
  "kaneo-mcp": "dist/index.js"
@@ -32,9 +37,9 @@
32
37
  },
33
38
  "dependencies": {
34
39
  "@modelcontextprotocol/sdk": "^1.26.0",
35
- "open": "^10.1.0",
40
+ "open": "^11.0.0",
36
41
  "prompts": "^2.4.2",
37
- "zod": "^3.25.0"
42
+ "zod": "^4.3.6"
38
43
  },
39
44
  "devDependencies": {
40
45
  "@kaneo/typescript-config": "workspace:*",