Skip to content

Commit 40025e4

Browse files
committed
feat(mcp): 实时更新和展示 MCP 服务器状态
- 新增 MCP 状态变更回调,支持 UI 实时刷新显示 - MCP 管理器中添加状态变更事件处理机制 - 调整 UI 组件以支持状态计数的高亮显示 - 移除 MCP 初始化失败的控制台错误输出,避免信息泄露 - 优化退出命令行提示颜色为灰色,提升可读性
1 parent 91e5240 commit 40025e4

4 files changed

Lines changed: 38 additions & 10 deletions

File tree

src/mcp/mcp-manager.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ export class McpManager {
4545
private configuredServerNames: string[] = [];
4646
private serverStatuses: McpServerStatus[] = [];
4747
private onToolsListChanged: (() => void) | null = null;
48+
private onStatusChanged: (() => void) | null = null;
4849

4950
prepare(servers?: Record<string, McpServerConfig>): void {
5051
if (!servers || Object.keys(servers).length === 0) return;
@@ -172,7 +173,8 @@ export class McpManager {
172173
if (this.disposed) break;
173174
client?.disconnect();
174175
const message = err instanceof Error ? err.message : String(err);
175-
process.stderr.write(`[deepcode] MCP server "${name}" failed to initialize: ${message}\n`);
176+
// 不在控制台输出错误日志,避免暴露敏感信息
177+
// process.stderr.write(`[deepcode] MCP server "${name}" failed to initialize: ${message}\n`);
176178
this.setStatus({
177179
name,
178180
status: "failed",
@@ -376,13 +378,19 @@ export class McpManager {
376378
this.onToolsListChanged = handler;
377379
}
378380

381+
setOnStatusChanged(handler: () => void): void {
382+
this.onStatusChanged = handler;
383+
}
384+
379385
private setStatus(status: McpServerStatus): void {
380386
if (this.disposed) return;
381387
const index = this.serverStatuses.findIndex((s) => s.name === status.name);
382388
if (index === -1) {
383389
this.serverStatuses.push(status);
384-
return;
390+
} else {
391+
this.serverStatuses[index] = status;
385392
}
386-
this.serverStatuses[index] = status;
393+
// 触发状态变更回调
394+
this.onStatusChanged?.();
387395
}
388396
}

src/session.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ type SessionManagerOptions = {
166166
onAssistantMessage: (message: SessionMessage, shouldConnect: boolean) => void;
167167
onSessionEntryUpdated?: (entry: SessionEntry) => void;
168168
onLlmStreamProgress?: (progress: LlmStreamProgress) => void;
169+
onMcpStatusChanged?: () => void;
169170
};
170171

171172
export type LlmStreamProgress = {
@@ -184,6 +185,7 @@ export class SessionManager {
184185
private readonly onAssistantMessage: (message: SessionMessage, shouldConnect: boolean) => void;
185186
private readonly onSessionEntryUpdated?: (entry: SessionEntry) => void;
186187
private readonly onLlmStreamProgress?: (progress: LlmStreamProgress) => void;
188+
private readonly onMcpStatusChanged?: () => void;
187189
private activeSessionId: string | null = null;
188190
private activePromptController: AbortController | null = null;
189191
private readonly sessionControllers = new Map<string, AbortController>();
@@ -198,6 +200,7 @@ export class SessionManager {
198200
this.onAssistantMessage = options.onAssistantMessage;
199201
this.onSessionEntryUpdated = options.onSessionEntryUpdated;
200202
this.onLlmStreamProgress = options.onLlmStreamProgress;
203+
this.onMcpStatusChanged = options.onMcpStatusChanged;
201204
this.toolExecutor = new ToolExecutor(this.projectRoot, this.createOpenAIClient, this.mcpManager);
202205
this.mcpManager.prepare(this.getResolvedSettings().mcpServers);
203206
}
@@ -206,6 +209,10 @@ export class SessionManager {
206209
this.mcpManager.setOnToolsListChanged(() => {
207210
this.mcpToolDefinitions = this.mcpManager.getMcpToolDefinitions();
208211
});
212+
// 设置状态变更回调,通知 UI 更新
213+
this.mcpManager.setOnStatusChanged(() => {
214+
this.onMcpStatusChanged?.();
215+
});
209216
await this.mcpManager.initialize(servers);
210217
this.mcpToolDefinitions = this.mcpManager.getMcpToolDefinitions();
211218
}

src/ui/App.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,10 @@ export function App({ projectRoot, version = "", onRestart }: AppProps): React.R
9494
}
9595
setStreamProgress(progress);
9696
},
97+
onMcpStatusChanged: () => {
98+
// 当 MCP 状态变更时,如果当前正在查看 MCP 状态页面,则更新显示
99+
setMcpStatuses(sessionManager.getMcpStatus());
100+
},
97101
});
98102
}, [projectRoot]);
99103

@@ -156,7 +160,7 @@ export function App({ projectRoot, version = "", onRestart }: AppProps): React.R
156160
const resolved = resolveCurrentSettings(projectRoot);
157161
const summary = buildExitSummaryText({ session, messages: allMessages, model: resolved.model });
158162
process.stdout.write("\n");
159-
process.stdout.write(chalk.green("> /exit "));
163+
process.stdout.write(chalk.rgb(128, 128, 128)("> /exit "));
160164
process.stdout.write("\n\n");
161165
process.stdout.write(summary);
162166
process.stdout.write("\n\n");

src/ui/McpStatusList.tsx

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -131,14 +131,23 @@ export function McpStatusList({ statuses, onCancel }: Props): React.ReactElement
131131
>
132132
<Box flexDirection="column" borderStyle="round" borderDimColor flexGrow={1} overflow="hidden">
133133
{/* Header row */}
134-
<Box paddingX={1}>
135-
<Text bold color="cyanBright">
136-
MCP Server Status
137-
</Text>
134+
<Box paddingX={1} gap={1}>
138135
<Text bold color="#229ac3">
139-
{" "}
140-
({readyCount} ready, {startingCount} starting, {failedCount} failed)
136+
Manage MCP servers
141137
</Text>
138+
<Box gap={1}>
139+
<Text dimColor>(</Text>
140+
<Text color="green" bold>
141+
{readyCount} ready,
142+
</Text>
143+
<Text color="yellow" bold>
144+
{startingCount} starting,
145+
</Text>
146+
<Text color="red" bold>
147+
{failedCount} failed
148+
</Text>
149+
<Text dimColor>)</Text>
150+
</Box>
142151
</Box>
143152
{/* Items list */}
144153
<Box

0 commit comments

Comments
 (0)