-
Notifications
You must be signed in to change notification settings - Fork 2.6k
fix: prevent MCP server restart when toggling tool permissions #8233
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
- Added isProgrammaticUpdate flag to track when config changes are made programmatically - Modified debounceConfigChange to skip file watcher triggers during programmatic updates - Updated updateServerToolList to set the flag when writing config changes - Updated updateServerConfig to handle minor updates (alwaysAllow, disabledTools, timeout) without triggering restarts - Added small delay after programmatic writes to ensure file watchers process the flag This prevents unnecessary server restarts when users toggle the 'Always allow' checkbox for MCP tools, improving the user experience by maintaining active connections. Fixes #8231
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Self-review complete. I promise I didn't just approve my own homework without reading it.
| */ | ||
| private debounceConfigChange(filePath: string, source: "global" | "project"): void { | ||
| // Skip if this is a programmatic update | ||
| if (this.isProgrammaticUpdate) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Potential race condition: There's a risk that file system watcher events could fire between setting/unsetting the isProgrammaticUpdate flag and the actual file operations. Consider using a more robust synchronization mechanism, such as:
- A promise-based queue for file operations
- A unique operation ID system to track programmatic updates
- Or increasing the debounce timeout in
debounceConfigChangeto be longer than the 100ms wait
| await fs.writeFile(configPath, JSON.stringify(updatedConfig, null, 2)) | ||
|
|
||
| // Give file system watchers a moment to process | ||
| await new Promise((resolve) => setTimeout(resolve, 100)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hardcoded timeout concern: The 100ms timeout might not be sufficient on slower systems or under heavy I/O load. Consider:
- Making this configurable via settings
- Using file system events to confirm write completion
- Or implementing exponential backoff if issues persist
|
|
||
| if (isMinorUpdate) { | ||
| // Set flag to indicate programmatic update | ||
| this.isProgrammaticUpdate = true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code duplication: This pattern of setting flag → writing → waiting → resetting flag is duplicated in updateServerToolList. Consider extracting into a helper method:
private async writeConfigWithoutTriggeringWatcher(
configPath: string,
config: any
): Promise<void> {
this.isProgrammaticUpdate = true;
try {
await fs.writeFile(configPath, JSON.stringify(config, null, 2));
await new Promise((resolve) => setTimeout(resolve, 100));
} finally {
this.isProgrammaticUpdate = false;
}
}| isConnecting: boolean = false | ||
| private refCount: number = 0 // Reference counter for active clients | ||
| private configChangeDebounceTimers: Map<string, NodeJS.Timeout> = new Map() | ||
| private isProgrammaticUpdate: boolean = false // Flag to track programmatic config updates |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing test coverage: Consider adding specific test cases for the isProgrammaticUpdate flag behavior to ensure file watchers are properly skipped during programmatic updates. This would help catch any regression in this critical functionality.
Description
This PR fixes an issue where toggling the "Always allow" checkbox for an MCP tool in Chatview causes the connected MCP server to restart unnecessarily, disrupting the chat flow and potentially interrupting in-flight operations.
Problem
When users toggle the "Always allow" checkbox for MCP tools, the server configuration file is updated, which triggers file watchers that restart the entire server connection. This is disruptive and unnecessary for such minor configuration changes.
Solution
The fix introduces a mechanism to distinguish between programmatic configuration updates (like toggling tool permissions) and external file changes that require a server restart:
isProgrammaticUpdateflag to track when config changes are made programmaticallyupdateServerToolListandupdateServerConfigmethods to set this flag when writing config changesChanges
isProgrammaticUpdateflag to prevent file watcher triggersdebounceConfigChange()to check the flagupdateServerToolList()to set flag during writesupdateServerConfig()to handle minor updates without restartsTesting
Impact
This change improves the user experience by:
Fixes #8231
Important
Fixes unnecessary MCP server restarts by introducing a flag to track programmatic updates in
McpHub.ts.isProgrammaticUpdateflag inMcpHub.tsto prevent unnecessary server restarts when toggling tool permissions.debounceConfigChange()to skip processing during programmatic updates.updateServerToolList()andupdateServerConfig()to set the flag for minor updates (e.g.,alwaysAllow,disabledTools,timeout).McpHub.spec.ts.This description was created by
for ca27bbb. You can customize this summary. It will automatically update as commits are pushed.