add-mcp 1.12.0 → 1.13.1

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
@@ -36,13 +36,13 @@ You can add env variables and arguments (stdio) and headers (remote) to the serv
36
36
 
37
37
  ## Find an MCP Servers
38
38
 
39
- Find and install MCP servers from the add-mcp curated registry and/or the official Anthropic MCP registry:
39
+ Find and install MCP servers from the integrations.sh MCP registry and/or the official Anthropic MCP registry:
40
40
 
41
41
  ```bash
42
42
  npx add-mcp find vercel
43
43
  ```
44
44
 
45
- When running `find`/`search` for the first time, the CLI prompts you to choose which registries to enable (add-mcp curated registry and/or official Anthropic registry). You can also add custom registries to the configuration file.
45
+ When running `find`/`search` for the first time, the CLI prompts you to choose which registries to enable (integrations.sh MCP registry and/or official Anthropic registry). You can also add custom registries to the configuration file.
46
46
 
47
47
  ## Supported Agents
48
48
 
@@ -290,14 +290,21 @@ If you run with `-y` before this one-time registry setup is completed, the CLI e
290
290
 
291
291
  ### Built-in Registries
292
292
 
293
- | Registry | Base URL | Description |
294
- | ------------------------------- | ------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
295
- | **add-mcp curated registry** | `https://mcp.agent-tooling.dev/api/v1/servers` | A curated list of first-party, verified MCP servers from popular developer tools and SaaS services. Designed to surface high-quality, officially maintained servers instead of a long tail of unmaintained or third-party entries. |
296
- | **Official Anthropic registry** | `https://registry.modelcontextprotocol.io/v0.1/servers` | The community-driven MCP server registry maintained by Anthropic. Contains the broadest catalog of MCP servers. |
293
+ | Registry | Base URL | Description |
294
+ | -------------------------------- | ------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
295
+ | **integrations.sh MCP registry** | `https://mcp.agent-tooling.dev/api/v1/servers` | MCP servers discovered by integrations.sh and exposed through an MCP registry-compatible API, using add-mcp's checked-in `registry.json` as the source of truth. |
296
+ | **Official Anthropic registry** | `https://registry.modelcontextprotocol.io/v0.1/servers` | The community-driven MCP server registry maintained by Anthropic. Contains the broadest catalog of MCP servers. |
297
297
 
298
- ### Missing A Server in add-mcp Curated Registry?
298
+ ### Missing A Server in integrations.sh?
299
299
 
300
- The source of truth for the add-mcp curated registry is [registry.json](registry.json) in this repository. You can contribute to the registry by opening a pull request to add or update a server.
300
+ The default add-mcp registry is generated from [integrations.sh](https://integrations.sh). To be listed in add-mcp, add your MCP server to integrations.sh. Package-only entries that integrations.sh cannot represent yet can still be contributed to add-mcp's `registry.overlay.json`.
301
+
302
+ Maintainers can refresh the checked-in registry snapshot with:
303
+
304
+ ```bash
305
+ bun run registry:sync
306
+ bun run registry:verify
307
+ ```
301
308
 
302
309
  ### Editing or Removing Registries
303
310
 
@@ -309,7 +316,7 @@ Registry selections are stored in `~/.config/add-mcp/config.json` under the `fin
309
316
  "findRegistries": [
310
317
  {
311
318
  "url": "https://mcp.agent-tooling.dev/api/v1/servers",
312
- "label": "add-mcp curated registry"
319
+ "label": "integrations.sh MCP registry"
313
320
  },
314
321
  {
315
322
  "url": "https://registry.modelcontextprotocol.io/v0.1/servers",
@@ -617,6 +617,13 @@ function getAgentTypes() {
617
617
  function supportsProjectConfig(agentType) {
618
618
  return agents[agentType].localConfigPath !== void 0;
619
619
  }
620
+ function getCommonInstallScopes(agentTypes) {
621
+ if (agentTypes.length === 0) return [];
622
+ if (agentTypes.some((agentType) => !supportsProjectConfig(agentType))) {
623
+ return ["global"];
624
+ }
625
+ return ["local", "global"];
626
+ }
620
627
  function getProjectCapableAgents() {
621
628
  return Object.keys(agents).filter(
622
629
  (type) => supportsProjectConfig(type)
@@ -1587,6 +1594,7 @@ export {
1587
1594
  agents,
1588
1595
  getAgentTypes,
1589
1596
  supportsProjectConfig,
1597
+ getCommonInstallScopes,
1590
1598
  getProjectCapableAgents,
1591
1599
  detectProjectAgents,
1592
1600
  detectGlobalAgents,
package/dist/index.js CHANGED
@@ -8,6 +8,7 @@ import {
8
8
  detectProjectAgents,
9
9
  findMatchingServers,
10
10
  getAgentTypes,
11
+ getCommonInstallScopes,
11
12
  getConfigPath,
12
13
  getFindRegistries,
13
14
  getLastSelectedAgents,
@@ -23,7 +24,7 @@ import {
23
24
  selectAgentsInteractive,
24
25
  supportsProjectConfig,
25
26
  updateGitignoreWithPaths
26
- } from "./chunk-IPCKQUBH.js";
27
+ } from "./chunk-3ZFFEEQJ.js";
27
28
 
28
29
  // src/index.ts
29
30
  import { program } from "commander";
@@ -357,7 +358,7 @@ function getDefaultFindRegistries() {
357
358
  return [
358
359
  {
359
360
  url: VERIFIED_ESSENTIALS_DEFAULT_SERVERS_URL,
360
- label: "add-mcp curated registry"
361
+ label: "integrations.sh MCP registry"
361
362
  },
362
363
  {
363
364
  url: resolveOfficialRegistryServersUrl(),
@@ -783,7 +784,7 @@ async function runFind(query, options) {
783
784
  // package.json
784
785
  var package_default = {
785
786
  name: "add-mcp",
786
- version: "1.12.0",
787
+ version: "1.13.1",
787
788
  description: "Add MCP servers to your favorite coding agents with a single command.",
788
789
  author: "Andre Landgraf <andre@neon.tech>",
789
790
  license: "Apache-2.0",
@@ -811,6 +812,7 @@ var package_default = {
811
812
  test: "tsx tests/source-parser.test.ts && tsx tests/agents.test.ts && tsx tests/config.test.ts && tsx tests/installer.test.ts && tsx tests/find.test.ts && tsx tests/package-arguments.test.ts && tsx tests/template.test.ts && tsx tests/reader.test.ts && tsx tests/formats-remove.test.ts && tsx tests/lib.test.ts && tsx tests/e2e/install.test.ts && tsx tests/e2e/cli.test.ts",
812
813
  "test:unit": "tsx tests/source-parser.test.ts && tsx tests/agents.test.ts && tsx tests/config.test.ts && tsx tests/installer.test.ts && tsx tests/find.test.ts && tsx tests/package-arguments.test.ts && tsx tests/template.test.ts && tsx tests/reader.test.ts && tsx tests/formats-remove.test.ts && tsx tests/lib.test.ts",
813
814
  "registry:sort": "tsx scripts/sort-registry.ts",
815
+ "registry:sync": "node scripts/sync-integrations-sh.mjs",
814
816
  "registry:verify": "tsx scripts/verify-registry.ts",
815
817
  "test:e2e": "tsx tests/e2e/install.test.ts && tsx tests/e2e/cli.test.ts",
816
818
  typecheck: "tsc --noEmit",
@@ -1192,7 +1194,7 @@ async function runFindCommand(keyword, rawOptions) {
1192
1194
  await main(installPlan.target, mergedOptions);
1193
1195
  }
1194
1196
  program.command("find [keyword]").description(
1195
- "Find MCP servers from curated registry data (omit keyword to browse)"
1197
+ "Find MCP servers from integrations.sh registry data (omit keyword to browse)"
1196
1198
  ).option(
1197
1199
  "-g, --global",
1198
1200
  "Install globally (user-level) instead of project-level"
@@ -1725,7 +1727,7 @@ async function main(target, options) {
1725
1727
  ` ${DIM}$${RESET} ${TEXT}npx add-mcp ${DIM}<url> ${TEXT}-a cursor${RESET} ${DIM}Install to specific agent${RESET}`
1726
1728
  );
1727
1729
  console.log(
1728
- ` ${DIM}$${RESET} ${TEXT}npx add-mcp find ${DIM}<keyword>${RESET} ${DIM}Search and install curated MCP servers${RESET}`
1730
+ ` ${DIM}$${RESET} ${TEXT}npx add-mcp find ${DIM}<keyword>${RESET} ${DIM}Search integrations.sh MCP servers${RESET}`
1729
1731
  );
1730
1732
  console.log();
1731
1733
  console.log(
@@ -1885,8 +1887,6 @@ async function main(target, options) {
1885
1887
  });
1886
1888
  let targetAgents;
1887
1889
  const allAgentTypes = getAgentTypes();
1888
- const hasExplicitAgentFlags = options.agent && options.agent.length > 0 || options.all === true;
1889
- let selectedViaPrompt = false;
1890
1890
  let agentRouting = /* @__PURE__ */ new Map();
1891
1891
  if (options.agent && options.agent.length > 0) {
1892
1892
  const resolved = [];
@@ -1946,7 +1946,7 @@ async function main(target, options) {
1946
1946
  );
1947
1947
  }
1948
1948
  } else {
1949
- const availableAgents = options.global ? allAgentTypes : getProjectCapableAgents();
1949
+ const availableAgents = allAgentTypes;
1950
1950
  p2.log.warn(
1951
1951
  options.global ? "No coding agents detected." : "No agents detected in this project."
1952
1952
  );
@@ -1957,18 +1957,14 @@ async function main(target, options) {
1957
1957
  p2.cancel("Installation cancelled");
1958
1958
  process.exit(0);
1959
1959
  }
1960
- selectedViaPrompt = true;
1961
1960
  targetAgents = selected;
1962
- for (const agent of targetAgents) {
1963
- agentRouting.set(agent, options.global ? "global" : "local");
1964
- }
1965
1961
  }
1966
1962
  } else if (options.yes) {
1967
1963
  targetAgents = detectedAgents;
1968
1964
  const agentNames = detectedAgents.map((a) => chalk.cyan(agents[a].displayName)).join(", ");
1969
1965
  p2.log.info(`Installing to: ${agentNames}`);
1970
1966
  } else {
1971
- const availableAgents = options.global ? allAgentTypes : getProjectCapableAgents();
1967
+ const availableAgents = allAgentTypes;
1972
1968
  let lastSelected;
1973
1969
  try {
1974
1970
  lastSelected = await getLastSelectedAgents();
@@ -1990,11 +1986,7 @@ async function main(target, options) {
1990
1986
  p2.cancel("Installation cancelled");
1991
1987
  process.exit(0);
1992
1988
  }
1993
- selectedViaPrompt = true;
1994
1989
  targetAgents = selected;
1995
- for (const agent of targetAgents) {
1996
- agentRouting.set(agent, options.global ? "global" : "local");
1997
- }
1998
1990
  }
1999
1991
  }
2000
1992
  const requiredTransport = isRemoteSource(parsed) ? resolvedTransport ?? "http" : "stdio";
@@ -2028,50 +2020,45 @@ async function main(target, options) {
2028
2020
  process.exit(1);
2029
2021
  }
2030
2022
  }
2031
- const hasSmartRouting = agentRouting.size > 0;
2032
2023
  if (options.global) {
2024
+ agentRouting = /* @__PURE__ */ new Map();
2033
2025
  for (const agent of targetAgents) {
2034
2026
  agentRouting.set(agent, "global");
2035
2027
  }
2036
- } else if (!hasSmartRouting) {
2037
- const selectedWithLocal = targetAgents.filter(
2038
- (a) => supportsProjectConfig(a)
2039
- );
2040
- const globalOnlySelected = targetAgents.filter(
2041
- (a) => !supportsProjectConfig(a)
2042
- );
2043
- for (const agent of globalOnlySelected) {
2044
- agentRouting.set(agent, "global");
2028
+ } else {
2029
+ const commonScopes = getCommonInstallScopes(targetAgents);
2030
+ if (commonScopes.length === 0) {
2031
+ p2.log.error("No agents selected");
2032
+ process.exit(1);
2045
2033
  }
2046
- if (selectedWithLocal.length > 0) {
2047
- let installLocally = true;
2048
- if (!options.yes) {
2049
- const scope = await p2.select({
2050
- message: "Installation scope",
2051
- options: [
2052
- {
2053
- value: true,
2054
- label: "Project",
2055
- hint: "Install in current directory (committed with your project)"
2056
- },
2057
- {
2058
- value: false,
2059
- label: "Global",
2060
- hint: "Install in home directory (available across all projects)"
2061
- }
2062
- ]
2063
- });
2064
- if (p2.isCancel(scope)) {
2065
- p2.cancel("Installation cancelled");
2066
- process.exit(0);
2067
- }
2068
- installLocally = scope;
2069
- }
2070
- for (const agent of selectedWithLocal) {
2071
- agentRouting.set(agent, installLocally ? "local" : "global");
2034
+ let installScope = commonScopes[0];
2035
+ if (commonScopes.length > 1 && !options.yes) {
2036
+ const scope = await p2.select({
2037
+ message: "Installation scope",
2038
+ options: [
2039
+ {
2040
+ value: "local",
2041
+ label: "Project",
2042
+ hint: "Install in current directory (committed with your project)"
2043
+ },
2044
+ {
2045
+ value: "global",
2046
+ label: "Global",
2047
+ hint: "Install in home directory (available across all projects)"
2048
+ }
2049
+ ]
2050
+ });
2051
+ if (p2.isCancel(scope)) {
2052
+ p2.cancel("Installation cancelled");
2053
+ process.exit(0);
2072
2054
  }
2073
- } else {
2074
- p2.log.info("Selected agents only support global installation");
2055
+ installScope = scope;
2056
+ } else if (installScope === "global") {
2057
+ p2.log.info("Selected agents require global installation");
2058
+ }
2059
+ agentRouting = /* @__PURE__ */ new Map();
2060
+ for (const agent of targetAgents) {
2061
+ agentRouting.set(agent, installScope);
2075
2062
  }
2076
2063
  }
2077
2064
  const summaryLines = [];
@@ -2088,15 +2075,7 @@ async function main(target, options) {
2088
2075
  const globalAgents = targetAgents.filter(
2089
2076
  (a) => agentRouting.get(a) === "global"
2090
2077
  );
2091
- if (localAgents.length > 0 && globalAgents.length > 0) {
2092
- summaryLines.push(`${chalk.cyan("Scope:")} Mixed (project + global)`);
2093
- summaryLines.push(
2094
- `${chalk.cyan(" Project:")} ${localAgents.map((a) => agents[a].displayName).join(", ")}`
2095
- );
2096
- summaryLines.push(
2097
- `${chalk.cyan(" Global:")} ${globalAgents.map((a) => agents[a].displayName).join(", ")}`
2098
- );
2099
- } else if (localAgents.length > 0) {
2078
+ if (localAgents.length > 0) {
2100
2079
  summaryLines.push(`${chalk.cyan("Scope:")} Project`);
2101
2080
  summaryLines.push(
2102
2081
  `${chalk.cyan("Agents:")} ${localAgents.map((a) => agents[a].displayName).join(", ")}`
@@ -2174,7 +2153,7 @@ async function main(target, options) {
2174
2153
  `${describeOptionalField(field)} is not supported by ${agentNames.join(", ")}; dropped from ${agentNames.length === 1 ? "that config" : "those configs"}.`
2175
2154
  );
2176
2155
  }
2177
- if (options.gitignore && options.global) {
2156
+ if (options.gitignore && localAgents.length === 0) {
2178
2157
  p2.log.warn(
2179
2158
  "--gitignore is only supported for project-scoped installations; ignoring."
2180
2159
  );
package/dist/lib.js CHANGED
@@ -10,7 +10,7 @@ import {
10
10
  listInstalledServers,
11
11
  readConfig,
12
12
  removeServerFromConfig
13
- } from "./chunk-IPCKQUBH.js";
13
+ } from "./chunk-3ZFFEEQJ.js";
14
14
 
15
15
  // src/lib.ts
16
16
  import { existsSync } from "fs";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "add-mcp",
3
- "version": "1.12.0",
3
+ "version": "1.13.1",
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",
@@ -28,6 +28,7 @@
28
28
  "test": "tsx tests/source-parser.test.ts && tsx tests/agents.test.ts && tsx tests/config.test.ts && tsx tests/installer.test.ts && tsx tests/find.test.ts && tsx tests/package-arguments.test.ts && tsx tests/template.test.ts && tsx tests/reader.test.ts && tsx tests/formats-remove.test.ts && tsx tests/lib.test.ts && tsx tests/e2e/install.test.ts && tsx tests/e2e/cli.test.ts",
29
29
  "test:unit": "tsx tests/source-parser.test.ts && tsx tests/agents.test.ts && tsx tests/config.test.ts && tsx tests/installer.test.ts && tsx tests/find.test.ts && tsx tests/package-arguments.test.ts && tsx tests/template.test.ts && tsx tests/reader.test.ts && tsx tests/formats-remove.test.ts && tsx tests/lib.test.ts",
30
30
  "registry:sort": "tsx scripts/sort-registry.ts",
31
+ "registry:sync": "node scripts/sync-integrations-sh.mjs",
31
32
  "registry:verify": "tsx scripts/verify-registry.ts",
32
33
  "test:e2e": "tsx tests/e2e/install.test.ts && tsx tests/e2e/cli.test.ts",
33
34
  "typecheck": "tsc --noEmit",