Feat: MCP Marketplace Setting (#1877)

* feat-mc-marketplace-setting

* add changeset

* Fixes

---------

Co-authored-by: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com>
This commit is contained in:
Shawn Smith
2025-02-19 23:40:22 -08:00
committed by GitHub
parent cd3f3e2150
commit 45e1f58bbc
6 changed files with 49 additions and 80 deletions
+5
View File
@@ -0,0 +1,5 @@
---
"claude-dev": patch
---
A new MCP Marketplace display setting has been added to VSCode settings. (It is defaulted to "true")
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "claude-dev",
"version": "3.4.1",
"version": "3.4.3",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "claude-dev",
"version": "3.4.1",
"version": "3.4.3",
"license": "Apache-2.0",
"dependencies": {
"@anthropic-ai/bedrock-sdk": "^0.10.2",
+5
View File
@@ -181,6 +181,11 @@
"type": "string",
"default": null,
"description": "Path to Chrome executable for browser use functionality. If not set, the extension will attempt to find or download it automatically."
},
"cline.mcpMarketplace.enabled": {
"type": "boolean",
"default": true,
"description": "Controls whether the MCP Marketplace is enabled."
}
}
}
+10 -1
View File
@@ -240,7 +240,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
this.disposables,
)
// Listen for when color changes
// Listen for configuration changes
vscode.workspace.onDidChangeConfiguration(
async (e) => {
if (e && e.affectsConfiguration("workbench.colorTheme")) {
@@ -250,6 +250,10 @@ export class ClineProvider implements vscode.WebviewViewProvider {
text: JSON.stringify(await getTheme()),
})
}
if (e && e.affectsConfiguration("cline.mcpMarketplace.enabled")) {
// Update state when marketplace tab setting changes
await this.postStateToWebview()
}
},
null,
this.disposables,
@@ -1581,6 +1585,7 @@ Here is the project's README to help you get started:\n\n${mcpDetails.readmeCont
chatSettings,
userInfo,
authToken,
mcpMarketplaceEnabled,
} = await this.getState()
return {
@@ -1599,6 +1604,7 @@ Here is the project's README to help you get started:\n\n${mcpDetails.readmeCont
chatSettings,
isLoggedIn: !!authToken,
userInfo,
mcpMarketplaceEnabled,
}
}
@@ -1776,6 +1782,8 @@ Here is the project's README to help you get started:\n\n${mcpDetails.readmeCont
.getConfiguration("cline.modelSettings.o3Mini")
.get("reasoningEffort", "medium")
const mcpMarketplaceEnabled = vscode.workspace.getConfiguration("cline").get<boolean>("mcpMarketplace.enabled", true)
return {
apiConfiguration: {
apiProvider,
@@ -1830,6 +1838,7 @@ Here is the project's README to help you get started:\n\n${mcpDetails.readmeCont
previousModeApiProvider,
previousModeModelId,
previousModeModelInfo,
mcpMarketplaceEnabled,
}
}
+1
View File
@@ -80,6 +80,7 @@ export interface ExtensionState {
email: string | null
photoURL: string | null
}
mcpMarketplaceEnabled?: boolean
}
export interface ClineMessage {
+26 -77
View File
@@ -1,92 +1,40 @@
import { VSCodeButton, VSCodeLink, VSCodePanels, VSCodePanelTab, VSCodePanelView } from "@vscode/webview-ui-toolkit/react"
import { useState, useEffect } from "react"
import { vscode } from "../../utils/vscode"
import { useExtensionState } from "../../context/ExtensionStateContext"
import { McpServer } from "../../../../src/shared/mcp"
import McpToolRow from "./McpToolRow"
import McpResourceRow from "./McpResourceRow"
import McpMarketplaceView from "./marketplace/McpMarketplaceView"
import { useEffect, useState } from "react"
import styled from "styled-components"
import { McpServer } from "../../../../src/shared/mcp"
import { useExtensionState } from "../../context/ExtensionStateContext"
import { getMcpServerDisplayName } from "../../utils/mcp"
import { vscode } from "../../utils/vscode"
import DangerButton from "../common/DangerButton"
import McpMarketplaceView from "./marketplace/McpMarketplaceView"
import McpResourceRow from "./McpResourceRow"
import McpToolRow from "./McpToolRow"
type McpViewProps = {
onDone: () => void
}
const McpView = ({ onDone }: McpViewProps) => {
const { mcpServers: servers } = useExtensionState()
const [activeTab, setActiveTab] = useState("marketplace")
const { mcpServers: servers, mcpMarketplaceEnabled } = useExtensionState()
const [activeTab, setActiveTab] = useState(mcpMarketplaceEnabled ? "marketplace" : "installed")
const handleTabChange = (tab: string) => {
setActiveTab(tab)
}
useEffect(() => {
vscode.postMessage({ type: "silentlyRefreshMcpMarketplace" })
vscode.postMessage({ type: "fetchLatestMcpServersFromHub" })
}, [])
if (!mcpMarketplaceEnabled && activeTab === "marketplace") {
// If marketplace is disabled and we're on marketplace tab, switch to installed
setActiveTab("installed")
}
}, [mcpMarketplaceEnabled, activeTab])
// const [servers, setServers] = useState<McpServer[]>([
// // Add some mock servers for testing
// {
// name: "local-tools",
// config: JSON.stringify({
// mcpServers: {
// "local-tools": {
// command: "npx",
// args: ["-y", "@modelcontextprotocol/server-tools"],
// },
// },
// }),
// status: "connected",
// tools: [
// {
// name: "execute_command",
// description: "Run a shell command on the local system",
// },
// {
// name: "read_file",
// description: "Read contents of a file from the filesystem",
// },
// ],
// },
// {
// name: "postgres-db",
// config: JSON.stringify({
// mcpServers: {
// "postgres-db": {
// command: "npx",
// args: ["-y", "@modelcontextprotocol/server-postgres", "postgresql://localhost/mydb"],
// },
// },
// }),
// status: "disconnected",
// error: "Failed to connect to database: Connection refused",
// },
// {
// name: "github-tools",
// config: JSON.stringify({
// mcpServers: {
// "github-tools": {
// command: "npx",
// args: ["-y", "@modelcontextprotocol/server-github"],
// },
// },
// }),
// status: "connecting",
// resources: [
// {
// uri: "github://repo/issues",
// name: "Repository Issues",
// },
// {
// uri: "github://repo/pulls",
// name: "Pull Requests",
// },
// ],
// },
// ])
useEffect(() => {
if (mcpMarketplaceEnabled) {
vscode.postMessage({ type: "silentlyRefreshMcpMarketplace" })
vscode.postMessage({ type: "fetchLatestMcpServersFromHub" })
}
}, [mcpMarketplaceEnabled])
return (
<div
@@ -119,9 +67,11 @@ const McpView = ({ onDone }: McpViewProps) => {
padding: "0 20px 0 20px",
borderBottom: "1px solid var(--vscode-panel-border)",
}}>
<TabButton isActive={activeTab === "marketplace"} onClick={() => handleTabChange("marketplace")}>
Marketplace
</TabButton>
{mcpMarketplaceEnabled && (
<TabButton isActive={activeTab === "marketplace"} onClick={() => handleTabChange("marketplace")}>
Marketplace
</TabButton>
)}
<TabButton isActive={activeTab === "installed"} onClick={() => handleTabChange("installed")}>
Installed
</TabButton>
@@ -129,7 +79,7 @@ const McpView = ({ onDone }: McpViewProps) => {
{/* Content container */}
<div style={{ width: "100%" }}>
{activeTab === "marketplace" && <McpMarketplaceView />}
{mcpMarketplaceEnabled && activeTab === "marketplace" && <McpMarketplaceView />}
{activeTab === "installed" && (
<div style={{ padding: "16px 20px" }}>
<div
@@ -472,7 +422,6 @@ const ServerRow = ({ server }: { server: McpServer }) => {
</VSCodeButton>
<DangerButton
// appearance="secondary"
onClick={handleDelete}
disabled={isDeleting}
style={{