add-mcp 0.3.2 → 0.3.5

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 +34 -45
  2. package/dist/index.js +88 -67
  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,26 +59,17 @@ 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
- ### Examples
45
-
46
- ```bash
47
- # Install to specific agents
48
- npx add-mcp https://mcp.example.com/mcp -a cursor -a claude-code
49
-
50
- # Install with SSE transport
51
- npx add-mcp https://mcp.neon.tech/sse --transport sse
52
-
53
- # Install with custom server name
54
- npx add-mcp @modelcontextprotocol/server-postgres --name postgres
62
+ ### Additional Commands
55
63
 
56
- # Non-interactive installation (CI/CD friendly)
57
- npx add-mcp https://mcp.example.com/mcp -g -a claude-code -y
64
+ Besides the implicit add command, `add-mcp` also supports the following commands:
58
65
 
59
- # Install to all agents
60
- npx add-mcp mcp-server-github --all
66
+ | Command | Description |
67
+ | ------------- | ------------------------------------------------------------ |
68
+ | `list-agents` | List all supported coding agents with scope (project/global) |
61
69
 
62
- # Install to all agents, globally, without prompts
63
- npx add-mcp mcp-server-github --all -g -y
70
+ ```bash
71
+ # List all supported agents
72
+ npx add-mcp list-agents
64
73
  ```
65
74
 
66
75
  ### Installation Scope
@@ -92,12 +101,12 @@ The CLI automatically detects agents based on your environment:
92
101
 
93
102
  ## Transport Types
94
103
 
95
- 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:
96
105
 
97
- | Transport | Flag | Description |
98
- | --------- | ------------------ | ---------------------------------------------- |
99
- | **HTTP** | `--transport http` | Streamable HTTP (default, modern standard) |
100
- | **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) |
101
110
 
102
111
  Local servers (npm packages, commands) always use **stdio** transport.
103
112
 
@@ -121,37 +130,17 @@ MCP servers can be installed to any of these agents:
121
130
 
122
131
  The CLI uses smart detection to find agents in your project directory and globally installed agents. See [Smart Detection](#smart-detection) for details.
123
132
 
124
- ### Transport Support
125
-
126
- Not all agents support all transport types:
127
-
128
- | Agent | stdio | http | sse |
129
- | -------------- | ----- | ---- | --- |
130
- | Claude Code | ✓ | ✓ | ✓ |
131
- | Claude Desktop | ✓ | ✓ | ✓ |
132
- | Codex | ✓ | ✓ | ✓ |
133
- | Cursor | ✓ | ✓ | ✓ |
134
- | Gemini CLI | ✓ | ✓ | ✓ |
135
- | Goose | ✓ | ✓ | ✗ |
136
- | OpenCode | ✓ | ✓ | ✓ |
137
- | VS Code | ✓ | ✓ | ✓ |
138
- | Zed | ✓ | ✓ | ✓ |
139
-
140
133
  ## What are MCP Servers?
141
134
 
142
135
  [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) servers extend your coding agent's capabilities by providing tools, resources, and context. MCP servers can:
143
136
 
137
+ - Integrate with external services (Notion, Linear, GitHub, etc.)
144
138
  - Connect to databases (PostgreSQL, MySQL, etc.)
145
- - Integrate with external services (GitHub, Linear, Notion)
146
139
  - Provide file system access
147
140
  - Offer specialized tools for your workflow
148
141
 
149
142
  ## Troubleshooting
150
143
 
151
- ### Transport mismatch error
152
-
153
- 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.
154
-
155
144
  ### Server not loading
156
145
 
157
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
@@ -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
  },
@@ -296,11 +296,41 @@ function isPackageName(input) {
296
296
  }
297
297
  return false;
298
298
  }
299
+ var commonTlds = /* @__PURE__ */ new Set([
300
+ "com",
301
+ "org",
302
+ "net",
303
+ "io",
304
+ "dev",
305
+ "ai",
306
+ "tech",
307
+ "co",
308
+ "app",
309
+ "cloud",
310
+ "sh",
311
+ "run"
312
+ ]);
313
+ function extractBrandFromHostname(hostname) {
314
+ const parts = hostname.split(".");
315
+ const meaningfulParts = parts.filter((part) => {
316
+ const lower = part.toLowerCase();
317
+ if (commonTlds.has(lower)) return false;
318
+ if (lower === "mcp" || lower === "api" || lower === "www") return false;
319
+ return true;
320
+ });
321
+ if (meaningfulParts.length > 0) {
322
+ return meaningfulParts[0];
323
+ }
324
+ if (parts.length >= 2) {
325
+ return parts[parts.length - 2];
326
+ }
327
+ return "mcp-server";
328
+ }
299
329
  function inferName(input, type) {
300
330
  if (type === "remote") {
301
331
  try {
302
332
  const url = new URL(input);
303
- return url.hostname.replace(/\./g, "-");
333
+ return extractBrandFromHostname(url.hostname);
304
334
  } catch {
305
335
  return "mcp-server";
306
336
  }
@@ -380,6 +410,38 @@ import { join as join2, dirname as dirname4 } from "path";
380
410
  import { readFileSync, writeFileSync, existsSync as existsSync2, mkdirSync } from "fs";
381
411
  import { dirname } from "path";
382
412
  import * as jsonc from "jsonc-parser";
413
+
414
+ // src/formats/utils.ts
415
+ function deepMerge(target, source) {
416
+ const result = { ...target };
417
+ for (const key in source) {
418
+ const sourceValue = source[key];
419
+ const targetValue = result[key];
420
+ if (sourceValue && typeof sourceValue === "object" && !Array.isArray(sourceValue)) {
421
+ result[key] = deepMerge(
422
+ targetValue && typeof targetValue === "object" ? targetValue : {},
423
+ sourceValue
424
+ );
425
+ } else {
426
+ result[key] = sourceValue;
427
+ }
428
+ }
429
+ return result;
430
+ }
431
+ function getNestedValue(obj, path) {
432
+ const keys = path.split(".");
433
+ let current = obj;
434
+ for (const key of keys) {
435
+ if (current && typeof current === "object" && key in current) {
436
+ current = current[key];
437
+ } else {
438
+ return void 0;
439
+ }
440
+ }
441
+ return current;
442
+ }
443
+
444
+ // src/formats/json.ts
383
445
  function detectIndent(text) {
384
446
  let result = null;
385
447
  jsonc.visit(text, {
@@ -423,34 +485,6 @@ function writeJsonConfig(filePath, config, configKey) {
423
485
  }
424
486
  writeFileSync(filePath, JSON.stringify(mergedConfig, null, 2));
425
487
  }
426
- function deepMerge(target, source) {
427
- const result = { ...target };
428
- for (const key in source) {
429
- const sourceValue = source[key];
430
- const targetValue = result[key];
431
- if (sourceValue && typeof sourceValue === "object" && !Array.isArray(sourceValue)) {
432
- result[key] = deepMerge(
433
- targetValue && typeof targetValue === "object" ? targetValue : {},
434
- sourceValue
435
- );
436
- } else {
437
- result[key] = sourceValue;
438
- }
439
- }
440
- return result;
441
- }
442
- function getNestedValue(obj, path) {
443
- const keys = path.split(".");
444
- let current = obj;
445
- for (const key of keys) {
446
- if (current && typeof current === "object" && key in current) {
447
- current = current[key];
448
- } else {
449
- return void 0;
450
- }
451
- }
452
- return current;
453
- }
454
488
  function setNestedValue(obj, path, value) {
455
489
  const keys = path.split(".");
456
490
  const lastKey = keys.pop();
@@ -486,7 +520,7 @@ function writeYamlConfig(filePath, config) {
486
520
  if (existsSync3(filePath)) {
487
521
  existingConfig = readYamlConfig(filePath);
488
522
  }
489
- const mergedConfig = deepMerge2(existingConfig, config);
523
+ const mergedConfig = deepMerge(existingConfig, config);
490
524
  const content = yaml.dump(mergedConfig, {
491
525
  indent: 2,
492
526
  lineWidth: -1,
@@ -494,22 +528,6 @@ function writeYamlConfig(filePath, config) {
494
528
  });
495
529
  writeFileSync2(filePath, content);
496
530
  }
497
- function deepMerge2(target, source) {
498
- const result = { ...target };
499
- for (const key in source) {
500
- const sourceValue = source[key];
501
- const targetValue = result[key];
502
- if (sourceValue && typeof sourceValue === "object" && !Array.isArray(sourceValue)) {
503
- result[key] = deepMerge2(
504
- targetValue && typeof targetValue === "object" ? targetValue : {},
505
- sourceValue
506
- );
507
- } else {
508
- result[key] = sourceValue;
509
- }
510
- }
511
- return result;
512
- }
513
531
 
514
532
  // src/formats/toml.ts
515
533
  import { readFileSync as readFileSync3, writeFileSync as writeFileSync3, existsSync as existsSync4, mkdirSync as mkdirSync3 } from "fs";
@@ -532,26 +550,10 @@ function writeTomlConfig(filePath, config) {
532
550
  if (existsSync4(filePath)) {
533
551
  existingConfig = readTomlConfig(filePath);
534
552
  }
535
- const mergedConfig = deepMerge3(existingConfig, config);
553
+ const mergedConfig = deepMerge(existingConfig, config);
536
554
  const content = TOML.stringify(mergedConfig);
537
555
  writeFileSync3(filePath, content);
538
556
  }
539
- function deepMerge3(target, source) {
540
- const result = { ...target };
541
- for (const key in source) {
542
- const sourceValue = source[key];
543
- const targetValue = result[key];
544
- if (sourceValue && typeof sourceValue === "object" && !Array.isArray(sourceValue)) {
545
- result[key] = deepMerge3(
546
- targetValue && typeof targetValue === "object" ? targetValue : {},
547
- sourceValue
548
- );
549
- } else {
550
- result[key] = sourceValue;
551
- }
552
- }
553
- return result;
554
- }
555
557
 
556
558
  // src/formats/index.ts
557
559
  function writeConfig(filePath, config, format, configKey) {
@@ -655,7 +657,7 @@ function installServer(serverName, serverConfig, agentTypes, options = {}) {
655
657
  // package.json
656
658
  var package_default = {
657
659
  name: "add-mcp",
658
- version: "0.3.2",
660
+ version: "0.3.5",
659
661
  description: "Add MCP servers to your favorite coding agents with a single command.",
660
662
  author: "Andre Landgraf <andre@neon.tech>",
661
663
  license: "Apache-2.0",
@@ -782,7 +784,26 @@ program.name("add-mcp").description(
782
784
  ).option("--type <type>", "Alias for --transport").option("-y, --yes", "Skip confirmation prompts").option("--all", "Install to all agents").action(async (target, options) => {
783
785
  await main(target, options);
784
786
  });
787
+ program.command("list-agents").description("List all supported coding agents").action(() => {
788
+ listAgents();
789
+ });
785
790
  program.parse();
791
+ function listAgents() {
792
+ showLogo();
793
+ console.log();
794
+ console.log(`${DIM}Supported agents:${RESET}`);
795
+ console.log();
796
+ const allAgentTypes = getAgentTypes();
797
+ for (const agentType of allAgentTypes) {
798
+ const agent = agents[agentType];
799
+ const hasProjectSupport = supportsProjectConfig(agentType);
800
+ const scope = hasProjectSupport ? "project, global" : "global";
801
+ console.log(
802
+ ` ${TEXT}${agent.displayName}${RESET} ${DIM}(${scope})${RESET}`
803
+ );
804
+ }
805
+ console.log();
806
+ }
786
807
  async function main(target, options) {
787
808
  showLogo();
788
809
  if (!target) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "add-mcp",
3
- "version": "0.3.2",
3
+ "version": "0.3.5",
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",