package contracts import ( "context" "git.fsdpf.net/go/req" "github.com/mark3labs/mcp-go/mcp" "github.com/mark3labs/mcp-go/server" openai "github.com/sashabaranov/go-openai" ) // InjectOption 是 InjectTools 的可选配置项。 type InjectOption func(*InjectOptions) type InjectOptions struct { Codes []string OnCall func(openai.ToolCall) // 工具执行前回调 OnResult func(openai.ToolCall, string) // 工具执行后回调 } // WithFilter 只注入指定 apiCode 的 MCP server 工具;不传则注入全部已注册的。 func WithFilter(codes ...string) InjectOption { return func(o *InjectOptions) { o.Codes = codes } } // WithOnCall 设置工具执行前回调,tc 为完整的 ToolCall 对象。 func WithOnCall(fn func(tc openai.ToolCall)) InjectOption { return func(o *InjectOptions) { o.OnCall = fn } } // WithOnResult 设置工具执行后回调,tc 为 ToolCall 对象,result 为返回文本。 func WithOnResult(fn func(tc openai.ToolCall, result string)) InjectOption { return func(o *InjectOptions) { o.OnResult = fn } } type MCPService interface { Serve(req.Route) MCPServer Shutdown() error // InjectTools 将工具列表注入 ChatCompletionRequest.Tools,同时返回 Instructions 和工具调用执行器。 // ctx 须携带 req.User(WithToolFilter 据此过滤工具)。 // 通过 WithOnCall / WithOnResult 设置实时进度回调,WithFilter 限定注入范围。 InjectTools(ctx context.Context, impl mcp.Implementation, req *openai.ChatCompletionRequest, opts ...InjectOption) ( instructions string, handleToolCalls func(toolCalls []openai.ToolCall) []openai.ChatCompletionMessage, err error, ) } type MCPServer interface { Server Shutdown() error } type MCPTool interface { Controller // 获取 MCPServer MCP() *server.MCPServer // Sent 在工具执行期间通过 notifications/progress 向客户端推送进度消息。 // 客户端请求须携带 _meta.progressToken,否则本方法为空操作。 Sent(ctx context.Context, data string) error // Execute 处理请求并返回响应数据,返回值支持以下类型: // - mcp.Content / []mcp.Content 直接作为工具内容返回 // - *mcp.CallToolResult 完整结果,直接透传 // - contracts.Errno / *contracts.Errno 业务错误码,转为工具错误 // - contracts.Err / *contracts.Err 同上 // - string 文本结果 // - []byte 文本结果(原始字节) // - error 工具错误 // - nil 空结果 // - 其他任意类型 JSON 序列化后返回,同时填充 StructuredContent Execute(context.Context, req.GlobalParams) any } type MCPResource interface { Controller }