This commit is contained in:
mats committed 2026-06-28 17:52:49 +02:00
1 parent e706f7d907
commit 21bcb63440
42 files changed
+5903

No files matched your search

+51
View File
@@ -0,0 +1,51 @@
package mcp
import (
"context"
"encoding/json"
"fmt"
)
// Tool is one MCP tool: its advertised schema plus the Invoke func that parses
// arguments, does the work, and returns a JSON-encodable payload. Invoke's error
// is surfaced to the client as a tool error (isError: true), not a protocol
// error. The context carries request scope (deadline, cancellation, trace span);
// it flows from the HTTP request through to Invoke.
type Tool struct {
Name string `json:"name"`
Description string `json:"description"`
InputSchema json.RawMessage `json:"inputSchema"`
Invoke func(ctx context.Context, args json.RawMessage) (any, error) `json:"-"`
}
// Text wraps a payload as a successful tools/call result: one JSON text block.
func Text(v any) any {
b, err := json.Marshal(v)
if err != nil {
return ErrorResult(err)
}
return map[string]any{
"content": []map[string]any{{"type": "text", "text": string(b)}},
}
}
// ErrorResult wraps an operational error as an isError tools/call result (a tool
// failure the model can read, not a JSON-RPC protocol error).
func ErrorResult(err error) any {
return map[string]any{
"isError": true,
"content": []map[string]any{{"type": "text", "text": err.Error()}},
}
}
// Decode unmarshals tool arguments into v, treating empty/null args as a no-op
// (zero value). Returns a wrapped error suitable for returning from Invoke.
func Decode(args json.RawMessage, v any) error {
if len(args) == 0 || string(args) == "null" {
return nil
}
if err := json.Unmarshal(args, v); err != nil {
return fmt.Errorf("invalid arguments: %w", err)
}
return nil
}