@mcp-abap-adt/configurator 0.0.12 β 0.1.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 +1 -0
- package/bin/mcp-conf-tui.js +159 -50
- package/bin/mcp-conf.js +158 -53
- package/docs/CLIENT_INSTALLERS.md +13 -6
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -20,6 +20,7 @@ mcp-conf --client codex --name abap-http --transport http --url http://localhost
|
|
|
20
20
|
mcp-conf --client opencode --name abap --transport http --url http://localhost:3000/mcp/stream/http
|
|
21
21
|
mcp-conf --client kilo --name abap --transport http --url http://localhost:3000/mcp/stream/http
|
|
22
22
|
mcp-conf --client copilot --name abap --transport http --url http://localhost:3000/mcp/stream/http --header x-mcp-destination=trial
|
|
23
|
+
mcp-conf --client qwen --name abap --transport http --url http://localhost:3000/mcp/stream/http
|
|
23
24
|
mcp-conf --client crush --name abap --mcp TRIAL
|
|
24
25
|
mcp-conf --client crush --name abap --transport http --url http://localhost:3000/mcp/stream/http
|
|
25
26
|
mcp-conf tui
|
package/bin/mcp-conf-tui.js
CHANGED
|
@@ -15,6 +15,7 @@ const CLIENTS = [
|
|
|
15
15
|
{ name: "opencode", message: "OpenCode (kilo)" },
|
|
16
16
|
{ name: "copilot", message: "GitHub Copilot" },
|
|
17
17
|
{ name: "antigravity", message: "Antigravity" },
|
|
18
|
+
{ name: "qwen", message: "Qwen" },
|
|
18
19
|
{ name: "crush", message: "Crush" },
|
|
19
20
|
];
|
|
20
21
|
|
|
@@ -35,26 +36,36 @@ async function main() {
|
|
|
35
36
|
};
|
|
36
37
|
|
|
37
38
|
result.tuiAction = await askSelect("Operation", [
|
|
38
|
-
"ls",
|
|
39
|
-
"show",
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
"enable",
|
|
44
|
-
"disable",
|
|
39
|
+
{ name: "ls", message: "π ls" },
|
|
40
|
+
{ name: "show", message: "π show" },
|
|
41
|
+
{ name: "sep-view", role: "separator", message: "ββββββββββββ" },
|
|
42
|
+
{ name: "add", message: "β add" },
|
|
43
|
+
{ name: "update", message: "βοΈ update" },
|
|
44
|
+
{ name: "enable", message: "β
enable" },
|
|
45
|
+
{ name: "disable", message: "βΈοΈ disable" },
|
|
46
|
+
{ name: "rm", message: "ποΈ rm" },
|
|
47
|
+
{ name: "sep-exit", role: "separator", message: "ββββββββββββ" },
|
|
48
|
+
{ name: "exit", message: "πͺ exit" },
|
|
45
49
|
]);
|
|
50
|
+
if (result.tuiAction === "exit") {
|
|
51
|
+
emitResult({ tuiAction: "exit" });
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
46
54
|
const client = await askSelect(
|
|
47
55
|
"Client",
|
|
48
56
|
CLIENTS.map((item) => item.name),
|
|
49
57
|
CLIENTS.map((item) => item.message),
|
|
50
58
|
);
|
|
51
59
|
result.clients = [client];
|
|
52
|
-
|
|
53
|
-
const scopes = getSupportedScopes(client);
|
|
54
|
-
result.scope = scopes.length === 1 ? scopes[0] : await askSelect("Scope", ["global", "local"]);
|
|
60
|
+
await configureScope(result, client);
|
|
55
61
|
|
|
56
62
|
if (["rm", "enable", "disable", "show", "update"].includes(result.tuiAction)) {
|
|
57
|
-
const serverNames = listExistingServers(
|
|
63
|
+
const serverNames = listExistingServers(
|
|
64
|
+
client,
|
|
65
|
+
result.scope,
|
|
66
|
+
result.allProjects,
|
|
67
|
+
result.projectPath,
|
|
68
|
+
);
|
|
58
69
|
if (serverNames.length === 0) {
|
|
59
70
|
throw new Error(`No existing MCP servers found for ${client} (${result.scope})`);
|
|
60
71
|
}
|
|
@@ -79,32 +90,37 @@ async function main() {
|
|
|
79
90
|
|
|
80
91
|
if (result.transport === "stdio") {
|
|
81
92
|
const authSource = await askSelect("Auth source for stdio", [
|
|
82
|
-
"
|
|
83
|
-
"
|
|
84
|
-
"
|
|
93
|
+
"destination (--mcp=<name>)",
|
|
94
|
+
"env name (--env=<name>)",
|
|
95
|
+
"env file (--env-path=<name>)",
|
|
85
96
|
]);
|
|
86
|
-
if (authSource.startsWith("
|
|
97
|
+
if (authSource.startsWith("destination")) {
|
|
87
98
|
result.mcpDestination = await askInput("Destination name", "TRIAL");
|
|
88
99
|
result.useSessionEnv = false;
|
|
100
|
+
result.envName = null;
|
|
89
101
|
result.envPath = null;
|
|
90
102
|
result.url = null;
|
|
91
103
|
emitResult(result);
|
|
92
104
|
return;
|
|
93
105
|
}
|
|
94
|
-
if (authSource.startsWith("
|
|
106
|
+
if (authSource.startsWith("env name")) {
|
|
107
|
+
result.envName = await askInput("Env name", "TRIAL");
|
|
108
|
+
result.useSessionEnv = false;
|
|
109
|
+
result.envPath = null;
|
|
110
|
+
result.mcpDestination = null;
|
|
111
|
+
result.url = null;
|
|
112
|
+
emitResult(result);
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
if (authSource.startsWith("env file")) {
|
|
95
116
|
result.envPath = await askInput("Path to .env file");
|
|
96
117
|
result.useSessionEnv = false;
|
|
118
|
+
result.envName = null;
|
|
97
119
|
result.mcpDestination = null;
|
|
98
120
|
result.url = null;
|
|
99
121
|
emitResult(result);
|
|
100
122
|
return;
|
|
101
123
|
}
|
|
102
|
-
result.useSessionEnv = true;
|
|
103
|
-
result.envPath = null;
|
|
104
|
-
result.mcpDestination = null;
|
|
105
|
-
result.url = null;
|
|
106
|
-
emitResult(result);
|
|
107
|
-
return;
|
|
108
124
|
}
|
|
109
125
|
|
|
110
126
|
result.url = await askInput("Server URL (http/https)");
|
|
@@ -118,7 +134,13 @@ async function main() {
|
|
|
118
134
|
}
|
|
119
135
|
|
|
120
136
|
async function configureUpdate(result, client) {
|
|
121
|
-
const current = getServerConfig(
|
|
137
|
+
const current = getServerConfig(
|
|
138
|
+
client,
|
|
139
|
+
result.scope,
|
|
140
|
+
result.name,
|
|
141
|
+
result.allProjects,
|
|
142
|
+
result.projectPath,
|
|
143
|
+
);
|
|
122
144
|
const currentTransport = current.transport || "stdio";
|
|
123
145
|
result.transport = currentTransport;
|
|
124
146
|
result.command = current.command || "mcp-abap-adt";
|
|
@@ -128,42 +150,48 @@ async function configureUpdate(result, client) {
|
|
|
128
150
|
|
|
129
151
|
if (currentTransport === "stdio") {
|
|
130
152
|
const authChoices = [
|
|
131
|
-
"
|
|
132
|
-
"
|
|
133
|
-
"
|
|
153
|
+
"destination (--mcp=<name>)",
|
|
154
|
+
"env name (--env=<name>)",
|
|
155
|
+
"env file (--env-path=<name>)",
|
|
134
156
|
];
|
|
135
157
|
const authType = current.auth?.type || "unknown";
|
|
136
158
|
const authInitial =
|
|
137
159
|
authType === "mcp" ? 0 : authType === "env" ? 1 : authType === "env-path" ? 2 : 0;
|
|
138
160
|
const authSource = await askSelect("Auth source for stdio", authChoices, null, authInitial);
|
|
139
|
-
if (authSource.startsWith("
|
|
161
|
+
if (authSource.startsWith("destination")) {
|
|
140
162
|
result.mcpDestination = await askInput("Destination name", current.auth?.value || "TRIAL");
|
|
141
163
|
result.useSessionEnv = false;
|
|
164
|
+
result.envName = null;
|
|
142
165
|
result.envPath = null;
|
|
143
166
|
result.url = null;
|
|
144
167
|
result.headers = {};
|
|
145
168
|
return;
|
|
146
169
|
}
|
|
147
|
-
if (authSource.startsWith("
|
|
170
|
+
if (authSource.startsWith("env name")) {
|
|
171
|
+
result.envName = await askInput("Env name", current.auth?.value || "TRIAL");
|
|
172
|
+
result.useSessionEnv = false;
|
|
173
|
+
result.envPath = null;
|
|
174
|
+
result.mcpDestination = null;
|
|
175
|
+
result.url = null;
|
|
176
|
+
result.headers = {};
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
if (authSource.startsWith("env file")) {
|
|
148
180
|
result.envPath = await askInput("Path to .env file", current.auth?.value || undefined);
|
|
149
181
|
result.useSessionEnv = false;
|
|
182
|
+
result.envName = null;
|
|
150
183
|
result.mcpDestination = null;
|
|
151
184
|
result.url = null;
|
|
152
185
|
result.headers = {};
|
|
153
186
|
return;
|
|
154
187
|
}
|
|
155
|
-
result.useSessionEnv = true;
|
|
156
|
-
result.envPath = null;
|
|
157
|
-
result.mcpDestination = null;
|
|
158
|
-
result.url = null;
|
|
159
|
-
result.headers = {};
|
|
160
|
-
return;
|
|
161
188
|
}
|
|
162
189
|
|
|
163
190
|
result.url = await askInput("Server URL (http/https)", current.url || undefined);
|
|
164
191
|
result.timeout = await askPositiveNumber("Timeout seconds", result.timeout);
|
|
165
192
|
result.headers = await askHeaders(current.headers || {});
|
|
166
193
|
result.useSessionEnv = false;
|
|
194
|
+
result.envName = null;
|
|
167
195
|
result.envPath = null;
|
|
168
196
|
result.mcpDestination = null;
|
|
169
197
|
}
|
|
@@ -173,10 +201,15 @@ function emitResult(result) {
|
|
|
173
201
|
}
|
|
174
202
|
|
|
175
203
|
async function askSelect(message, choices, choiceLabels, initial = 0) {
|
|
176
|
-
const promptChoices = choices.map((value, index) =>
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
204
|
+
const promptChoices = choices.map((value, index) => {
|
|
205
|
+
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
206
|
+
return value;
|
|
207
|
+
}
|
|
208
|
+
return {
|
|
209
|
+
name: value,
|
|
210
|
+
message: choiceLabels?.[index] || value,
|
|
211
|
+
};
|
|
212
|
+
});
|
|
180
213
|
const select = new Select({
|
|
181
214
|
name: "value",
|
|
182
215
|
message,
|
|
@@ -233,12 +266,39 @@ function getSupportedScopes(clientName) {
|
|
|
233
266
|
if (clientName === "copilot") {
|
|
234
267
|
return ["local"];
|
|
235
268
|
}
|
|
236
|
-
if (["cline", "goose", "windsurf", "antigravity"].includes(clientName)) {
|
|
269
|
+
if (["cline", "goose", "windsurf", "antigravity", "qwen"].includes(clientName)) {
|
|
237
270
|
return ["global"];
|
|
238
271
|
}
|
|
239
272
|
return ["global", "local"];
|
|
240
273
|
}
|
|
241
274
|
|
|
275
|
+
async function configureScope(result, clientName) {
|
|
276
|
+
result.allProjects = false;
|
|
277
|
+
result.projectPath = null;
|
|
278
|
+
|
|
279
|
+
if (clientName === "claude") {
|
|
280
|
+
result.scope = await askSelect("Scope", ["global", "local"]);
|
|
281
|
+
if (result.scope === "local") {
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
284
|
+
if (supportsClaudeGlobalAllProjects(result.tuiAction)) {
|
|
285
|
+
const globalMode = await askSelect("Claude global", [
|
|
286
|
+
{ name: "single", message: "for current project" },
|
|
287
|
+
{ name: "all", message: "for all projects" },
|
|
288
|
+
]);
|
|
289
|
+
result.allProjects = globalMode === "all";
|
|
290
|
+
}
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
const scopes = getSupportedScopes(clientName);
|
|
295
|
+
result.scope = scopes.length === 1 ? scopes[0] : await askSelect("Scope", ["global", "local"]);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
function supportsClaudeGlobalAllProjects(action) {
|
|
299
|
+
return ["ls", "show", "rm", "enable", "disable"].includes(action);
|
|
300
|
+
}
|
|
301
|
+
|
|
242
302
|
function getSupportedTransports(clientName) {
|
|
243
303
|
if (clientName === "codex") {
|
|
244
304
|
return ["stdio", "http"];
|
|
@@ -246,10 +306,16 @@ function getSupportedTransports(clientName) {
|
|
|
246
306
|
return ["stdio", "sse", "http"];
|
|
247
307
|
}
|
|
248
308
|
|
|
249
|
-
function listExistingServers(clientName, scope) {
|
|
309
|
+
function listExistingServers(clientName, scope, allProjects = false, projectPath = null) {
|
|
250
310
|
const cliPath = path.join(__dirname, "mcp-conf.js");
|
|
251
311
|
const scopeArg = scope === "local" ? "--local" : "--global";
|
|
252
|
-
const
|
|
312
|
+
const cliArgs = [cliPath, "ls", "--client", clientName, scopeArg];
|
|
313
|
+
if (allProjects) {
|
|
314
|
+
cliArgs.push("--all-projects");
|
|
315
|
+
} else if (projectPath) {
|
|
316
|
+
cliArgs.push("--project", projectPath);
|
|
317
|
+
}
|
|
318
|
+
const run = spawnSync(process.execPath, cliArgs, {
|
|
253
319
|
encoding: "utf8",
|
|
254
320
|
});
|
|
255
321
|
if (run.status !== 0) {
|
|
@@ -271,16 +337,28 @@ function listExistingServers(clientName, scope) {
|
|
|
271
337
|
return [...new Set(names)].sort((a, b) => a.localeCompare(b));
|
|
272
338
|
}
|
|
273
339
|
|
|
274
|
-
function getServerConfig(clientName, scope, serverName) {
|
|
340
|
+
function getServerConfig(clientName, scope, serverName, allProjects = false, projectPath = null) {
|
|
275
341
|
const cliPath = path.join(__dirname, "mcp-conf.js");
|
|
276
342
|
const scopeArg = scope === "local" ? "--local" : "--global";
|
|
277
|
-
const
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
343
|
+
const cliArgs = [
|
|
344
|
+
cliPath,
|
|
345
|
+
"show",
|
|
346
|
+
"--client",
|
|
347
|
+
clientName,
|
|
348
|
+
"--name",
|
|
349
|
+
serverName,
|
|
350
|
+
scopeArg,
|
|
351
|
+
"--json",
|
|
352
|
+
"--normalized",
|
|
353
|
+
];
|
|
354
|
+
if (allProjects) {
|
|
355
|
+
cliArgs.push("--all-projects");
|
|
356
|
+
} else if (projectPath) {
|
|
357
|
+
cliArgs.push("--project", projectPath);
|
|
358
|
+
}
|
|
359
|
+
const run = spawnSync(process.execPath, cliArgs, {
|
|
360
|
+
encoding: "utf8",
|
|
361
|
+
});
|
|
284
362
|
if (run.status !== 0) {
|
|
285
363
|
const stderr = String(run.stderr || "").trim();
|
|
286
364
|
throw new Error(stderr || "Failed to read existing server config");
|
|
@@ -293,9 +371,40 @@ function getServerConfig(clientName, scope, serverName) {
|
|
|
293
371
|
}
|
|
294
372
|
|
|
295
373
|
main().catch((error) => {
|
|
296
|
-
if (error
|
|
374
|
+
if (isPromptCancelError(error)) {
|
|
375
|
+
process.exit(0);
|
|
376
|
+
}
|
|
377
|
+
process.stderr.write(`${error?.message || String(error)}\n`);
|
|
378
|
+
process.exit(1);
|
|
379
|
+
});
|
|
380
|
+
|
|
381
|
+
process.on("uncaughtException", (error) => {
|
|
382
|
+
if (isPromptCancelError(error)) {
|
|
297
383
|
process.exit(0);
|
|
298
384
|
}
|
|
299
385
|
process.stderr.write(`${error?.message || String(error)}\n`);
|
|
300
386
|
process.exit(1);
|
|
301
387
|
});
|
|
388
|
+
|
|
389
|
+
process.on("unhandledRejection", (error) => {
|
|
390
|
+
if (isPromptCancelError(error)) {
|
|
391
|
+
process.exit(0);
|
|
392
|
+
}
|
|
393
|
+
process.stderr.write(`${error?.message || String(error)}\n`);
|
|
394
|
+
process.exit(1);
|
|
395
|
+
});
|
|
396
|
+
|
|
397
|
+
function isPromptCancelError(error) {
|
|
398
|
+
if (error === "" || error === null || error === undefined) {
|
|
399
|
+
return true;
|
|
400
|
+
}
|
|
401
|
+
if (typeof error === "string") {
|
|
402
|
+
return error.toLowerCase().includes("cancel");
|
|
403
|
+
}
|
|
404
|
+
const message = String(error?.message || "");
|
|
405
|
+
return (
|
|
406
|
+
error?.code === "ERR_USE_AFTER_CLOSE" ||
|
|
407
|
+
message.toLowerCase().includes("cancel") ||
|
|
408
|
+
message.toLowerCase().includes("readline was closed")
|
|
409
|
+
);
|
|
410
|
+
}
|
package/bin/mcp-conf.js
CHANGED
|
@@ -34,6 +34,7 @@ if (
|
|
|
34
34
|
}
|
|
35
35
|
const options = {
|
|
36
36
|
clients: [],
|
|
37
|
+
envName: null,
|
|
37
38
|
envPath: null,
|
|
38
39
|
useSessionEnv: false,
|
|
39
40
|
mcpDestination: null,
|
|
@@ -52,6 +53,7 @@ const options = {
|
|
|
52
53
|
where: false,
|
|
53
54
|
show: false,
|
|
54
55
|
outputJson: false,
|
|
56
|
+
outputNormalized: false,
|
|
55
57
|
url: null,
|
|
56
58
|
headers: {},
|
|
57
59
|
timeout: 60,
|
|
@@ -76,30 +78,45 @@ for (let i = 0; i < args.length; i += 1) {
|
|
|
76
78
|
if (arg === "--client") {
|
|
77
79
|
options.clients.push(normalizeClientName(args[i + 1]));
|
|
78
80
|
i += 1;
|
|
81
|
+
} else if (arg.startsWith("--env=")) {
|
|
82
|
+
options.envName = arg.slice("--env=".length);
|
|
83
|
+
options.useSessionEnv = false;
|
|
84
|
+
options.envPath = null;
|
|
85
|
+
options.mcpDestination = null;
|
|
79
86
|
} else if (arg === "--env") {
|
|
80
87
|
const maybePath = args[i + 1];
|
|
81
88
|
if (maybePath && !maybePath.startsWith("-")) {
|
|
82
|
-
|
|
83
|
-
|
|
89
|
+
if (looksLikeEnvPath(maybePath)) {
|
|
90
|
+
// Backward-compatible form: --env /path/to/.env
|
|
91
|
+
options.envPath = maybePath;
|
|
92
|
+
options.envName = null;
|
|
93
|
+
} else {
|
|
94
|
+
options.envName = maybePath;
|
|
95
|
+
options.envPath = null;
|
|
96
|
+
}
|
|
84
97
|
options.useSessionEnv = false;
|
|
85
98
|
options.mcpDestination = null;
|
|
86
99
|
i += 1;
|
|
87
100
|
} else {
|
|
88
101
|
options.useSessionEnv = true;
|
|
102
|
+
options.envName = null;
|
|
89
103
|
options.envPath = null;
|
|
90
104
|
options.mcpDestination = null;
|
|
91
105
|
}
|
|
92
106
|
} else if (arg === "--env-path") {
|
|
93
107
|
options.envPath = args[i + 1];
|
|
108
|
+
options.envName = null;
|
|
94
109
|
options.useSessionEnv = false;
|
|
95
110
|
options.mcpDestination = null;
|
|
96
111
|
i += 1;
|
|
97
112
|
} else if (arg === "--session-env") {
|
|
98
113
|
options.useSessionEnv = true;
|
|
114
|
+
options.envName = null;
|
|
99
115
|
options.envPath = null;
|
|
100
116
|
options.mcpDestination = null;
|
|
101
117
|
} else if (arg === "--mcp") {
|
|
102
118
|
options.mcpDestination = args[i + 1];
|
|
119
|
+
options.envName = null;
|
|
103
120
|
options.useSessionEnv = false;
|
|
104
121
|
options.envPath = null;
|
|
105
122
|
i += 1;
|
|
@@ -154,6 +171,8 @@ for (let i = 0; i < args.length; i += 1) {
|
|
|
154
171
|
options.force = true;
|
|
155
172
|
} else if (arg === "--json") {
|
|
156
173
|
options.outputJson = true;
|
|
174
|
+
} else if (arg === "--normalized") {
|
|
175
|
+
options.outputNormalized = true;
|
|
157
176
|
}
|
|
158
177
|
}
|
|
159
178
|
|
|
@@ -169,6 +188,9 @@ if (action === "tui") {
|
|
|
169
188
|
runTuiWizard(options);
|
|
170
189
|
effectiveAction = options.tuiAction || "add";
|
|
171
190
|
}
|
|
191
|
+
if (effectiveAction === "exit") {
|
|
192
|
+
process.exit(0);
|
|
193
|
+
}
|
|
172
194
|
|
|
173
195
|
if (options.clients.length === 0) {
|
|
174
196
|
fail("Provide at least one --client.");
|
|
@@ -242,8 +264,8 @@ const requiresConnectionParams =
|
|
|
242
264
|
!options.remove && !options.toggle && !options.list && !options.where && !options.show;
|
|
243
265
|
|
|
244
266
|
if (requiresConnectionParams && options.transport === "stdio") {
|
|
245
|
-
if (!options.envPath && !options.mcpDestination && !options.useSessionEnv) {
|
|
246
|
-
fail("Provide --env
|
|
267
|
+
if (!options.envName && !options.envPath && !options.mcpDestination && !options.useSessionEnv) {
|
|
268
|
+
fail("Provide --env <name>, --env-path <path>, --session-env, or --mcp <destination>.");
|
|
247
269
|
}
|
|
248
270
|
}
|
|
249
271
|
|
|
@@ -251,8 +273,8 @@ if (requiresConnectionParams && options.transport !== "stdio") {
|
|
|
251
273
|
if (!options.url) {
|
|
252
274
|
fail("Provide --url <http(s)://...> for sse/http transports.");
|
|
253
275
|
}
|
|
254
|
-
if (options.envPath || options.mcpDestination || options.useSessionEnv) {
|
|
255
|
-
fail("--env/--env-path/--mcp are only valid for stdio transport.");
|
|
276
|
+
if (options.envName || options.envPath || options.mcpDestination || options.useSessionEnv) {
|
|
277
|
+
fail("--env/--env-path/--session-env/--mcp are only valid for stdio transport.");
|
|
256
278
|
}
|
|
257
279
|
}
|
|
258
280
|
|
|
@@ -263,13 +285,15 @@ const userProfile = process.env.USERPROFILE || home;
|
|
|
263
285
|
|
|
264
286
|
const serverArgsRaw = [
|
|
265
287
|
`--transport=${options.transport}`,
|
|
266
|
-
options.
|
|
267
|
-
?
|
|
268
|
-
: options.
|
|
269
|
-
?
|
|
270
|
-
: options.
|
|
271
|
-
? `--
|
|
272
|
-
:
|
|
288
|
+
options.envName
|
|
289
|
+
? `--env=${options.envName}`
|
|
290
|
+
: options.useSessionEnv
|
|
291
|
+
? "--session-env"
|
|
292
|
+
: options.envPath
|
|
293
|
+
? `--env-path=${options.envPath}`
|
|
294
|
+
: options.mcpDestination
|
|
295
|
+
? `--mcp=${options.mcpDestination.toLowerCase()}`
|
|
296
|
+
: undefined,
|
|
273
297
|
];
|
|
274
298
|
const serverArgs = serverArgsRaw.filter(Boolean);
|
|
275
299
|
|
|
@@ -395,6 +419,18 @@ for (const client of options.clients) {
|
|
|
395
419
|
writeJsonConfig(getAntigravityPath(home, scope), options.name, serverArgs, "antigravity");
|
|
396
420
|
}
|
|
397
421
|
break;
|
|
422
|
+
case "qwen":
|
|
423
|
+
requireScope("Qwen", ["global"], scope);
|
|
424
|
+
if (options.list) {
|
|
425
|
+
listJsonConfig(getQwenPath(home), "qwen");
|
|
426
|
+
} else if (options.show) {
|
|
427
|
+
showJsonConfig(getQwenPath(home), "qwen", options.name);
|
|
428
|
+
} else if (options.where) {
|
|
429
|
+
whereJsonConfig(getQwenPath(home), "qwen", options.name);
|
|
430
|
+
} else {
|
|
431
|
+
writeJsonConfig(getQwenPath(home), options.name, serverArgs, "qwen");
|
|
432
|
+
}
|
|
433
|
+
break;
|
|
398
434
|
case "copilot":
|
|
399
435
|
requireScope("GitHub Copilot", ["local"], scope);
|
|
400
436
|
if (options.list) {
|
|
@@ -489,7 +525,8 @@ function runTuiWizard(opts) {
|
|
|
489
525
|
const rawPayload = run.output?.[3] || "";
|
|
490
526
|
const payload = String(rawPayload).trim();
|
|
491
527
|
if (!payload) {
|
|
492
|
-
|
|
528
|
+
opts.tuiAction = "exit";
|
|
529
|
+
return;
|
|
493
530
|
}
|
|
494
531
|
let selected;
|
|
495
532
|
try {
|
|
@@ -590,6 +627,10 @@ function getAntigravityPath(homeDir, scopeValue) {
|
|
|
590
627
|
return path.join(homeDir, ".gemini", "antigravity", "mcp_config.json");
|
|
591
628
|
}
|
|
592
629
|
|
|
630
|
+
function getQwenPath(homeDir) {
|
|
631
|
+
return path.join(homeDir, ".qwen", "settings.json");
|
|
632
|
+
}
|
|
633
|
+
|
|
593
634
|
function getWindsurfPath(platformValue, homeDir, userProfileDir) {
|
|
594
635
|
if (platformValue === "win32") {
|
|
595
636
|
return path.join(userProfileDir, ".codeium", "windsurf", "mcp_config.json");
|
|
@@ -1314,7 +1355,10 @@ function showJsonConfig(filePath, clientType, serverName) {
|
|
|
1314
1355
|
if (!entry) {
|
|
1315
1356
|
fail(`Server "${serverName}" not found in ${filePath}.`);
|
|
1316
1357
|
}
|
|
1317
|
-
|
|
1358
|
+
const details = options.outputNormalized
|
|
1359
|
+
? normalizeServerDetails(clientType, serverName, entry)
|
|
1360
|
+
: cloneJsonLike(entry);
|
|
1361
|
+
outputShow(filePath, serverName, details);
|
|
1318
1362
|
}
|
|
1319
1363
|
|
|
1320
1364
|
function showCodexConfig(filePath, serverName) {
|
|
@@ -1327,7 +1371,10 @@ function showCodexConfig(filePath, serverName) {
|
|
|
1327
1371
|
if (!entry) {
|
|
1328
1372
|
fail(`Server "${serverName}" not found in ${filePath}.`);
|
|
1329
1373
|
}
|
|
1330
|
-
|
|
1374
|
+
const details = options.outputNormalized
|
|
1375
|
+
? normalizeServerDetails("codex", serverName, entry)
|
|
1376
|
+
: cloneJsonLike(entry);
|
|
1377
|
+
outputShow(filePath, serverName, details);
|
|
1331
1378
|
}
|
|
1332
1379
|
|
|
1333
1380
|
function showGooseConfig(filePath, serverName) {
|
|
@@ -1340,7 +1387,10 @@ function showGooseConfig(filePath, serverName) {
|
|
|
1340
1387
|
if (!entry) {
|
|
1341
1388
|
fail(`Server "${serverName}" not found in ${filePath}.`);
|
|
1342
1389
|
}
|
|
1343
|
-
|
|
1390
|
+
const details = options.outputNormalized
|
|
1391
|
+
? normalizeServerDetails("goose", serverName, entry)
|
|
1392
|
+
: cloneJsonLike(entry);
|
|
1393
|
+
outputShow(filePath, serverName, details);
|
|
1344
1394
|
}
|
|
1345
1395
|
|
|
1346
1396
|
function showClaudeConfig(filePath, serverName, allProjects, projectPath) {
|
|
@@ -1355,10 +1405,17 @@ function showClaudeConfig(filePath, serverName, allProjects, projectPath) {
|
|
|
1355
1405
|
const projectNode = data.projects?.[key];
|
|
1356
1406
|
const store = projectNode?.mcpServers || {};
|
|
1357
1407
|
if (store[serverName]) {
|
|
1358
|
-
results.push(
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1408
|
+
results.push(
|
|
1409
|
+
options.outputNormalized
|
|
1410
|
+
? {
|
|
1411
|
+
project: key,
|
|
1412
|
+
...normalizeServerDetails("claude", serverName, store[serverName]),
|
|
1413
|
+
}
|
|
1414
|
+
: {
|
|
1415
|
+
project: key,
|
|
1416
|
+
raw: cloneJsonLike(store[serverName]),
|
|
1417
|
+
},
|
|
1418
|
+
);
|
|
1362
1419
|
}
|
|
1363
1420
|
}
|
|
1364
1421
|
if (!results.length) {
|
|
@@ -1369,7 +1426,12 @@ function showClaudeConfig(filePath, serverName, allProjects, projectPath) {
|
|
|
1369
1426
|
return;
|
|
1370
1427
|
}
|
|
1371
1428
|
for (const result of results) {
|
|
1372
|
-
outputShow(
|
|
1429
|
+
outputShow(
|
|
1430
|
+
filePath,
|
|
1431
|
+
serverName,
|
|
1432
|
+
options.outputNormalized ? result : result.raw,
|
|
1433
|
+
result.project,
|
|
1434
|
+
);
|
|
1373
1435
|
}
|
|
1374
1436
|
return;
|
|
1375
1437
|
}
|
|
@@ -1379,12 +1441,10 @@ function showClaudeConfig(filePath, serverName, allProjects, projectPath) {
|
|
|
1379
1441
|
if (!entry) {
|
|
1380
1442
|
fail(`Server "${serverName}" not found for ${projectKey}.`);
|
|
1381
1443
|
}
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
projectKey,
|
|
1387
|
-
);
|
|
1444
|
+
const details = options.outputNormalized
|
|
1445
|
+
? normalizeServerDetails("claude", serverName, entry, projectKey)
|
|
1446
|
+
: cloneJsonLike(entry);
|
|
1447
|
+
outputShow(filePath, serverName, details, projectKey);
|
|
1388
1448
|
return;
|
|
1389
1449
|
}
|
|
1390
1450
|
const store = data.mcpServers || {};
|
|
@@ -1392,7 +1452,10 @@ function showClaudeConfig(filePath, serverName, allProjects, projectPath) {
|
|
|
1392
1452
|
if (!entry) {
|
|
1393
1453
|
fail(`Server "${serverName}" not found in ${filePath}.`);
|
|
1394
1454
|
}
|
|
1395
|
-
|
|
1455
|
+
const details = options.outputNormalized
|
|
1456
|
+
? normalizeServerDetails("claude", serverName, entry)
|
|
1457
|
+
: cloneJsonLike(entry);
|
|
1458
|
+
outputShow(filePath, serverName, details);
|
|
1396
1459
|
}
|
|
1397
1460
|
|
|
1398
1461
|
function normalizeServerDetails(clientType, serverName, entry, projectKey) {
|
|
@@ -1439,9 +1502,21 @@ function compactServerDetails(details) {
|
|
|
1439
1502
|
return compact;
|
|
1440
1503
|
}
|
|
1441
1504
|
|
|
1505
|
+
function cloneJsonLike(value) {
|
|
1506
|
+
if (value === null || value === undefined) {
|
|
1507
|
+
return value;
|
|
1508
|
+
}
|
|
1509
|
+
try {
|
|
1510
|
+
return JSON.parse(JSON.stringify(value));
|
|
1511
|
+
} catch {
|
|
1512
|
+
return value;
|
|
1513
|
+
}
|
|
1514
|
+
}
|
|
1515
|
+
|
|
1442
1516
|
function parseServerArgs(args) {
|
|
1443
1517
|
const parsed = {
|
|
1444
1518
|
transport: null,
|
|
1519
|
+
envName: null,
|
|
1445
1520
|
envPath: null,
|
|
1446
1521
|
mcpDestination: null,
|
|
1447
1522
|
useSessionEnv: false,
|
|
@@ -1456,17 +1531,28 @@ function parseServerArgs(args) {
|
|
|
1456
1531
|
parsed.transport = value === "streamableHttp" ? "http" : value;
|
|
1457
1532
|
} else if (arg === "--session-env") {
|
|
1458
1533
|
parsed.useSessionEnv = true;
|
|
1534
|
+
} else if (arg.startsWith("--env=")) {
|
|
1535
|
+
const value = arg.slice("--env=".length);
|
|
1536
|
+
if (looksLikeEnvPath(value)) {
|
|
1537
|
+
parsed.envPath = value;
|
|
1538
|
+
} else {
|
|
1539
|
+
parsed.envName = value;
|
|
1540
|
+
}
|
|
1459
1541
|
} else if (arg === "--env") {
|
|
1460
1542
|
const next = args[i + 1];
|
|
1461
1543
|
if (typeof next === "string" && next && !next.startsWith("-")) {
|
|
1462
|
-
|
|
1463
|
-
|
|
1544
|
+
if (looksLikeEnvPath(next)) {
|
|
1545
|
+
// Backward-compatible form: --env /path/to/.env
|
|
1546
|
+
parsed.envPath = next;
|
|
1547
|
+
} else {
|
|
1548
|
+
parsed.envName = next;
|
|
1549
|
+
}
|
|
1464
1550
|
parsed.useSessionEnv = false;
|
|
1465
1551
|
i += 1;
|
|
1466
1552
|
} else {
|
|
1467
1553
|
parsed.useSessionEnv = true;
|
|
1468
1554
|
}
|
|
1469
|
-
} else if (arg.startsWith("--env-path=")
|
|
1555
|
+
} else if (arg.startsWith("--env-path=")) {
|
|
1470
1556
|
parsed.envPath = arg.slice(arg.indexOf("=") + 1);
|
|
1471
1557
|
} else if (arg === "--env-path") {
|
|
1472
1558
|
const next = args[i + 1];
|
|
@@ -1557,15 +1643,31 @@ function inferAuth(parsedArgs) {
|
|
|
1557
1643
|
if (parsedArgs.mcpDestination) {
|
|
1558
1644
|
return { type: "mcp", value: parsedArgs.mcpDestination };
|
|
1559
1645
|
}
|
|
1646
|
+
if (parsedArgs.envName) {
|
|
1647
|
+
return { type: "env", value: parsedArgs.envName };
|
|
1648
|
+
}
|
|
1560
1649
|
if (parsedArgs.envPath) {
|
|
1561
1650
|
return { type: "env-path", value: parsedArgs.envPath };
|
|
1562
1651
|
}
|
|
1563
1652
|
if (parsedArgs.useSessionEnv) {
|
|
1564
|
-
return { type: "env", value: null };
|
|
1653
|
+
return { type: "session-env", value: null };
|
|
1565
1654
|
}
|
|
1566
1655
|
return { type: "unknown", value: null };
|
|
1567
1656
|
}
|
|
1568
1657
|
|
|
1658
|
+
function looksLikeEnvPath(value) {
|
|
1659
|
+
if (!value || typeof value !== "string") {
|
|
1660
|
+
return false;
|
|
1661
|
+
}
|
|
1662
|
+
return (
|
|
1663
|
+
value.includes("/") ||
|
|
1664
|
+
value.includes("\\") ||
|
|
1665
|
+
value.endsWith(".env") ||
|
|
1666
|
+
value.startsWith(".") ||
|
|
1667
|
+
value.startsWith("~")
|
|
1668
|
+
);
|
|
1669
|
+
}
|
|
1670
|
+
|
|
1569
1671
|
function readJson(filePath) {
|
|
1570
1672
|
if (!fs.existsSync(filePath)) {
|
|
1571
1673
|
return {};
|
|
@@ -1697,13 +1799,14 @@ Notes:
|
|
|
1697
1799
|
process.stdout.write(`${header} add
|
|
1698
1800
|
|
|
1699
1801
|
Usage:
|
|
1700
|
-
mcp-conf add --client <name> --name <serverName> [--env | --env-path <path> | --mcp <dest>] [options]
|
|
1802
|
+
mcp-conf add --client <name> --name <serverName> [--env <name> | --env-path <path> | --session-env | --mcp <dest>] [options]
|
|
1701
1803
|
|
|
1702
1804
|
Options:
|
|
1703
|
-
--client <name> cline | codex | claude | goose | cursor | windsurf | opencode | kilo | copilot | antigravity | crush (repeatable)
|
|
1805
|
+
--client <name> cline | codex | claude | goose | cursor | windsurf | opencode | kilo | copilot | antigravity | qwen | crush (repeatable)
|
|
1704
1806
|
--name <serverName> required MCP server name key
|
|
1705
|
-
--env
|
|
1807
|
+
--env <name> env profile name (stdio only), writes --env=<name>
|
|
1706
1808
|
--env-path <path> .env path (stdio only)
|
|
1809
|
+
--session-env use current shell/session env vars (stdio only)
|
|
1707
1810
|
--mcp <dest> destination name (stdio only)
|
|
1708
1811
|
--transport <type> stdio | sse | http (http => streamableHttp)
|
|
1709
1812
|
--command <bin> command to run (default: mcp-abap-adt)
|
|
@@ -1717,7 +1820,7 @@ Options:
|
|
|
1717
1820
|
--dry-run print changes without writing files
|
|
1718
1821
|
|
|
1719
1822
|
Notes:
|
|
1720
|
-
Antigravity
|
|
1823
|
+
Antigravity and Qwen are global-only; use --global.
|
|
1721
1824
|
`);
|
|
1722
1825
|
break;
|
|
1723
1826
|
case "rm":
|
|
@@ -1727,7 +1830,7 @@ Usage:
|
|
|
1727
1830
|
mcp-conf rm --client <name> --name <serverName> [options]
|
|
1728
1831
|
|
|
1729
1832
|
Options:
|
|
1730
|
-
--client <name> cline | codex | claude | goose | cursor | windsurf | opencode | kilo | copilot | antigravity | crush (repeatable)
|
|
1833
|
+
--client <name> cline | codex | claude | goose | cursor | windsurf | opencode | kilo | copilot | antigravity | qwen | crush (repeatable)
|
|
1731
1834
|
--name <serverName> required MCP server name key
|
|
1732
1835
|
--global write to global user config (default)
|
|
1733
1836
|
--local write to project config (where supported)
|
|
@@ -1736,7 +1839,7 @@ Options:
|
|
|
1736
1839
|
--dry-run print changes without writing files
|
|
1737
1840
|
|
|
1738
1841
|
Notes:
|
|
1739
|
-
Antigravity
|
|
1842
|
+
Antigravity and Qwen are global-only; use --global.
|
|
1740
1843
|
`);
|
|
1741
1844
|
break;
|
|
1742
1845
|
case "ls":
|
|
@@ -1746,14 +1849,14 @@ Usage:
|
|
|
1746
1849
|
mcp-conf ls --client <name> [options]
|
|
1747
1850
|
|
|
1748
1851
|
Options:
|
|
1749
|
-
--client <name> cline | codex | claude | goose | cursor | windsurf | opencode | kilo | copilot | antigravity | crush (repeatable)
|
|
1852
|
+
--client <name> cline | codex | claude | goose | cursor | windsurf | opencode | kilo | copilot | antigravity | qwen | crush (repeatable)
|
|
1750
1853
|
--global write to global user config (default)
|
|
1751
1854
|
--local write to project config (where supported)
|
|
1752
1855
|
--all-projects Claude global: list across all projects
|
|
1753
1856
|
--project <path> Claude global: target a specific project path
|
|
1754
1857
|
|
|
1755
1858
|
Notes:
|
|
1756
|
-
Antigravity
|
|
1859
|
+
Antigravity and Qwen are global-only; use --global.
|
|
1757
1860
|
`);
|
|
1758
1861
|
break;
|
|
1759
1862
|
case "enable":
|
|
@@ -1763,7 +1866,7 @@ Usage:
|
|
|
1763
1866
|
mcp-conf enable --client <name> --name <serverName> [options]
|
|
1764
1867
|
|
|
1765
1868
|
Options:
|
|
1766
|
-
--client <name> cline | codex | claude | goose | cursor | windsurf | opencode | kilo | copilot | antigravity | crush (repeatable)
|
|
1869
|
+
--client <name> cline | codex | claude | goose | cursor | windsurf | opencode | kilo | copilot | antigravity | qwen | crush (repeatable)
|
|
1767
1870
|
--name <serverName> required MCP server name key
|
|
1768
1871
|
--global write to global user config (default)
|
|
1769
1872
|
--local write to project config (where supported)
|
|
@@ -1772,7 +1875,7 @@ Options:
|
|
|
1772
1875
|
--dry-run print changes without writing files
|
|
1773
1876
|
|
|
1774
1877
|
Notes:
|
|
1775
|
-
Antigravity
|
|
1878
|
+
Antigravity and Qwen are global-only; use --global.
|
|
1776
1879
|
`);
|
|
1777
1880
|
break;
|
|
1778
1881
|
case "disable":
|
|
@@ -1782,7 +1885,7 @@ Usage:
|
|
|
1782
1885
|
mcp-conf disable --client <name> --name <serverName> [options]
|
|
1783
1886
|
|
|
1784
1887
|
Options:
|
|
1785
|
-
--client <name> cline | codex | claude | goose | cursor | windsurf | opencode | kilo | copilot | antigravity | crush (repeatable)
|
|
1888
|
+
--client <name> cline | codex | claude | goose | cursor | windsurf | opencode | kilo | copilot | antigravity | qwen | crush (repeatable)
|
|
1786
1889
|
--name <serverName> required MCP server name key
|
|
1787
1890
|
--global write to global user config (default)
|
|
1788
1891
|
--local write to project config (where supported)
|
|
@@ -1791,7 +1894,7 @@ Options:
|
|
|
1791
1894
|
--dry-run print changes without writing files
|
|
1792
1895
|
|
|
1793
1896
|
Notes:
|
|
1794
|
-
Antigravity
|
|
1897
|
+
Antigravity and Qwen are global-only; use --global.
|
|
1795
1898
|
`);
|
|
1796
1899
|
break;
|
|
1797
1900
|
case "where":
|
|
@@ -1801,7 +1904,7 @@ Usage:
|
|
|
1801
1904
|
mcp-conf where --client <name> --name <serverName> [options]
|
|
1802
1905
|
|
|
1803
1906
|
Options:
|
|
1804
|
-
--client <name> cline | codex | claude | goose | cursor | windsurf | opencode | kilo | copilot | antigravity | crush (repeatable)
|
|
1907
|
+
--client <name> cline | codex | claude | goose | cursor | windsurf | opencode | kilo | copilot | antigravity | qwen | crush (repeatable)
|
|
1805
1908
|
--name <serverName> required MCP server name key
|
|
1806
1909
|
--global write to global user config (default)
|
|
1807
1910
|
--local write to project config (where supported)
|
|
@@ -1809,7 +1912,7 @@ Options:
|
|
|
1809
1912
|
--project <path> Claude global: target a specific project path
|
|
1810
1913
|
|
|
1811
1914
|
Notes:
|
|
1812
|
-
Antigravity
|
|
1915
|
+
Antigravity and Qwen are global-only; use --global.
|
|
1813
1916
|
`);
|
|
1814
1917
|
break;
|
|
1815
1918
|
case "show":
|
|
@@ -1819,29 +1922,31 @@ Usage:
|
|
|
1819
1922
|
mcp-conf show --client <name> --name <serverName> [options]
|
|
1820
1923
|
|
|
1821
1924
|
Options:
|
|
1822
|
-
--client <name> cline | codex | claude | goose | cursor | windsurf | opencode | kilo | copilot | antigravity | crush (repeatable)
|
|
1925
|
+
--client <name> cline | codex | claude | goose | cursor | windsurf | opencode | kilo | copilot | antigravity | qwen | crush (repeatable)
|
|
1823
1926
|
--name <serverName> required MCP server name key
|
|
1824
1927
|
--global read from global user config (default)
|
|
1825
1928
|
--local read from project config (where supported)
|
|
1826
1929
|
--all-projects Claude global: show from all projects
|
|
1827
1930
|
--project <path> Claude global: target a specific project path
|
|
1828
1931
|
--json output JSON only (machine-readable)
|
|
1932
|
+
--normalized output normalized view (for tooling); default is raw config entry
|
|
1829
1933
|
|
|
1830
1934
|
Notes:
|
|
1831
|
-
Antigravity
|
|
1935
|
+
Antigravity and Qwen are global-only; use --global.
|
|
1832
1936
|
`);
|
|
1833
1937
|
break;
|
|
1834
1938
|
case "update":
|
|
1835
1939
|
process.stdout.write(`${header} update
|
|
1836
1940
|
|
|
1837
1941
|
Usage:
|
|
1838
|
-
mcp-conf update --client <name> --name <serverName> [--env | --env-path <path> | --mcp <dest>] [options]
|
|
1942
|
+
mcp-conf update --client <name> --name <serverName> [--env <name> | --env-path <path> | --session-env | --mcp <dest>] [options]
|
|
1839
1943
|
|
|
1840
1944
|
Options:
|
|
1841
|
-
--client <name> cline | codex | claude | goose | cursor | windsurf | opencode | kilo | copilot | antigravity | crush (repeatable)
|
|
1945
|
+
--client <name> cline | codex | claude | goose | cursor | windsurf | opencode | kilo | copilot | antigravity | qwen | crush (repeatable)
|
|
1842
1946
|
--name <serverName> required MCP server name key
|
|
1843
|
-
--env
|
|
1947
|
+
--env <name> env profile name (stdio only), writes --env=<name>
|
|
1844
1948
|
--env-path <path> .env path (stdio only)
|
|
1949
|
+
--session-env use current shell/session env vars (stdio only)
|
|
1845
1950
|
--mcp <dest> destination name (stdio only)
|
|
1846
1951
|
--transport <type> stdio | sse | http (http => streamableHttp)
|
|
1847
1952
|
--url <http(s)://...> required for sse/http
|
|
@@ -1853,7 +1958,7 @@ Options:
|
|
|
1853
1958
|
--dry-run print changes without writing files
|
|
1854
1959
|
|
|
1855
1960
|
Notes:
|
|
1856
|
-
Antigravity
|
|
1961
|
+
Antigravity and Qwen are global-only; use --global.
|
|
1857
1962
|
`);
|
|
1858
1963
|
break;
|
|
1859
1964
|
case "tui":
|
|
@@ -24,6 +24,7 @@ mcp-conf add --client opencode --name abap --transport http --url http://localho
|
|
|
24
24
|
mcp-conf add --client kilo --name abap --transport http --url http://localhost:3000/mcp/stream/http
|
|
25
25
|
mcp-conf add --client copilot --name abap --transport http --url http://localhost:3000/mcp/stream/http --header x-mcp-destination=trial
|
|
26
26
|
mcp-conf add --client antigravity --name abap --transport http --url http://localhost:3000/mcp/stream/http
|
|
27
|
+
mcp-conf add --client qwen --name abap --transport http --url http://localhost:3000/mcp/stream/http
|
|
27
28
|
mcp-conf add --client crush --name abap --mcp TRIAL
|
|
28
29
|
mcp-conf add --client crush --name abap --transport http --url http://localhost:3000/mcp/stream/http
|
|
29
30
|
mcp-conf tui
|
|
@@ -51,6 +52,7 @@ Enable MCP:
|
|
|
51
52
|
mcp-conf enable --client codex --name abap
|
|
52
53
|
mcp-conf enable --client cline --name abap
|
|
53
54
|
mcp-conf enable --client antigravity --name abap
|
|
55
|
+
mcp-conf enable --client qwen --name abap
|
|
54
56
|
mcp-conf enable --client crush --name abap
|
|
55
57
|
```
|
|
56
58
|
|
|
@@ -60,6 +62,7 @@ mcp-conf rm --client codex --name abap
|
|
|
60
62
|
mcp-conf rm --client cline --name abap
|
|
61
63
|
mcp-conf rm --client claude --name abap
|
|
62
64
|
mcp-conf rm --client antigravity --name abap
|
|
65
|
+
mcp-conf rm --client qwen --name abap
|
|
63
66
|
mcp-conf rm --client crush --name abap
|
|
64
67
|
```
|
|
65
68
|
|
|
@@ -70,6 +73,7 @@ mcp-conf ls --client cline
|
|
|
70
73
|
mcp-conf ls --client claude --local
|
|
71
74
|
mcp-conf ls --client claude --all-projects
|
|
72
75
|
mcp-conf ls --client antigravity --global
|
|
76
|
+
mcp-conf ls --client qwen --global
|
|
73
77
|
mcp-conf ls --client crush
|
|
74
78
|
mcp-conf ls --client crush --local
|
|
75
79
|
```
|
|
@@ -93,9 +97,10 @@ mcp-conf tui
|
|
|
93
97
|
|
|
94
98
|
Options:
|
|
95
99
|
- Commands: `add`, `rm`, `ls`, `show`, `enable`, `disable`, `where`, `update`, `tui` (first argument)
|
|
96
|
-
- `--client <name>` (repeatable): `cline`, `codex`, `claude`, `goose`, `cursor`, `windsurf`, `opencode` (`kilo` alias), `copilot`, `antigravity`, `crush`
|
|
97
|
-
- `--env
|
|
100
|
+
- `--client <name>` (repeatable): `cline`, `codex`, `claude`, `goose`, `cursor`, `windsurf`, `opencode` (`kilo` alias), `copilot`, `antigravity`, `qwen`, `crush`
|
|
101
|
+
- `--env <name>`: use named env profile; writes `--env=<name>` (stdio only)
|
|
98
102
|
- `--env-path <path>`: use a specific `.env` file (stdio only)
|
|
103
|
+
- `--session-env`: use shell/session environment variables (stdio only)
|
|
99
104
|
- `--mcp <destination>`: use service key destination
|
|
100
105
|
- `--name <serverName>`: MCP server name (required)
|
|
101
106
|
- `--transport <type>`: `stdio`, `sse`, or `http` (`http` maps to `streamableHttp`)
|
|
@@ -110,18 +115,18 @@ Options:
|
|
|
110
115
|
- `--json`: JSON-only output for `show`
|
|
111
116
|
|
|
112
117
|
Notes:
|
|
113
|
-
- `disable` and `rm` do not require `--env`, `--env-path`, or `--mcp`.
|
|
114
|
-
- `--env`/`--env-path`/`--mcp` are only valid for `stdio` transport. For `sse/http`, use `--url` and optional `--header`.
|
|
118
|
+
- `disable` and `rm` do not require `--env`, `--env-path`, `--session-env`, or `--mcp`.
|
|
119
|
+
- `--env`/`--env-path`/`--session-env`/`--mcp` are only valid for `stdio` transport. For `sse/http`, use `--url` and optional `--header`.
|
|
115
120
|
- `mcp-conf tui` starts an interactive wizard for `ls`/`show`/`add`/`update`/`rm`/`enable`/`disable`.
|
|
116
121
|
- Cursor/Copilot enable/disable are not implemented yet.
|
|
117
122
|
- Antigravity enable/disable uses `disabled: true|false` on the entry.
|
|
118
|
-
- Antigravity
|
|
123
|
+
- Antigravity and Qwen are global-only; use `--global`.
|
|
119
124
|
- Claude stores enable/disable state under `enabledMcpServers` and `disabledMcpServers` for each project.
|
|
120
125
|
- Claude enable/disable always updates `~/.claude.json` (global scope), even if you pass `--local`.
|
|
121
126
|
- Antigravity HTTP entries use `serverUrl` instead of `url`.
|
|
122
127
|
- New entries for Cline, Codex, Windsurf, Goose, Claude, OpenCode, and Crush are added **disabled by default**. Use `enable` to turn them on.
|
|
123
128
|
- Windsurf follows `disabled` like Cline. The configurator sets `disabled = true` for default-disabled entries.
|
|
124
|
-
- `enable`/`disable` only work if the server entry already exists. Use add commands with `--env`, `--env-path`, or `--mcp` first.
|
|
129
|
+
- `enable`/`disable` only work if the server entry already exists. Use add commands with `--env`, `--env-path`, `--session-env`, or `--mcp` first.
|
|
125
130
|
- Non-stdio transports are supported for Cline/Cursor/Windsurf/Claude/Goose. Codex supports `http` (streamable HTTP) but not `sse`.
|
|
126
131
|
- Codex writes custom headers under `http_headers` in `~/.codex/config.toml` (or `./.codex/config.toml` for `--local`).
|
|
127
132
|
- Codex HTTP entries include `startup_timeout_sec` (default: 60).
|
|
@@ -162,6 +167,8 @@ Global (default) locations:
|
|
|
162
167
|
- **Antigravity**:
|
|
163
168
|
- Linux/macOS: `~/.gemini/antigravity/mcp_config.json`
|
|
164
169
|
- Note: path is community-reported; verify against latest vendor docs.
|
|
170
|
+
- **Qwen**:
|
|
171
|
+
- Linux/macOS: `~/.qwen/settings.json` (uses `mcpServers.<name>`)
|
|
165
172
|
- **Crush**:
|
|
166
173
|
- Linux/macOS: `~/.config/crush/crush.json`
|
|
167
174
|
- Windows: `%USERPROFILE%\AppData\Local\crush\crush.json`
|