From 8cfc0fa4f4c43d9ee62ce0e09f5bd917bd959e79 Mon Sep 17 00:00:00 2001 From: Evan Date: Sat, 18 Jan 2025 15:45:17 +0800 Subject: [PATCH 01/13] basic changes with debugging logs --- src/core/webview/ClineProvider.ts | 18 ++++++++++---- src/shared/WebviewMessage.ts | 1 + webview-ui/src/components/mcp/McpView.tsx | 2 +- .../src/components/settings/SettingsView.tsx | 24 ++++++++++++++++--- 4 files changed, 37 insertions(+), 8 deletions(-) diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index 54e47055f2..06a17e99f3 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -550,10 +550,11 @@ export class ClineProvider implements vscode.WebviewViewProvider { this.cancelTask() break case "openMcpSettings": { - const mcpSettingsFilePath = await this.mcpHub?.getMcpSettingsFilePath() - if (mcpSettingsFilePath) { - openFile(mcpSettingsFilePath) - } + await vscode.commands.executeCommand("workbench.action.openSettings") + // const mcpSettingsFilePath = await this.mcpHub?.getMcpSettingsFilePath() + // if (mcpSettingsFilePath) { + // openFile(mcpSettingsFilePath) + // } break } case "restartMcpServer": { @@ -564,6 +565,15 @@ export class ClineProvider implements vscode.WebviewViewProvider { } break } + case "openExtensionSettings": { + const mcpSettingsFilePath = await this.mcpHub?.getMcpSettingsFilePath() + if (mcpSettingsFilePath) { + openFile(mcpSettingsFilePath) + } + break + // await vscode.commands.executeCommand("workbench.action.openSettings") + // 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/WebviewMessage.ts b/src/shared/WebviewMessage.ts index 4fa90b3e36..1344b652f9 100644 --- a/src/shared/WebviewMessage.ts +++ b/src/shared/WebviewMessage.ts @@ -31,6 +31,7 @@ export interface WebviewMessage { | "checkpointDiff" | "checkpointRestore" | "taskCompletionViewChanges" + | "openExtensionSettings" // | "relaunchChromeDebugMode" text?: string askResponse?: ClineAskResponse diff --git a/webview-ui/src/components/mcp/McpView.tsx b/webview-ui/src/components/mcp/McpView.tsx index 7fce15a96d..54c8098984 100644 --- a/webview-ui/src/components/mcp/McpView.tsx +++ b/webview-ui/src/components/mcp/McpView.tsx @@ -141,7 +141,7 @@ const McpView = ({ onDone }: McpViewProps) => { vscode.postMessage({ type: "openMcpSettings" }) }}> - Edit MCP Settings + Edit MCP Settingssss diff --git a/webview-ui/src/components/settings/SettingsView.tsx b/webview-ui/src/components/settings/SettingsView.tsx index 0e328ecb42..4b2b79f338 100644 --- a/webview-ui/src/components/settings/SettingsView.tsx +++ b/webview-ui/src/components/settings/SettingsView.tsx @@ -5,7 +5,8 @@ import { validateApiConfiguration, validateModelId } from "../../utils/validate" import { vscode } from "../../utils/vscode" import ApiOptions from "./ApiOptions" -const IS_DEV = false // FIXME: use flags when packaging +// In development, process.env.NODE_ENV is 'development' +const IS_DEV = process.env.NODE_ENV === 'development' type SettingsViewProps = { onDone: () => void @@ -128,14 +129,31 @@ const SettingsView = ({ onDone }: SettingsViewProps) => { )} +
+ vscode.postMessage({ type: "openExtensionSettings" })} + style={{ + margin: "0 0 16px 0", + minWidth: "fit-content", + whiteSpace: "nowrap", + }}> + Advanced Settings + +

Date: Sat, 18 Jan 2025 16:32:45 +0800 Subject: [PATCH 02/13] completed adding advanced settings button --- src/core/webview/ClineProvider.ts | 16 +++++----------- webview-ui/src/components/mcp/McpView.tsx | 2 +- .../src/components/settings/SettingsView.tsx | 3 +-- 3 files changed, 7 insertions(+), 14 deletions(-) diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index 06a17e99f3..fc9d1b9fcc 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -550,11 +550,10 @@ export class ClineProvider implements vscode.WebviewViewProvider { this.cancelTask() break case "openMcpSettings": { - await vscode.commands.executeCommand("workbench.action.openSettings") - // const mcpSettingsFilePath = await this.mcpHub?.getMcpSettingsFilePath() - // if (mcpSettingsFilePath) { - // openFile(mcpSettingsFilePath) - // } + const mcpSettingsFilePath = await this.mcpHub?.getMcpSettingsFilePath() + if (mcpSettingsFilePath) { + openFile(mcpSettingsFilePath) + } break } case "restartMcpServer": { @@ -566,13 +565,8 @@ export class ClineProvider implements vscode.WebviewViewProvider { break } case "openExtensionSettings": { - const mcpSettingsFilePath = await this.mcpHub?.getMcpSettingsFilePath() - if (mcpSettingsFilePath) { - openFile(mcpSettingsFilePath) - } + await vscode.commands.executeCommand("workbench.action.openSettings", "@ext:saoudrizwan.claude-dev") break - // await vscode.commands.executeCommand("workbench.action.openSettings") - // 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/webview-ui/src/components/mcp/McpView.tsx b/webview-ui/src/components/mcp/McpView.tsx index 54c8098984..7fce15a96d 100644 --- a/webview-ui/src/components/mcp/McpView.tsx +++ b/webview-ui/src/components/mcp/McpView.tsx @@ -141,7 +141,7 @@ const McpView = ({ onDone }: McpViewProps) => { vscode.postMessage({ type: "openMcpSettings" }) }}> - Edit MCP Settingssss + Edit MCP Settings

diff --git a/webview-ui/src/components/settings/SettingsView.tsx b/webview-ui/src/components/settings/SettingsView.tsx index 4b2b79f338..c5526fb32c 100644 --- a/webview-ui/src/components/settings/SettingsView.tsx +++ b/webview-ui/src/components/settings/SettingsView.tsx @@ -5,8 +5,7 @@ import { validateApiConfiguration, validateModelId } from "../../utils/validate" import { vscode } from "../../utils/vscode" import ApiOptions from "./ApiOptions" -// In development, process.env.NODE_ENV is 'development' -const IS_DEV = process.env.NODE_ENV === 'development' +const IS_DEV = false // FIXME: use flags when packaging type SettingsViewProps = { onDone: () => void From 1d97429e28a2ca1e362789b58e2a3346c6a07b9e Mon Sep 17 00:00:00 2001 From: Evan Date: Sun, 19 Jan 2025 13:26:18 +0800 Subject: [PATCH 03/13] toggle MCP --- package.json | 10 ++++ src/core/Cline.ts | 8 +++ src/core/prompts/system.ts | 86 ++++++++++++++++++++----------- src/core/webview/ClineProvider.ts | 4 ++ src/services/mcp/McpHub.ts | 4 ++ 5 files changed, 83 insertions(+), 29 deletions(-) diff --git a/package.json b/package.json index def6b5b323..3b01e6bb90 100644 --- a/package.json +++ b/package.json @@ -46,6 +46,16 @@ "activationEvents": [], "main": "./dist/extension.js", "contributes": { + "configuration": { + "title": "Cline", + "properties": { + "cline.mcp.includeInPrompt": { + "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." + } + } + }, "viewsContainers": { "activitybar": [ { diff --git a/src/core/Cline.ts b/src/core/Cline.ts index 5b4204105d..14a5bac5e3 100644 --- a/src/core/Cline.ts +++ b/src/core/Cline.ts @@ -1192,6 +1192,14 @@ export class Cline { mcpHub, this.browserSettings, ) + this.providerRef + .deref() + ?.log( + `System prompt length with MCP ${mcpHub.shouldIncludeInPrompt() ? "enabled" : "disabled"}: ${systemPrompt.length} characters`, + ) + // console.error( + // `System prompt length with MCP ${mcpHub.shouldIncludeInPrompt() ? "enabled" : "disabled"}: ${systemPrompt.length} characters`, + // ) let settingsCustomInstructions = this.customInstructions?.trim() const clineRulesFilePath = path.resolve(cwd, GlobalFileNames.clineRules) let clineRulesFileInstructions: string | undefined diff --git a/src/core/prompts/system.ts b/src/core/prompts/system.ts index d6b0d2ca22..239a390046 100644 --- a/src/core/prompts/system.ts +++ b/src/core/prompts/system.ts @@ -177,6 +177,9 @@ Usage: : "" } +${ + mcpHub.shouldIncludeInPrompt() + ? ` ## 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. Parameters: @@ -205,6 +208,9 @@ Usage: server name here resource URI here +` + : "" +} ## ask_followup_question Description: Ask the user a question to gather additional information needed to complete the task. This tool should be used when you encounter ambiguities, need clarification, or require more details to proceed effectively. It allows for interactive problem-solving by enabling direct communication with the user. Use this tool judiciously to maintain a balance between gathering necessary information and avoiding excessive back-and-forth. @@ -238,27 +244,7 @@ Your final result description here false -## Example 2: Requesting to use an MCP tool - - -weather-server -get_forecast - -{ - "city": "San Francisco", - "days": 5 -} - - - -## Example 3: Requesting to access an MCP resource - - -weather-server -weather://san-francisco/current - - -## Example 4: Requesting to create a new file +## Example 2: Requesting to create a new file src/frontend-config.json @@ -280,7 +266,7 @@ Your final result description here -## Example 6: Requesting to make targeted edits to a file +## Example 3: Requesting to make targeted edits to a file src/components/App.tsx @@ -314,6 +300,31 @@ return ( >>>>>>> REPLACE +${ + mcpHub.shouldIncludeInPrompt() + ? ` + +## Example 4: Requesting to use an MCP tool + + +weather-server +get_forecast + +{ + "city": "San Francisco", + "days": 5 +} + + + +## Example 5: Requesting to access an MCP resource + + +weather-server +weather://san-francisco/current +` + : "" +} # Tool Use Guidelines @@ -336,6 +347,9 @@ 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() + ? ` ==== MCP SERVERS @@ -727,11 +741,11 @@ npm run build ## Editing MCP Servers The user may ask to add tools or resources that may make sense to add to an existing MCP server (listed under 'Connected MCP Servers' above: ${ - mcpHub - .getServers() - .map((server) => server.name) - .join(", ") || "(None running currently)" -}, e.g. if it would use the same API. This would be possible if you can locate the MCP server repository on the user's system by looking at the server arguments for a filepath. You might then use list_files and read_file to explore the files in the repository, and use replace_in_file to make changes to the files. + mcpHub + .getServers() + .map((server) => server.name) + .join(", ") || "(None running currently)" + }, e.g. if it would use the same API. This would be possible if you can locate the MCP server repository on the user's system by looking at the server arguments for a filepath. You might then use list_files and read_file to explore the files in the repository, and use replace_in_file to make changes to the files. However some MCP servers may be running from installed packages rather than a local repository, in which case it may make more sense to create a new MCP server. @@ -740,7 +754,9 @@ However some MCP servers may be running from installed packages rather than a lo The user may not always request the use or creation of MCP servers. Instead, they might provide tasks that can be completed with existing tools. While using the MCP SDK to extend your capabilities can be useful, it's important to understand that this is just one specialized type of task you can accomplish. You should only implement MCP servers when the user explicitly requests it (e.g., "add a tool that..."). Remember: The MCP documentation and example provided above are to help you understand and work with existing MCP servers or create new ones when requested by the user. You already have access to tools and capabilities that can be used to accomplish a wide range of tasks. - +` + : "" +} ==== EDITING FILES @@ -832,7 +848,13 @@ CAPABILITIES ? "\n- You can use the browser_action tool to interact with websites (including html files and locally running development servers) through a Puppeteer-controlled browser when you feel it is necessary in accomplishing the user's task. This tool is particularly useful for web development tasks as it allows you to launch a browser, navigate to pages, interact with elements through clicks and keyboard input, and capture the results through screenshots and console logs. This tool may be useful at key stages of web development tasks-such as after implementing new features, making substantial changes, when troubleshooting issues, or to verify the result of your work. You can analyze the provided screenshots to ensure correct rendering or identify errors, and review console logs for runtime issues.\n - For example, if asked to add a component to a react website, you might create the necessary files, use execute_command to run the site locally, then use browser_action to launch the browser, navigate to the local server, and verify the component renders & functions correctly before closing the browser." : "" } +${ + mcpHub.shouldIncludeInPrompt() + ? ` - 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. +` + : "" +} ==== @@ -861,7 +883,6 @@ RULES - When presented with images, utilize your vision capabilities to thoroughly examine them and extract meaningful information. Incorporate these insights into your thought process as you accomplish the user's task. - At the end of each user message, you will automatically receive environment_details. This information is not written by the user themselves, but is auto-generated to provide potentially relevant context about the project structure and environment. While this information can be valuable for understanding the project context, do not treat it as a direct part of the user's request or response. Use it to inform your actions and decisions, but don't assume the user is explicitly asking about or referring to this information unless they clearly do so in their message. When using environment_details, explain your actions clearly to ensure the user understands, as they may not be aware of these details. - Before executing commands, check the "Actively Running Terminals" section in environment_details. If present, consider how these active processes might impact your task. For example, if a local development server is already running, you wouldn't need to start it again. If no active terminals are listed, proceed with command execution as normal. -- MCP operations should be used one at a time, similar to other tool usage. Wait for confirmation of success before proceeding with additional operations. - When using the replace_in_file tool, you must include complete lines in your SEARCH blocks, not partial lines. The system requires exact line matches and cannot match partial lines. For example, if you want to match a line containing "const x = 5;", your SEARCH block must include the entire line, not just "x = 5" or other fragments. - When using the replace_in_file tool, if you use multiple SEARCH/REPLACE blocks, list them in the order they appear in the file. For example if you need to make changes to both line 10 and line 50, first include the SEARCH/REPLACE block for line 10, followed by the SEARCH/REPLACE block for line 50. - It is critical you wait for the user's response after each tool use, in order to confirm the success of the tool use. For example, if asked to make a todo app, you would create a file, wait for the user's response it was created successfully, then create another file if needed, wait for the user's response it was created successfully, etc.${ @@ -869,6 +890,13 @@ RULES ? " Then if you want to test your work, you might use browser_action to launch the site, wait for the user's response confirming the site was launched along with a screenshot, then perhaps e.g., click a button to test functionality if needed, wait for the user's response confirming the button was clicked along with a screenshot of the new state, before finally closing the browser." : "" } +${ + mcpHub.shouldIncludeInPrompt() + ? ` +- 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 fc9d1b9fcc..13d630cae0 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -84,6 +84,10 @@ export class ClineProvider implements vscode.WebviewViewProvider { mcpHub?: McpHub private latestAnnouncementId = "jan-6-2025" // update to some unique identifier when we add a new announcement + public log(message: string) { + this.outputChannel.appendLine(message) + } + constructor( readonly context: vscode.ExtensionContext, private readonly outputChannel: vscode.OutputChannel, diff --git a/src/services/mcp/McpHub.ts b/src/services/mcp/McpHub.ts index 59dd3bf38b..d210d58702 100644 --- a/src/services/mcp/McpHub.ts +++ b/src/services/mcp/McpHub.ts @@ -54,6 +54,10 @@ export class McpHub { return this.connections.map((conn) => conn.server) } + shouldIncludeInPrompt(): boolean { + return vscode.workspace.getConfiguration("cline.mcp").get("includeInPrompt") ?? true + } + async getMcpServersPath(): Promise { const provider = this.providerRef.deref() if (!provider) { From 7ed03022f5a019597c2fb5e70f674ea1919a37f0 Mon Sep 17 00:00:00 2001 From: Evan Date: Sun, 19 Jan 2025 18:15:38 +0800 Subject: [PATCH 04/13] removing logging --- src/core/Cline.ts | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/core/Cline.ts b/src/core/Cline.ts index 14a5bac5e3..44e1d40ee5 100644 --- a/src/core/Cline.ts +++ b/src/core/Cline.ts @@ -1192,14 +1192,7 @@ export class Cline { mcpHub, this.browserSettings, ) - this.providerRef - .deref() - ?.log( - `System prompt length with MCP ${mcpHub.shouldIncludeInPrompt() ? "enabled" : "disabled"}: ${systemPrompt.length} characters`, - ) - // console.error( - // `System prompt length with MCP ${mcpHub.shouldIncludeInPrompt() ? "enabled" : "disabled"}: ${systemPrompt.length} characters`, - // ) + let settingsCustomInstructions = this.customInstructions?.trim() const clineRulesFilePath = path.resolve(cwd, GlobalFileNames.clineRules) let clineRulesFileInstructions: string | undefined From 96005f0ad98c852ceeb2dc6e8b592a8f2a0eaaa9 Mon Sep 17 00:00:00 2001 From: Evan Date: Mon, 20 Jan 2025 15:49:35 +0800 Subject: [PATCH 05/13] 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 06/13] 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 7b894f100f13f77ae8d1d44fe155f3ab4b2389ee Mon Sep 17 00:00:00 2001 From: Evan Date: Mon, 20 Jan 2025 20:36:11 +0800 Subject: [PATCH 07/13] removing logging method --- src/core/webview/ClineProvider.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index 13d630cae0..fc9d1b9fcc 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -84,10 +84,6 @@ export class ClineProvider implements vscode.WebviewViewProvider { mcpHub?: McpHub private latestAnnouncementId = "jan-6-2025" // update to some unique identifier when we add a new announcement - public log(message: string) { - this.outputChannel.appendLine(message) - } - constructor( readonly context: vscode.ExtensionContext, private readonly outputChannel: vscode.OutputChannel, From 1627f412157c81a2688dde3535173873cf872b24 Mon Sep 17 00:00:00 2001 From: Evan Date: Tue, 21 Jan 2025 12:49:20 +0800 Subject: [PATCH 08/13] filtering MCP servers based on connected status --- src/core/prompts/system.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/prompts/system.ts b/src/core/prompts/system.ts index 239a390046..1ea58fee1a 100644 --- a/src/core/prompts/system.ts +++ b/src/core/prompts/system.ts @@ -740,9 +740,10 @@ npm run build ## Editing MCP Servers -The user may ask to add tools or resources that may make sense to add to an existing MCP server (listed under 'Connected MCP Servers' above: ${ +The user may ask to add tools or resources that may make sense to add to an existing MCP server (listed under 'Connected MCP Servers' below: ${ mcpHub .getServers() + .filter((server) => server.status === "connected") .map((server) => server.name) .join(", ") || "(None running currently)" }, e.g. if it would use the same API. This would be possible if you can locate the MCP server repository on the user's system by looking at the server arguments for a filepath. You might then use list_files and read_file to explore the files in the repository, and use replace_in_file to make changes to the files. From 0c7b12a2c04ed72da73784d98c27a18679d84ce8 Mon Sep 17 00:00:00 2001 From: Evan Date: Wed, 22 Jan 2025 12:25:56 +0800 Subject: [PATCH 09/13] button styling changes; extracted to separate component --- .../src/components/common/SettingsButton.tsx | 36 +++++++++++++++++++ .../src/components/settings/SettingsView.tsx | 9 +++-- 2 files changed, 40 insertions(+), 5 deletions(-) create mode 100644 webview-ui/src/components/common/SettingsButton.tsx diff --git a/webview-ui/src/components/common/SettingsButton.tsx b/webview-ui/src/components/common/SettingsButton.tsx new file mode 100644 index 0000000000..2f63240c71 --- /dev/null +++ b/webview-ui/src/components/common/SettingsButton.tsx @@ -0,0 +1,36 @@ +import { VSCodeButton } from "@vscode/webview-ui-toolkit/react" +import styled from "styled-components" + +const StyledButton = styled(VSCodeButton)` + --settings-button-bg: var(--vscode-button-secondaryBackground); + --settings-button-hover: var(--vscode-button-secondaryHoverBackground); + --settings-button-active: var(--vscode-button-secondaryBackground); + + background-color: var(--settings-button-bg) !important; + border-color: var(--settings-button-bg) !important; + width: 100% !important; + + &:hover { + background-color: var(--settings-button-hover) !important; + border-color: var(--settings-button-hover) !important; + } + + &:active { + background-color: var(--settings-button-active) !important; + border-color: var(--settings-button-active) !important; + } + + i.codicon { + margin-right: 6px; + flex-shrink: 0; + font-size: 16px !important; + } +` + +interface SettingsButtonProps extends React.ComponentProps {} + +const SettingsButton: React.FC = (props) => { + return +} + +export default SettingsButton diff --git a/webview-ui/src/components/settings/SettingsView.tsx b/webview-ui/src/components/settings/SettingsView.tsx index 7a74be34f3..6c1daf60e0 100644 --- a/webview-ui/src/components/settings/SettingsView.tsx +++ b/webview-ui/src/components/settings/SettingsView.tsx @@ -4,6 +4,7 @@ import { useExtensionState } from "../../context/ExtensionStateContext" import { validateApiConfiguration, validateModelId } from "../../utils/validate" import { vscode } from "../../utils/vscode" import ApiOptions from "./ApiOptions" +import SettingsButton from "../common/SettingsButton" const IS_DEV = false // FIXME: use flags when packaging @@ -137,16 +138,14 @@ const SettingsView = ({ onDone }: SettingsViewProps) => { display: "flex", justifyContent: "center", }}> - vscode.postMessage({ type: "openExtensionSettings" })} style={{ margin: "0 0 16px 0", - minWidth: "fit-content", - whiteSpace: "nowrap", }}> + Advanced Settings - +
Date: Wed, 22 Jan 2025 19:19:52 +0800 Subject: [PATCH 10/13] guard additional MCP sentence --- src/core/prompts/system.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/prompts/system.ts b/src/core/prompts/system.ts index 1ea58fee1a..ddadd97bd4 100644 --- a/src/core/prompts/system.ts +++ b/src/core/prompts/system.ts @@ -876,7 +876,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.shouldIncludeInPrompt() ? "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. From 5f97b4b7faf4c5539d15d204e7c8ca2e13fa114e Mon Sep 17 00:00:00 2001 From: Evan Date: Wed, 22 Jan 2025 20:32:56 +0800 Subject: [PATCH 11/13] 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 */}
From 884e56f0e53fa181d69f819af67a79d4f24f5b6c Mon Sep 17 00:00:00 2001 From: Evan Date: Wed, 22 Jan 2025 21:01:14 +0800 Subject: [PATCH 12/13] duplicated configuration key due to improper merge --- package.json | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index b36fa00eba..6fda5089f6 100644 --- a/package.json +++ b/package.json @@ -46,16 +46,6 @@ "activationEvents": [], "main": "./dist/extension.js", "contributes": { - "configuration": { - "title": "Cline", - "properties": { - "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." - } - } - }, "viewsContainers": { "activitybar": [ { @@ -151,6 +141,11 @@ } }, "description": "Settings for VSCode Language Model API" + }, + "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." } } } From e8369ad576de73bd21e4b45e7d4884e98f9b131d Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Wed, 22 Jan 2025 14:24:24 -0800 Subject: [PATCH 13/13] Change copy --- webview-ui/src/components/mcp/McpView.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webview-ui/src/components/mcp/McpView.tsx b/webview-ui/src/components/mcp/McpView.tsx index df08137766..b8afdbb05f 100644 --- a/webview-ui/src/components/mcp/McpView.tsx +++ b/webview-ui/src/components/mcp/McpView.tsx @@ -156,7 +156,7 @@ const McpView = ({ onDone }: McpViewProps) => { }) }} style={{ fontSize: "12px" }}> - Edit Advanced MCP Settings... + Advanced MCP Settings