Add MCP Servers view

This commit is contained in:
Saoud Rizwan
2024-12-01 12:13:16 -08:00
parent b5d03dd523
commit 5052944efe
6 changed files with 11441 additions and 11371 deletions

View File

@@ -69,6 +69,11 @@
"title": "New Task", "title": "New Task",
"icon": "$(add)" "icon": "$(add)"
}, },
{
"command": "cline.mcpButtonClicked",
"title": "MCP Servers",
"icon": "$(server)"
},
{ {
"command": "cline.historyButtonClicked", "command": "cline.historyButtonClicked",
"title": "History", "title": "History",
@@ -98,19 +103,24 @@
"when": "view == claude-dev.SidebarProvider" "when": "view == claude-dev.SidebarProvider"
}, },
{ {
"command": "cline.historyButtonClicked", "command": "cline.mcpButtonClicked",
"group": "navigation@2", "group": "navigation@2",
"when": "view == claude-dev.SidebarProvider" "when": "view == claude-dev.SidebarProvider"
}, },
{ {
"command": "cline.popoutButtonClicked", "command": "cline.historyButtonClicked",
"group": "navigation@3", "group": "navigation@3",
"when": "view == claude-dev.SidebarProvider" "when": "view == claude-dev.SidebarProvider"
}, },
{ {
"command": "cline.settingsButtonClicked", "command": "cline.popoutButtonClicked",
"group": "navigation@4", "group": "navigation@4",
"when": "view == claude-dev.SidebarProvider" "when": "view == claude-dev.SidebarProvider"
},
{
"command": "cline.settingsButtonClicked",
"group": "navigation@5",
"when": "view == claude-dev.SidebarProvider"
} }
] ]
} }

View File

@@ -43,6 +43,12 @@ export function activate(context: vscode.ExtensionContext) {
}), }),
) )
context.subscriptions.push(
vscode.commands.registerCommand("cline.mcpButtonClicked", () => {
sidebarProvider.postMessageToWebview({ type: "action", action: "mcpButtonClicked" })
}),
)
const openClineInNewTab = async () => { const openClineInNewTab = async () => {
outputChannel.appendLine("Opening Cline in new tab") outputChannel.appendLine("Opening Cline in new tab")
// (this example uses webviewProvider activation event which is necessary to deserialize cached webview, but since we use retainContextWhenHidden, we don't need to use that event) // (this example uses webviewProvider activation event which is necessary to deserialize cached webview, but since we use retainContextWhenHidden, we don't need to use that event)

View File

@@ -17,7 +17,12 @@ export interface ExtensionMessage {
| "partialMessage" | "partialMessage"
| "openRouterModels" | "openRouterModels"
text?: string text?: string
action?: "chatButtonClicked" | "settingsButtonClicked" | "historyButtonClicked" | "didBecomeVisible" action?:
| "chatButtonClicked"
| "mcpButtonClicked"
| "settingsButtonClicked"
| "historyButtonClicked"
| "didBecomeVisible"
invoke?: "sendMessage" | "primaryButtonClick" | "secondaryButtonClick" invoke?: "sendMessage" | "primaryButtonClick" | "secondaryButtonClick"
state?: ExtensionState state?: ExtensionState
images?: string[] images?: string[]

View File

@@ -7,11 +7,13 @@ import SettingsView from "./components/settings/SettingsView"
import WelcomeView from "./components/welcome/WelcomeView" import WelcomeView from "./components/welcome/WelcomeView"
import { ExtensionStateContextProvider, useExtensionState } from "./context/ExtensionStateContext" import { ExtensionStateContextProvider, useExtensionState } from "./context/ExtensionStateContext"
import { vscode } from "./utils/vscode" import { vscode } from "./utils/vscode"
import McpView from "./components/mcp/McpView"
const AppContent = () => { const AppContent = () => {
const { didHydrateState, showWelcome, shouldShowAnnouncement } = useExtensionState() const { didHydrateState, showWelcome, shouldShowAnnouncement } = useExtensionState()
const [showSettings, setShowSettings] = useState(false) const [showSettings, setShowSettings] = useState(false)
const [showHistory, setShowHistory] = useState(false) const [showHistory, setShowHistory] = useState(false)
const [showMcp, setShowMcp] = useState(false)
const [showAnnouncement, setShowAnnouncement] = useState(false) const [showAnnouncement, setShowAnnouncement] = useState(false)
const handleMessage = useCallback((e: MessageEvent) => { const handleMessage = useCallback((e: MessageEvent) => {
@@ -22,14 +24,22 @@ const AppContent = () => {
case "settingsButtonClicked": case "settingsButtonClicked":
setShowSettings(true) setShowSettings(true)
setShowHistory(false) setShowHistory(false)
setShowMcp(false)
break break
case "historyButtonClicked": case "historyButtonClicked":
setShowSettings(false) setShowSettings(false)
setShowHistory(true) setShowHistory(true)
setShowMcp(false)
break
case "mcpButtonClicked":
setShowSettings(false)
setShowHistory(false)
setShowMcp(true)
break break
case "chatButtonClicked": case "chatButtonClicked":
setShowSettings(false) setShowSettings(false)
setShowHistory(false) setShowHistory(false)
setShowMcp(false)
break break
} }
break break
@@ -57,13 +67,15 @@ const AppContent = () => {
<> <>
{showSettings && <SettingsView onDone={() => setShowSettings(false)} />} {showSettings && <SettingsView onDone={() => setShowSettings(false)} />}
{showHistory && <HistoryView onDone={() => setShowHistory(false)} />} {showHistory && <HistoryView onDone={() => setShowHistory(false)} />}
{showMcp && <McpView onDone={() => setShowMcp(false)} />}
{/* Do not conditionally load ChatView, it's expensive and there's state we don't want to lose (user input, disableInput, askResponse promise, etc.) */} {/* Do not conditionally load ChatView, it's expensive and there's state we don't want to lose (user input, disableInput, askResponse promise, etc.) */}
<ChatView <ChatView
showHistoryView={() => { showHistoryView={() => {
setShowSettings(false) setShowSettings(false)
setShowMcp(false)
setShowHistory(true) setShowHistory(true)
}} }}
isHidden={showSettings || showHistory} isHidden={showSettings || showHistory || showMcp}
showAnnouncement={showAnnouncement} showAnnouncement={showAnnouncement}
hideAnnouncement={() => { hideAnnouncement={() => {
setShowAnnouncement(false) setShowAnnouncement(false)

View File

@@ -0,0 +1,37 @@
import { VSCodeButton } from "@vscode/webview-ui-toolkit/react"
type McpViewProps = {
onDone: () => void
}
const McpView = ({ onDone }: McpViewProps) => {
return (
<div
style={{
position: "fixed",
top: 0,
left: 0,
right: 0,
bottom: 0,
display: "flex",
flexDirection: "column",
overflow: "hidden",
}}>
<div
style={{
display: "flex",
justifyContent: "space-between",
alignItems: "center",
padding: "10px 17px 10px 20px",
}}>
<h3 style={{ color: "var(--vscode-foreground)", margin: 0 }}>MCP</h3>
<VSCodeButton onClick={onDone}>Done</VSCodeButton>
</div>
<div style={{ padding: "20px", display: "flex", justifyContent: "center" }}>
<VSCodeButton>Add Server</VSCodeButton>
</div>
</div>
)
}
export default McpView