update , add mcp server stdio and sse

This commit is contained in:
duanfuxiang
2025-06-02 20:38:40 +08:00
parent 8ca5216b71
commit b1315aa6b1
30 changed files with 2639 additions and 955 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
// @ts-nocheck
import { ClineProvider } from "../../core/webview/ClineProvider"
import { App } from "obsidian"
import { McpHub } from "./McpHub"
@@ -10,8 +10,8 @@ import { McpHub } from "./McpHub"
*/
export class McpServerManager {
private static instance: McpHub | null = null
private static readonly GLOBAL_STATE_KEY = "mcpHubInstanceId"
private static providers: Set<ClineProvider> = new Set()
// private static readonly GLOBAL_STATE_KEY = "mcpHubInstanceId"
// private static providers: Set<ClineProvider> = new Set()
private static initializationPromise: Promise<McpHub> | null = null
/**
@@ -19,9 +19,10 @@ export class McpServerManager {
* Creates a new instance if one doesn't exist.
* Thread-safe implementation using a promise-based lock.
*/
static async getInstance(context: vscode.ExtensionContext, provider: ClineProvider): Promise<McpHub> {
static async getInstance(app: App): Promise<McpHub> {
// Register the provider
this.providers.add(provider)
// this.providers.add(provider)
// If we already have an instance, return it
if (this.instance) {
@@ -38,9 +39,9 @@ export class McpServerManager {
try {
// Double-check instance in case it was created while we were waiting
if (!this.instance) {
this.instance = new McpHub(provider)
this.instance = new McpHub(app)
// Store a unique identifier in global state to track the primary instance
await context.globalState.update(this.GLOBAL_STATE_KEY, Date.now().toString())
// await app.globalState.update(this.GLOBAL_STATE_KEY, Date.now().toString())
}
return this.instance
} finally {
@@ -52,34 +53,34 @@ export class McpServerManager {
return this.initializationPromise
}
/**
* Remove a provider from the tracked set.
* This is called when a webview is disposed.
*/
static unregisterProvider(provider: ClineProvider): void {
this.providers.delete(provider)
}
// /**
// * Remove a provider from the tracked set.
// * This is called when a webview is disposed.
// */
// static unregisterProvider(provider: ClineProvider): void {
// this.providers.delete(provider)
// }
/**
* Notify all registered providers of server state changes.
*/
static notifyProviders(message: any): void {
this.providers.forEach((provider) => {
provider.postMessageToWebview(message).catch((error) => {
console.error("Failed to notify provider:", error)
})
})
}
// /**
// * Notify all registered providers of server state changes.
// */
// static notifyProviders(message: any): void {
// this.providers.forEach((provider) => {
// provider.postMessageToWebview(message).catch((error) => {
// console.error("Failed to notify provider:", error)
// })
// })
// }
/**
* Clean up the singleton instance and all its resources.
*/
static async cleanup(context: vscode.ExtensionContext): Promise<void> {
static async cleanup(): Promise<void> {
if (this.instance) {
await this.instance.dispose()
this.instance = null
await context.globalState.update(this.GLOBAL_STATE_KEY, undefined)
// await app.globalState.update(this.GLOBAL_STATE_KEY, undefined)
}
this.providers.clear()
// this.providers.clear()
}
}

81
src/core/mcp/type.ts Normal file
View File

@@ -0,0 +1,81 @@
export type McpErrorEntry = {
message: string
timestamp: number
level: "error" | "warn" | "info"
}
export type McpServer = {
name: string
config: string
status: "connected" | "connecting" | "disconnected"
error?: string
errorHistory?: McpErrorEntry[]
tools?: McpTool[]
resources?: McpResource[]
resourceTemplates?: McpResourceTemplate[]
disabled?: boolean
timeout?: number
source: "global" | "project"
projectPath?: string
}
export type McpTool = {
name: string
description?: string
inputSchema?: object
alwaysAllow?: boolean
}
export type McpResource = {
uri: string
name: string
mimeType?: string
description?: string
}
export type McpResourceTemplate = {
uriTemplate: string
name: string
description?: string
mimeType?: string
}
export type McpResourceResponse = {
_meta?: Record<string, any>
contents: Array<{
uri: string
mimeType?: string
text?: string
blob?: string
}>
}
export type McpToolCallResponse = {
_meta?: Record<string, any>
content: Array<
| {
type: "text"
text: string
}
| {
type: "image"
data: string
mimeType: string
}
| {
type: "audio"
data: string
mimeType: string
}
| {
type: "resource"
resource: {
uri: string
mimeType?: string
text?: string
blob?: string
}
}
>
isError?: boolean
}