From 891ca31baf9c4f1539ca38799e13ba70bbab1bef Mon Sep 17 00:00:00 2001 From: deviantony Date: Sun, 13 Apr 2025 22:12:44 +0000 Subject: [PATCH 1/2] introduce NewToolResultErrorWithErr and update docs --- README.md | 10 +++++----- mcp/utils.go | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index a55d174..8137054 100644 --- a/README.md +++ b/README.md @@ -163,7 +163,7 @@ func main() { result = x * y case "divide": if y == 0 { - return nil, errors.New("Cannot divide by zero") + return mcp.NewToolResultError("cannot divide by zero"), nil } result = x / y } @@ -325,7 +325,7 @@ s.AddTool(calculatorTool, func(ctx context.Context, request mcp.CallToolRequest) result = x * y case "divide": if y == 0 { - return nil, errors.New("Division by zero is not allowed") + return mcp.NewToolResultError("cannot divide by zero"), nil } result = x / y } @@ -370,20 +370,20 @@ s.AddTool(httpTool, func(ctx context.Context, request mcp.CallToolRequest) (*mcp req, err = http.NewRequest(method, url, nil) } if err != nil { - return nil, fmt.Errorf("Failed to create request: %v", err) + return mcp.NewToolResultErrorWithErr("unable to create request", err), nil } client := &http.Client{} resp, err := client.Do(req) if err != nil { - return nil, fmt.Errorf("Request failed: %v", err) + return mcp.NewToolResultErrorWithErr("unable to execute request", err), nil } defer resp.Body.Close() // Return response respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, fmt.Errorf("Failed to read response: %v", err) + return mcp.NewToolResultErrorWithErr("unable to read request response", err), nil } return mcp.NewToolResultText(fmt.Sprintf("Status: %d\nBody: %s", resp.StatusCode, string(respBody))), nil diff --git a/mcp/utils.go b/mcp/utils.go index 236164c..ae51078 100644 --- a/mcp/utils.go +++ b/mcp/utils.go @@ -266,6 +266,24 @@ func NewToolResultError(text string) *CallToolResult { } } +// NewToolResultErrorWithErr creates a new CallToolResult with an error message. +// If an error is provided, its details will be appended to the text message. +// Any errors that originate from the tool SHOULD be reported inside the result object. +func NewToolResultErrorWithErr(text string, err error) *CallToolResult { + if err != nil { + text = fmt.Sprintf("%s: %v", text, err) + } + return &CallToolResult{ + Content: []Content{ + TextContent{ + Type: "text", + Text: text, + }, + }, + IsError: true, + } +} + // NewListResourcesResult creates a new ListResourcesResult func NewListResourcesResult( resources []Resource, From de1c08e54076f2d440d9655e646a1dab0adfc8d8 Mon Sep 17 00:00:00 2001 From: deviantony Date: Mon, 14 Apr 2025 20:44:43 +0000 Subject: [PATCH 2/2] rename to NewToolResultErrorFromErr --- README.md | 6 +++--- mcp/utils.go | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 8137054..332ab3d 100644 --- a/README.md +++ b/README.md @@ -370,20 +370,20 @@ s.AddTool(httpTool, func(ctx context.Context, request mcp.CallToolRequest) (*mcp req, err = http.NewRequest(method, url, nil) } if err != nil { - return mcp.NewToolResultErrorWithErr("unable to create request", err), nil + return mcp.NewToolResultErrorFromErr("unable to create request", err), nil } client := &http.Client{} resp, err := client.Do(req) if err != nil { - return mcp.NewToolResultErrorWithErr("unable to execute request", err), nil + return mcp.NewToolResultErrorFromErr("unable to execute request", err), nil } defer resp.Body.Close() // Return response respBody, err := io.ReadAll(resp.Body) if err != nil { - return mcp.NewToolResultErrorWithErr("unable to read request response", err), nil + return mcp.NewToolResultErrorFromErr("unable to read request response", err), nil } return mcp.NewToolResultText(fmt.Sprintf("Status: %d\nBody: %s", resp.StatusCode, string(respBody))), nil diff --git a/mcp/utils.go b/mcp/utils.go index ae51078..55a708e 100644 --- a/mcp/utils.go +++ b/mcp/utils.go @@ -266,10 +266,10 @@ func NewToolResultError(text string) *CallToolResult { } } -// NewToolResultErrorWithErr creates a new CallToolResult with an error message. +// NewToolResultErrorFromErr creates a new CallToolResult with an error message. // If an error is provided, its details will be appended to the text message. // Any errors that originate from the tool SHOULD be reported inside the result object. -func NewToolResultErrorWithErr(text string, err error) *CallToolResult { +func NewToolResultErrorFromErr(text string, err error) *CallToolResult { if err != nil { text = fmt.Sprintf("%s: %v", text, err) }