From 96005f0ad98c852ceeb2dc6e8b592a8f2a0eaaa9 Mon Sep 17 00:00:00 2001 From: Evan Date: Mon, 20 Jan 2025 15:49:35 +0800 Subject: [PATCH 1/3] Changing MCP settings UI to reflect new toggle --- package.json | 2 +- src/core/prompts/system.ts | 10 +- src/core/webview/ClineProvider.ts | 22 +++- src/services/mcp/McpHub.ts | 4 +- src/shared/ExtensionMessage.ts | 4 + src/shared/WebviewMessage.ts | 5 +- webview-ui/src/components/mcp/McpView.tsx | 117 ++++++++++++++++++---- 7 files changed, 137 insertions(+), 27 deletions(-) diff --git a/package.json b/package.json index 3b01e6bb90..daa4653dc8 100644 --- a/package.json +++ b/package.json @@ -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." diff --git a/src/core/prompts/system.ts b/src/core/prompts/system.ts index 239a390046..0b7036641c 100644 --- a/src/core/prompts/system.ts +++ b/src/core/prompts/system.ts @@ -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 ( ${ - 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. ` diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index 13d630cae0..053a52fd68 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -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) } diff --git a/src/services/mcp/McpHub.ts b/src/services/mcp/McpHub.ts index d210d58702..a12d489671 100644 --- a/src/services/mcp/McpHub.ts +++ b/src/services/mcp/McpHub.ts @@ -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 { diff --git a/src/shared/ExtensionMessage.ts b/src/shared/ExtensionMessage.ts index fe5584c54d..b7b1931475 100644 --- a/src/shared/ExtensionMessage.ts +++ b/src/shared/ExtensionMessage.ts @@ -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 mcpServers?: McpServer[] + enabled?: boolean // For mcpEnabled message } export interface ExtensionState { diff --git a/src/shared/WebviewMessage.ts b/src/shared/WebviewMessage.ts index 1344b652f9..668b5d6852 100644 --- a/src/shared/WebviewMessage.ts +++ b/src/shared/WebviewMessage.ts @@ -32,7 +32,9 @@ export interface WebviewMessage { | "checkpointRestore" | "taskCompletionViewChanges" | "openExtensionSettings" - // | "relaunchChromeDebugMode" + | "getMcpEnabled" + | "toggleMcp" + // | "relaunchChromeDebugMode" text?: string askResponse?: ClineAskResponse apiConfiguration?: ApiConfiguration @@ -41,6 +43,7 @@ export interface WebviewMessage { number?: number autoApprovalSettings?: AutoApprovalSettings browserSettings?: BrowserSettings + enabled?: boolean // For toggleMcp message } export type ClineAskResponse = "yesButtonClicked" | "noButtonClicked" | "messageResponse" diff --git a/webview-ui/src/components/mcp/McpView.tsx b/webview-ui/src/components/mcp/McpView.tsx index 7fce15a96d..4fdeaee6df 100644 --- a/webview-ui/src/components/mcp/McpView.tsx +++ b/webview-ui/src/components/mcp/McpView.tsx @@ -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([ // // 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) => { - {/* Server List */} - {servers.length > 0 && ( + {/* MCP Toggle Section */} +
+
+ + Enable MCP + + {isMcpEnabled && ( +
+ Disabling MCP will save on tokens passed in the context. +
+ )} + {!isMcpEnabled && ( +
+ MCP is currently disabled. Enable MCP to use MCP servers and tools. Enabling MCP will use additional tokens. +
+ )} +
+
+ + {servers.length > 0 && isMcpEnabled && (
{
)} - {/* Edit Settings Button */} -
- { - vscode.postMessage({ type: "openMcpSettings" }) - }}> - - Edit MCP Settings - -
+ {/* Server Configuration Button */} + {isMcpEnabled && ( +
+ { + vscode.postMessage({ type: "openMcpSettings" }) + }}> + + Configure MCP Servers + +
+ )} {/* Bottom padding */}
From ab8f5d6f36b8f60a36132f3420d79571984cf908 Mon Sep 17 00:00:00 2001 From: Evan Date: Mon, 20 Jan 2025 20:23:00 +0800 Subject: [PATCH 2/3] minor formatting --- src/core/webview/ClineProvider.ts | 4 ++-- src/shared/WebviewMessage.ts | 2 +- webview-ui/src/components/mcp/McpView.tsx | 3 ++- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index 053a52fd68..31061d0802 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -209,7 +209,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { const enabled = this.mcpHub?.isMcpEnabled() ?? true await this.postMessageToWebview({ type: "mcpEnabled", - enabled + enabled, }) } }, @@ -584,7 +584,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { const enabled = this.mcpHub?.isMcpEnabled() ?? true await this.postMessageToWebview({ type: "mcpEnabled", - enabled + enabled, }) break } diff --git a/src/shared/WebviewMessage.ts b/src/shared/WebviewMessage.ts index 668b5d6852..e7faec225a 100644 --- a/src/shared/WebviewMessage.ts +++ b/src/shared/WebviewMessage.ts @@ -34,7 +34,7 @@ export interface WebviewMessage { | "openExtensionSettings" | "getMcpEnabled" | "toggleMcp" - // | "relaunchChromeDebugMode" + // | "relaunchChromeDebugMode" text?: string askResponse?: ClineAskResponse apiConfiguration?: ApiConfiguration diff --git a/webview-ui/src/components/mcp/McpView.tsx b/webview-ui/src/components/mcp/McpView.tsx index 4fdeaee6df..8841669e0d 100644 --- a/webview-ui/src/components/mcp/McpView.tsx +++ b/webview-ui/src/components/mcp/McpView.tsx @@ -194,7 +194,8 @@ const McpView = ({ onDone }: McpViewProps) => { fontSize: "12px", lineHeight: "1.4", }}> - MCP is currently disabled. Enable MCP to use MCP servers and tools. Enabling MCP will use additional tokens. + MCP is currently disabled. Enable MCP to use MCP servers and tools. Enabling MCP will use + additional tokens.
)} From 5f97b4b7faf4c5539d15d204e7c8ca2e13fa114e Mon Sep 17 00:00:00 2001 From: Evan Date: Wed, 22 Jan 2025 20:32:56 +0800 Subject: [PATCH 3/3] removed most of the UI, only leaving a link to advanced settings --- src/core/prompts/system.ts | 2 +- src/core/webview/ClineProvider.ts | 22 +--- src/shared/ExtensionMessage.ts | 4 - src/shared/WebviewMessage.ts | 3 - webview-ui/src/components/mcp/McpView.tsx | 127 +++++----------------- 5 files changed, 31 insertions(+), 127 deletions(-) diff --git a/src/core/prompts/system.ts b/src/core/prompts/system.ts index 0b7036641c..e3c44875f4 100644 --- a/src/core/prompts/system.ts +++ b/src/core/prompts/system.ts @@ -875,7 +875,7 @@ RULES - The user may provide a file's contents directly in their message, in which case you shouldn't use the read_file tool to get the file contents again since you already have it. - Your goal is to try to accomplish the user's task, NOT engage in a back and forth conversation.${ supportsComputerUse - ? '\n- The user may ask generic non-development tasks, such as "what\'s the latest news" or "look up the weather in San Diego", in which case you might use the browser_action tool to complete the task if it makes sense to do so, rather than trying to create a website or using curl to answer the question. However, if an available MCP server tool or resource can be used instead, you should prefer to use it over browser_action.' + ? `\n- The user may ask generic non-development tasks, such as "what\'s the latest news" or "look up the weather in San Diego", in which case you might use the browser_action tool to complete the task if it makes sense to do so, rather than trying to create a website or using curl to answer the question.${mcpHub.isMcpEnabled() ? "However, if an available MCP server tool or resource can be used instead, you should prefer to use it over browser_action." : ""}` : "" } - NEVER end attempt_completion result with a question or request to engage in further conversation! Formulate the end of your result in a way that is final and does not require further input from the user. diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index 31061d0802..13d630cae0 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -194,7 +194,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { this.disposables, ) - // Listen for when color changes or MCP settings + // Listen for when color changes vscode.workspace.onDidChangeConfiguration( async (e) => { if (e && e.affectsConfiguration("workbench.colorTheme")) { @@ -204,14 +204,6 @@ 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, @@ -580,18 +572,6 @@ 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) } diff --git a/src/shared/ExtensionMessage.ts b/src/shared/ExtensionMessage.ts index b7b1931475..fe5584c54d 100644 --- a/src/shared/ExtensionMessage.ts +++ b/src/shared/ExtensionMessage.ts @@ -21,9 +21,6 @@ export interface ExtensionMessage { | "openRouterModels" | "mcpServers" | "relinquishControl" - | "getMcpEnabled" - | "mcpEnabled" - | "toggleMcp" text?: string action?: "chatButtonClicked" | "mcpButtonClicked" | "settingsButtonClicked" | "historyButtonClicked" | "didBecomeVisible" invoke?: "sendMessage" | "primaryButtonClick" | "secondaryButtonClick" @@ -35,7 +32,6 @@ export interface ExtensionMessage { partialMessage?: ClineMessage openRouterModels?: Record mcpServers?: McpServer[] - enabled?: boolean // For mcpEnabled message } export interface ExtensionState { diff --git a/src/shared/WebviewMessage.ts b/src/shared/WebviewMessage.ts index e7faec225a..1344b652f9 100644 --- a/src/shared/WebviewMessage.ts +++ b/src/shared/WebviewMessage.ts @@ -32,8 +32,6 @@ export interface WebviewMessage { | "checkpointRestore" | "taskCompletionViewChanges" | "openExtensionSettings" - | "getMcpEnabled" - | "toggleMcp" // | "relaunchChromeDebugMode" text?: string askResponse?: ClineAskResponse @@ -43,7 +41,6 @@ export interface WebviewMessage { number?: number autoApprovalSettings?: AutoApprovalSettings browserSettings?: BrowserSettings - enabled?: boolean // For toggleMcp message } export type ClineAskResponse = "yesButtonClicked" | "noButtonClicked" | "messageResponse" diff --git a/webview-ui/src/components/mcp/McpView.tsx b/webview-ui/src/components/mcp/McpView.tsx index 8841669e0d..7f2f0ba386 100644 --- a/webview-ui/src/components/mcp/McpView.tsx +++ b/webview-ui/src/components/mcp/McpView.tsx @@ -1,12 +1,5 @@ -import { - VSCodeButton, - VSCodeLink, - VSCodePanels, - VSCodePanelTab, - VSCodePanelView, - VSCodeCheckbox, -} from "@vscode/webview-ui-toolkit/react" -import { useEffect, useState } from "react" +import { VSCodeButton, VSCodeLink, VSCodePanels, VSCodePanelTab, VSCodePanelView } from "@vscode/webview-ui-toolkit/react" +import { useState } from "react" import { vscode } from "../../utils/vscode" import { useExtensionState } from "../../context/ExtensionStateContext" import { McpServer } from "../../../../src/shared/mcp" @@ -19,31 +12,7 @@ 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([ // // Add some mock servers for testing // { @@ -150,58 +119,7 @@ const McpView = ({ onDone }: McpViewProps) => { - {/* MCP Toggle Section */} -
-
- - Enable MCP - - {isMcpEnabled && ( -
- Disabling MCP will save on tokens passed in the context. -
- )} - {!isMcpEnabled && ( -
- MCP is currently disabled. Enable MCP to use MCP servers and tools. Enabling MCP will use - additional tokens. -
- )} -
-
- - {servers.length > 0 && isMcpEnabled && ( + {servers.length > 0 && (
{ )} {/* Server Configuration Button */} - {isMcpEnabled && ( -
- { - vscode.postMessage({ type: "openMcpSettings" }) - }}> - - Configure MCP Servers - -
- )} + +
+ { + vscode.postMessage({ type: "openMcpSettings" }) + }}> + + Configure MCP Servers + +
+ + {/* Advanced Settings Link */} +
+ { + vscode.postMessage({ + type: "openExtensionSettings", + text: "cline.mcp", + }) + }} + style={{ fontSize: "12px" }}> + Edit Advanced MCP Settings... + +
{/* Bottom padding */}