add-mcp 0.3.4 → 0.4.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 (3) hide show
  1. package/README.md +31 -53
  2. package/dist/index.js +45 -76
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -10,10 +10,10 @@ Supports **OpenCode**, **Claude Code**, **Codex**, **Cursor**, and [5 more](#sup
10
10
  npx add-mcp https://mcp.example.com/sse
11
11
  ```
12
12
 
13
- ### Source Formats
13
+ ### Usage Examples
14
14
 
15
15
  ```bash
16
- # Remote MCP server (HTTP streamable - default)
16
+ # Remote MCP server (streamable HTTP)
17
17
  npx add-mcp https://mcp.example.com/mcp
18
18
 
19
19
  # Remote MCP server (SSE transport)
@@ -22,11 +22,29 @@ npx add-mcp https://mcp.example.com/sse --transport sse
22
22
  # npm package (runs via npx)
23
23
  npx add-mcp @modelcontextprotocol/server-postgres
24
24
 
25
+ # Non-interactive installation to all detected agents in the project directory
26
+ npx add-mcp https://mcp.example.com/mcp -y
27
+
28
+ # Non-interactive installation to the global Claude Code config
29
+ npx add-mcp https://mcp.example.com/mcp -g -a claude-code -y
30
+
25
31
  # Full command with arguments
26
32
  npx add-mcp "npx -y @org/mcp-server --flag value"
27
33
 
28
34
  # Node.js script
29
35
  npx add-mcp "node /path/to/server.js --port 3000"
36
+
37
+ # Install for Cursor and Claude Code
38
+ npx add-mcp https://mcp.example.com/mcp -a cursor -a claude-code
39
+
40
+ # Install with custom server name
41
+ npx add-mcp @modelcontextprotocol/server-postgres --name postgres
42
+
43
+ # Install to all supported agents
44
+ npx add-mcp mcp-server-github --all
45
+
46
+ # Install to all agents, globally, without prompts
47
+ npx add-mcp mcp-server-github --all -g -y
30
48
  ```
31
49
 
32
50
  ### Options
@@ -41,7 +59,9 @@ npx add-mcp "node /path/to/server.js --port 3000"
41
59
  | `-y, --yes` | Skip all confirmation prompts |
42
60
  | `--all` | Install to all agents |
43
61
 
44
- ### Commands
62
+ ### Additional Commands
63
+
64
+ Besides the implicit add command, `add-mcp` also supports the following commands:
45
65
 
46
66
  | Command | Description |
47
67
  | ------------- | ------------------------------------------------------------ |
@@ -52,28 +72,6 @@ npx add-mcp "node /path/to/server.js --port 3000"
52
72
  npx add-mcp list-agents
53
73
  ```
54
74
 
55
- ### Examples
56
-
57
- ```bash
58
- # Install to specific agents
59
- npx add-mcp https://mcp.example.com/mcp -a cursor -a claude-code
60
-
61
- # Install with SSE transport
62
- npx add-mcp https://mcp.neon.tech/sse --transport sse
63
-
64
- # Install with custom server name
65
- npx add-mcp @modelcontextprotocol/server-postgres --name postgres
66
-
67
- # Non-interactive installation (CI/CD friendly)
68
- npx add-mcp https://mcp.example.com/mcp -g -a claude-code -y
69
-
70
- # Install to all agents
71
- npx add-mcp mcp-server-github --all
72
-
73
- # Install to all agents, globally, without prompts
74
- npx add-mcp mcp-server-github --all -g -y
75
- ```
76
-
77
75
  ### Installation Scope
78
76
 
79
77
  | Scope | Flag | Location | Use Case |
@@ -103,12 +101,12 @@ The CLI automatically detects agents based on your environment:
103
101
 
104
102
  ## Transport Types
105
103
 
106
- MCP supports different transport mechanisms for remote servers:
104
+ `add-mcp` supports all three transport types: HTTP, SSE, and stdio. Some agents require `type` option to be set to specify the transport type. You can use the `--type` or `--transport` option to specify the transport type:
107
105
 
108
- | Transport | Flag | Description |
109
- | --------- | ------------------ | ---------------------------------------------- |
110
- | **HTTP** | `--transport http` | Streamable HTTP (default, modern standard) |
111
- | **SSE** | `--transport sse` | Server-Sent Events (legacy, still widely used) |
106
+ | Transport | Flag | Description |
107
+ | --------- | ------------------ | ----------------------------------------------------- |
108
+ | **HTTP** | `--transport http` | Streamable HTTP (default) |
109
+ | **SSE** | `--transport sse` | Server-Sent Events (deprecated by MCP but still used) |
112
110
 
113
111
  Local servers (npm packages, commands) always use **stdio** transport.
114
112
 
@@ -120,49 +118,29 @@ MCP servers can be installed to any of these agents:
120
118
  | -------------- | ---------------- | ----------------------- | ----------------------------------------------------------------- |
121
119
  | Claude Code | `claude-code` | `.mcp.json` | `~/.claude.json` |
122
120
  | Claude Desktop | `claude-desktop` | - | `~/Library/Application Support/Claude/claude_desktop_config.json` |
123
- | Codex | `codex` | - | `~/.codex/config.toml` |
121
+ | Codex | `codex` | `.codex/config.toml` | `~/.codex/config.toml` |
124
122
  | Cursor | `cursor` | `.cursor/mcp.json` | `~/.cursor/mcp.json` |
125
123
  | Gemini CLI | `gemini-cli` | `.gemini/settings.json` | `~/.gemini/settings.json` |
126
124
  | Goose | `goose` | `.goose/config.yaml` | `~/.config/goose/config.yaml` |
127
125
  | OpenCode | `opencode` | `.opencode.json` | `~/.config/opencode/opencode.json` |
128
126
  | VS Code | `vscode` | `.vscode/mcp.json` | `~/Library/Application Support/Code/User/mcp.json` |
129
- | Zed | `zed` | - | `~/.config/zed/settings.json` |
127
+ | Zed | `zed` | `.zed/settings.json` | `~/Library/Application Support/Zed/settings.json` |
130
128
 
131
129
  **Aliases:** `github-copilot` → `vscode`
132
130
 
133
131
  The CLI uses smart detection to find agents in your project directory and globally installed agents. See [Smart Detection](#smart-detection) for details.
134
132
 
135
- ### Transport Support
136
-
137
- Not all agents support all transport types:
138
-
139
- | Agent | stdio | http | sse |
140
- | -------------- | ----- | ---- | --- |
141
- | Claude Code | ✓ | ✓ | ✓ |
142
- | Claude Desktop | ✓ | ✓ | ✓ |
143
- | Codex | ✓ | ✓ | ✓ |
144
- | Cursor | ✓ | ✓ | ✓ |
145
- | Gemini CLI | ✓ | ✓ | ✓ |
146
- | Goose | ✓ | ✓ | ✗ |
147
- | OpenCode | ✓ | ✓ | ✓ |
148
- | VS Code | ✓ | ✓ | ✓ |
149
- | Zed | ✓ | ✓ | ✓ |
150
-
151
133
  ## What are MCP Servers?
152
134
 
153
135
  [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) servers extend your coding agent's capabilities by providing tools, resources, and context. MCP servers can:
154
136
 
137
+ - Integrate with external services (Notion, Linear, GitHub, etc.)
155
138
  - Connect to databases (PostgreSQL, MySQL, etc.)
156
- - Integrate with external services (GitHub, Linear, Notion)
157
139
  - Provide file system access
158
140
  - Offer specialized tools for your workflow
159
141
 
160
142
  ## Troubleshooting
161
143
 
162
- ### Transport mismatch error
163
-
164
- If you get an error about transport not being supported, check that the agent supports your chosen transport type. For example, Goose doesn't support SSE transport.
165
-
166
144
  ### Server not loading
167
145
 
168
146
  - Verify the server URL is correct and accessible
package/dist/index.js CHANGED
@@ -40,9 +40,10 @@ function getPlatformPaths() {
40
40
  var { appSupport, vscodePath } = getPlatformPaths();
41
41
  function transformGooseConfig(serverName, config) {
42
42
  if (config.url) {
43
+ const gooseType = config.type === "sse" ? "sse" : "streamable_http";
43
44
  return {
44
45
  name: serverName,
45
- type: "streamable_http",
46
+ type: gooseType,
46
47
  url: config.url,
47
48
  enabled: true,
48
49
  timeout: 300
@@ -139,8 +140,8 @@ var agents = {
139
140
  process.env.CODEX_HOME || join(home, ".codex"),
140
141
  "config.toml"
141
142
  ),
142
- projectDetectPaths: [],
143
- // Global only - no project support
143
+ localConfigPath: ".codex/config.toml",
144
+ projectDetectPaths: [".codex"],
144
145
  configKey: "mcp_servers",
145
146
  format: "toml",
146
147
  supportedTransports: ["stdio", "http", "sse"],
@@ -183,8 +184,7 @@ var agents = {
183
184
  projectDetectPaths: [".goose"],
184
185
  configKey: "extensions",
185
186
  format: "yaml",
186
- supportedTransports: ["stdio", "http"],
187
- // Goose does not support SSE
187
+ supportedTransports: ["stdio", "http", "sse"],
188
188
  detectGlobalInstall: async () => {
189
189
  return existsSync(join(home, ".config", "goose"));
190
190
  },
@@ -220,18 +220,15 @@ var agents = {
220
220
  zed: {
221
221
  name: "zed",
222
222
  displayName: "Zed",
223
- configPath: process.platform === "win32" ? join(
224
- process.env.APPDATA || join(home, "AppData", "Roaming"),
225
- "Zed",
226
- "settings.json"
227
- ) : join(home, ".config", "zed", "settings.json"),
228
- projectDetectPaths: [],
229
- // Global only - no project support
223
+ configPath: process.platform === "darwin" || process.platform === "win32" ? join(appSupport, "Zed", "settings.json") : join(appSupport, "zed", "settings.json"),
224
+ localConfigPath: ".zed/settings.json",
225
+ projectDetectPaths: [".zed"],
230
226
  configKey: "context_servers",
231
227
  format: "json",
232
228
  supportedTransports: ["stdio", "http", "sse"],
233
229
  detectGlobalInstall: async () => {
234
- return existsSync(join(home, ".config", "zed")) || existsSync(join(process.env.APPDATA || "", "Zed"));
230
+ const configDir = process.platform === "darwin" || process.platform === "win32" ? join(appSupport, "Zed") : join(appSupport, "zed");
231
+ return existsSync(configDir);
235
232
  },
236
233
  transformConfig: transformZedConfig
237
234
  }
@@ -410,6 +407,38 @@ import { join as join2, dirname as dirname4 } from "path";
410
407
  import { readFileSync, writeFileSync, existsSync as existsSync2, mkdirSync } from "fs";
411
408
  import { dirname } from "path";
412
409
  import * as jsonc from "jsonc-parser";
410
+
411
+ // src/formats/utils.ts
412
+ function deepMerge(target, source) {
413
+ const result = { ...target };
414
+ for (const key in source) {
415
+ const sourceValue = source[key];
416
+ const targetValue = result[key];
417
+ if (sourceValue && typeof sourceValue === "object" && !Array.isArray(sourceValue)) {
418
+ result[key] = deepMerge(
419
+ targetValue && typeof targetValue === "object" ? targetValue : {},
420
+ sourceValue
421
+ );
422
+ } else {
423
+ result[key] = sourceValue;
424
+ }
425
+ }
426
+ return result;
427
+ }
428
+ function getNestedValue(obj, path) {
429
+ const keys = path.split(".");
430
+ let current = obj;
431
+ for (const key of keys) {
432
+ if (current && typeof current === "object" && key in current) {
433
+ current = current[key];
434
+ } else {
435
+ return void 0;
436
+ }
437
+ }
438
+ return current;
439
+ }
440
+
441
+ // src/formats/json.ts
413
442
  function detectIndent(text) {
414
443
  let result = null;
415
444
  jsonc.visit(text, {
@@ -453,34 +482,6 @@ function writeJsonConfig(filePath, config, configKey) {
453
482
  }
454
483
  writeFileSync(filePath, JSON.stringify(mergedConfig, null, 2));
455
484
  }
456
- function deepMerge(target, source) {
457
- const result = { ...target };
458
- for (const key in source) {
459
- const sourceValue = source[key];
460
- const targetValue = result[key];
461
- if (sourceValue && typeof sourceValue === "object" && !Array.isArray(sourceValue)) {
462
- result[key] = deepMerge(
463
- targetValue && typeof targetValue === "object" ? targetValue : {},
464
- sourceValue
465
- );
466
- } else {
467
- result[key] = sourceValue;
468
- }
469
- }
470
- return result;
471
- }
472
- function getNestedValue(obj, path) {
473
- const keys = path.split(".");
474
- let current = obj;
475
- for (const key of keys) {
476
- if (current && typeof current === "object" && key in current) {
477
- current = current[key];
478
- } else {
479
- return void 0;
480
- }
481
- }
482
- return current;
483
- }
484
485
  function setNestedValue(obj, path, value) {
485
486
  const keys = path.split(".");
486
487
  const lastKey = keys.pop();
@@ -516,7 +517,7 @@ function writeYamlConfig(filePath, config) {
516
517
  if (existsSync3(filePath)) {
517
518
  existingConfig = readYamlConfig(filePath);
518
519
  }
519
- const mergedConfig = deepMerge2(existingConfig, config);
520
+ const mergedConfig = deepMerge(existingConfig, config);
520
521
  const content = yaml.dump(mergedConfig, {
521
522
  indent: 2,
522
523
  lineWidth: -1,
@@ -524,22 +525,6 @@ function writeYamlConfig(filePath, config) {
524
525
  });
525
526
  writeFileSync2(filePath, content);
526
527
  }
527
- function deepMerge2(target, source) {
528
- const result = { ...target };
529
- for (const key in source) {
530
- const sourceValue = source[key];
531
- const targetValue = result[key];
532
- if (sourceValue && typeof sourceValue === "object" && !Array.isArray(sourceValue)) {
533
- result[key] = deepMerge2(
534
- targetValue && typeof targetValue === "object" ? targetValue : {},
535
- sourceValue
536
- );
537
- } else {
538
- result[key] = sourceValue;
539
- }
540
- }
541
- return result;
542
- }
543
528
 
544
529
  // src/formats/toml.ts
545
530
  import { readFileSync as readFileSync3, writeFileSync as writeFileSync3, existsSync as existsSync4, mkdirSync as mkdirSync3 } from "fs";
@@ -562,26 +547,10 @@ function writeTomlConfig(filePath, config) {
562
547
  if (existsSync4(filePath)) {
563
548
  existingConfig = readTomlConfig(filePath);
564
549
  }
565
- const mergedConfig = deepMerge3(existingConfig, config);
550
+ const mergedConfig = deepMerge(existingConfig, config);
566
551
  const content = TOML.stringify(mergedConfig);
567
552
  writeFileSync3(filePath, content);
568
553
  }
569
- function deepMerge3(target, source) {
570
- const result = { ...target };
571
- for (const key in source) {
572
- const sourceValue = source[key];
573
- const targetValue = result[key];
574
- if (sourceValue && typeof sourceValue === "object" && !Array.isArray(sourceValue)) {
575
- result[key] = deepMerge3(
576
- targetValue && typeof targetValue === "object" ? targetValue : {},
577
- sourceValue
578
- );
579
- } else {
580
- result[key] = sourceValue;
581
- }
582
- }
583
- return result;
584
- }
585
554
 
586
555
  // src/formats/index.ts
587
556
  function writeConfig(filePath, config, format, configKey) {
@@ -685,7 +654,7 @@ function installServer(serverName, serverConfig, agentTypes, options = {}) {
685
654
  // package.json
686
655
  var package_default = {
687
656
  name: "add-mcp",
688
- version: "0.3.4",
657
+ version: "0.4.0",
689
658
  description: "Add MCP servers to your favorite coding agents with a single command.",
690
659
  author: "Andre Landgraf <andre@neon.tech>",
691
660
  license: "Apache-2.0",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "add-mcp",
3
- "version": "0.3.4",
3
+ "version": "0.4.0",
4
4
  "description": "Add MCP servers to your favorite coding agents with a single command.",
5
5
  "author": "Andre Landgraf <andre@neon.tech>",
6
6
  "license": "Apache-2.0",