Skip to content

Commit 0f1607a

Browse files
authored
Merge pull request #266 from RooVetGit/mcp_toggle
Add toggle to enable or disable MCP servers on the system prompt
2 parents 657e237 + 9665e78 commit 0f1607a

File tree

12 files changed

+117
-36
lines changed

12 files changed

+117
-36
lines changed

.changeset/slimy-pans-obey.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"roo-cline": patch
3+
---
4+
5+
Add toggle to enable/disable the MCP-related sections of the system prompt (thanks @daniel-lxs!)

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ A fork of Cline, an autonomous coding agent, with some additional experimental f
1818
- Support for Meta 3, 3.1, and 3.2 models via AWS Bedrock
1919
- Support for listing models from OpenAI-compatible providers
2020
- Per-tool MCP auto-approval
21-
- Enable/disable MCP servers
21+
- Enable/disable individual MCP servers
22+
- Enable/disable the MCP feature overall
2223
- Configurable delay after auto-writes to allow diagnostics to detect potential problems
2324
- Control the number of terminal output lines to pass to the model when executing commands
2425
- Runs alongside the original Cline

src/core/Cline.ts

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ import { ClineProvider, GlobalFileNames } from "./webview/ClineProvider"
5050
import { detectCodeOmission } from "../integrations/editor/detect-omission"
5151
import { BrowserSession } from "../services/browser/BrowserSession"
5252
import { OpenRouterHandler } from "../api/providers/openrouter"
53+
import { McpHub } from "../services/mcp/McpHub"
5354

5455
const cwd =
5556
vscode.workspace.workspaceFolders?.map((folder) => folder.uri.fsPath).at(0) ?? path.join(os.homedir(), "Desktop") // may or may not exist but fs checking existence would immediately ask for permission which would be bad UX, need to come up with a better solution
@@ -778,14 +779,19 @@ export class Cline {
778779
}
779780

780781
async *attemptApiRequest(previousApiReqIndex: number): ApiStream {
781-
// Wait for MCP servers to be connected before generating system prompt
782-
await pWaitFor(() => this.providerRef.deref()?.mcpHub?.isConnecting !== true, { timeout: 10_000 }).catch(() => {
783-
console.error("MCP servers failed to connect in time")
784-
})
782+
let mcpHub: McpHub | undefined
783+
784+
const { mcpEnabled } = await this.providerRef.deref()?.getState() ?? {}
785785

786-
const mcpHub = this.providerRef.deref()?.mcpHub
787-
if (!mcpHub) {
788-
throw new Error("MCP hub not available")
786+
if (mcpEnabled ?? true) {
787+
mcpHub = this.providerRef.deref()?.mcpHub
788+
if (!mcpHub) {
789+
throw new Error("MCP hub not available")
790+
}
791+
// Wait for MCP servers to be connected before generating system prompt
792+
await pWaitFor(() => mcpHub!.isConnecting !== true, { timeout: 10_000 }).catch(() => {
793+
console.error("MCP servers failed to connect in time")
794+
})
789795
}
790796

791797
const { browserViewportSize, preferredLanguage } = await this.providerRef.deref()?.getState() ?? {}

src/core/prompts/system.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { McpHub } from "../../services/mcp/McpHub"
99
export const SYSTEM_PROMPT = async (
1010
cwd: string,
1111
supportsComputerUse: boolean,
12-
mcpHub: McpHub,
12+
mcpHub?: McpHub,
1313
diffStrategy?: DiffStrategy,
1414
browserViewportSize?: string
1515
) => `You are Cline, a highly skilled software engineer with extensive knowledge in many programming languages, frameworks, design patterns, and best practices.
@@ -146,6 +146,7 @@ Usage:
146146
: ""
147147
}
148148
149+
${mcpHub ? `
149150
## use_mcp_tool
150151
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.
151152
Parameters:
@@ -173,7 +174,7 @@ Usage:
173174
<access_mcp_resource>
174175
<server_name>server name here</server_name>
175176
<uri>resource URI here</uri>
176-
</access_mcp_resource>
177+
</access_mcp_resource>` : ''}
177178
178179
## ask_followup_question
179180
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.
@@ -229,6 +230,7 @@ Your final result description here
229230
<line_count>14</line_count>
230231
</write_to_file>
231232
233+
${mcpHub ? `
232234
## Example 3: Requesting to use an MCP tool
233235
234236
<use_mcp_tool>
@@ -247,7 +249,7 @@ Your final result description here
247249
<access_mcp_resource>
248250
<server_name>weather-server</server_name>
249251
<uri>weather://san-francisco/current</uri>
250-
</access_mcp_resource>
252+
</access_mcp_resource>` : ''}
251253
252254
# Tool Use Guidelines
253255
@@ -272,6 +274,7 @@ By waiting for and carefully considering the user's response after each tool use
272274
273275
====
274276
277+
${mcpHub ? `
275278
MCP SERVERS
276279
277280
The Model Context Protocol (MCP) enables communication between the system and locally running MCP servers that provide additional tools and resources to extend your capabilities.
@@ -675,7 +678,7 @@ However some MCP servers may be running from installed packages rather than a lo
675678
676679
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...").
677680
678-
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.
681+
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.` : ''}
679682
680683
====
681684
@@ -693,7 +696,9 @@ CAPABILITIES
693696
? "\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."
694697
: ""
695698
}
699+
${mcpHub ? `
696700
- 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.
701+
` : ''}
697702
698703
====
699704

src/core/webview/ClineProvider.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ type GlobalStateKey =
7878
| "preferredLanguage" // Language setting for Cline's communication
7979
| "writeDelayMs"
8080
| "terminalOutputLineLimit"
81-
81+
| "mcpEnabled"
8282
export const GlobalFileNames = {
8383
apiConversationHistory: "api_conversation_history.json",
8484
uiMessages: "ui_messages.json",
@@ -606,6 +606,11 @@ export class ClineProvider implements vscode.WebviewViewProvider {
606606
}
607607
break
608608
}
609+
case "mcpEnabled":
610+
const mcpEnabled = message.bool ?? true
611+
await this.updateGlobalState("mcpEnabled", mcpEnabled)
612+
await this.postStateToWebview()
613+
break
609614
case "playSound":
610615
if (message.audioType) {
611616
const soundPath = path.join(this.context.extensionPath, "audio", `${message.audioType}.wav`)
@@ -1056,6 +1061,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
10561061
writeDelayMs,
10571062
terminalOutputLineLimit,
10581063
fuzzyMatchThreshold,
1064+
mcpEnabled,
10591065
} = await this.getState()
10601066

10611067
const allowedCommands = vscode.workspace
@@ -1087,6 +1093,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
10871093
writeDelayMs: writeDelayMs ?? 1000,
10881094
terminalOutputLineLimit: terminalOutputLineLimit ?? 500,
10891095
fuzzyMatchThreshold: fuzzyMatchThreshold ?? 1.0,
1096+
mcpEnabled: mcpEnabled ?? true,
10901097
}
10911098
}
10921099

@@ -1188,6 +1195,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
11881195
writeDelayMs,
11891196
screenshotQuality,
11901197
terminalOutputLineLimit,
1198+
mcpEnabled,
11911199
] = await Promise.all([
11921200
this.getGlobalState("apiProvider") as Promise<ApiProvider | undefined>,
11931201
this.getGlobalState("apiModelId") as Promise<string | undefined>,
@@ -1234,6 +1242,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
12341242
this.getGlobalState("writeDelayMs") as Promise<number | undefined>,
12351243
this.getGlobalState("screenshotQuality") as Promise<number | undefined>,
12361244
this.getGlobalState("terminalOutputLineLimit") as Promise<number | undefined>,
1245+
this.getGlobalState("mcpEnabled") as Promise<boolean | undefined>,
12371246
])
12381247

12391248
let apiProvider: ApiProvider
@@ -1324,6 +1333,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
13241333
// Return mapped language or default to English
13251334
return langMap[vscodeLang.split('-')[0]] ?? 'English';
13261335
})(),
1336+
mcpEnabled: mcpEnabled ?? true,
13271337
}
13281338
}
13291339

src/core/webview/__tests__/ClineProvider.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,7 @@ describe('ClineProvider', () => {
255255
writeDelayMs: 1000,
256256
browserViewportSize: "900x600",
257257
fuzzyMatchThreshold: 1.0,
258+
mcpEnabled: true,
258259
}
259260

260261
const message: ExtensionMessage = {

src/shared/ExtensionMessage.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ export interface ExtensionState {
6262
preferredLanguage: string
6363
writeDelayMs: number
6464
terminalOutputLineLimit?: number
65+
mcpEnabled: boolean
6566
}
6667

6768
export interface ClineMessage {

src/shared/WebviewMessage.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ export interface WebviewMessage {
4949
| "draggedImages"
5050
| "deleteMessage"
5151
| "terminalOutputLineLimit"
52+
| "mcpEnabled"
5253
text?: string
5354
disabled?: boolean
5455
askResponse?: ClineAskResponse
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { VSCodeCheckbox } from "@vscode/webview-ui-toolkit/react"
2+
import { FormEvent } from "react"
3+
import { useExtensionState } from "../../context/ExtensionStateContext"
4+
import { vscode } from "../../utils/vscode"
5+
6+
const McpEnabledToggle = () => {
7+
const { mcpEnabled, setMcpEnabled } = useExtensionState()
8+
9+
const handleChange = (e: Event | FormEvent<HTMLElement>) => {
10+
const target = ('target' in e ? e.target : null) as HTMLInputElement | null
11+
if (!target) return
12+
setMcpEnabled(target.checked)
13+
vscode.postMessage({ type: "mcpEnabled", bool: target.checked })
14+
}
15+
16+
return (
17+
<div style={{ marginBottom: "20px" }}>
18+
<VSCodeCheckbox
19+
checked={mcpEnabled}
20+
onChange={handleChange}>
21+
<span style={{ fontWeight: "500" }}>Enable MCP Servers</span>
22+
</VSCodeCheckbox>
23+
<p style={{
24+
fontSize: "12px",
25+
marginTop: "5px",
26+
color: "var(--vscode-descriptionForeground)",
27+
}}>
28+
When enabled, Cline will be able to interact with MCP servers for advanced functionality. If you're not using MCP, you can disable this to reduce Cline's token usage.
29+
</p>
30+
</div>
31+
)
32+
}
33+
34+
export default McpEnabledToggle

webview-ui/src/components/mcp/McpView.tsx

Lines changed: 29 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,14 @@ import { useExtensionState } from "../../context/ExtensionStateContext"
1111
import { McpServer } from "../../../../src/shared/mcp"
1212
import McpToolRow from "./McpToolRow"
1313
import McpResourceRow from "./McpResourceRow"
14+
import McpEnabledToggle from "./McpEnabledToggle"
1415

1516
type McpViewProps = {
1617
onDone: () => void
1718
}
1819

1920
const McpView = ({ onDone }: McpViewProps) => {
20-
const { mcpServers: servers, alwaysAllowMcp } = useExtensionState()
21+
const { mcpServers: servers, alwaysAllowMcp, mcpEnabled } = useExtensionState()
2122
// const [servers, setServers] = useState<McpServer[]>([
2223
// // Add some mock servers for testing
2324
// {
@@ -106,7 +107,7 @@ const McpView = ({ onDone }: McpViewProps) => {
106107
style={{
107108
color: "var(--vscode-foreground)",
108109
fontSize: "13px",
109-
marginBottom: "20px",
110+
marginBottom: "10px",
110111
marginTop: "5px",
111112
}}>
112113
The{" "}
@@ -122,27 +123,33 @@ const McpView = ({ onDone }: McpViewProps) => {
122123
npm docs").
123124
</div>
124125

125-
{/* Server List */}
126-
{servers.length > 0 && (
127-
<div style={{ display: "flex", flexDirection: "column", gap: "10px" }}>
128-
{servers.map((server) => (
129-
<ServerRow key={server.name} server={server} alwaysAllowMcp={alwaysAllowMcp} />
130-
))}
131-
</div>
132-
)}
126+
<McpEnabledToggle />
133127

134-
{/* Edit Settings Button */}
135-
<div style={{ marginTop: "10px", width: "100%" }}>
136-
<VSCodeButton
137-
appearance="secondary"
138-
style={{ width: "100%" }}
139-
onClick={() => {
140-
vscode.postMessage({ type: "openMcpSettings" })
141-
}}>
142-
<span className="codicon codicon-edit" style={{ marginRight: "6px" }}></span>
143-
Edit MCP Settings
144-
</VSCodeButton>
145-
</div>
128+
{mcpEnabled && (
129+
<>
130+
{/* Server List */}
131+
{servers.length > 0 && (
132+
<div style={{ display: "flex", flexDirection: "column", gap: "10px" }}>
133+
{servers.map((server) => (
134+
<ServerRow key={server.name} server={server} alwaysAllowMcp={alwaysAllowMcp} />
135+
))}
136+
</div>
137+
)}
138+
139+
{/* Edit Settings Button */}
140+
<div style={{ marginTop: "10px", width: "100%" }}>
141+
<VSCodeButton
142+
appearance="secondary"
143+
style={{ width: "100%" }}
144+
onClick={() => {
145+
vscode.postMessage({ type: "openMcpSettings" })
146+
}}>
147+
<span className="codicon codicon-edit" style={{ marginRight: "6px" }}></span>
148+
Edit MCP Settings
149+
</VSCodeButton>
150+
</div>
151+
</>
152+
)}
146153

147154
{/* Bottom padding */}
148155
<div style={{ height: "20px" }} />

0 commit comments

Comments
 (0)