mirror of
https://github.com/alibaba/higress.git
synced 2026-04-21 20:17:29 +08:00
refactor: migrate MCP SDK to main repo (#3516)
This commit is contained in:
127
plugins/wasm-go/pkg/mcp/server/composed_server.go
Normal file
127
plugins/wasm-go/pkg/mcp/server/composed_server.go
Normal file
@@ -0,0 +1,127 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/higress-group/wasm-go/pkg/log"
|
||||
"github.com/alibaba/higress/plugins/wasm-go/pkg/mcp/consts"
|
||||
)
|
||||
|
||||
// ComposedMCPServer represents a server composed of tools from other servers.
|
||||
type ComposedMCPServer struct {
|
||||
name string // Name of the composed server (from toolSet.name)
|
||||
serverTools []ServerToolConfig // Configuration of which tools to include
|
||||
registry *GlobalToolRegistry // Reference to the global tool registry
|
||||
config []byte // Configuration for the composed server itself (if any)
|
||||
}
|
||||
|
||||
// NewComposedMCPServer creates a new ComposedMCPServer.
|
||||
func NewComposedMCPServer(name string, serverToolsConfig []ServerToolConfig, registry *GlobalToolRegistry) *ComposedMCPServer {
|
||||
return &ComposedMCPServer{
|
||||
name: name,
|
||||
serverTools: serverToolsConfig,
|
||||
registry: registry,
|
||||
}
|
||||
}
|
||||
|
||||
// GetName returns the name of the composed server.
|
||||
func (cs *ComposedMCPServer) GetName() string {
|
||||
return cs.name
|
||||
}
|
||||
|
||||
// AddMCPTool for ComposedMCPServer is a no-op as tools are defined by toolSet.
|
||||
func (cs *ComposedMCPServer) AddMCPTool(name string, tool Tool) Server {
|
||||
log.Warnf("AddMCPTool called on ComposedMCPServer '%s'; this is a no-op.", cs.name)
|
||||
return cs
|
||||
}
|
||||
|
||||
// GetMCPTools constructs and returns the map of tools exposed by this composed server.
|
||||
// The tool names are prefixed with their original server name, e.g., "${originalServer}___${toolName}".
|
||||
// The Tool instances are DescriptiveTool, only providing Description and InputSchema.
|
||||
func (cs *ComposedMCPServer) GetMCPTools() map[string]Tool {
|
||||
composedTools := make(map[string]Tool)
|
||||
for _, stc := range cs.serverTools {
|
||||
originalServerName := stc.ServerName
|
||||
for _, originalToolName := range stc.Tools {
|
||||
toolInfo, found := cs.registry.GetToolInfo(originalServerName, originalToolName)
|
||||
if !found {
|
||||
log.Warnf("Tool %s/%s not found in global registry for composed server %s", originalServerName, originalToolName, cs.name)
|
||||
continue
|
||||
}
|
||||
|
||||
composedToolName := fmt.Sprintf("%s%s%s", originalServerName, consts.ToolSetNameSplitter, originalToolName)
|
||||
composedTools[composedToolName] = &DescriptiveTool{
|
||||
description: toolInfo.Description,
|
||||
inputSchema: toolInfo.InputSchema,
|
||||
outputSchema: toolInfo.OutputSchema, // New field for MCP Protocol Version 2025-06-18
|
||||
}
|
||||
}
|
||||
}
|
||||
return composedTools
|
||||
}
|
||||
|
||||
// SetConfig sets the configuration for the composed server itself.
|
||||
func (cs *ComposedMCPServer) SetConfig(config []byte) {
|
||||
cs.config = config
|
||||
}
|
||||
|
||||
// GetConfig retrieves the configuration of the composed server itself.
|
||||
func (cs *ComposedMCPServer) GetConfig(v any) {
|
||||
if len(cs.config) == 0 {
|
||||
return
|
||||
}
|
||||
if ptrBytes, ok := v.(*[]byte); ok {
|
||||
*ptrBytes = cs.config
|
||||
} else {
|
||||
// If you need to unmarshal to a struct, you'd do it here.
|
||||
// For now, keeping it simple as per previous discussions.
|
||||
log.Warnf("ComposedMCPServer.GetConfig called with unhandled type for v. Config not set.")
|
||||
}
|
||||
}
|
||||
|
||||
// Clone creates a new instance of the ComposedMCPServer with the same configuration.
|
||||
func (cs *ComposedMCPServer) Clone() Server {
|
||||
cloned := NewComposedMCPServer(cs.name, cs.serverTools, cs.registry)
|
||||
cloned.SetConfig(cs.config)
|
||||
return cloned
|
||||
}
|
||||
|
||||
// DescriptiveTool is a placeholder Tool implementation for ComposedMCPServer.
|
||||
// Its Call and Create methods should never be invoked.
|
||||
type DescriptiveTool struct {
|
||||
description string
|
||||
inputSchema map[string]any
|
||||
outputSchema map[string]any // New field for MCP Protocol Version 2025-06-18
|
||||
}
|
||||
|
||||
// Create for DescriptiveTool should not be called.
|
||||
func (dt *DescriptiveTool) Create(params []byte) Tool {
|
||||
log.Errorf("DescriptiveTool.Create called for tool used in ComposedMCPServer. This should not happen.")
|
||||
// Return a new instance to fulfill the interface, though it's an error state.
|
||||
return &DescriptiveTool{
|
||||
description: dt.description,
|
||||
inputSchema: dt.inputSchema,
|
||||
outputSchema: dt.outputSchema,
|
||||
}
|
||||
}
|
||||
|
||||
// Call for DescriptiveTool should not be called.
|
||||
func (dt *DescriptiveTool) Call(httpCtx HttpContext, server Server) error {
|
||||
log.Errorf("DescriptiveTool.Call called for tool used in ComposedMCPServer. This should not happen.")
|
||||
return fmt.Errorf("DescriptiveTool.Call should not be invoked on a ComposedMCPServer's tool")
|
||||
}
|
||||
|
||||
// Description returns the tool's description.
|
||||
func (dt *DescriptiveTool) Description() string {
|
||||
return dt.description
|
||||
}
|
||||
|
||||
// InputSchema returns the tool's input schema.
|
||||
func (dt *DescriptiveTool) InputSchema() map[string]any {
|
||||
return dt.inputSchema
|
||||
}
|
||||
|
||||
// OutputSchema returns the tool's output schema (MCP Protocol Version 2025-06-18).
|
||||
func (dt *DescriptiveTool) OutputSchema() map[string]any {
|
||||
return dt.outputSchema
|
||||
}
|
||||
Reference in New Issue
Block a user