feat(capability/mcp): MCP 客户端(stdlib JSON-RPC over stdio/SSE)+ Registry 自动注册/Unregister(registry 增 Remove)
This commit is contained in:
1 parent
08223c06a5
commit
488cf9c79c
14 files changed
+2212
No files matched your search
@@ -0,0 +1,63 @@
|
||||
package mcp
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// mcpTool adapts an MCP tool to the pkg/plugins/sdk Tool interface so it can be
|
||||
// registered and invoked like any built-in tool. It is immutable and safe for
|
||||
// concurrent use.
|
||||
type mcpTool struct {
|
||||
client *Client
|
||||
info ToolInfo
|
||||
}
|
||||
|
||||
// Name returns the MCP tool identifier.
|
||||
func (t *mcpTool) Name() string {
|
||||
return t.info.Name
|
||||
}
|
||||
|
||||
// Description returns the MCP tool description.
|
||||
func (t *mcpTool) Description() string {
|
||||
return t.info.Description
|
||||
}
|
||||
|
||||
// Parameters returns the MCP tool input schema, defaulting to an empty object
|
||||
// schema when the server omits one.
|
||||
func (t *mcpTool) Parameters() (map[string]any, error) {
|
||||
if t.info.InputSchema == nil {
|
||||
return map[string]any{"type": "object", "properties": map[string]any{}}, nil
|
||||
}
|
||||
return t.info.InputSchema, nil
|
||||
}
|
||||
|
||||
// Execute invokes the MCP tool and returns its concatenated text content.
|
||||
func (t *mcpTool) Execute(ctx context.Context, args any) (any, error) {
|
||||
res, err := t.client.CallTool(ctx, t.info.Name, args)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return contentText(res.Content), nil
|
||||
}
|
||||
|
||||
// contentText concatenates the text blocks of a tool result into a single
|
||||
// string, ignoring non-text blocks.
|
||||
func contentText(content []ContentBlock) string {
|
||||
var b strings.Builder
|
||||
for _, blk := range content {
|
||||
if blk.Type == "" || blk.Type == "text" {
|
||||
b.WriteString(blk.Text)
|
||||
}
|
||||
}
|
||||
return b.String()
|
||||
}
|
||||
|
||||
// toContentBlocks converts wire content blocks to the public content block type.
|
||||
func toContentBlocks(wire []contentBlock) []ContentBlock {
|
||||
out := make([]ContentBlock, 0, len(wire))
|
||||
for _, c := range wire {
|
||||
out = append(out, ContentBlock{Type: c.Type, Text: c.Text})
|
||||
}
|
||||
return out
|
||||
}
|
||||
Reference in new issue
Block a user