mirror of
https://github.com/cline/cline.git
synced 2026-09-19 02:05:44 +08:00
Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a24d48a445 | ||
|
|
4a8ffb98e9 | ||
|
|
cf256c9f94 |
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"claude-dev": minor
|
||||||
|
---
|
||||||
|
|
||||||
|
Migrate addRemoteServer to protobus
|
||||||
@@ -7,6 +7,20 @@ import "common.proto";
|
|||||||
service McpService {
|
service McpService {
|
||||||
rpc toggleMcpServer(ToggleMcpServerRequest) returns (McpServers);
|
rpc toggleMcpServer(ToggleMcpServerRequest) returns (McpServers);
|
||||||
rpc updateMcpTimeout(UpdateMcpTimeoutRequest) returns (McpServers);
|
rpc updateMcpTimeout(UpdateMcpTimeoutRequest) returns (McpServers);
|
||||||
|
rpc addRemoteServer(AddRemoteServerRequest) returns (AddRemoteServer);
|
||||||
|
}
|
||||||
|
|
||||||
|
message AddRemoteServerRequest {
|
||||||
|
Metadata metadata = 1;
|
||||||
|
string server_name = 2;
|
||||||
|
string server_url = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message AddRemoteServer {
|
||||||
|
bool success = 1;
|
||||||
|
string server_name = 2;
|
||||||
|
optional string error = 3;
|
||||||
|
repeated McpServer mcp_servers = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
message ToggleMcpServerRequest {
|
message ToggleMcpServerRequest {
|
||||||
|
|||||||
@@ -186,28 +186,6 @@ export class Controller {
|
|||||||
*/
|
*/
|
||||||
async handleWebviewMessage(message: WebviewMessage) {
|
async handleWebviewMessage(message: WebviewMessage) {
|
||||||
switch (message.type) {
|
switch (message.type) {
|
||||||
case "addRemoteServer": {
|
|
||||||
try {
|
|
||||||
await this.mcpHub?.addRemoteServer(message.serverName!, message.serverUrl!)
|
|
||||||
await this.postMessageToWebview({
|
|
||||||
type: "addRemoteServerResult",
|
|
||||||
addRemoteServerResult: {
|
|
||||||
success: true,
|
|
||||||
serverName: message.serverName!,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
} catch (error) {
|
|
||||||
await this.postMessageToWebview({
|
|
||||||
type: "addRemoteServerResult",
|
|
||||||
addRemoteServerResult: {
|
|
||||||
success: false,
|
|
||||||
serverName: message.serverName!,
|
|
||||||
error: error.message,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
case "authStateChanged":
|
case "authStateChanged":
|
||||||
await this.setUserInfo(message.user || undefined)
|
await this.setUserInfo(message.user || undefined)
|
||||||
await this.postStateToWebview()
|
await this.postStateToWebview()
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
import { AddRemoteServer, AddRemoteServerRequest } from "@/shared/proto/mcp"
|
||||||
|
import { Controller } from ".."
|
||||||
|
import { convertMcpServersToProtoMcpServers } from "@/shared/proto-conversions/mcp/mcp-server-conversion"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a remote MCP server
|
||||||
|
* @param controller The controller instance
|
||||||
|
* @param request The request message
|
||||||
|
* @returns The result of adding the remote server
|
||||||
|
*/
|
||||||
|
export async function addRemoteServer(controller: Controller, request: AddRemoteServerRequest): Promise<AddRemoteServer> {
|
||||||
|
try {
|
||||||
|
const mcpServers = await controller.mcpHub?.addRemoteServerRPC(request.serverName, request.serverUrl)
|
||||||
|
|
||||||
|
const mcpServersProto = convertMcpServersToProtoMcpServers(mcpServers)
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
serverName: request.serverName,
|
||||||
|
mcpServers: mcpServersProto,
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
serverName: request.serverName,
|
||||||
|
error: error instanceof Error ? error.message : String(error),
|
||||||
|
mcpServers: [], // Empty array for error case
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,12 +3,14 @@
|
|||||||
|
|
||||||
// Import all method implementations
|
// Import all method implementations
|
||||||
import { registerMethod } from "./index"
|
import { registerMethod } from "./index"
|
||||||
|
import { addRemoteServer } from "./addRemoteServer"
|
||||||
import { toggleMcpServer } from "./toggleMcpServer"
|
import { toggleMcpServer } from "./toggleMcpServer"
|
||||||
import { updateMcpTimeout } from "./updateMcpTimeout"
|
import { updateMcpTimeout } from "./updateMcpTimeout"
|
||||||
|
|
||||||
// Register all mcp service methods
|
// Register all mcp service methods
|
||||||
export function registerAllMethods(): void {
|
export function registerAllMethods(): void {
|
||||||
// Register each method with the registry
|
// Register each method with the registry
|
||||||
|
registerMethod("addRemoteServer", addRemoteServer)
|
||||||
registerMethod("toggleMcpServer", toggleMcpServer)
|
registerMethod("toggleMcpServer", toggleMcpServer)
|
||||||
registerMethod("updateMcpTimeout", updateMcpTimeout)
|
registerMethod("updateMcpTimeout", updateMcpTimeout)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -691,14 +691,14 @@ export class McpHub {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async addRemoteServer(serverName: string, serverUrl: string) {
|
public async addRemoteServerRPC(serverName: string, serverUrl: string) {
|
||||||
try {
|
try {
|
||||||
const settings = await this.readAndValidateMcpSettingsFile()
|
const config = await this.readAndValidateMcpSettingsFile()
|
||||||
if (!settings) {
|
if (!config) {
|
||||||
throw new Error("Failed to read MCP settings")
|
throw new Error("Failed to read MCP settings")
|
||||||
}
|
}
|
||||||
|
|
||||||
if (settings.mcpServers[serverName]) {
|
if (config.mcpServers[serverName]) {
|
||||||
throw new Error(`An MCP server with the name "${serverName}" already exists`)
|
throw new Error(`An MCP server with the name "${serverName}" already exists`)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -715,7 +715,7 @@ export class McpHub {
|
|||||||
|
|
||||||
const parsedConfig = ServerConfigSchema.parse(serverConfig)
|
const parsedConfig = ServerConfigSchema.parse(serverConfig)
|
||||||
|
|
||||||
settings.mcpServers[serverName] = parsedConfig
|
config.mcpServers[serverName] = parsedConfig
|
||||||
const settingsPath = await this.getMcpSettingsFilePath()
|
const settingsPath = await this.getMcpSettingsFilePath()
|
||||||
|
|
||||||
// We don't write the zod-transformed version to the file.
|
// We don't write the zod-transformed version to the file.
|
||||||
@@ -725,12 +725,21 @@ export class McpHub {
|
|||||||
// ToDo: We could benefit from input / output types reflecting the non-transformed / transformed versions
|
// ToDo: We could benefit from input / output types reflecting the non-transformed / transformed versions
|
||||||
await fs.writeFile(
|
await fs.writeFile(
|
||||||
settingsPath,
|
settingsPath,
|
||||||
JSON.stringify({ mcpServers: { ...settings.mcpServers, [serverName]: serverConfig } }, null, 2),
|
JSON.stringify({ mcpServers: { ...config.mcpServers, [serverName]: serverConfig } }, null, 2),
|
||||||
)
|
)
|
||||||
|
|
||||||
await this.updateServerConnections(settings.mcpServers)
|
await this.updateServerConnectionsRPC(config.mcpServers)
|
||||||
|
|
||||||
vscode.window.showInformationMessage(`Added ${serverName} MCP server`)
|
const serverOrder = Object.keys(config.mcpServers || {})
|
||||||
|
const updatedMcpServers = [...this.connections]
|
||||||
|
.sort((a, b) => {
|
||||||
|
const indexA = serverOrder.indexOf(a.server.name)
|
||||||
|
const indexB = serverOrder.indexOf(b.server.name)
|
||||||
|
return indexA - indexB
|
||||||
|
})
|
||||||
|
.map((connection) => connection.server)
|
||||||
|
|
||||||
|
return updatedMcpServers
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Failed to add remote MCP server:", error)
|
console.error("Failed to add remote MCP server:", error)
|
||||||
|
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ export interface ExtensionMessage {
|
|||||||
| "openGraphData"
|
| "openGraphData"
|
||||||
| "isImageUrlResult"
|
| "isImageUrlResult"
|
||||||
| "didUpdateSettings"
|
| "didUpdateSettings"
|
||||||
| "addRemoteServerResult"
|
|
||||||
| "userCreditsBalance"
|
| "userCreditsBalance"
|
||||||
| "userCreditsUsage"
|
| "userCreditsUsage"
|
||||||
| "userCreditsPayments"
|
| "userCreditsPayments"
|
||||||
@@ -103,11 +102,6 @@ export interface ExtensionMessage {
|
|||||||
type: "file" | "folder"
|
type: "file" | "folder"
|
||||||
label?: string
|
label?: string
|
||||||
}>
|
}>
|
||||||
addRemoteServerResult?: {
|
|
||||||
success: boolean
|
|
||||||
serverName: string
|
|
||||||
error?: string
|
|
||||||
}
|
|
||||||
tab?: McpViewTab
|
tab?: McpViewTab
|
||||||
grpc_response?: {
|
grpc_response?: {
|
||||||
message?: any // JSON serialized protobuf message
|
message?: any // JSON serialized protobuf message
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import { McpViewTab } from "./mcp"
|
|||||||
|
|
||||||
export interface WebviewMessage {
|
export interface WebviewMessage {
|
||||||
type:
|
type:
|
||||||
| "addRemoteServer"
|
|
||||||
| "apiConfiguration"
|
| "apiConfiguration"
|
||||||
| "webviewDidLaunch"
|
| "webviewDidLaunch"
|
||||||
| "newTask"
|
| "newTask"
|
||||||
|
|||||||
@@ -16,8 +16,9 @@ export const AccountServiceDefinition = {
|
|||||||
fullName: "cline.AccountService",
|
fullName: "cline.AccountService",
|
||||||
methods: {
|
methods: {
|
||||||
/**
|
/**
|
||||||
* The user clicked on the login link in the UI.
|
* Handles the user clicking the login link in the UI.
|
||||||
* Returns the login URL.
|
* Generates a secure nonce for state validation, stores it in secrets,
|
||||||
|
* and opens the authentication URL in the external browser.
|
||||||
*/
|
*/
|
||||||
accountLoginClicked: {
|
accountLoginClicked: {
|
||||||
name: "accountLoginClicked",
|
name: "accountLoginClicked",
|
||||||
|
|||||||
@@ -53,6 +53,19 @@ export function mcpServerStatusToJSON(object: McpServerStatus): string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface AddRemoteServerRequest {
|
||||||
|
metadata?: Metadata | undefined
|
||||||
|
serverName: string
|
||||||
|
serverUrl: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AddRemoteServer {
|
||||||
|
success: boolean
|
||||||
|
serverName: string
|
||||||
|
error?: string | undefined
|
||||||
|
mcpServers: McpServer[]
|
||||||
|
}
|
||||||
|
|
||||||
export interface ToggleMcpServerRequest {
|
export interface ToggleMcpServerRequest {
|
||||||
metadata?: Metadata | undefined
|
metadata?: Metadata | undefined
|
||||||
serverName: string
|
serverName: string
|
||||||
@@ -102,6 +115,209 @@ export interface McpServers {
|
|||||||
mcpServers: McpServer[]
|
mcpServers: McpServer[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createBaseAddRemoteServerRequest(): AddRemoteServerRequest {
|
||||||
|
return { metadata: undefined, serverName: "", serverUrl: "" }
|
||||||
|
}
|
||||||
|
|
||||||
|
export const AddRemoteServerRequest: MessageFns<AddRemoteServerRequest> = {
|
||||||
|
encode(message: AddRemoteServerRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
||||||
|
if (message.metadata !== undefined) {
|
||||||
|
Metadata.encode(message.metadata, writer.uint32(10).fork()).join()
|
||||||
|
}
|
||||||
|
if (message.serverName !== "") {
|
||||||
|
writer.uint32(18).string(message.serverName)
|
||||||
|
}
|
||||||
|
if (message.serverUrl !== "") {
|
||||||
|
writer.uint32(26).string(message.serverUrl)
|
||||||
|
}
|
||||||
|
return writer
|
||||||
|
},
|
||||||
|
|
||||||
|
decode(input: BinaryReader | Uint8Array, length?: number): AddRemoteServerRequest {
|
||||||
|
const reader = input instanceof BinaryReader ? input : new BinaryReader(input)
|
||||||
|
let end = length === undefined ? reader.len : reader.pos + length
|
||||||
|
const message = createBaseAddRemoteServerRequest()
|
||||||
|
while (reader.pos < end) {
|
||||||
|
const tag = reader.uint32()
|
||||||
|
switch (tag >>> 3) {
|
||||||
|
case 1: {
|
||||||
|
if (tag !== 10) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
message.metadata = Metadata.decode(reader, reader.uint32())
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
case 2: {
|
||||||
|
if (tag !== 18) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
message.serverName = reader.string()
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
case 3: {
|
||||||
|
if (tag !== 26) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
message.serverUrl = reader.string()
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((tag & 7) === 4 || tag === 0) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
reader.skip(tag & 7)
|
||||||
|
}
|
||||||
|
return message
|
||||||
|
},
|
||||||
|
|
||||||
|
fromJSON(object: any): AddRemoteServerRequest {
|
||||||
|
return {
|
||||||
|
metadata: isSet(object.metadata) ? Metadata.fromJSON(object.metadata) : undefined,
|
||||||
|
serverName: isSet(object.serverName) ? globalThis.String(object.serverName) : "",
|
||||||
|
serverUrl: isSet(object.serverUrl) ? globalThis.String(object.serverUrl) : "",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
toJSON(message: AddRemoteServerRequest): unknown {
|
||||||
|
const obj: any = {}
|
||||||
|
if (message.metadata !== undefined) {
|
||||||
|
obj.metadata = Metadata.toJSON(message.metadata)
|
||||||
|
}
|
||||||
|
if (message.serverName !== "") {
|
||||||
|
obj.serverName = message.serverName
|
||||||
|
}
|
||||||
|
if (message.serverUrl !== "") {
|
||||||
|
obj.serverUrl = message.serverUrl
|
||||||
|
}
|
||||||
|
return obj
|
||||||
|
},
|
||||||
|
|
||||||
|
create<I extends Exact<DeepPartial<AddRemoteServerRequest>, I>>(base?: I): AddRemoteServerRequest {
|
||||||
|
return AddRemoteServerRequest.fromPartial(base ?? ({} as any))
|
||||||
|
},
|
||||||
|
fromPartial<I extends Exact<DeepPartial<AddRemoteServerRequest>, I>>(object: I): AddRemoteServerRequest {
|
||||||
|
const message = createBaseAddRemoteServerRequest()
|
||||||
|
message.metadata =
|
||||||
|
object.metadata !== undefined && object.metadata !== null ? Metadata.fromPartial(object.metadata) : undefined
|
||||||
|
message.serverName = object.serverName ?? ""
|
||||||
|
message.serverUrl = object.serverUrl ?? ""
|
||||||
|
return message
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
function createBaseAddRemoteServer(): AddRemoteServer {
|
||||||
|
return { success: false, serverName: "", error: undefined, mcpServers: [] }
|
||||||
|
}
|
||||||
|
|
||||||
|
export const AddRemoteServer: MessageFns<AddRemoteServer> = {
|
||||||
|
encode(message: AddRemoteServer, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
||||||
|
if (message.success !== false) {
|
||||||
|
writer.uint32(8).bool(message.success)
|
||||||
|
}
|
||||||
|
if (message.serverName !== "") {
|
||||||
|
writer.uint32(18).string(message.serverName)
|
||||||
|
}
|
||||||
|
if (message.error !== undefined) {
|
||||||
|
writer.uint32(26).string(message.error)
|
||||||
|
}
|
||||||
|
for (const v of message.mcpServers) {
|
||||||
|
McpServer.encode(v!, writer.uint32(34).fork()).join()
|
||||||
|
}
|
||||||
|
return writer
|
||||||
|
},
|
||||||
|
|
||||||
|
decode(input: BinaryReader | Uint8Array, length?: number): AddRemoteServer {
|
||||||
|
const reader = input instanceof BinaryReader ? input : new BinaryReader(input)
|
||||||
|
let end = length === undefined ? reader.len : reader.pos + length
|
||||||
|
const message = createBaseAddRemoteServer()
|
||||||
|
while (reader.pos < end) {
|
||||||
|
const tag = reader.uint32()
|
||||||
|
switch (tag >>> 3) {
|
||||||
|
case 1: {
|
||||||
|
if (tag !== 8) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
message.success = reader.bool()
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
case 2: {
|
||||||
|
if (tag !== 18) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
message.serverName = reader.string()
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
case 3: {
|
||||||
|
if (tag !== 26) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
message.error = reader.string()
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
case 4: {
|
||||||
|
if (tag !== 34) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
message.mcpServers.push(McpServer.decode(reader, reader.uint32()))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((tag & 7) === 4 || tag === 0) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
reader.skip(tag & 7)
|
||||||
|
}
|
||||||
|
return message
|
||||||
|
},
|
||||||
|
|
||||||
|
fromJSON(object: any): AddRemoteServer {
|
||||||
|
return {
|
||||||
|
success: isSet(object.success) ? globalThis.Boolean(object.success) : false,
|
||||||
|
serverName: isSet(object.serverName) ? globalThis.String(object.serverName) : "",
|
||||||
|
error: isSet(object.error) ? globalThis.String(object.error) : undefined,
|
||||||
|
mcpServers: globalThis.Array.isArray(object?.mcpServers)
|
||||||
|
? object.mcpServers.map((e: any) => McpServer.fromJSON(e))
|
||||||
|
: [],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
toJSON(message: AddRemoteServer): unknown {
|
||||||
|
const obj: any = {}
|
||||||
|
if (message.success !== false) {
|
||||||
|
obj.success = message.success
|
||||||
|
}
|
||||||
|
if (message.serverName !== "") {
|
||||||
|
obj.serverName = message.serverName
|
||||||
|
}
|
||||||
|
if (message.error !== undefined) {
|
||||||
|
obj.error = message.error
|
||||||
|
}
|
||||||
|
if (message.mcpServers?.length) {
|
||||||
|
obj.mcpServers = message.mcpServers.map((e) => McpServer.toJSON(e))
|
||||||
|
}
|
||||||
|
return obj
|
||||||
|
},
|
||||||
|
|
||||||
|
create<I extends Exact<DeepPartial<AddRemoteServer>, I>>(base?: I): AddRemoteServer {
|
||||||
|
return AddRemoteServer.fromPartial(base ?? ({} as any))
|
||||||
|
},
|
||||||
|
fromPartial<I extends Exact<DeepPartial<AddRemoteServer>, I>>(object: I): AddRemoteServer {
|
||||||
|
const message = createBaseAddRemoteServer()
|
||||||
|
message.success = object.success ?? false
|
||||||
|
message.serverName = object.serverName ?? ""
|
||||||
|
message.error = object.error ?? undefined
|
||||||
|
message.mcpServers = object.mcpServers?.map((e) => McpServer.fromPartial(e)) || []
|
||||||
|
return message
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
function createBaseToggleMcpServerRequest(): ToggleMcpServerRequest {
|
function createBaseToggleMcpServerRequest(): ToggleMcpServerRequest {
|
||||||
return { metadata: undefined, serverName: "", disabled: false }
|
return { metadata: undefined, serverName: "", disabled: false }
|
||||||
}
|
}
|
||||||
@@ -897,6 +1113,14 @@ export const McpServiceDefinition = {
|
|||||||
responseStream: false,
|
responseStream: false,
|
||||||
options: {},
|
options: {},
|
||||||
},
|
},
|
||||||
|
addRemoteServer: {
|
||||||
|
name: "addRemoteServer",
|
||||||
|
requestType: AddRemoteServerRequest,
|
||||||
|
requestStream: false,
|
||||||
|
responseType: AddRemoteServer,
|
||||||
|
responseStream: false,
|
||||||
|
options: {},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
} as const
|
} as const
|
||||||
|
|
||||||
|
|||||||
+36
-44
@@ -1,50 +1,20 @@
|
|||||||
import { useCallback, useRef, useState } from "react"
|
import { useState } from "react"
|
||||||
import { vscode } from "@/utils/vscode"
|
import { vscode } from "@/utils/vscode"
|
||||||
import { VSCodeButton, VSCodeLink, VSCodeTextField } 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"
|
import { LINKS } from "@/constants"
|
||||||
|
import { McpServiceClient } from "@/services/grpc-client"
|
||||||
|
import { convertProtoMcpServersToMcpServers } from "@shared/proto-conversions/mcp/mcp-server-conversion"
|
||||||
|
import { AddRemoteServer, AddRemoteServerRequest } from "@shared/proto/mcp"
|
||||||
|
import { useExtensionState } from "@/context/ExtensionStateContext"
|
||||||
const AddRemoteServerForm = ({ onServerAdded }: { onServerAdded: () => void }) => {
|
const AddRemoteServerForm = ({ onServerAdded }: { onServerAdded: () => void }) => {
|
||||||
const [serverName, setServerName] = useState("")
|
const [serverName, setServerName] = useState("")
|
||||||
const [serverUrl, setServerUrl] = useState("")
|
const [serverUrl, setServerUrl] = useState("")
|
||||||
const [isSubmitting, setIsSubmitting] = useState(false)
|
const [isSubmitting, setIsSubmitting] = useState(false)
|
||||||
const [error, setError] = useState("")
|
const [error, setError] = useState("")
|
||||||
const [showConnectingMessage, setShowConnectingMessage] = useState(false)
|
const [showConnectingMessage, setShowConnectingMessage] = useState(false)
|
||||||
|
const { setMcpServers } = useExtensionState()
|
||||||
|
|
||||||
// Store submitted values to check if the server was added
|
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
|
||||||
const submittedValues = useRef<{ name: string } | null>(null)
|
|
||||||
|
|
||||||
const handleMessage = useCallback(
|
|
||||||
(event: MessageEvent) => {
|
|
||||||
const message = event.data
|
|
||||||
|
|
||||||
if (
|
|
||||||
message.type === "addRemoteServerResult" &&
|
|
||||||
isSubmitting &&
|
|
||||||
submittedValues.current &&
|
|
||||||
message.addRemoteServerResult?.serverName === submittedValues.current.name
|
|
||||||
) {
|
|
||||||
if (message.addRemoteServerResult.success) {
|
|
||||||
// Handle success
|
|
||||||
setIsSubmitting(false)
|
|
||||||
setServerName("")
|
|
||||||
setServerUrl("")
|
|
||||||
submittedValues.current = null
|
|
||||||
onServerAdded()
|
|
||||||
setShowConnectingMessage(false)
|
|
||||||
} else {
|
|
||||||
// Handle error
|
|
||||||
setIsSubmitting(false)
|
|
||||||
setError(message.addRemoteServerResult.error || "Failed to add server")
|
|
||||||
setShowConnectingMessage(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[isSubmitting, onServerAdded],
|
|
||||||
)
|
|
||||||
|
|
||||||
useEvent("message", handleMessage)
|
|
||||||
|
|
||||||
const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
|
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
|
|
||||||
if (!serverName.trim()) {
|
if (!serverName.trim()) {
|
||||||
@@ -66,15 +36,37 @@ const AddRemoteServerForm = ({ onServerAdded }: { onServerAdded: () => void }) =
|
|||||||
|
|
||||||
setError("")
|
setError("")
|
||||||
|
|
||||||
submittedValues.current = { name: serverName.trim() }
|
|
||||||
|
|
||||||
setIsSubmitting(true)
|
setIsSubmitting(true)
|
||||||
setShowConnectingMessage(true)
|
setShowConnectingMessage(true)
|
||||||
vscode.postMessage({
|
|
||||||
type: "addRemoteServer",
|
try {
|
||||||
serverName: serverName.trim(),
|
const response: AddRemoteServer = await McpServiceClient.addRemoteServer({
|
||||||
serverUrl: serverUrl.trim(),
|
serverName: serverName.trim(),
|
||||||
})
|
serverUrl: serverUrl.trim(),
|
||||||
|
} as AddRemoteServerRequest)
|
||||||
|
|
||||||
|
if (response.success) {
|
||||||
|
const mcpServers = convertProtoMcpServersToMcpServers(response.mcpServers)
|
||||||
|
setMcpServers(mcpServers)
|
||||||
|
setIsSubmitting(false)
|
||||||
|
setServerName("")
|
||||||
|
setServerUrl("")
|
||||||
|
|
||||||
|
// Switch to the installed tab
|
||||||
|
onServerAdded()
|
||||||
|
setShowConnectingMessage(false)
|
||||||
|
} else {
|
||||||
|
setIsSubmitting(false)
|
||||||
|
setError(response.error || "Failed to add server")
|
||||||
|
setShowConnectingMessage(false)
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
// Handle any exceptions during the gRPC call
|
||||||
|
console.error("Error adding remote server:", err)
|
||||||
|
setIsSubmitting(false)
|
||||||
|
setError(err instanceof Error ? err.message : String(err))
|
||||||
|
setShowConnectingMessage(false)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
Reference in New Issue
Block a user