Changing MCP settings UI to reflect new toggle

This commit is contained in:
Evan 2025-01-20 15:49:35 +08:00
parent 7ed03022f5
commit 96005f0ad9
7 changed files with 137 additions and 27 deletions

View File

@ -49,7 +49,7 @@
"configuration": {
"title": "Cline",
"properties": {
"cline.mcp.includeInPrompt": {
"cline.mcp.enabled": {
"type": "boolean",
"default": true,
"description": "Include MCP server functionality in AI prompts. When disabled, the AI will not be aware of MCP capabilities. This saves context window tokens."

View File

@ -178,7 +178,7 @@ Usage:
}
${
mcpHub.shouldIncludeInPrompt()
mcpHub.isMcpEnabled()
? `
## use_mcp_tool
Description: Request to use a tool provided by a connected MCP server. Each MCP server can provide multiple tools with different capabilities. Tools have defined input schemas that specify required and optional parameters.
@ -301,7 +301,7 @@ return (
</diff>
</replace_in_file>
${
mcpHub.shouldIncludeInPrompt()
mcpHub.isMcpEnabled()
? `
## Example 4: Requesting to use an MCP tool
@ -348,7 +348,7 @@ It is crucial to proceed step-by-step, waiting for the user's message after each
By waiting for and carefully considering the user's response after each tool use, you can react accordingly and make informed decisions about how to proceed with the task. This iterative process helps ensure the overall success and accuracy of your work.
${
mcpHub.shouldIncludeInPrompt()
mcpHub.isMcpEnabled()
? `
====
@ -849,7 +849,7 @@ CAPABILITIES
: ""
}
${
mcpHub.shouldIncludeInPrompt()
mcpHub.isMcpEnabled()
? `
- You have access to MCP servers that may provide additional tools and resources. Each server may provide different capabilities that you can use to accomplish tasks more effectively.
`
@ -891,7 +891,7 @@ RULES
: ""
}
${
mcpHub.shouldIncludeInPrompt()
mcpHub.isMcpEnabled()
? `
- MCP operations should be used one at a time, similar to other tool usage. Wait for confirmation of success before proceeding with additional operations.
`

View File

@ -194,7 +194,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
this.disposables,
)
// Listen for when color changes
// Listen for when color changes or MCP settings
vscode.workspace.onDidChangeConfiguration(
async (e) => {
if (e && e.affectsConfiguration("workbench.colorTheme")) {
@ -204,6 +204,14 @@ export class ClineProvider implements vscode.WebviewViewProvider {
text: JSON.stringify(await getTheme()),
})
}
if (e && e.affectsConfiguration("cline.mcp.enabled")) {
// Send updated MCP enabled state
const enabled = this.mcpHub?.isMcpEnabled() ?? true
await this.postMessageToWebview({
type: "mcpEnabled",
enabled
})
}
},
null,
this.disposables,
@ -572,6 +580,18 @@ export class ClineProvider implements vscode.WebviewViewProvider {
await vscode.commands.executeCommand("workbench.action.openSettings", "@ext:saoudrizwan.claude-dev")
break
}
case "getMcpEnabled": {
const enabled = this.mcpHub?.isMcpEnabled() ?? true
await this.postMessageToWebview({
type: "mcpEnabled",
enabled
})
break
}
case "toggleMcp": {
await vscode.workspace.getConfiguration("cline.mcp").update("enabled", message.enabled, true)
break
}
// Add more switch case statements here as more webview message commands
// are created within the webview context (i.e. inside media/main.js)
}

View File

@ -54,8 +54,8 @@ export class McpHub {
return this.connections.map((conn) => conn.server)
}
shouldIncludeInPrompt(): boolean {
return vscode.workspace.getConfiguration("cline.mcp").get("includeInPrompt") ?? true
isMcpEnabled(): boolean {
return vscode.workspace.getConfiguration("cline.mcp").get("enabled") ?? true
}
async getMcpServersPath(): Promise<string> {

View File

@ -21,6 +21,9 @@ export interface ExtensionMessage {
| "openRouterModels"
| "mcpServers"
| "relinquishControl"
| "getMcpEnabled"
| "mcpEnabled"
| "toggleMcp"
text?: string
action?: "chatButtonClicked" | "mcpButtonClicked" | "settingsButtonClicked" | "historyButtonClicked" | "didBecomeVisible"
invoke?: "sendMessage" | "primaryButtonClick" | "secondaryButtonClick"
@ -32,6 +35,7 @@ export interface ExtensionMessage {
partialMessage?: ClineMessage
openRouterModels?: Record<string, ModelInfo>
mcpServers?: McpServer[]
enabled?: boolean // For mcpEnabled message
}
export interface ExtensionState {

View File

@ -32,6 +32,8 @@ export interface WebviewMessage {
| "checkpointRestore"
| "taskCompletionViewChanges"
| "openExtensionSettings"
| "getMcpEnabled"
| "toggleMcp"
// | "relaunchChromeDebugMode"
text?: string
askResponse?: ClineAskResponse
@ -41,6 +43,7 @@ export interface WebviewMessage {
number?: number
autoApprovalSettings?: AutoApprovalSettings
browserSettings?: BrowserSettings
enabled?: boolean // For toggleMcp message
}
export type ClineAskResponse = "yesButtonClicked" | "noButtonClicked" | "messageResponse"

View File

@ -1,5 +1,12 @@
import { VSCodeButton, VSCodeLink, VSCodePanels, VSCodePanelTab, VSCodePanelView } from "@vscode/webview-ui-toolkit/react"
import { useState } from "react"
import {
VSCodeButton,
VSCodeLink,
VSCodePanels,
VSCodePanelTab,
VSCodePanelView,
VSCodeCheckbox,
} from "@vscode/webview-ui-toolkit/react"
import { useEffect, useState } from "react"
import { vscode } from "../../utils/vscode"
import { useExtensionState } from "../../context/ExtensionStateContext"
import { McpServer } from "../../../../src/shared/mcp"
@ -12,6 +19,31 @@ type McpViewProps = {
const McpView = ({ onDone }: McpViewProps) => {
const { mcpServers: servers } = useExtensionState()
const [isMcpEnabled, setIsMcpEnabled] = useState(true)
useEffect(() => {
// Get initial MCP enabled state
vscode.postMessage({ type: "getMcpEnabled" })
}, [])
useEffect(() => {
const handler = (event: MessageEvent) => {
const message = event.data
if (message.type === "mcpEnabled") {
setIsMcpEnabled(message.enabled)
}
}
window.addEventListener("message", handler)
return () => window.removeEventListener("message", handler)
}, [])
const toggleMcp = () => {
vscode.postMessage({
type: "toggleMcp",
enabled: !isMcpEnabled,
})
setIsMcpEnabled(!isMcpEnabled)
}
// const [servers, setServers] = useState<McpServer[]>([
// // Add some mock servers for testing
// {
@ -100,7 +132,7 @@ const McpView = ({ onDone }: McpViewProps) => {
style={{
color: "var(--vscode-foreground)",
fontSize: "13px",
marginBottom: "20px",
marginBottom: "16px",
marginTop: "5px",
}}>
The{" "}
@ -118,8 +150,57 @@ const McpView = ({ onDone }: McpViewProps) => {
</VSCodeLink>
</div>
{/* Server List */}
{servers.length > 0 && (
{/* MCP Toggle Section */}
<div
style={{
marginBottom: "16px",
paddingBottom: "16px",
borderBottom: "1px solid var(--vscode-textSeparator-foreground)",
}}>
<div>
<VSCodeCheckbox
checked={isMcpEnabled}
onChange={toggleMcp}
style={{
display: "flex",
alignItems: "center",
gap: "8px",
padding: "4px 0",
cursor: "pointer",
fontSize: "13px",
}}>
Enable MCP
</VSCodeCheckbox>
{isMcpEnabled && (
<div
style={{
marginTop: "4px",
marginLeft: "24px",
color: "var(--vscode-descriptionForeground)",
fontSize: "12px",
}}>
Disabling MCP will save on tokens passed in the context.
</div>
)}
{!isMcpEnabled && (
<div
style={{
padding: "8px 12px",
marginTop: "8px",
background: "var(--vscode-textBlockQuote-background)",
border: "1px solid var(--vscode-textBlockQuote-border)",
borderRadius: "4px",
color: "var(--vscode-descriptionForeground)",
fontSize: "12px",
lineHeight: "1.4",
}}>
MCP is currently disabled. Enable MCP to use MCP servers and tools. Enabling MCP will use additional tokens.
</div>
)}
</div>
</div>
{servers.length > 0 && isMcpEnabled && (
<div
style={{
display: "flex",
@ -132,7 +213,8 @@ const McpView = ({ onDone }: McpViewProps) => {
</div>
)}
{/* Edit Settings Button */}
{/* Server Configuration Button */}
{isMcpEnabled && (
<div style={{ marginTop: "10px", width: "100%" }}>
<VSCodeButton
appearance="secondary"
@ -140,10 +222,11 @@ const McpView = ({ onDone }: McpViewProps) => {
onClick={() => {
vscode.postMessage({ type: "openMcpSettings" })
}}>
<span className="codicon codicon-edit" style={{ marginRight: "6px" }}></span>
Edit MCP Settings
<span className="codicon codicon-server" style={{ marginRight: "6px" }}></span>
Configure MCP Servers
</VSCodeButton>
</div>
)}
{/* Bottom padding */}
<div style={{ height: "20px" }} />