fix(coding-agent): reload MCP servers on /reload-plugins

/reload-plugins documents MCP in its reload scope but the TUI handler only
reset skill/command/capability caches and never reconnected MCP servers or
refreshed the session MCP tool registry, so .mcp.json edits stayed inactive
until process restart.

Route the TUI reload pipeline through a shared reloadTuiPluginState() helper
that also runs the disconnect/rediscover/refreshMCPTools path used by
/mcp reload, exposed as MCPCommandController.reloadServers().

Fixes #7189
This commit is contained in:
roboomp
2026-07-31 16:33:28 +00:00
parent 4df68d6043
commit c7fb9140fb
4 changed files with 103 additions and 23 deletions
@@ -1228,7 +1228,7 @@ export class MCPCommandController {
await addMCPServer(filePath, name, config);
// Reload MCP manager
await this.#reloadMCP();
await this.reloadServers();
const state =
config.enabled === false
? "disconnected"
@@ -1486,7 +1486,7 @@ export class MCPCommandController {
await removeMCPServer(filePath, name);
// Reload MCP manager
await this.#reloadMCP();
await this.reloadServers();
this.#showMessage(["", theme.fg("success", `- Removed server "${name}" from ${scope} config`), ""].join("\n"));
} catch (error) {
@@ -1736,7 +1736,7 @@ export class MCPCommandController {
);
return;
}
await this.#reloadMCP();
await this.reloadServers();
this.#showMessage(
["", theme.fg("success", `- Cleared auth for "${name}" (${found.scope} config)`), ""].join("\n"),
);
@@ -1745,7 +1745,7 @@ export class MCPCommandController {
const updated = this.#stripOAuthAuth(found.config);
await updateMCPServer(found.filePath, name, updated);
await this.#reloadMCP();
await this.reloadServers();
this.#showMessage(
["", theme.fg("success", `- Cleared auth for "${name}" (${found.scope} config)`), ""].join("\n"),
@@ -1856,7 +1856,7 @@ export class MCPCommandController {
await updateMCPServer(found.filePath, name, updatedConfig);
}
if (options.reload !== false) {
await this.#reloadMCP();
await this.reloadServers();
const state = await this.#waitForServerConnectionWithAnimation(name);
const lines = [
@@ -1891,7 +1891,7 @@ export class MCPCommandController {
async #handleReload(): Promise<void> {
try {
this.#showMessage(["", theme.fg("muted", "Reloading MCP servers and runtime tools..."), ""].join("\n"));
await this.#reloadMCP();
await this.reloadServers();
const connectedCount = this.ctx.mcpManager?.getConnectedServers().length ?? 0;
this.#showMessage(
[
@@ -1979,9 +1979,14 @@ export class MCPCommandController {
}
/**
* Reload MCP manager with new configs
* Reconnect every configured MCP server and rebind the session's MCP tools.
*
* Disconnects all live connections, rediscovers `.mcp.json` configs, and
* calls `session.refreshMCPTools(...)` so config edits take effect without a
* restart. Public because `/reload-plugins` reuses it alongside `/mcp reload`
* and the config-mutation flows in this controller.
*/
async #reloadMCP(): Promise<void> {
async reloadServers(): Promise<void> {
if (!this.ctx.mcpManager) {
return;
}