This repository was archived by the owner on Mar 6, 2026. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathexecutor.go
More file actions
81 lines (69 loc) · 2.27 KB
/
executor.go
File metadata and controls
81 lines (69 loc) · 2.27 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
package mcpserve
import (
"context"
"encoding/base64"
"fmt"
"strings"
"github.com/tinywasm/mcp"
)
// BinaryData represents binary response from tools (imported from handlers)
type BinaryData struct {
MimeType string
Data []byte
}
// mcpExecuteTool creates a GENERIC tool executor that works for ANY handler tool
// It extracts args, collects progress, executes the tool, and returns results
// NO domain-specific logic here - handlers provide their own Execute functions
// mcpExecuteTool creates a GENERIC tool executor that works for ANY handler tool
// It extracts args, collects logs via SetLog, executes the tool, and returns results
func (h *Handler) mcpExecuteTool(targetHandler any, executor ToolExecutor) func(context.Context, mcp.CallToolRequest) (*mcp.CallToolResult, error) {
return func(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
// 1. Extract arguments (generic)
args, ok := req.Params.Arguments.(map[string]any)
if !ok {
args = make(map[string]any)
}
// 2. Setup capturing logger if handler is Loggable
messages := []string{}
var binaryResponse *BinaryData
if loggable, ok := targetHandler.(Loggable); ok {
// Inject temporary capturing logger
loggable.SetLog(func(message ...any) {
if len(message) == 0 {
return
}
for _, m := range message {
switch v := m.(type) {
case BinaryData:
binaryResponse = &v
case string:
messages = append(messages, v)
default:
// Convert other types to string
messages = append(messages, fmt.Sprintf("%v", v))
}
}
})
}
// 3. Execute handler-specific logic
executor(args)
// 4. Refresh UI (generic)
if h.tui != nil {
h.tui.RefreshUI()
}
// 5. Handle binary response (if present) - prioritize over text
if binaryResponse != nil {
base64Data := base64.StdEncoding.EncodeToString(binaryResponse.Data)
textSummary := ""
if len(messages) > 0 {
textSummary = strings.Join(messages, "\n")
}
return mcp.NewToolResultImage(textSummary, base64Data, binaryResponse.MimeType), nil
}
// 6. Return text messages (if no binary)
if len(messages) == 0 {
return mcp.NewToolResultText("Operation completed successfully"), nil
}
return mcp.NewToolResultText(strings.Join(messages, "\n")), nil
}
}