add-mcp 1.11.0 → 1.12.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.
- package/README.md +60 -29
- package/dist/{chunk-2OCTBM45.js → chunk-IPCKQUBH.js} +118 -11
- package/dist/index.js +66 -7
- package/dist/lib.d.ts +16 -1
- package/dist/lib.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -50,7 +50,7 @@ MCP servers can be installed to any of these agents:
|
|
|
50
50
|
|
|
51
51
|
| Agent | `--agent` | Project Path | Global Path |
|
|
52
52
|
| ---------------------- | -------------------- | ----------------------- | --------------------------------------------------------------------------------------------------------------- |
|
|
53
|
-
| Antigravity | `antigravity` | - | `~/.gemini/
|
|
53
|
+
| Antigravity | `antigravity` | - | `~/.gemini/config/mcp_config.json` (shared by Antigravity, Antigravity IDE, and Antigravity CLI) |
|
|
54
54
|
| Cline VSCode Extension | `cline` | - | `~/Library/Application Support/Code/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json` |
|
|
55
55
|
| Cline CLI | `cline-cli` | - | `~/.cline/data/settings/cline_mcp_settings.json` |
|
|
56
56
|
| Claude Code | `claude-code` | `.mcp.json` | `~/.claude.json` |
|
|
@@ -128,6 +128,12 @@ npx add-mcp https://mcp.example.com/mcp --header "Authorization: Bearer $TOKEN"
|
|
|
128
128
|
# (each agent only keeps the fields it supports; others are dropped with a warning)
|
|
129
129
|
npx add-mcp https://mcp.example.com/mcp --timeout 30000 --scopes "read,write"
|
|
130
130
|
|
|
131
|
+
# Auto-approve all tools for agents that support it (Codex, Claude Code)
|
|
132
|
+
npx add-mcp "executor mcp" --name executor -a codex -a claude-code --auto-approve
|
|
133
|
+
|
|
134
|
+
# Auto-approve only selected tools
|
|
135
|
+
npx add-mcp "executor mcp" --name executor -a codex --auto-approve --approve-tool execute
|
|
136
|
+
|
|
131
137
|
# npm package (runs via npx)
|
|
132
138
|
npx add-mcp @modelcontextprotocol/server-postgres
|
|
133
139
|
|
|
@@ -164,21 +170,23 @@ npx add-mcp https://mcp.example.com/mcp -a cursor -y --gitignore
|
|
|
164
170
|
|
|
165
171
|
### Options
|
|
166
172
|
|
|
167
|
-
| Option
|
|
168
|
-
|
|
|
169
|
-
| `-g, --global`
|
|
170
|
-
| `-a, --agent <agent>`
|
|
171
|
-
| `-t, --transport <type>`
|
|
172
|
-
| `--type <type>`
|
|
173
|
-
| `-h, --header <header>`
|
|
174
|
-
| `--env <env>`
|
|
175
|
-
| `--timeout <ms>`
|
|
176
|
-
| `--scopes <scopes>`
|
|
177
|
-
| `--oauth-scopes <scopes
|
|
178
|
-
|
|
|
179
|
-
|
|
|
180
|
-
|
|
|
181
|
-
|
|
|
173
|
+
| Option | Description |
|
|
174
|
+
| ------------------------- | ------------------------------------------------------------------------ |
|
|
175
|
+
| `-g, --global` | Install to user directory instead of project |
|
|
176
|
+
| `-a, --agent <agent>` | Target specific agents (e.g., `cursor`, `claude-code`). Can be repeated. |
|
|
177
|
+
| `-t, --transport <type>` | Transport type for remote servers: `http` (default), `sse` |
|
|
178
|
+
| `--type <type>` | Alias for `--transport` |
|
|
179
|
+
| `-h, --header <header>` | HTTP header for remote servers (repeatable, `Key: Value`) |
|
|
180
|
+
| `--env <env>` | Env var for local stdio servers (repeatable, `KEY=VALUE`) |
|
|
181
|
+
| `--timeout <ms>` | Request timeout (ms) for remote servers (capability-gated, see below) |
|
|
182
|
+
| `--scopes <scopes>` | OAuth scopes for remote servers, comma-separated (capability-gated) |
|
|
183
|
+
| `--oauth-scopes <scopes>` | Alias for `--scopes` |
|
|
184
|
+
| `--auto-approve` | Auto-approve MCP tool calls for supported agents (Codex, Claude Code) |
|
|
185
|
+
| `--approve-tool <tool>` | Tool to auto-approve with `--auto-approve` (repeatable; defaults to all) |
|
|
186
|
+
| `-n, --name <name>` | Server name (auto-inferred if not provided) |
|
|
187
|
+
| `-y, --yes` | Skip all confirmation prompts |
|
|
188
|
+
| `--all` | Install to all agents |
|
|
189
|
+
| `--gitignore` | Add generated config files to `.gitignore` |
|
|
182
190
|
|
|
183
191
|
#### Capability-gated fields (`--timeout`, `--scopes`)
|
|
184
192
|
|
|
@@ -186,15 +194,36 @@ Not every MCP client understands every field. `add-mcp` keeps one canonical
|
|
|
186
194
|
server config and each agent declares which optional fields it supports, mapping
|
|
187
195
|
them into that client's native shape:
|
|
188
196
|
|
|
189
|
-
| Field
|
|
190
|
-
|
|
|
191
|
-
| Timeout
|
|
192
|
-
| OAuth scopes
|
|
197
|
+
| Field | Flag | Supported by | Mapped to |
|
|
198
|
+
| ------------------ | ----------------------------------- | ----------------------- | -------------------------------------------------------- |
|
|
199
|
+
| Timeout | `--timeout` | Claude Code, Gemini CLI | `timeout` (milliseconds) |
|
|
200
|
+
| OAuth scopes | `--scopes` | Cursor, Gemini CLI | Cursor `auth.scopes`, Gemini `oauth.scopes` |
|
|
201
|
+
| Tool auto-approval | `--auto-approve` / `--approve-tool` | Codex, Claude Code | Codex approval modes; Claude Code permission allow rules |
|
|
193
202
|
|
|
194
203
|
When you target an agent that does not support a field, `add-mcp` drops it from
|
|
195
204
|
that agent's config and prints a warning (e.g. _"request timeout is not
|
|
196
205
|
supported by VS Code; dropped from that config."_). Other agents still receive
|
|
197
|
-
it.
|
|
206
|
+
it. `--timeout` and `--scopes` apply to remote servers only; `--auto-approve`
|
|
207
|
+
applies to both remote and local servers.
|
|
208
|
+
|
|
209
|
+
#### Auto-approving tool calls (`--auto-approve`)
|
|
210
|
+
|
|
211
|
+
`--auto-approve` preconfigures agent-level approval so the agent doesn't prompt
|
|
212
|
+
before each MCP tool call — useful for servers that already gate actions
|
|
213
|
+
internally. Use `--approve-tool <name>` (repeatable) to approve only specific
|
|
214
|
+
tools; without it, all tools are approved.
|
|
215
|
+
|
|
216
|
+
- **Codex** — writes approval modes into `config.toml`: per-tool
|
|
217
|
+
`tools.<name>.approval_mode = "approve"`, or `default_tools_approval_mode = "approve"` for all tools.
|
|
218
|
+
- **Claude Code** — writes permission allow rules to a separate settings file
|
|
219
|
+
(`.claude/settings.local.json` for project installs, `~/.claude/settings.json`
|
|
220
|
+
for global), e.g. `mcp__<server>__<tool>`, or `mcp__<server>` for all tools.
|
|
221
|
+
The MCP server entry itself stays clean.
|
|
222
|
+
|
|
223
|
+
> Note: Claude Code's all-tools rule (`mcp__<server>`) follows the documented
|
|
224
|
+
> format, but a known Claude Code bug ([#34739](https://github.com/anthropics/claude-code/issues/34739))
|
|
225
|
+
> can still prompt for non-fully-qualified MCP rules. Listing tools explicitly
|
|
226
|
+
> with `--approve-tool` is the most reliable path there.
|
|
198
227
|
|
|
199
228
|
### Transport Types
|
|
200
229
|
|
|
@@ -232,14 +261,16 @@ npx add-mcp find github --all --gitignore
|
|
|
232
261
|
|
|
233
262
|
### Options
|
|
234
263
|
|
|
235
|
-
| Option
|
|
236
|
-
|
|
|
237
|
-
| `-g, --global`
|
|
238
|
-
| `-a, --agent <agent>`
|
|
239
|
-
| `-n, --name <name>`
|
|
240
|
-
| `-y, --yes`
|
|
241
|
-
| `--
|
|
242
|
-
| `--
|
|
264
|
+
| Option | Description |
|
|
265
|
+
| ----------------------- | ------------------------------------------------------------------------ |
|
|
266
|
+
| `-g, --global` | Install to user directory instead of project |
|
|
267
|
+
| `-a, --agent <agent>` | Target specific agents (e.g., `cursor`, `claude-code`). Can be repeated. |
|
|
268
|
+
| `-n, --name <name>` | Server name override (defaults to the selected catalog entry name) |
|
|
269
|
+
| `-y, --yes` | Skip confirmation prompts |
|
|
270
|
+
| `--auto-approve` | Auto-approve MCP tool calls for supported agents (Codex, Claude Code) |
|
|
271
|
+
| `--approve-tool <tool>` | Tool to auto-approve with `--auto-approve` (repeatable; defaults to all) |
|
|
272
|
+
| `--all` | Install to all agents |
|
|
273
|
+
| `--gitignore` | Add generated config files to `.gitignore` |
|
|
243
274
|
|
|
244
275
|
Transport for `find`/`search` is inferred from registry metadata. The CLI prefers HTTP remotes when available and only falls back to SSE when HTTP is not available for the selected install context.
|
|
245
276
|
|
|
@@ -133,7 +133,7 @@ var { appSupport, vscodePath, gooseConfigPath } = getPlatformPaths();
|
|
|
133
133
|
var antigravityConfigPath = join2(
|
|
134
134
|
home,
|
|
135
135
|
".gemini",
|
|
136
|
-
"
|
|
136
|
+
"config",
|
|
137
137
|
"mcp_config.json"
|
|
138
138
|
);
|
|
139
139
|
var clineCliConfigPath = join2(
|
|
@@ -250,6 +250,17 @@ function transformOpenCodeConfig(_serverName, config) {
|
|
|
250
250
|
environment: config.env || {}
|
|
251
251
|
};
|
|
252
252
|
}
|
|
253
|
+
function applyCodexApproval(target, autoApproveTools) {
|
|
254
|
+
if (!autoApproveTools) return target;
|
|
255
|
+
if (autoApproveTools.length === 0) {
|
|
256
|
+
target.default_tools_approval_mode = "approve";
|
|
257
|
+
return target;
|
|
258
|
+
}
|
|
259
|
+
target.tools = Object.fromEntries(
|
|
260
|
+
autoApproveTools.map((tool) => [tool, { approval_mode: "approve" }])
|
|
261
|
+
);
|
|
262
|
+
return target;
|
|
263
|
+
}
|
|
253
264
|
function transformCodexConfig(_serverName, config) {
|
|
254
265
|
if (config.url) {
|
|
255
266
|
const remoteConfig = {
|
|
@@ -259,13 +270,16 @@ function transformCodexConfig(_serverName, config) {
|
|
|
259
270
|
if (config.headers && Object.keys(config.headers).length > 0) {
|
|
260
271
|
remoteConfig.http_headers = config.headers;
|
|
261
272
|
}
|
|
262
|
-
return remoteConfig;
|
|
273
|
+
return applyCodexApproval(remoteConfig, config.autoApproveTools);
|
|
263
274
|
}
|
|
264
|
-
return
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
275
|
+
return applyCodexApproval(
|
|
276
|
+
{
|
|
277
|
+
command: config.command,
|
|
278
|
+
args: config.args || [],
|
|
279
|
+
env: config.env
|
|
280
|
+
},
|
|
281
|
+
config.autoApproveTools
|
|
282
|
+
);
|
|
269
283
|
}
|
|
270
284
|
function transformCursorConfig(_serverName, config) {
|
|
271
285
|
if (config.url) {
|
|
@@ -375,7 +389,7 @@ var agents = {
|
|
|
375
389
|
supportedTransports: ["stdio", "http", "sse"],
|
|
376
390
|
supportedFields: [],
|
|
377
391
|
detectGlobalInstall: async () => {
|
|
378
|
-
return existsSync(join2(home, ".gemini"));
|
|
392
|
+
return existsSync(join2(home, ".gemini", "config"));
|
|
379
393
|
},
|
|
380
394
|
transformConfig: transformAntigravityConfig
|
|
381
395
|
},
|
|
@@ -418,7 +432,7 @@ var agents = {
|
|
|
418
432
|
configKey: "mcpServers",
|
|
419
433
|
format: "json",
|
|
420
434
|
supportedTransports: ["stdio", "http", "sse"],
|
|
421
|
-
supportedFields: ["timeout"],
|
|
435
|
+
supportedFields: ["timeout", "autoApprove"],
|
|
422
436
|
detectGlobalInstall: async () => {
|
|
423
437
|
return existsSync(join2(home, ".claude"));
|
|
424
438
|
},
|
|
@@ -452,7 +466,7 @@ var agents = {
|
|
|
452
466
|
configKey: "mcp_servers",
|
|
453
467
|
format: "toml",
|
|
454
468
|
supportedTransports: ["stdio", "http", "sse"],
|
|
455
|
-
supportedFields: [],
|
|
469
|
+
supportedFields: ["autoApprove"],
|
|
456
470
|
detectGlobalInstall: async () => {
|
|
457
471
|
return existsSync(join2(home, ".codex"));
|
|
458
472
|
},
|
|
@@ -1181,6 +1195,15 @@ var OPTIONAL_FIELD_SPECS = {
|
|
|
1181
1195
|
clear: (config) => {
|
|
1182
1196
|
delete config.oauthScopes;
|
|
1183
1197
|
}
|
|
1198
|
+
},
|
|
1199
|
+
autoApprove: {
|
|
1200
|
+
label: "tool auto-approval",
|
|
1201
|
+
// An empty array is meaningful ("approve all tools"), so presence alone
|
|
1202
|
+
// counts as set — unlike scopes where an empty list means "nothing".
|
|
1203
|
+
isSet: (config) => Array.isArray(config.autoApproveTools),
|
|
1204
|
+
clear: (config) => {
|
|
1205
|
+
delete config.autoApproveTools;
|
|
1206
|
+
}
|
|
1184
1207
|
}
|
|
1185
1208
|
};
|
|
1186
1209
|
var ALL_OPTIONAL_FIELDS = Object.keys(
|
|
@@ -1193,6 +1216,7 @@ function applyFieldSupport(config, supportedFields) {
|
|
|
1193
1216
|
const supported = new Set(supportedFields);
|
|
1194
1217
|
const copy = { ...config };
|
|
1195
1218
|
if (copy.oauthScopes) copy.oauthScopes = [...copy.oauthScopes];
|
|
1219
|
+
if (copy.autoApproveTools) copy.autoApproveTools = [...copy.autoApproveTools];
|
|
1196
1220
|
const dropped = [];
|
|
1197
1221
|
for (const field of ALL_OPTIONAL_FIELDS) {
|
|
1198
1222
|
const spec = OPTIONAL_FIELD_SPECS[field];
|
|
@@ -1206,7 +1230,9 @@ function applyFieldSupport(config, supportedFields) {
|
|
|
1206
1230
|
|
|
1207
1231
|
// src/installer.ts
|
|
1208
1232
|
import { existsSync as existsSync5, mkdirSync as mkdirSync4, readFileSync as readFileSync4, writeFileSync as writeFileSync4 } from "fs";
|
|
1233
|
+
import { homedir as homedir3 } from "os";
|
|
1209
1234
|
import { join as join3, dirname as dirname6, isAbsolute, relative, sep } from "path";
|
|
1235
|
+
var home2 = homedir3();
|
|
1210
1236
|
function buildServerConfig(parsed, options = {}) {
|
|
1211
1237
|
if (parsed.type === "remote") {
|
|
1212
1238
|
const config2 = {
|
|
@@ -1222,6 +1248,9 @@ function buildServerConfig(parsed, options = {}) {
|
|
|
1222
1248
|
if (options.oauthScopes && options.oauthScopes.length > 0) {
|
|
1223
1249
|
config2.oauthScopes = options.oauthScopes;
|
|
1224
1250
|
}
|
|
1251
|
+
if (options.autoApproveTools) {
|
|
1252
|
+
config2.autoApproveTools = options.autoApproveTools;
|
|
1253
|
+
}
|
|
1225
1254
|
return config2;
|
|
1226
1255
|
}
|
|
1227
1256
|
if (parsed.type === "command") {
|
|
@@ -1243,6 +1272,9 @@ function buildServerConfig(parsed, options = {}) {
|
|
|
1243
1272
|
if (options.env && Object.keys(options.env).length > 0) {
|
|
1244
1273
|
config2.env = options.env;
|
|
1245
1274
|
}
|
|
1275
|
+
if (options.autoApproveTools) {
|
|
1276
|
+
config2.autoApproveTools = options.autoApproveTools;
|
|
1277
|
+
}
|
|
1246
1278
|
return config2;
|
|
1247
1279
|
}
|
|
1248
1280
|
const config = {
|
|
@@ -1252,8 +1284,66 @@ function buildServerConfig(parsed, options = {}) {
|
|
|
1252
1284
|
if (options.env && Object.keys(options.env).length > 0) {
|
|
1253
1285
|
config.env = options.env;
|
|
1254
1286
|
}
|
|
1287
|
+
if (options.autoApproveTools) {
|
|
1288
|
+
config.autoApproveTools = options.autoApproveTools;
|
|
1289
|
+
}
|
|
1255
1290
|
return config;
|
|
1256
1291
|
}
|
|
1292
|
+
function readJsonObject(filePath) {
|
|
1293
|
+
if (!existsSync5(filePath)) {
|
|
1294
|
+
return {};
|
|
1295
|
+
}
|
|
1296
|
+
const parsed = JSON.parse(readFileSync4(filePath, "utf-8"));
|
|
1297
|
+
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
|
|
1298
|
+
}
|
|
1299
|
+
function writeJsonObject(filePath, value) {
|
|
1300
|
+
const dir = dirname6(filePath);
|
|
1301
|
+
if (!existsSync5(dir)) {
|
|
1302
|
+
mkdirSync4(dir, { recursive: true });
|
|
1303
|
+
}
|
|
1304
|
+
writeFileSync4(filePath, `${JSON.stringify(value, null, 2)}
|
|
1305
|
+
`, "utf-8");
|
|
1306
|
+
}
|
|
1307
|
+
function addUniqueStrings(existing, additions) {
|
|
1308
|
+
const values = Array.isArray(existing) ? existing.filter((value) => typeof value === "string") : [];
|
|
1309
|
+
for (const addition of additions) {
|
|
1310
|
+
if (!values.includes(addition)) {
|
|
1311
|
+
values.push(addition);
|
|
1312
|
+
}
|
|
1313
|
+
}
|
|
1314
|
+
return values;
|
|
1315
|
+
}
|
|
1316
|
+
function claudeAutoApproveRules(serverName, tools) {
|
|
1317
|
+
if (tools.length === 0) {
|
|
1318
|
+
return [`mcp__${serverName}`];
|
|
1319
|
+
}
|
|
1320
|
+
return tools.map((tool) => `mcp__${serverName}__${tool}`);
|
|
1321
|
+
}
|
|
1322
|
+
function getClaudeCodeSettingsPath(options = {}) {
|
|
1323
|
+
const local = Boolean(options.local);
|
|
1324
|
+
const cwd = options.cwd || process.cwd();
|
|
1325
|
+
return local ? join3(cwd, ".claude", "settings.local.json") : join3(home2, ".claude", "settings.json");
|
|
1326
|
+
}
|
|
1327
|
+
function installClaudeCodeAutoApproval(serverName, tools, options = {}) {
|
|
1328
|
+
const settingsPath = getClaudeCodeSettingsPath(options);
|
|
1329
|
+
try {
|
|
1330
|
+
const settings = readJsonObject(settingsPath);
|
|
1331
|
+
const permissions = settings.permissions && typeof settings.permissions === "object" && !Array.isArray(settings.permissions) ? settings.permissions : {};
|
|
1332
|
+
permissions.allow = addUniqueStrings(
|
|
1333
|
+
permissions.allow,
|
|
1334
|
+
claudeAutoApproveRules(serverName, tools)
|
|
1335
|
+
);
|
|
1336
|
+
settings.permissions = permissions;
|
|
1337
|
+
writeJsonObject(settingsPath, settings);
|
|
1338
|
+
return { success: true, path: settingsPath };
|
|
1339
|
+
} catch (error) {
|
|
1340
|
+
return {
|
|
1341
|
+
success: false,
|
|
1342
|
+
path: settingsPath,
|
|
1343
|
+
error: error instanceof Error ? error.message : "Unknown error"
|
|
1344
|
+
};
|
|
1345
|
+
}
|
|
1346
|
+
}
|
|
1257
1347
|
function updateGitignoreWithPaths(paths, options = {}) {
|
|
1258
1348
|
const cwd = options.cwd || process.cwd();
|
|
1259
1349
|
const gitignorePath = join3(cwd, ".gitignore");
|
|
@@ -1324,10 +1414,27 @@ function installServerForAgent(serverName, serverConfig, agentType, options = {}
|
|
|
1324
1414
|
const configKey = getConfigKey(agent, options);
|
|
1325
1415
|
const config = buildConfigWithKey(configKey, serverName, transformedConfig);
|
|
1326
1416
|
writeConfig2(configPath, config, agent.format, configKey);
|
|
1417
|
+
const extraPaths = [];
|
|
1418
|
+
if (agentType === "claude-code" && gatedConfig.autoApproveTools) {
|
|
1419
|
+
const approval = installClaudeCodeAutoApproval(
|
|
1420
|
+
serverName,
|
|
1421
|
+
gatedConfig.autoApproveTools,
|
|
1422
|
+
options
|
|
1423
|
+
);
|
|
1424
|
+
if (!approval.success) {
|
|
1425
|
+
return {
|
|
1426
|
+
success: false,
|
|
1427
|
+
path: approval.path,
|
|
1428
|
+
error: approval.error
|
|
1429
|
+
};
|
|
1430
|
+
}
|
|
1431
|
+
extraPaths.push(approval.path);
|
|
1432
|
+
}
|
|
1327
1433
|
return {
|
|
1328
1434
|
success: true,
|
|
1329
1435
|
path: configPath,
|
|
1330
|
-
...dropped.length > 0 ? { droppedFields: dropped } : {}
|
|
1436
|
+
...dropped.length > 0 ? { droppedFields: dropped } : {},
|
|
1437
|
+
...extraPaths.length > 0 ? { extraPaths } : {}
|
|
1331
1438
|
};
|
|
1332
1439
|
} catch (error) {
|
|
1333
1440
|
return {
|
package/dist/index.js
CHANGED
|
@@ -23,7 +23,7 @@ import {
|
|
|
23
23
|
selectAgentsInteractive,
|
|
24
24
|
supportsProjectConfig,
|
|
25
25
|
updateGitignoreWithPaths
|
|
26
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-IPCKQUBH.js";
|
|
27
27
|
|
|
28
28
|
// src/index.ts
|
|
29
29
|
import { program } from "commander";
|
|
@@ -783,7 +783,7 @@ async function runFind(query, options) {
|
|
|
783
783
|
// package.json
|
|
784
784
|
var package_default = {
|
|
785
785
|
name: "add-mcp",
|
|
786
|
-
version: "1.
|
|
786
|
+
version: "1.12.0",
|
|
787
787
|
description: "Add MCP servers to your favorite coding agents with a single command.",
|
|
788
788
|
author: "Andre Landgraf <andre@neon.tech>",
|
|
789
789
|
license: "Apache-2.0",
|
|
@@ -974,6 +974,25 @@ function extractSubcommandOptionsFromArgv() {
|
|
|
974
974
|
result.gitignore = true;
|
|
975
975
|
continue;
|
|
976
976
|
}
|
|
977
|
+
if (arg === "--auto-approve") {
|
|
978
|
+
result.autoApprove = true;
|
|
979
|
+
continue;
|
|
980
|
+
}
|
|
981
|
+
if (arg === "--approve-tool") {
|
|
982
|
+
const tools = result.approveTool ? [...result.approveTool] : [];
|
|
983
|
+
let j = i + 1;
|
|
984
|
+
while (j < argv.length) {
|
|
985
|
+
const value = argv[j];
|
|
986
|
+
if (!value || value.startsWith("-")) break;
|
|
987
|
+
tools.push(value);
|
|
988
|
+
j += 1;
|
|
989
|
+
}
|
|
990
|
+
if (tools.length > 0) {
|
|
991
|
+
result.approveTool = tools;
|
|
992
|
+
}
|
|
993
|
+
i = j - 1;
|
|
994
|
+
continue;
|
|
995
|
+
}
|
|
977
996
|
if ((arg === "-h" || arg === "--header") && argv[i + 1]) {
|
|
978
997
|
const headers = result.header ? [...result.header] : [];
|
|
979
998
|
headers.push(argv[i + 1]);
|
|
@@ -1126,7 +1145,15 @@ program.name("add-mcp").description(
|
|
|
1126
1145
|
).option(
|
|
1127
1146
|
"--scopes <scopes>",
|
|
1128
1147
|
"OAuth scopes to request for remote servers (comma-separated). Only applied to agents that support it (e.g. Cursor, Gemini CLI); dropped with a warning elsewhere."
|
|
1129
|
-
).option("--oauth-scopes <scopes>", "Alias for --scopes").option(
|
|
1148
|
+
).option("--oauth-scopes <scopes>", "Alias for --scopes").option(
|
|
1149
|
+
"--auto-approve",
|
|
1150
|
+
"Auto-approve MCP tool calls for agents that support it (Codex, Claude Code). Dropped with a warning for other agents."
|
|
1151
|
+
).option(
|
|
1152
|
+
"--approve-tool <tool>",
|
|
1153
|
+
"Tool name to auto-approve when --auto-approve is set (repeatable; defaults to all tools)",
|
|
1154
|
+
collect,
|
|
1155
|
+
[]
|
|
1156
|
+
).option("-y, --yes", "Skip confirmation prompts").option("--all", "Install to all agents").option("--gitignore", "Add generated project config files to .gitignore").action(async (target, options) => {
|
|
1130
1157
|
await main(target, options);
|
|
1131
1158
|
});
|
|
1132
1159
|
program.command("list-agents").description("List all supported coding agents").action(() => {
|
|
@@ -1172,7 +1199,15 @@ program.command("find [keyword]").description(
|
|
|
1172
1199
|
).option("-a, --agent <agent>", "Specify agents to install to", collect, []).option(
|
|
1173
1200
|
"-n, --name <name>",
|
|
1174
1201
|
"Server name override (defaults to catalog entry name)"
|
|
1175
|
-
).option("-y, --yes", "Skip confirmation prompts").option(
|
|
1202
|
+
).option("-y, --yes", "Skip confirmation prompts").option(
|
|
1203
|
+
"--auto-approve",
|
|
1204
|
+
"Auto-approve MCP tool calls for agents that support it (Codex, Claude Code)"
|
|
1205
|
+
).option(
|
|
1206
|
+
"--approve-tool <tool>",
|
|
1207
|
+
"Tool name to auto-approve when --auto-approve is set (repeatable; defaults to all tools)",
|
|
1208
|
+
collect,
|
|
1209
|
+
[]
|
|
1210
|
+
).option("--all", "Install to all agents").option("--gitignore", "Add generated project config files to .gitignore").action(
|
|
1176
1211
|
async (keyword, options) => {
|
|
1177
1212
|
await runFindCommand(keyword, options);
|
|
1178
1213
|
}
|
|
@@ -1183,7 +1218,15 @@ program.command("search [keyword]").description("Alias for find").option(
|
|
|
1183
1218
|
).option("-a, --agent <agent>", "Specify agents to install to", collect, []).option(
|
|
1184
1219
|
"-n, --name <name>",
|
|
1185
1220
|
"Server name override (defaults to catalog entry name)"
|
|
1186
|
-
).option("-y, --yes", "Skip confirmation prompts").option(
|
|
1221
|
+
).option("-y, --yes", "Skip confirmation prompts").option(
|
|
1222
|
+
"--auto-approve",
|
|
1223
|
+
"Auto-approve MCP tool calls for agents that support it (Codex, Claude Code)"
|
|
1224
|
+
).option(
|
|
1225
|
+
"--approve-tool <tool>",
|
|
1226
|
+
"Tool name to auto-approve when --auto-approve is set (repeatable; defaults to all tools)",
|
|
1227
|
+
collect,
|
|
1228
|
+
[]
|
|
1229
|
+
).option("--all", "Install to all agents").option("--gitignore", "Add generated project config files to .gitignore").action(
|
|
1187
1230
|
async (keyword, options) => {
|
|
1188
1231
|
await runFindCommand(keyword, options);
|
|
1189
1232
|
}
|
|
@@ -1829,13 +1872,16 @@ async function main(target, options) {
|
|
|
1829
1872
|
p2.log.warn("--scopes is only used for remote URLs, ignoring");
|
|
1830
1873
|
}
|
|
1831
1874
|
}
|
|
1875
|
+
const approveTools = [...new Set(options.approveTool ?? [])];
|
|
1876
|
+
const autoApproveTools = options.autoApprove || approveTools.length > 0 ? approveTools : void 0;
|
|
1832
1877
|
const serverConfig = buildServerConfig(parsed, {
|
|
1833
1878
|
transport: resolvedTransport,
|
|
1834
1879
|
headers: headersForConfig && Object.keys(headersForConfig).length > 0 ? headersForConfig : void 0,
|
|
1835
1880
|
env: envForConfig && Object.keys(envForConfig).length > 0 ? envForConfig : void 0,
|
|
1836
1881
|
args: argsForConfig && argsForConfig.length > 0 ? argsForConfig : void 0,
|
|
1837
1882
|
timeout: resolvedTimeout,
|
|
1838
|
-
oauthScopes: resolvedScopes
|
|
1883
|
+
oauthScopes: resolvedScopes,
|
|
1884
|
+
autoApproveTools
|
|
1839
1885
|
});
|
|
1840
1886
|
let targetAgents;
|
|
1841
1887
|
const allAgentTypes = getAgentTypes();
|
|
@@ -2031,6 +2077,11 @@ async function main(target, options) {
|
|
|
2031
2077
|
const summaryLines = [];
|
|
2032
2078
|
summaryLines.push(`${chalk.cyan("Server:")} ${serverName}`);
|
|
2033
2079
|
summaryLines.push(`${chalk.cyan("Type:")} ${sourceType}`);
|
|
2080
|
+
if (autoApproveTools) {
|
|
2081
|
+
summaryLines.push(
|
|
2082
|
+
`${chalk.cyan("Auto-approve:")} ${autoApproveTools.length === 0 ? "All tools" : autoApproveTools.join(", ")}`
|
|
2083
|
+
);
|
|
2084
|
+
}
|
|
2034
2085
|
const localAgents = targetAgents.filter(
|
|
2035
2086
|
(a) => agentRouting.get(a) === "local"
|
|
2036
2087
|
);
|
|
@@ -2083,6 +2134,11 @@ async function main(target, options) {
|
|
|
2083
2134
|
resultLines.push(
|
|
2084
2135
|
`${chalk.green("\u2713")} ${agent.displayName}: ${chalk.dim(shortPath)}`
|
|
2085
2136
|
);
|
|
2137
|
+
for (const extraPath of result.extraPaths ?? []) {
|
|
2138
|
+
resultLines.push(
|
|
2139
|
+
` ${chalk.dim("\u21B3 permissions:")} ${chalk.dim(shortenPath(extraPath))}`
|
|
2140
|
+
);
|
|
2141
|
+
}
|
|
2086
2142
|
}
|
|
2087
2143
|
p2.note(
|
|
2088
2144
|
resultLines.join("\n"),
|
|
@@ -2123,7 +2179,10 @@ async function main(target, options) {
|
|
|
2123
2179
|
"--gitignore is only supported for project-scoped installations; ignoring."
|
|
2124
2180
|
);
|
|
2125
2181
|
} else if (options.gitignore) {
|
|
2126
|
-
const successfulPaths = successful.
|
|
2182
|
+
const successfulPaths = successful.flatMap(([_, result]) => [
|
|
2183
|
+
result.path,
|
|
2184
|
+
...result.extraPaths ?? []
|
|
2185
|
+
]);
|
|
2127
2186
|
const gitignoreUpdate = updateGitignoreWithPaths(successfulPaths);
|
|
2128
2187
|
if (gitignoreUpdate.added.length > 0) {
|
|
2129
2188
|
p2.log.info(
|
package/dist/lib.d.ts
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* before its transform runs, guaranteeing that only known fields are ever
|
|
9
9
|
* written to a client config.
|
|
10
10
|
*/
|
|
11
|
-
type OptionalField = "timeout" | "scopes";
|
|
11
|
+
type OptionalField = "timeout" | "scopes" | "autoApprove";
|
|
12
12
|
|
|
13
13
|
type AgentType = "antigravity" | "cline" | "cline-cli" | "claude-code" | "claude-desktop" | "codex" | "cursor" | "gemini-cli" | "goose" | "github-copilot-cli" | "mcporter" | "opencode" | "vscode" | "windsurf" | "zed";
|
|
14
14
|
type ConfigFormat = "json" | "yaml" | "toml";
|
|
@@ -79,6 +79,15 @@ interface McpServerConfig {
|
|
|
79
79
|
* their own native shape (e.g. Cursor `auth.scopes`, Gemini `oauth.scopes`).
|
|
80
80
|
*/
|
|
81
81
|
oauthScopes?: string[];
|
|
82
|
+
/**
|
|
83
|
+
* Tools to auto-approve (skip the agent's per-call approval prompt). An empty
|
|
84
|
+
* array means "all tools". This is an install directive rather than a literal
|
|
85
|
+
* server-config key: capability-gated via `"autoApprove"` in `supportedFields`
|
|
86
|
+
* and each supporting agent applies it in its own way (e.g. Codex emits
|
|
87
|
+
* approval modes in its config; Claude Code writes permission allow rules to a
|
|
88
|
+
* separate settings file). It is never written into a server entry verbatim.
|
|
89
|
+
*/
|
|
90
|
+
autoApproveTools?: string[];
|
|
82
91
|
}
|
|
83
92
|
|
|
84
93
|
interface InstallOptions {
|
|
@@ -96,6 +105,12 @@ interface InstallResult {
|
|
|
96
105
|
* does not support them. Empty/undefined when nothing was dropped.
|
|
97
106
|
*/
|
|
98
107
|
droppedFields?: OptionalField[];
|
|
108
|
+
/**
|
|
109
|
+
* Additional files written beyond the main config (e.g. a Claude Code
|
|
110
|
+
* permissions settings file for auto-approval). Surfaced so the CLI can
|
|
111
|
+
* report them and include them in `--gitignore`.
|
|
112
|
+
*/
|
|
113
|
+
extraPaths?: string[];
|
|
99
114
|
}
|
|
100
115
|
|
|
101
116
|
declare const agents: Record<AgentType, AgentConfig>;
|
package/dist/lib.js
CHANGED