Compare commits

...
Author SHA1 Message Date
Saoud Rizwan 398b90c32c Fix max width 2025-04-03 21:36:18 -07:00
celestial-vault 63ba98008f punctuation 2025-04-03 17:24:44 -07:00
celestial-vault 142370f61d changeset 2025-04-03 10:53:26 -07:00
celestial-vault c0997ac8f6 docs links 2025-04-03 10:51:22 -07:00
Saoud Rizwan 08dd2a2b00 Remove form 2025-04-01 20:58:05 -07:00
Saoud Rizwan fa36d70b6a Add local mcp servers tab 2025-04-01 20:23:26 -07:00
6 changed files with 119 additions and 33 deletions
+5
View File
@@ -0,0 +1,5 @@
---
"claude-dev": minor
---
Added a tab for configuring local servers and documentation links
+31 -4
View File
@@ -19,6 +19,7 @@ import McpResourceRow from "./McpResourceRow"
import McpToolRow from "./McpToolRow"
import DangerButton from "../common/DangerButton"
import AddRemoteServerForm from "./tabs/AddRemoteServerForm"
import AddLocalServerForm from "./tabs/AddLocalServerForm"
type McpViewProps = {
onDone: () => void
@@ -27,6 +28,7 @@ type McpViewProps = {
const McpView = ({ onDone }: McpViewProps) => {
const { mcpServers: servers, mcpMarketplaceEnabled } = useExtensionState()
const [activeTab, setActiveTab] = useState(mcpMarketplaceEnabled ? "marketplace" : "installed")
const [activeSubTab, setActiveSubTab] = useState("remote")
const handleTabChange = (tab: string) => {
setActiveTab(tab)
@@ -83,7 +85,7 @@ const McpView = ({ onDone }: McpViewProps) => {
</TabButton>
)}
<TabButton isActive={activeTab === "addRemote"} onClick={() => handleTabChange("addRemote")}>
Remote Servers
Add Server
</TabButton>
<TabButton isActive={activeTab === "installed"} onClick={() => handleTabChange("installed")}>
Installed
@@ -93,7 +95,33 @@ const McpView = ({ onDone }: McpViewProps) => {
{/* Content container */}
<div style={{ width: "100%" }}>
{mcpMarketplaceEnabled && activeTab === "marketplace" && <McpMarketplaceView />}
{activeTab === "addRemote" && <AddRemoteServerForm onServerAdded={() => handleTabChange("installed")} />}
{activeTab === "addRemote" && (
<div style={{ padding: "5px 0 0 0" }}>
<div
style={{
display: "flex",
gap: "1px",
padding: "0 20px 0 20px",
borderBottom: "1px solid var(--vscode-panel-border)",
}}>
<TabButton isActive={activeSubTab === "remote"} onClick={() => setActiveSubTab("remote")}>
Remote (SSE)
</TabButton>
<TabButton isActive={activeSubTab === "local"} onClick={() => setActiveSubTab("local")}>
Local (Command)
</TabButton>
</div>
<div>
{activeSubTab === "remote" && (
<AddRemoteServerForm onServerAdded={() => handleTabChange("installed")} />
)}
{activeSubTab === "local" && (
<AddLocalServerForm onServerAdded={() => handleTabChange("installed")} />
)}
</div>
</div>
)}
{activeTab === "installed" && (
<div style={{ padding: "16px 20px" }}>
<div
@@ -153,8 +181,7 @@ const McpView = ({ onDone }: McpViewProps) => {
onClick={() => {
vscode.postMessage({ type: "openMcpSettings" })
}}>
<span className="codicon codicon-server" style={{ marginRight: "6px" }}></span>
Configure MCP Servers
Edit Configuration
</VSCodeButton>
<div style={{ textAlign: "center" }}>
@@ -0,0 +1,41 @@
import { VSCodeButton, VSCodeLink } from "@vscode/webview-ui-toolkit/react"
import { vscode } from "../../../utils/vscode"
import styled from "styled-components"
import { LINKS } from "../../../constants"
type AddLocalServerFormProps = {
onServerAdded: () => void
}
const AddLocalServerForm = ({ onServerAdded }: AddLocalServerFormProps) => {
return (
<FormContainer>
<div className="text-[var(--vscode-foreground)]">
Add a local MCP server by configuring it in <code>cline_mcp_settings.json</code>. You'll need to specify the
server name, command, arguments, and any required environment variables in the JSON configuration. Learn more
<VSCodeLink href={LINKS.DOCUMENTATION.LOCAL_MCP_SERVER_DOCS} style={{ display: "inline" }}>
here.
</VSCodeLink>
</div>
<VSCodeButton
appearance="primary"
style={{ width: "100%", marginBottom: "5px", marginTop: 8 }}
onClick={() => {
vscode.postMessage({ type: "openMcpSettings" })
}}>
Open cline_mcp_settings.json
</VSCodeButton>
</FormContainer>
)
}
const FormContainer = styled.div`
padding: 16px 20px;
display: flex;
flex-direction: column;
gap: 8px;
`
export default AddLocalServerForm
@@ -1,8 +1,8 @@
import { useCallback, useEffect, useRef, useState } from "react"
import { useCallback, useRef, useState } from "react"
import { vscode } from "../../../utils/vscode"
import { VSCodeButton } from "@vscode/webview-ui-toolkit/react"
import { VSCodeButton, VSCodeLink, VSCodeTextField } from "@vscode/webview-ui-toolkit/react"
import { useEvent } from "react-use"
import { LINKS } from "../../../constants"
const AddRemoteServerForm = ({ onServerAdded }: { onServerAdded: () => void }) => {
const [serverName, setServerName] = useState("")
const [serverUrl, setServerUrl] = useState("")
@@ -79,48 +79,46 @@ const AddRemoteServerForm = ({ onServerAdded }: { onServerAdded: () => void }) =
return (
<div className="p-4 px-5">
<div className="text-[var(--vscode-foreground)] text-sm mb-4 mt-1 max-w-lg">
Add a remote MCP server by providing a name and its URL endpoint.
<div className="text-[var(--vscode-foreground)] mb-2">
Add a remote MCP server by providing a name and its URL endpoint. Learn more{" "}
<VSCodeLink href={LINKS.DOCUMENTATION.REMOTE_MCP_SERVER_DOCS} style={{ display: "inline" }}>
here.
</VSCodeLink>
</div>
<form onSubmit={handleSubmit}>
{error && (
<div className="text-[var(--vscode-testing-iconFailed)] mb-3 p-2 rounded bg-[var(--vscode-inputValidation-warningBackground)] border border-[var(--vscode-inputValidation-warningBorder)]">
{error}
</div>
)}
<div className="mb-4 mr-4">
<label className="block mb-1">Server Name</label>
<input
type="text"
<div className="mb-2">
<VSCodeTextField
value={serverName}
onChange={(e) => {
setServerName(e.target.value)
setServerName((e.target as HTMLInputElement).value)
setError("")
}}
disabled={isSubmitting}
className="w-full max-w-md mr-4 p-2 bg-[var(--vscode-input-background)] text-[var(--vscode-input-foreground)] border border-[var(--vscode-input-border)] rounded"
/>
className="w-full"
placeholder="mcp-server">
Server Name
</VSCodeTextField>
</div>
<div className="mb-4 mr-4">
<label className="block mb-1">Server URL</label>
<input
type="text"
<div className="mb-2">
<VSCodeTextField
value={serverUrl}
onChange={(e) => {
setServerUrl(e.target.value)
setServerUrl((e.target as HTMLInputElement).value)
setError("")
}}
disabled={isSubmitting}
placeholder="https://example.com/mcp-sse"
className="w-full max-w-md mr-4 p-2 bg-[var(--vscode-input-background)] text-[var(--vscode-input-foreground)] border border-[var(--vscode-input-border)] rounded"
/>
placeholder="https://example.com/mcp-server"
className="w-full mr-4">
Server URL
</VSCodeTextField>
</div>
<div className="flex items-center mt-3">
<VSCodeButton type="submit" disabled={isSubmitting}>
{error && <div className="mb-3 text-[var(--vscode-errorForeground)]">{error}</div>}
<div className="flex items-center mt-3 w-full">
<VSCodeButton type="submit" disabled={isSubmitting} className="w-full">
{isSubmitting ? "Adding..." : "Add Server"}
</VSCodeButton>
@@ -130,6 +128,15 @@ const AddRemoteServerForm = ({ onServerAdded }: { onServerAdded: () => void }) =
</div>
)}
</div>
<VSCodeButton
appearance="secondary"
style={{ width: "100%", marginBottom: "5px", marginTop: 15 }}
onClick={() => {
vscode.postMessage({ type: "openMcpSettings" })
}}>
Edit Configuration
</VSCodeButton>
</form>
</div>
)
@@ -1212,7 +1212,7 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, is
style={{
fontSize: "12px",
marginTop: "5px",
color: "var(--vscode-charts-green)",
color: "var(--vscode-descriptionForeground)",
}}>
Extended thinking is available for models as Sonnet-3-7, o3-mini, Deepseek R1, etc. More info on{" "}
<VSCodeLink
+6
View File
@@ -0,0 +1,6 @@
export const LINKS = {
DOCUMENTATION: {
REMOTE_MCP_SERVER_DOCS: "https://docs.cline.bot/mcp-servers/connecting-to-a-remote-server",
LOCAL_MCP_SERVER_DOCS: "https://docs.cline.bot/mcp-servers/configuring-mcp-servers#editing-mcp-settings-files",
},
}