Add delete button to MCP server

This commit is contained in:
Saoud Rizwan 2025-02-19 18:02:20 -08:00
parent a925e672ed
commit 26be9469c4
5 changed files with 85 additions and 0 deletions

View file

@ -791,6 +791,12 @@ export class ClineProvider implements vscode.WebviewViewProvider {
}
break
}
case "deleteMcpServer": {
if (message.serverName) {
this.mcpHub?.deleteServer(message.serverName)
}
break
}
case "fetchLatestMcpServersFromHub": {
this.mcpHub?.sendLatestMcpServers()
break

View file

@ -636,6 +636,33 @@ export class McpHub {
}
}
public async deleteServer(serverName: string) {
try {
const settingsPath = await this.getMcpSettingsFilePath()
const content = await fs.readFile(settingsPath, "utf-8")
const config = JSON.parse(content)
if (!config.mcpServers || typeof config.mcpServers !== "object") {
config.mcpServers = {}
}
if (config.mcpServers[serverName]) {
delete config.mcpServers[serverName]
const updatedConfig = {
mcpServers: config.mcpServers,
}
await fs.writeFile(settingsPath, JSON.stringify(updatedConfig, null, 2))
await this.updateServerConnections(config.mcpServers)
vscode.window.showInformationMessage(`Deleted ${serverName} MCP server`)
} else {
vscode.window.showWarningMessage(`${serverName} not found in MCP configuration`)
}
} catch (error) {
vscode.window.showErrorMessage(
`Failed to delete MCP server: ${error instanceof Error ? error.message : String(error)}`,
)
throw error
}
}
async dispose(): Promise<void> {
this.removeAllFileWatchers()
for (const connection of this.connections) {

View file

@ -29,6 +29,7 @@ export interface WebviewMessage {
| "refreshOpenAiModels"
| "openMcpSettings"
| "restartMcpServer"
| "deleteMcpServer"
| "autoApprovalSettings"
| "browserSettings"
| "togglePlanActMode"

View file

@ -0,0 +1,30 @@
import { VSCodeButton } from "@vscode/webview-ui-toolkit/react"
import styled from "styled-components"
const StyledButton = styled(VSCodeButton)`
--danger-button-bg: #c42b2b;
--danger-button-hover: #a82424;
--danger-button-active: #8f1f1f;
background-color: var(--danger-button-bg) !important;
border-color: var(--danger-button-bg) !important;
color: #ffffff !important;
&:hover {
background-color: var(--danger-button-hover) !important;
border-color: var(--danger-button-hover) !important;
}
&:active {
background-color: var(--danger-button-active) !important;
border-color: var(--danger-button-active) !important;
}
`
interface DangerButtonProps extends React.ComponentProps<typeof VSCodeButton> {}
const DangerButton: React.FC<DangerButtonProps> = (props) => {
return <StyledButton {...props} />
}
export default DangerButton

View file

@ -8,6 +8,7 @@ import McpResourceRow from "./McpResourceRow"
import McpMarketplaceView from "./marketplace/McpMarketplaceView"
import styled from "styled-components"
import { getMcpServerDisplayName } from "../../utils/mcp"
import DangerButton from "../common/DangerButton"
type McpViewProps = {
onDone: () => void
@ -240,6 +241,7 @@ const ServerRow = ({ server }: { server: McpServer }) => {
const { mcpMarketplaceCatalog } = useExtensionState()
const [isExpanded, setIsExpanded] = useState(false)
const [isDeleting, setIsDeleting] = useState(false)
const getStatusColor = () => {
switch (server.status) {
@ -265,6 +267,14 @@ const ServerRow = ({ server }: { server: McpServer }) => {
})
}
const handleDelete = () => {
setIsDeleting(true)
vscode.postMessage({
type: "deleteMcpServer",
serverName: server.name,
})
}
return (
<div style={{ marginBottom: "10px" }}>
<div
@ -460,6 +470,17 @@ const ServerRow = ({ server }: { server: McpServer }) => {
}}>
{server.status === "connecting" ? "Restarting..." : "Restart Server"}
</VSCodeButton>
<DangerButton
// appearance="secondary"
onClick={handleDelete}
disabled={isDeleting}
style={{
width: "calc(100% - 14px)",
margin: "5px 7px 3px 7px",
}}>
{isDeleting ? "Deleting..." : "Delete Server"}
</DangerButton>
</div>
)
)}