@fitchmultz/pi-mcp-adapter 8.0.5 → 8.0.7
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/CHANGELOG.md +140 -7
- package/OAUTH.md +13 -16
- package/README.md +8 -8
- package/cli.js +67 -28
- package/dist/abort.js +18 -9
- package/dist/client-operations.js +4 -2
- package/dist/commands.js +77 -43
- package/dist/config.js +194 -105
- package/dist/connection-runtime.d.ts +2 -2
- package/dist/connection-runtime.js +29 -18
- package/dist/consent-manager.d.ts +2 -2
- package/dist/consent-manager.js +5 -2
- package/dist/direct-tools.d.ts +1 -1
- package/dist/direct-tools.js +13 -7
- package/dist/elicitation-handler.d.ts +2 -3
- package/dist/elicitation-handler.js +113 -58
- package/dist/gateway-arguments.d.ts +1 -1
- package/dist/gateway-arguments.js +90 -23
- package/dist/glimpse-ui.js +10 -5
- package/dist/host-html-template.d.ts +3 -1
- package/dist/host-html-template.js +9 -12
- package/dist/index.d.ts +1 -1
- package/dist/index.js +264 -119
- package/dist/init.d.ts +1 -3
- package/dist/init.js +91 -51
- package/dist/legacy-migration.d.ts +1 -1
- package/dist/legacy-migration.js +17 -12
- package/dist/lifecycle.d.ts +3 -3
- package/dist/lifecycle.js +33 -17
- package/dist/logger.d.ts +2 -2
- package/dist/logger.js +4 -2
- package/dist/mcp-auth-flow.js +150 -58
- package/dist/mcp-auth.d.ts +7 -7
- package/dist/mcp-auth.js +189 -138
- package/dist/mcp-callback-server.js +19 -8
- package/dist/mcp-code.js +168 -54
- package/dist/mcp-keyring-helper.cjs +57 -23
- package/dist/mcp-oauth-provider.d.ts +6 -7
- package/dist/mcp-oauth-provider.js +146 -72
- package/dist/mcp-oauth-runtime.js +29 -16
- package/dist/mcp-output-guard.js +193 -65
- package/dist/mcp-output-preview.js +41 -20
- package/dist/mcp-panel.d.ts +9 -9
- package/dist/mcp-panel.js +141 -70
- package/dist/mcp-script-worker.mjs +135 -43
- package/dist/mcp-setup-panel.d.ts +8 -8
- package/dist/mcp-setup-panel.js +130 -44
- package/dist/mcp-status.js +14 -7
- package/dist/mcp-trace.d.ts +10 -5
- package/dist/mcp-trace.js +127 -61
- package/dist/metadata-cache.d.ts +3 -4
- package/dist/metadata-cache.js +83 -43
- package/dist/npx-resolver.js +101 -60
- package/dist/onboarding-state.js +4 -2
- package/dist/plain-result-reader.js +78 -31
- package/dist/prompts.js +36 -20
- package/dist/proxy-modes.js +670 -193
- package/dist/resource-tools.js +30 -9
- package/dist/runtime-owner.js +36 -18
- package/dist/sampling-handler.d.ts +1 -2
- package/dist/sampling-handler.js +41 -21
- package/dist/search-ranking.d.ts +1 -1
- package/dist/search-ranking.js +67 -34
- package/dist/server-manager.d.ts +11 -11
- package/dist/server-manager.js +283 -166
- package/dist/session-recovery.js +113 -61
- package/dist/tool-approval.js +9 -3
- package/dist/tool-loader.js +154 -55
- package/dist/tool-metadata.d.ts +1 -1
- package/dist/tool-metadata.js +51 -23
- package/dist/tool-registrar.js +32 -10
- package/dist/tool-result-renderer.d.ts +3 -3
- package/dist/tool-result-renderer.js +65 -44
- package/dist/types.d.ts +2 -2
- package/dist/types.js +39 -18
- package/dist/ui-message-history.js +33 -13
- package/dist/ui-resource-handler.d.ts +3 -3
- package/dist/ui-resource-handler.js +37 -21
- package/dist/ui-server.js +101 -43
- package/dist/ui-session.js +66 -29
- package/dist/ui-stream-types.js +14 -4
- package/dist/ui-tool-visibility.js +12 -6
- package/dist/unix-socket-transport.d.ts +1 -2
- package/dist/unix-socket-transport.js +19 -12
- package/dist/utils.d.ts +2 -0
- package/dist/utils.js +60 -35
- package/package.json +29 -5
- package/skills/mcp-scripting/SKILL.md +6 -6
package/dist/commands.js
CHANGED
|
@@ -1,18 +1,19 @@
|
|
|
1
|
-
import { isServerDisabled, isNonInteractiveOAuth } from "./types.js";
|
|
1
|
+
import { isServerDisabled, isNonInteractiveOAuth, } from "./types.js";
|
|
2
2
|
import { ensureCompatibilityImports, getMcpDiscoverySummary, getProjectConfigPath, getServerProvenance, previewCompatibilityImports, previewSharedServerEntry, previewStarterProjectConfig, writeDirectToolsConfig, writeSharedServerEntry, writeStarterProjectConfig, } from "./config.js";
|
|
3
|
-
import { MAX_CONCURRENT_SERVER_CONNECTS, markKeepAliveAfterConnect, notifyToolMetadataUpdated, updateMetadataCache, updateStatusBar, getFailureAgeSeconds, getFailureMessage, clearFailure, recordFailure } from "./init.js";
|
|
3
|
+
import { MAX_CONCURRENT_SERVER_CONNECTS, markKeepAliveAfterConnect, notifyToolMetadataUpdated, updateMetadataCache, updateStatusBar, getFailureAgeSeconds, getFailureMessage, clearFailure, recordFailure, } from "./init.js";
|
|
4
4
|
import { loadMetadataCache, reconstructPromptMetadata } from "./metadata-cache.js";
|
|
5
5
|
import { buildToolMetadata } from "./tool-metadata.js";
|
|
6
6
|
import { supportsOAuth } from "./mcp-oauth-runtime.js";
|
|
7
7
|
import { getAuthStorageOptions, inspectAuthForUrl } from "./mcp-auth.js";
|
|
8
|
-
import { loadOnboardingState, markSetupCompleted as persistSetupCompleted, markSharedConfigHintShown } from "./onboarding-state.js";
|
|
8
|
+
import { loadOnboardingState, markSetupCompleted as persistSetupCompleted, markSharedConfigHintShown, } from "./onboarding-state.js";
|
|
9
9
|
import { openPath, parallelLimit, resolveServerUrl, sanitizeTerminalText } from "./utils.js";
|
|
10
10
|
import { isAbortError } from "./runtime-owner.js";
|
|
11
11
|
import { createMcpPanel } from "./mcp-panel.js";
|
|
12
12
|
import { createMcpSetupPanel } from "./mcp-setup-panel.js";
|
|
13
13
|
export async function showStatus(state, ctx) {
|
|
14
|
-
if (!ctx.hasUI)
|
|
14
|
+
if (!ctx.hasUI) {
|
|
15
15
|
return;
|
|
16
|
+
}
|
|
16
17
|
const lines = ["MCP Server Status:", ""];
|
|
17
18
|
for (const name of Object.keys(state.config.mcpServers)) {
|
|
18
19
|
const definition = state.config.mcpServers[name];
|
|
@@ -22,8 +23,8 @@ export async function showStatus(state, ctx) {
|
|
|
22
23
|
}
|
|
23
24
|
const connection = state.manager.getConnection(name);
|
|
24
25
|
const metadata = state.toolMetadata.get(name);
|
|
25
|
-
const toolCount = metadata?.filter(tool => tool.resourceUri === undefined).length ?? 0;
|
|
26
|
-
const resourceCount = metadata?.filter(tool => tool.resourceUri !== undefined).length ?? 0;
|
|
26
|
+
const toolCount = metadata?.filter((tool) => tool.resourceUri === undefined).length ?? 0;
|
|
27
|
+
const resourceCount = metadata?.filter((tool) => tool.resourceUri !== undefined).length ?? 0;
|
|
27
28
|
const failedAgo = getFailureAgeSeconds(state, name);
|
|
28
29
|
let status = "not connected";
|
|
29
30
|
let statusIcon = "○";
|
|
@@ -45,9 +46,11 @@ export async function showStatus(state, ctx) {
|
|
|
45
46
|
else if (metadata !== undefined) {
|
|
46
47
|
status = "cached";
|
|
47
48
|
}
|
|
48
|
-
const toolSuffix = failed
|
|
49
|
-
? "
|
|
50
|
-
:
|
|
49
|
+
const toolSuffix = failed
|
|
50
|
+
? ""
|
|
51
|
+
: metadata === undefined
|
|
52
|
+
? " (undiscovered)"
|
|
53
|
+
: ` (${toolCount} tool${toolCount === 1 ? "" : "s"}, ${resourceCount} resource${resourceCount === 1 ? "" : "s"}${status === "cached" ? ", cached" : ""})`;
|
|
51
54
|
lines.push(`${statusIcon} ${name}: ${status}${toolSuffix}`);
|
|
52
55
|
}
|
|
53
56
|
if (Object.keys(state.config.mcpServers).length === 0) {
|
|
@@ -57,8 +60,9 @@ export async function showStatus(state, ctx) {
|
|
|
57
60
|
ctx.ui.notify(lines.join("\n"), "info");
|
|
58
61
|
}
|
|
59
62
|
export async function showPrompts(state, ctx) {
|
|
60
|
-
if (!ctx.hasUI)
|
|
63
|
+
if (!ctx.hasUI) {
|
|
61
64
|
return;
|
|
65
|
+
}
|
|
62
66
|
const allPrompts = [...(state.promptMetadata?.values() ?? [])].flat();
|
|
63
67
|
const failedPromptServers = [...(state.manager.getAllConnections?.() ?? [])]
|
|
64
68
|
.filter(([, connection]) => connection.status === "connected" && connection.promptDiscoveryFailed)
|
|
@@ -81,10 +85,13 @@ export async function showPrompts(state, ctx) {
|
|
|
81
85
|
for (const [serverName, prompts] of [...grouped.entries()].sort(([a], [b]) => a.localeCompare(b))) {
|
|
82
86
|
lines.push(`${serverName}:`);
|
|
83
87
|
for (const prompt of prompts.sort((a, b) => a.commandName.localeCompare(b.commandName))) {
|
|
84
|
-
const args = prompt.arguments
|
|
88
|
+
const args = prompt.arguments
|
|
89
|
+
.map((argument) => (argument.required ? `<${argument.name}>` : `[${argument.name}]`))
|
|
90
|
+
.join(" ");
|
|
85
91
|
lines.push(` /${prompt.commandName}${args ? ` ${args}` : ""}`);
|
|
86
|
-
if (prompt.description)
|
|
92
|
+
if (prompt.description) {
|
|
87
93
|
lines.push(` ${prompt.description}`);
|
|
94
|
+
}
|
|
88
95
|
}
|
|
89
96
|
lines.push("");
|
|
90
97
|
}
|
|
@@ -95,11 +102,12 @@ export async function showPrompts(state, ctx) {
|
|
|
95
102
|
ctx.ui.notify(lines.join("\n"), "info");
|
|
96
103
|
}
|
|
97
104
|
export async function showTools(state, ctx) {
|
|
98
|
-
if (!ctx.hasUI)
|
|
105
|
+
if (!ctx.hasUI) {
|
|
99
106
|
return;
|
|
107
|
+
}
|
|
100
108
|
const allTools = [...state.toolMetadata.entries()]
|
|
101
109
|
.filter(([serverName]) => !isServerDisabled(state.config.mcpServers[serverName]))
|
|
102
|
-
.flatMap(([, metadata]) => metadata.filter(tool => tool.resourceUri === undefined).map(tool => tool.name));
|
|
110
|
+
.flatMap(([, metadata]) => metadata.filter((tool) => tool.resourceUri === undefined).map((tool) => tool.name));
|
|
103
111
|
if (allTools.length === 0) {
|
|
104
112
|
ctx.ui.notify("No MCP tools discovered. Use mcp_search to discover tools.", "info");
|
|
105
113
|
return;
|
|
@@ -107,7 +115,7 @@ export async function showTools(state, ctx) {
|
|
|
107
115
|
const lines = [
|
|
108
116
|
"Discovered MCP Tools:",
|
|
109
117
|
"",
|
|
110
|
-
...allTools.map(t => ` ${t}`),
|
|
118
|
+
...allTools.map((t) => ` ${t}`),
|
|
111
119
|
"",
|
|
112
120
|
`Total: ${allTools.length} tool${allTools.length === 1 ? "" : "s"}`,
|
|
113
121
|
];
|
|
@@ -124,14 +132,16 @@ export async function reconnectServer(state, ctx, name, afterAuth = false) {
|
|
|
124
132
|
return false;
|
|
125
133
|
}
|
|
126
134
|
if (isServerDisabled(definition)) {
|
|
127
|
-
if (ui)
|
|
135
|
+
if (ui) {
|
|
128
136
|
ui.notify(`MCP: ${name} is disabled. Run /mcp enable ${name}, then /reload.`, "warning");
|
|
137
|
+
}
|
|
129
138
|
return false;
|
|
130
139
|
}
|
|
131
140
|
try {
|
|
132
141
|
const previous = afterAuth ? state.manager.getConnection(name) : undefined;
|
|
133
|
-
if (!afterAuth)
|
|
142
|
+
if (!afterAuth) {
|
|
134
143
|
await state.manager.close(name);
|
|
144
|
+
}
|
|
135
145
|
state.owner?.throwIfInactive();
|
|
136
146
|
const connection = previous
|
|
137
147
|
? await state.manager.reconnect(name, definition, previous, signal)
|
|
@@ -174,8 +184,9 @@ export async function reconnectServer(state, ctx, name, afterAuth = false) {
|
|
|
174
184
|
}
|
|
175
185
|
catch (error) {
|
|
176
186
|
const message = error instanceof Error ? error.message : String(error);
|
|
177
|
-
if (isAbortError(error, signal))
|
|
187
|
+
if (isAbortError(error, signal)) {
|
|
178
188
|
throw error;
|
|
189
|
+
}
|
|
179
190
|
recordFailure(state, name, message);
|
|
180
191
|
if (ui) {
|
|
181
192
|
ui.notify(`MCP: Failed to reconnect to ${name}: ${sanitizeTerminalText(message)}`, "error");
|
|
@@ -192,15 +203,16 @@ export async function reconnectServers(state, ctx, targetServer) {
|
|
|
192
203
|
return;
|
|
193
204
|
}
|
|
194
205
|
const names = targetServer ? [targetServer] : Object.keys(state.config.mcpServers);
|
|
195
|
-
await parallelLimit(names, MAX_CONCURRENT_SERVER_CONNECTS, name => reconnectServer(state, ctx, name));
|
|
206
|
+
await parallelLimit(names, MAX_CONCURRENT_SERVER_CONNECTS, (name) => reconnectServer(state, ctx, name));
|
|
196
207
|
updateStatusBar(state);
|
|
197
208
|
}
|
|
198
209
|
export async function authenticateServer(serverName, config, ctx, signal, runtime) {
|
|
199
210
|
const ui = ctx.hasUI ? ctx.ui : undefined;
|
|
200
211
|
const cwd = ctx.cwd;
|
|
201
212
|
signal ??= ctx.signal;
|
|
202
|
-
if (!ui)
|
|
213
|
+
if (!ui) {
|
|
203
214
|
return { ok: false, message: "OAuth authentication requires an interactive session." };
|
|
215
|
+
}
|
|
204
216
|
const definition = config.mcpServers[serverName];
|
|
205
217
|
if (!definition) {
|
|
206
218
|
const message = `Server "${serverName}" not found in config`;
|
|
@@ -237,8 +249,9 @@ export async function authenticateServer(serverName, config, ctx, signal, runtim
|
|
|
237
249
|
...(signal ? { signal } : {}),
|
|
238
250
|
...(runtime ? { runtime } : {}),
|
|
239
251
|
});
|
|
240
|
-
if (signal?.aborted)
|
|
252
|
+
if (signal?.aborted) {
|
|
241
253
|
signal.throwIfAborted();
|
|
254
|
+
}
|
|
242
255
|
if (status === "authenticated") {
|
|
243
256
|
const message = `OAuth authentication successful for "${serverName}".`;
|
|
244
257
|
ui.notify(message, "info");
|
|
@@ -249,15 +262,17 @@ export async function authenticateServer(serverName, config, ctx, signal, runtim
|
|
|
249
262
|
return { ok: false, message };
|
|
250
263
|
}
|
|
251
264
|
catch (error) {
|
|
252
|
-
if (signal?.aborted)
|
|
265
|
+
if (signal?.aborted) {
|
|
253
266
|
throw error;
|
|
267
|
+
}
|
|
254
268
|
const message = error instanceof Error ? error.message : String(error);
|
|
255
269
|
ui.notify(`Failed to authenticate "${serverName}": ${message}`, "error");
|
|
256
270
|
return { ok: false, message };
|
|
257
271
|
}
|
|
258
272
|
finally {
|
|
259
|
-
if (!signal?.aborted)
|
|
273
|
+
if (!signal?.aborted) {
|
|
260
274
|
ui.setStatus("mcp-auth", undefined);
|
|
275
|
+
}
|
|
261
276
|
}
|
|
262
277
|
}
|
|
263
278
|
export async function logoutServer(serverName, state, ctx) {
|
|
@@ -265,18 +280,24 @@ export async function logoutServer(serverName, state, ctx) {
|
|
|
265
280
|
const ui = ctx.hasUI ? ctx.ui : undefined;
|
|
266
281
|
if (!definition) {
|
|
267
282
|
const message = `Server "${serverName}" not found in config`;
|
|
268
|
-
if (ui)
|
|
283
|
+
if (ui) {
|
|
269
284
|
ui.notify(message, "error");
|
|
285
|
+
}
|
|
270
286
|
return { ok: false, message };
|
|
271
287
|
}
|
|
272
288
|
const signal = state.owner?.signal;
|
|
273
289
|
try {
|
|
274
290
|
const { removeAuth } = await import("./mcp-auth-flow.js");
|
|
275
|
-
await removeAuth(serverName, {
|
|
291
|
+
await removeAuth(serverName, {
|
|
292
|
+
authStorageOptions: state.authStorageOptions,
|
|
293
|
+
signal,
|
|
294
|
+
runtime: state.oauthRuntime,
|
|
295
|
+
});
|
|
276
296
|
}
|
|
277
297
|
catch (error) {
|
|
278
|
-
if (isAbortError(error, signal))
|
|
298
|
+
if (isAbortError(error, signal)) {
|
|
279
299
|
throw error;
|
|
300
|
+
}
|
|
280
301
|
const message = error instanceof Error ? error.message : String(error);
|
|
281
302
|
if (ui) {
|
|
282
303
|
ui.notify(`Failed to clear OAuth credentials for "${serverName}": ${sanitizeTerminalText(message)}`, "error");
|
|
@@ -288,8 +309,9 @@ export async function logoutServer(serverName, state, ctx) {
|
|
|
288
309
|
await state.manager.close(serverName);
|
|
289
310
|
}
|
|
290
311
|
catch (error) {
|
|
291
|
-
if (isAbortError(error, signal))
|
|
312
|
+
if (isAbortError(error, signal)) {
|
|
292
313
|
throw error;
|
|
314
|
+
}
|
|
293
315
|
const message = error instanceof Error ? error.message : String(error);
|
|
294
316
|
if (ui) {
|
|
295
317
|
ui.notify(`OAuth credentials were cleared for "${serverName}", but its connection could not be closed: ${sanitizeTerminalText(message)}`, "error");
|
|
@@ -299,15 +321,17 @@ export async function logoutServer(serverName, state, ctx) {
|
|
|
299
321
|
state.owner?.throwIfInactive();
|
|
300
322
|
updateStatusBar(state);
|
|
301
323
|
const message = `OAuth credentials cleared for "${serverName}". Run /mcp-auth ${serverName} to authenticate again.`;
|
|
302
|
-
if (ui)
|
|
324
|
+
if (ui) {
|
|
303
325
|
ui.notify(message, "info");
|
|
326
|
+
}
|
|
304
327
|
return { ok: true, message };
|
|
305
328
|
}
|
|
306
329
|
function buildSharedConfigNoticeLines(configOverridePath, cwd) {
|
|
307
330
|
const discovery = getMcpDiscoverySummary(configOverridePath, cwd);
|
|
308
331
|
const onboardingState = loadOnboardingState();
|
|
309
|
-
if (!discovery.hasSharedServers || onboardingState.sharedConfigHintShown)
|
|
332
|
+
if (!discovery.hasSharedServers || onboardingState.sharedConfigHintShown) {
|
|
310
333
|
return [];
|
|
334
|
+
}
|
|
311
335
|
const sharedSources = discovery.sources.filter((source) => source.kind === "shared" && source.serverCount > 0);
|
|
312
336
|
const sourceList = sharedSources.map((source) => source.path).join(", ");
|
|
313
337
|
return [
|
|
@@ -316,8 +340,9 @@ function buildSharedConfigNoticeLines(configOverridePath, cwd) {
|
|
|
316
340
|
];
|
|
317
341
|
}
|
|
318
342
|
export async function openMcpSetup(state, pi, ctx, configOverridePath, mode = "setup") {
|
|
319
|
-
if (!ctx.hasUI)
|
|
343
|
+
if (!ctx.hasUI) {
|
|
320
344
|
return { configChanged: false };
|
|
345
|
+
}
|
|
321
346
|
if (!ctx.isProjectTrusted()) {
|
|
322
347
|
ctx.ui.notify("Project MCP setup is unavailable until this project is trusted.", "warning");
|
|
323
348
|
return { configChanged: false };
|
|
@@ -338,15 +363,17 @@ export async function openMcpSetup(state, pi, ctx, configOverridePath, mode = "s
|
|
|
338
363
|
previewStarterProject: () => previewStarterProjectConfig(ctx.cwd),
|
|
339
364
|
previewRepoPrompt: () => {
|
|
340
365
|
const repoPrompt = getMcpDiscoverySummary(configOverridePath, ctx.cwd).repoPrompt;
|
|
341
|
-
if (!repoPrompt.entry || !repoPrompt.targetPath || !repoPrompt.serverName)
|
|
366
|
+
if (!repoPrompt.entry || !repoPrompt.targetPath || !repoPrompt.serverName) {
|
|
342
367
|
return null;
|
|
368
|
+
}
|
|
343
369
|
return previewSharedServerEntry(repoPrompt.targetPath, repoPrompt.serverName, repoPrompt.entry);
|
|
344
370
|
},
|
|
345
371
|
previewKnownServer: (preset) => previewSharedServerEntry(getProjectConfigPath(ctx.cwd), preset.id, preset.entry),
|
|
346
372
|
adoptImports: async (imports) => {
|
|
347
373
|
const result = ensureCompatibilityImports(imports, configOverridePath);
|
|
348
|
-
if (result.added.length > 0)
|
|
374
|
+
if (result.added.length > 0) {
|
|
349
375
|
configChanged = true;
|
|
376
|
+
}
|
|
350
377
|
return result;
|
|
351
378
|
},
|
|
352
379
|
scaffoldProjectConfig: async () => {
|
|
@@ -397,8 +424,9 @@ function buildMcpPanelCallbacks(state, config, ctx) {
|
|
|
397
424
|
getConnectionStatus: (serverName) => {
|
|
398
425
|
authStatusFailures.delete(serverName);
|
|
399
426
|
const definition = config.mcpServers[serverName];
|
|
400
|
-
if (isServerDisabled(definition))
|
|
427
|
+
if (isServerDisabled(definition)) {
|
|
401
428
|
return "disabled";
|
|
429
|
+
}
|
|
402
430
|
const connection = state.manager.getConnection(serverName);
|
|
403
431
|
let serverUrl;
|
|
404
432
|
try {
|
|
@@ -407,10 +435,10 @@ function buildMcpPanelCallbacks(state, config, ctx) {
|
|
|
407
435
|
catch {
|
|
408
436
|
return "failed";
|
|
409
437
|
}
|
|
410
|
-
if (definition?.auth === "oauth"
|
|
411
|
-
&&
|
|
412
|
-
|
|
413
|
-
|
|
438
|
+
if (definition?.auth === "oauth" &&
|
|
439
|
+
serverUrl &&
|
|
440
|
+
definition.oauth !== false &&
|
|
441
|
+
!isNonInteractiveOAuth(definition.oauth)) {
|
|
414
442
|
const authStatus = inspectAuthForUrl(serverName, serverUrl, state.authStorageOptions);
|
|
415
443
|
if (authStatus.status === "unavailable") {
|
|
416
444
|
authStatusFailures.set(serverName, authStatus.message);
|
|
@@ -420,12 +448,15 @@ function buildMcpPanelCallbacks(state, config, ctx) {
|
|
|
420
448
|
return "needs-auth";
|
|
421
449
|
}
|
|
422
450
|
}
|
|
423
|
-
if (connection?.status === "needs-auth")
|
|
451
|
+
if (connection?.status === "needs-auth") {
|
|
424
452
|
return "needs-auth";
|
|
425
|
-
|
|
453
|
+
}
|
|
454
|
+
if (connection?.status === "connected") {
|
|
426
455
|
return "connected";
|
|
427
|
-
|
|
456
|
+
}
|
|
457
|
+
if (getFailureAgeSeconds(state, serverName) !== null) {
|
|
428
458
|
return "failed";
|
|
459
|
+
}
|
|
429
460
|
return "idle";
|
|
430
461
|
},
|
|
431
462
|
getFailureMessage: (serverName) => authStatusFailures.get(serverName) ?? getFailureMessage(state, serverName),
|
|
@@ -437,8 +468,9 @@ function buildMcpPanelCallbacks(state, config, ctx) {
|
|
|
437
468
|
}
|
|
438
469
|
export async function openMcpPanel(state, pi, ctx, configOverridePath, onDirectToolsConfigChanged) {
|
|
439
470
|
if (!ctx.isProjectTrusted() || ctx.mode !== "tui") {
|
|
440
|
-
if (ctx.hasUI)
|
|
471
|
+
if (ctx.hasUI) {
|
|
441
472
|
await showStatus(state, ctx);
|
|
473
|
+
}
|
|
442
474
|
return { configChanged: false };
|
|
443
475
|
}
|
|
444
476
|
if (state.programmaticConfig) {
|
|
@@ -479,13 +511,15 @@ export async function openMcpPanel(state, pi, ctx, configOverridePath, onDirectT
|
|
|
479
511
|
}, { noticeLines, keybindings });
|
|
480
512
|
}, { overlay: true, overlayOptions: { anchor: "center", width: 82 } });
|
|
481
513
|
});
|
|
482
|
-
if (noticeLines.length > 0)
|
|
514
|
+
if (noticeLines.length > 0) {
|
|
483
515
|
markSharedConfigHintShown();
|
|
516
|
+
}
|
|
484
517
|
return { configChanged };
|
|
485
518
|
}
|
|
486
519
|
export async function openMcpAuthPanel(state, ctx, configOverridePath) {
|
|
487
|
-
if (!ctx.hasUI)
|
|
520
|
+
if (!ctx.hasUI) {
|
|
488
521
|
return { configChanged: false };
|
|
522
|
+
}
|
|
489
523
|
if (!ctx.isProjectTrusted()) {
|
|
490
524
|
ctx.ui.notify("Use /mcp-auth <server> while this project is untrusted.", "info");
|
|
491
525
|
return { configChanged: false };
|