cline/webview-ui/src/components/mcp/configuration/tabs/installed/server-row/McpToolRow.tsx
Evan dfcb3d5d9b
PROTOBUS: toggleMcpServer (#3063)
* wip

* migrate toggleMcpServer

* changeset

* support optional types and enum type
2025-04-22 16:29:13 -07:00

128 lines
3.3 KiB
TypeScript

import { VSCodeCheckbox } from "@vscode/webview-ui-toolkit/react"
import { McpTool } from "@shared/mcp"
import { vscode } from "@/utils/vscode"
import { useExtensionState } from "@/context/ExtensionStateContext"
type McpToolRowProps = {
tool: McpTool
serverName?: string
}
const McpToolRow = ({ tool, serverName }: McpToolRowProps) => {
const { autoApprovalSettings } = useExtensionState()
// Accept the event object
const handleAutoApproveChange = (event: any) => {
// Only proceed if the event was triggered by a direct user interaction
if (!serverName) {
return
}
vscode.postMessage({
type: "toggleToolAutoApprove",
serverName,
toolNames: [tool.name],
autoApprove: !tool.autoApprove,
})
}
return (
<div
key={tool.name}
style={{
padding: "3px 0",
}}>
<div
data-testid="tool-row-container"
style={{ display: "flex", alignItems: "center", justifyContent: "space-between" }}
onClick={(e) => e.stopPropagation()}>
<div style={{ display: "flex", alignItems: "center" }}>
<span className="codicon codicon-symbol-method" style={{ marginRight: "6px" }}></span>
<span style={{ fontWeight: 500 }}>{tool.name}</span>
</div>
{serverName && autoApprovalSettings.enabled && autoApprovalSettings.actions.useMcp && (
<VSCodeCheckbox checked={tool.autoApprove ?? false} onChange={handleAutoApproveChange} data-tool={tool.name}>
Auto-approve
</VSCodeCheckbox>
)}
</div>
{tool.description && (
<div
style={{
marginLeft: "0px",
marginTop: "4px",
opacity: 0.8,
fontSize: "12px",
}}>
{tool.description}
</div>
)}
{tool.inputSchema &&
"properties" in tool.inputSchema &&
Object.keys(tool.inputSchema.properties as Record<string, any>).length > 0 && (
<div
style={{
marginTop: "8px",
fontSize: "12px",
border: "1px solid color-mix(in srgb, var(--vscode-descriptionForeground) 30%, transparent)",
borderRadius: "3px",
padding: "8px",
}}>
<div
style={{
marginBottom: "4px",
opacity: 0.8,
fontSize: "11px",
textTransform: "uppercase",
}}>
Parameters
</div>
{Object.entries(tool.inputSchema.properties as Record<string, any>).map(([paramName, schema]) => {
const isRequired =
tool.inputSchema &&
"required" in tool.inputSchema &&
Array.isArray(tool.inputSchema.required) &&
tool.inputSchema.required.includes(paramName)
return (
<div
key={paramName}
style={{
display: "flex",
alignItems: "baseline",
marginTop: "4px",
}}>
<code
style={{
color: "var(--vscode-textPreformat-foreground)",
marginRight: "8px",
}}>
{paramName}
{isRequired && (
<span
style={{
color: "var(--vscode-errorForeground)",
}}>
*
</span>
)}
</code>
<span
style={{
opacity: 0.8,
overflowWrap: "break-word",
wordBreak: "break-word",
}}>
{schema.description || "No description"}
</span>
</div>
)
})}
</div>
)}
</div>
)
}
export default McpToolRow