mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-09-07 08:26:51 +00:00
Merge pull request #1056 from hannesrudolph/add-delete-mcp-button
Added MCP server deletion with confirmation dialog
This commit is contained in:
commit
39173711ce
4 changed files with 107 additions and 0 deletions
|
|
@ -941,6 +941,22 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
|||
}
|
||||
break
|
||||
}
|
||||
case "deleteMcpServer": {
|
||||
if (!message.serverName) {
|
||||
break
|
||||
}
|
||||
|
||||
try {
|
||||
this.outputChannel.appendLine(`Attempting to delete MCP server: ${message.serverName}`)
|
||||
await this.mcpHub?.deleteServer(message.serverName)
|
||||
this.outputChannel.appendLine(`Successfully deleted MCP server: ${message.serverName}`)
|
||||
} catch (error) {
|
||||
const errorMessage = error instanceof Error ? error.message : String(error)
|
||||
this.outputChannel.appendLine(`Failed to delete MCP server: ${errorMessage}`)
|
||||
// Error messages are already handled by McpHub.deleteServer
|
||||
}
|
||||
break
|
||||
}
|
||||
case "restartMcpServer": {
|
||||
try {
|
||||
await this.mcpHub?.restartConnection(message.text!)
|
||||
|
|
|
|||
|
|
@ -576,6 +576,59 @@ export class McpHub {
|
|||
}
|
||||
}
|
||||
|
||||
public async deleteServer(serverName: string): Promise<void> {
|
||||
try {
|
||||
const settingsPath = await this.getMcpSettingsFilePath()
|
||||
|
||||
// Ensure the settings file exists and is accessible
|
||||
try {
|
||||
await fs.access(settingsPath)
|
||||
} catch (error) {
|
||||
throw new Error("Settings file not accessible")
|
||||
}
|
||||
|
||||
const content = await fs.readFile(settingsPath, "utf-8")
|
||||
const config = JSON.parse(content)
|
||||
|
||||
// Validate the config structure
|
||||
if (!config || typeof config !== "object") {
|
||||
throw new Error("Invalid config structure")
|
||||
}
|
||||
|
||||
if (!config.mcpServers || typeof config.mcpServers !== "object") {
|
||||
config.mcpServers = {}
|
||||
}
|
||||
|
||||
// Remove the server from the settings
|
||||
if (config.mcpServers[serverName]) {
|
||||
delete config.mcpServers[serverName]
|
||||
|
||||
// Write the entire config back
|
||||
const updatedConfig = {
|
||||
mcpServers: config.mcpServers,
|
||||
}
|
||||
|
||||
await fs.writeFile(settingsPath, JSON.stringify(updatedConfig, null, 2))
|
||||
|
||||
// Update server connections
|
||||
await this.updateServerConnections(config.mcpServers)
|
||||
|
||||
vscode.window.showInformationMessage(`Deleted MCP server: ${serverName}`)
|
||||
} else {
|
||||
vscode.window.showWarningMessage(`Server "${serverName}" not found in configuration`)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Failed to delete MCP server:", error)
|
||||
if (error instanceof Error) {
|
||||
console.error("Error details:", error.message, error.stack)
|
||||
}
|
||||
vscode.window.showErrorMessage(
|
||||
`Failed to delete MCP server: ${error instanceof Error ? error.message : String(error)}`,
|
||||
)
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
async readResource(serverName: string, uri: string): Promise<McpResourceResponse> {
|
||||
const connection = this.connections.find((conn) => conn.server.name === serverName)
|
||||
if (!connection) {
|
||||
|
|
|
|||
|
|
@ -93,6 +93,7 @@ export interface WebviewMessage {
|
|||
| "openCustomModesSettings"
|
||||
| "checkpointDiff"
|
||||
| "checkpointRestore"
|
||||
| "deleteMcpServer"
|
||||
| "maxOpenTabsContext"
|
||||
text?: string
|
||||
disabled?: boolean
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import { McpServer } from "../../../../src/shared/mcp"
|
|||
import McpToolRow from "./McpToolRow"
|
||||
import McpResourceRow from "./McpResourceRow"
|
||||
import McpEnabledToggle from "./McpEnabledToggle"
|
||||
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter } from "../ui/dialog"
|
||||
|
||||
type McpViewProps = {
|
||||
onDone: () => void
|
||||
|
|
@ -129,6 +130,7 @@ const McpView = ({ onDone }: McpViewProps) => {
|
|||
// Server Row Component
|
||||
const ServerRow = ({ server, alwaysAllowMcp }: { server: McpServer; alwaysAllowMcp?: boolean }) => {
|
||||
const [isExpanded, setIsExpanded] = useState(false)
|
||||
const [showDeleteConfirm, setShowDeleteConfirm] = useState(false)
|
||||
const [timeoutValue, setTimeoutValue] = useState(() => {
|
||||
const configTimeout = JSON.parse(server.config)?.timeout
|
||||
return configTimeout ?? 60 // Default 1 minute (60 seconds)
|
||||
|
|
@ -179,6 +181,14 @@ const ServerRow = ({ server, alwaysAllowMcp }: { server: McpServer; alwaysAllowM
|
|||
})
|
||||
}
|
||||
|
||||
const handleDelete = () => {
|
||||
vscode.postMessage({
|
||||
type: "deleteMcpServer",
|
||||
serverName: server.name,
|
||||
})
|
||||
setShowDeleteConfirm(false)
|
||||
}
|
||||
|
||||
return (
|
||||
<div style={{ marginBottom: "10px" }}>
|
||||
<div
|
||||
|
|
@ -202,6 +212,12 @@ const ServerRow = ({ server, alwaysAllowMcp }: { server: McpServer; alwaysAllowM
|
|||
<div
|
||||
style={{ display: "flex", alignItems: "center", marginRight: "8px" }}
|
||||
onClick={(e) => e.stopPropagation()}>
|
||||
<VSCodeButton
|
||||
appearance="icon"
|
||||
onClick={() => setShowDeleteConfirm(true)}
|
||||
style={{ marginRight: "8px" }}>
|
||||
<span className="codicon codicon-trash" style={{ fontSize: "14px" }}></span>
|
||||
</VSCodeButton>
|
||||
<VSCodeButton
|
||||
appearance="icon"
|
||||
onClick={handleRestart}
|
||||
|
|
@ -393,6 +409,27 @@ const ServerRow = ({ server, alwaysAllowMcp }: { server: McpServer; alwaysAllowM
|
|||
</div>
|
||||
)
|
||||
)}
|
||||
|
||||
{/* Delete Confirmation Dialog */}
|
||||
<Dialog open={showDeleteConfirm} onOpenChange={setShowDeleteConfirm}>
|
||||
<DialogContent>
|
||||
<DialogHeader>
|
||||
<DialogTitle>Delete MCP Server</DialogTitle>
|
||||
<DialogDescription>
|
||||
Are you sure you want to delete the MCP server "{server.name}"? This action cannot be
|
||||
undone.
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
<DialogFooter>
|
||||
<VSCodeButton appearance="secondary" onClick={() => setShowDeleteConfirm(false)}>
|
||||
Cancel
|
||||
</VSCodeButton>
|
||||
<VSCodeButton appearance="primary" onClick={handleDelete}>
|
||||
Delete
|
||||
</VSCodeButton>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue