In the following post we present creation of MCP Client in GO including API, implementation, and stub. This method of providing APIs is critical for a successful testing which should not access any external entity. Note that in this case, we also provide a factory API, implementation, and stub further enabling the code to create MCP client even when it is running in the tests scope.
MCP Client
The client API:
type McpToolInfo struct {
ToolName string
ToolDescription string
InputSchema string
OutputSchema string
}
type McpClientApi interface {
ListTools() []*McpToolInfo
CloseSession()
}
The implementation:
// static - to use connection pool for all servers
var staticWebClient = web.ProduceClientImpl(core.Config.McpConnectionTimeout)
type McpClientImpl struct {
session *mcp.ClientSession
context context.Context
}
func ProduceMcpClientImpl(
mcpServerUrl string,
) *McpClientImpl {
m := &McpClientImpl{
context: context.Background(),
}
client := mcp.NewClient(
&mcp.Implementation{
Name: "my-go-client",
Version: "1.0.0",
},
nil,
)
transport := &mcp.StreamableClientTransport{
Endpoint: mcpServerUrl,
HTTPClient: staticWebClient.UsedClient(),
}
session, err := client.Connect(m.context, transport, nil)
kiterr.RaiseIfError(err)
m.session = session
return m
}
func (m *McpClientImpl) ListTools() []*McpToolInfo {
parameters := mcp.ListToolsParams{}
tools, err := m.session.ListTools(m.context, ¶meters)
kiterr.RaiseIfError(err)
var result []*McpToolInfo
for _, tool := range tools.Tools {
info := McpToolInfo{
ToolName: tool.Name,
ToolDescription: tool.Description,
InputSchema: fmt.Sprintf("%v", tool.InputSchema),
OutputSchema: fmt.Sprintf("%v", tool.OutputSchema),
}
result = append(result, &info)
}
return result
}
func (m *McpClientImpl) CloseSession() {
err := m.session.Close()
m.session = nil
kiterr.RaiseIfError(err)
}
And the stub:
type McpClientStub struct {
}
func ProduceMcpClientStub(
mcpServerUrl string,
) *McpClientStub {
return &McpClientStub{}
}
func (m *McpClientStub) ListTools() []*McpToolInfo {
return []*McpToolInfo{
{
ToolName: "tool-1",
ToolDescription: "the best tool",
InputSchema: "my-schema-input",
OutputSchema: "my-schema-output",
},
}
}
func (m *McpClientStub) CloseSession() {
}
MCP Client Factory
The factory API:
import "radware.com/mcpp/commons/mcp/client"
type McpClientFactoryApi interface {
ProduceMcpClient(
mcpServerUrl string,
) client.McpClientApi
}
The factory implementation:
type McpClientFactoryImpl struct {
}
func ProduceMcpClientFactoryImpl() *McpClientFactoryImpl {
return &McpClientFactoryImpl{}
}
func (f *McpClientFactoryImpl) ProduceMcpClient(
mcpServerUrl string,
) client.McpClientApi {
return client.ProduceMcpClientImpl(mcpServerUrl)
}
And the stub:
type McpClientFactoryStub struct {
}
func ProduceMcpClientFactoryStub() *McpClientFactoryStub {
return &McpClientFactoryStub{}
}
func (f *McpClientFactoryStub) ProduceMcpClient(
mcpServerUrl string,
) client.McpClientApi {
return client.ProduceMcpClientStub(mcpServerUrl)
}
No comments:
Post a Comment