64 lines
1.7 KiB
Go
64 lines
1.7 KiB
Go
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
|
|
}
|