mirror of
https://github.com/googleapis/genai-toolbox.git
synced 2026-01-09 15:38:08 -05:00
feat(server/mcp): Support ping mechanism (#1178)
Send back an empty result with a `ping` request following the [MCP ping spec](https://modelcontextprotocol.io/specification/2025-06-18/basic/utilities/ping). <img width="577" height="481" alt="Screenshot 2025-08-18 at 4 20 09 PM" src="https://github.com/user-attachments/assets/fd48725e-298e-4938-9368-d704bea0a546" />
This commit is contained in:
@@ -28,6 +28,8 @@ import (
|
||||
// ProcessMethod returns a response for the request.
|
||||
func ProcessMethod(ctx context.Context, id jsonrpc.RequestId, method string, toolset tools.Toolset, tools map[string]tools.Tool, body []byte) (any, error) {
|
||||
switch method {
|
||||
case PING:
|
||||
return pingHandler(id)
|
||||
case TOOLS_LIST:
|
||||
return toolsListHandler(id, toolset, body)
|
||||
case TOOLS_CALL:
|
||||
@@ -38,6 +40,15 @@ func ProcessMethod(ctx context.Context, id jsonrpc.RequestId, method string, too
|
||||
}
|
||||
}
|
||||
|
||||
// pingHandler handles the "ping" method by returning an empty response.
|
||||
func pingHandler(id jsonrpc.RequestId) (any, error) {
|
||||
return jsonrpc.JSONRPCResponse{
|
||||
Jsonrpc: jsonrpc.JSONRPC_VERSION,
|
||||
Id: id,
|
||||
Result: struct{}{},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func toolsListHandler(id jsonrpc.RequestId, toolset tools.Toolset, body []byte) (any, error) {
|
||||
var req ListToolsRequest
|
||||
if err := json.Unmarshal(body, &req); err != nil {
|
||||
|
||||
@@ -27,6 +27,7 @@ const PROTOCOL_VERSION = "2024-11-05"
|
||||
|
||||
// methods that are supported.
|
||||
const (
|
||||
PING = "ping"
|
||||
TOOLS_LIST = "tools/list"
|
||||
TOOLS_CALL = "tools/call"
|
||||
)
|
||||
|
||||
@@ -28,6 +28,8 @@ import (
|
||||
// ProcessMethod returns a response for the request.
|
||||
func ProcessMethod(ctx context.Context, id jsonrpc.RequestId, method string, toolset tools.Toolset, tools map[string]tools.Tool, body []byte) (any, error) {
|
||||
switch method {
|
||||
case PING:
|
||||
return pingHandler(id)
|
||||
case TOOLS_LIST:
|
||||
return toolsListHandler(id, toolset, body)
|
||||
case TOOLS_CALL:
|
||||
@@ -38,6 +40,15 @@ func ProcessMethod(ctx context.Context, id jsonrpc.RequestId, method string, too
|
||||
}
|
||||
}
|
||||
|
||||
// pingHandler handles the "ping" method by returning an empty response.
|
||||
func pingHandler(id jsonrpc.RequestId) (any, error) {
|
||||
return jsonrpc.JSONRPCResponse{
|
||||
Jsonrpc: jsonrpc.JSONRPC_VERSION,
|
||||
Id: id,
|
||||
Result: struct{}{},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func toolsListHandler(id jsonrpc.RequestId, toolset tools.Toolset, body []byte) (any, error) {
|
||||
var req ListToolsRequest
|
||||
if err := json.Unmarshal(body, &req); err != nil {
|
||||
|
||||
@@ -27,6 +27,7 @@ const PROTOCOL_VERSION = "2025-03-26"
|
||||
|
||||
// methods that are supported.
|
||||
const (
|
||||
PING = "ping"
|
||||
TOOLS_LIST = "tools/list"
|
||||
TOOLS_CALL = "tools/call"
|
||||
)
|
||||
|
||||
@@ -28,6 +28,8 @@ import (
|
||||
// ProcessMethod returns a response for the request.
|
||||
func ProcessMethod(ctx context.Context, id jsonrpc.RequestId, method string, toolset tools.Toolset, tools map[string]tools.Tool, body []byte) (any, error) {
|
||||
switch method {
|
||||
case PING:
|
||||
return pingHandler(id)
|
||||
case TOOLS_LIST:
|
||||
return toolsListHandler(id, toolset, body)
|
||||
case TOOLS_CALL:
|
||||
@@ -38,6 +40,15 @@ func ProcessMethod(ctx context.Context, id jsonrpc.RequestId, method string, too
|
||||
}
|
||||
}
|
||||
|
||||
// pingHandler handles the "ping" method by returning an empty response.
|
||||
func pingHandler(id jsonrpc.RequestId) (any, error) {
|
||||
return jsonrpc.JSONRPCResponse{
|
||||
Jsonrpc: jsonrpc.JSONRPC_VERSION,
|
||||
Id: id,
|
||||
Result: struct{}{},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func toolsListHandler(id jsonrpc.RequestId, toolset tools.Toolset, body []byte) (any, error) {
|
||||
var req ListToolsRequest
|
||||
if err := json.Unmarshal(body, &req); err != nil {
|
||||
|
||||
@@ -27,6 +27,7 @@ const PROTOCOL_VERSION = "2025-06-18"
|
||||
|
||||
// methods that are supported.
|
||||
const (
|
||||
PING = "ping"
|
||||
TOOLS_LIST = "tools/list"
|
||||
TOOLS_CALL = "tools/call"
|
||||
)
|
||||
|
||||
@@ -81,6 +81,23 @@ func TestMcpEndpointWithoutInitialized(t *testing.T) {
|
||||
body jsonrpc.JSONRPCRequest
|
||||
want map[string]any
|
||||
}{
|
||||
{
|
||||
name: "ping",
|
||||
url: "/",
|
||||
body: jsonrpc.JSONRPCRequest{
|
||||
Jsonrpc: jsonrpcVersion,
|
||||
Id: "ping-test-123",
|
||||
Request: jsonrpc.Request{
|
||||
Method: "ping",
|
||||
},
|
||||
},
|
||||
isErr: false,
|
||||
want: map[string]any{
|
||||
"jsonrpc": "2.0",
|
||||
"id": "ping-test-123",
|
||||
"result": map[string]any{},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "tools/list",
|
||||
url: "/",
|
||||
@@ -333,6 +350,22 @@ func TestMcpEndpoint(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "ping",
|
||||
url: "/",
|
||||
body: jsonrpc.JSONRPCRequest{
|
||||
Jsonrpc: jsonrpcVersion,
|
||||
Id: "ping-test-123",
|
||||
Request: jsonrpc.Request{
|
||||
Method: "ping",
|
||||
},
|
||||
},
|
||||
want: map[string]any{
|
||||
"jsonrpc": "2.0",
|
||||
"id": "ping-test-123",
|
||||
"result": map[string]any{},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "tools/list",
|
||||
url: "/",
|
||||
|
||||
Reference in New Issue
Block a user