This repository has been archived on 2026-08-16. You can view files and clone it, but cannot push or open issues or pull requests.
ollie-core/tools/executor.go

73 lines
1.8 KiB
Go

package tools
import (
"encoding/json"
"fmt"
"ollie/mcp"
)
// ToolInfo describes a tool provided by an MCP server.
type ToolInfo struct {
Server string
Name string
Description string
InputSchema json.RawMessage
}
// Executor routes tool calls to the MCP server that owns them.
type Executor struct {
servers map[string]*mcp.Client
}
// NewExecutor creates an empty Executor.
func NewExecutor() *Executor {
return &Executor{servers: make(map[string]*mcp.Client)}
}
// AddServer registers an MCP client under the given name.
func (e *Executor) AddServer(name string, client *mcp.Client) {
e.servers[name] = client
}
// ListTools returns all tools advertised by all connected servers.
func (e *Executor) ListTools() ([]ToolInfo, error) {
var all []ToolInfo
for serverName, client := range e.servers {
result, err := client.Call("tools/list", nil)
if err != nil {
return nil, fmt.Errorf("server %s: %w", serverName, err)
}
var resp struct {
Tools []struct {
Name string `json:"name"`
Description string `json:"description"`
InputSchema json.RawMessage `json:"inputSchema"`
} `json:"tools"`
}
if err := json.Unmarshal(result, &resp); err != nil {
return nil, err
}
for _, t := range resp.Tools {
all = append(all, ToolInfo{
Server: serverName,
Name: t.Name,
Description: t.Description,
InputSchema: t.InputSchema,
})
}
}
return all, nil
}
// Execute calls a named tool on the named server.
func (e *Executor) Execute(serverName, toolName string, args json.RawMessage) (json.RawMessage, error) {
client, ok := e.servers[serverName]
if !ok {
return nil, fmt.Errorf("server not found: %s", serverName)
}
return client.Call("tools/call", map[string]any{
"name": toolName,
"arguments": args,
})
}