Files
higress/plugins/wasm-go/pkg/mcp/utils/mcp_rpc.go

118 lines
3.7 KiB
Go

// Copyright (c) 2022 Alibaba Group Holding Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package utils
import (
"encoding/base64"
"encoding/json"
"fmt"
"github.com/higress-group/wasm-go/pkg/wrapper"
)
func OnMCPResponseSuccess(ctx wrapper.HttpContext, result map[string]any, debugInfo string) {
OnJsonRpcResponseSuccess(ctx, result, debugInfo)
// TODO: support pub to redis when use POST + SSE
}
func OnMCPResponseError(ctx wrapper.HttpContext, err error, code int, debugInfo string) {
OnJsonRpcResponseError(ctx, err, code, debugInfo)
// TODO: support pub to redis when use POST + SSE
}
func OnMCPToolCallSuccess(ctx wrapper.HttpContext, content []map[string]any, debugInfo string) {
OnMCPResponseSuccess(ctx, map[string]any{
"content": content,
"isError": false,
}, debugInfo)
}
// OnMCPToolCallSuccessWithStructuredContent sends a successful MCP tool response with structured content
// According to MCP spec, structuredContent is a field in tool results, not a capability
func OnMCPToolCallSuccessWithStructuredContent(ctx wrapper.HttpContext, content []map[string]any, structuredContent json.RawMessage, debugInfo string) {
response := map[string]any{
"content": content,
"isError": false,
}
if structuredContent != nil && len(structuredContent) > 0 {
response["structuredContent"] = structuredContent
}
OnMCPResponseSuccess(ctx, response, debugInfo)
}
func OnMCPToolCallError(ctx wrapper.HttpContext, err error, debugInfo ...string) {
responseDebugInfo := fmt.Sprintf("mcp:tools/call:error(%s)", err)
if len(debugInfo) > 0 {
responseDebugInfo = debugInfo[0]
}
OnMCPResponseSuccess(ctx, map[string]any{
"content": []map[string]any{
{
"type": "text",
"text": err.Error(),
},
},
"isError": true,
}, responseDebugInfo)
}
func SendMCPToolTextResult(ctx wrapper.HttpContext, result string, debugInfo ...string) {
responseDebugInfo := "mcp:tools/call::result"
if len(debugInfo) > 0 {
responseDebugInfo = debugInfo[0]
}
OnMCPToolCallSuccess(ctx, []map[string]any{
{
"type": "text",
"text": result,
},
}, responseDebugInfo)
}
func SendMCPToolImageResult(ctx wrapper.HttpContext, image []byte, contentType string, debugInfo ...string) {
responseDebugInfo := "mcp:tools/call::result"
if len(debugInfo) > 0 {
responseDebugInfo = debugInfo[0]
}
content := []map[string]any{
{
"type": "image",
"data": base64.StdEncoding.EncodeToString(image),
"mimeType": contentType,
},
}
// Use traditional response format since no structured data is provided
OnMCPToolCallSuccess(ctx, content, responseDebugInfo)
}
// SendMCPToolTextResultWithStructuredContent sends a tool result with both text content and structured content
// According to MCP spec, for backward compatibility, tools that return structured content
// SHOULD also return the serialized JSON in a TextContent block
func SendMCPToolTextResultWithStructuredContent(ctx wrapper.HttpContext, textResult string, structuredContent json.RawMessage, debugInfo ...string) {
responseDebugInfo := "mcp:tools/call::result"
if len(debugInfo) > 0 {
responseDebugInfo = debugInfo[0]
}
content := []map[string]any{
{
"type": "text",
"text": textResult,
},
}
OnMCPToolCallSuccessWithStructuredContent(ctx, content, structuredContent, responseDebugInfo)
}