micro--go-micro
59397834b4
goreleaser / goreleaser (push) Has been cancelled
* gateway/mcp: swappable Resolver + mountable JSON-RPC HTTP handler Adds a Resolver interface (Manual/Registry) so the tool source is pluggable, and NewHandler(resolver) serving standard MCP JSON-RPC over HTTP as an http.Handler you can mount on your own server. Neither resolver exposes the internal store/broker tools. Additive — the existing Serve() path is unchanged. * gateway/mcp: swappable Resolver + mountable JSON-RPC HTTP handler Adds a Resolver interface (Manual/Registry) so the tool source is pluggable, and NewHandler(resolver) serving standard MCP JSON-RPC over HTTP as an http.Handler you can mount on your own server. Neither resolver exposes the internal store/broker tools. Additive — the existing Serve() path is unchanged. * gateway/mcp: swappable Resolver + mountable JSON-RPC HTTP handler Adds a Resolver interface (Manual/Registry) so the tool source is pluggable, and NewHandler(resolver) serving standard MCP JSON-RPC over HTTP as an http.Handler you can mount on your own server. Neither resolver exposes the internal store/broker tools. Additive — the existing Serve() path is unchanged.
59 行
1.8 KiB
Go
59 行
1.8 KiB
Go
package mcp
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestManualResolverHandler(t *testing.T) {
|
|
res := NewManualResolver().Add(
|
|
Tool{Name: "echo", Description: "echoes text", InputSchema: map[string]interface{}{
|
|
"type": "object", "properties": map[string]interface{}{"text": map[string]interface{}{"type": "string"}},
|
|
}},
|
|
func(_ context.Context, args map[string]interface{}) (string, error) {
|
|
s, _ := args["text"].(string)
|
|
return "you said: " + s, nil
|
|
},
|
|
)
|
|
ts := httptest.NewServer(NewHandler(res))
|
|
defer ts.Close()
|
|
|
|
rpc := func(body string) map[string]interface{} {
|
|
resp, err := http.Post(ts.URL, "application/json", strings.NewReader(body))
|
|
if err != nil {
|
|
t.Fatalf("post: %v", err)
|
|
}
|
|
defer resp.Body.Close()
|
|
var out map[string]interface{}
|
|
json.NewDecoder(resp.Body).Decode(&out)
|
|
return out
|
|
}
|
|
|
|
// initialize
|
|
if out := rpc(`{"jsonrpc":"2.0","id":1,"method":"initialize"}`); out["result"] == nil {
|
|
t.Fatalf("initialize: %v", out)
|
|
}
|
|
// tools/list
|
|
out := rpc(`{"jsonrpc":"2.0","id":2,"method":"tools/list"}`)
|
|
tools := out["result"].(map[string]interface{})["tools"].([]interface{})
|
|
if len(tools) != 1 || tools[0].(map[string]interface{})["name"] != "echo" {
|
|
t.Fatalf("tools/list: %v", out)
|
|
}
|
|
// tools/call
|
|
out = rpc(`{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"echo","arguments":{"text":"hi"}}}`)
|
|
content := out["result"].(map[string]interface{})["content"].([]interface{})
|
|
got := content[0].(map[string]interface{})["text"].(string)
|
|
if got != "you said: hi" {
|
|
t.Fatalf("tools/call text = %q", got)
|
|
}
|
|
// unknown tool -> error
|
|
out = rpc(`{"jsonrpc":"2.0","id":4,"method":"tools/call","params":{"name":"nope","arguments":{}}}`)
|
|
if out["error"] == nil {
|
|
t.Fatalf("expected error for unknown tool, got %v", out)
|
|
}
|
|
}
|