Help us shape the future of Go! Take the 2026 Go Developer Survey

mcptest

package
v0.0.114 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 11, 2026 License: MIT Imports: 8 Imported by: 0

README

MCP Gateway Test Harness

This document describes the test harness infrastructure for validating the MCP gateway integration.

Overview

The test harness provides three main components:

  1. Configurable MCP Test Server - A test server that can be configured with custom tools and resources
  2. Test Driver - Manages multiple test servers and provides transport creation
  3. Validator Client - A client that can explore and assert about MCP server capabilities

Components

1. Configurable MCP Test Server

Located in internal/testutil/mcptest/server.go and config.go.

Features:

  • Configure server name and version
  • Add custom tools with handlers
  • Add resources with content
  • Support for stdio transport via in-memory connections

Example Usage:

// Create a test server with tools
config := mcptest.DefaultServerConfig().
    WithTool(mcptest.SimpleEchoTool("echo")).
    WithResource(mcptest.ResourceConfig{
        URI:         "test://doc1",
        Name:        "Document 1",
        Description: "A test document",
        MimeType:    "text/plain",
        Content:     "Test content",
    })

server := mcptest.NewServer(config)
server.Start()
defer server.Stop()
2. Test Driver

Located in internal/testutil/mcptest/driver.go.

Features:

  • Spawn multiple test servers
  • Create in-memory transports for testing
  • Manage lifecycle (start/stop) of test infrastructure

Example Usage:

driver := mcptest.NewTestDriver()
defer driver.Stop()

// Add test servers
driver.AddTestServer("backend1", config1)
driver.AddTestServer("backend2", config2)

// Create transport to connect to a test server
transport, err := driver.CreateStdioTransport("backend1")
3. Validator Client

Located in internal/testutil/mcptest/validator.go.

Features:

  • Connect to any MCP server via a transport
  • List available tools and resources
  • Call tools with arguments
  • Read resources
  • Validate server information

Example Usage:

validator, err := mcptest.NewValidatorClient(ctx, transport)
defer validator.Close()

// List and validate tools
tools, err := validator.ListTools()
assert.Equal(t, 2, len(tools))

// Call a tool
result, err := validator.CallTool("test_tool", map[string]interface{}{
    "input": "test",
})

Test Examples

Basic Server Test

Test a simple MCP server with one tool:

func TestBasicServerWithOneTool(t *testing.T) {
    config := mcptest.DefaultServerConfig().
        WithTool(mcptest.SimpleEchoTool("test_echo"))
    
    driver := mcptest.NewTestDriver()
    defer driver.Stop()
    
    driver.AddTestServer("test", config)
    transport, _ := driver.CreateStdioTransport("test")
    
    validator, _ := mcptest.NewValidatorClient(ctx, transport)
    defer validator.Close()
    
    tools, _ := validator.ListTools()
    assert.Equal(t, 1, len(tools))
}
Gateway Integration Test

Test the AWMG gateway with multiple backends:

func TestGatewayRoutedMode(t *testing.T) {
    // Create gateway config
    gatewayCfg := &config.Config{
        Servers: map[string]*config.ServerConfig{
            "backend1": {Command: "echo", Args: []string{}},
            "backend2": {Command: "echo", Args: []string{}},
        },
    }
    
    us, _ := server.NewUnified(ctx, gatewayCfg)
    defer us.Close()
    
    // Inject test tools
    us.RegisterTestTool("backend1___tool1", &server.ToolInfo{...})
    us.RegisterTestTool("backend2___tool2", &server.ToolInfo{...})
    
    // Create HTTP server in routed mode
    httpServer := server.CreateHTTPServerForRoutedMode("127.0.0.1:0", us)
    ts := httptest.NewServer(httpServer.Handler)
    defer ts.Close()
    
    // Verify backend isolation
    assert.Equal(t, 1, len(us.GetToolsForBackend("backend1")))
    assert.Equal(t, 1, len(us.GetToolsForBackend("backend2")))
}

Custom Tools

You can create custom tools for testing specific scenarios:

customTool := mcptest.ToolConfig{
    Name:        "calculator",
    Description: "Adds two numbers",
    InputSchema: map[string]interface{}{
        "type": "object",
        "properties": map[string]interface{}{
            "a": map[string]interface{}{"type": "number"},
            "b": map[string]interface{}{"type": "number"},
        },
    },
    Handler: func(args map[string]interface{}) ([]sdk.Content, error) {
        a := args["a"].(float64)
        b := args["b"].(float64)
        return []sdk.Content{
            &sdk.TextContent{Text: fmt.Sprintf("%g", a+b)},
        }, nil
    },
}

Running Tests

Run all test harness tests:

go test -v ./internal/testutil/mcptest/...

Run specific test categories:

# Basic harness tests
go test -v ./internal/testutil/mcptest/... -run TestBasic

# Gateway integration tests
go test -v ./internal/testutil/mcptest/... -run TestGateway

Architecture

┌─────────────────────────────────────────────────────┐
│                 Validator Client                     │
│  (Lists tools, calls tools, reads resources)        │
└──────────────────┬──────────────────────────────────┘
                   │ Transport (in-memory)
┌──────────────────┴──────────────────────────────────┐
│              MCP Test Server                         │
│  - Configured tools                                  │
│  - Configured resources                              │
│  - Custom handlers                                   │
└─────────────────────────────────────────────────────┘

Or for gateway testing:

┌─────────────────────────────────────────────────────┐
│                 HTTP Client                          │
│                                                      │
└──────────────────┬──────────────────────────────────┘
                   │ HTTP
┌──────────────────┴──────────────────────────────────┐
│              AWMG Gateway (Routed)                   │
│  /mcp/backend1 ──> Test Backend 1                   │
│  /mcp/backend2 ──> Test Backend 2                   │
└─────────────────────────────────────────────────────┘

Benefits

  1. Isolated Testing - Test gateway functionality without external dependencies
  2. Fast Execution - In-memory transports provide millisecond test execution
  3. Flexible Configuration - Easy to create complex test scenarios
  4. Comprehensive Validation - Validator client checks all MCP capabilities
  5. Gateway Integration - Test routed and unified modes with multiple backends

Future Enhancements

  • Support for HTTP transport testing (SSE)
  • Built-in assertions for common test patterns
  • Mock resource templates
  • Mock prompts support
  • Performance testing utilities
  • Concurrent client testing

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CreateCommandTransport

func CreateCommandTransport(ctx context.Context, command string, args ...string) sdk.Transport

CreateCommandTransport creates a command-based transport that runs a command This is useful for testing with actual executables

Types

type ResourceConfig

type ResourceConfig struct {
	// URI of the resource
	URI string
	// Name of the resource
	Name string
	// Description of the resource
	Description string
	// MimeType of the resource content
	MimeType string
	// Content is the actual resource data
	Content string
}

ResourceConfig defines a resource for the test server

type Server

type Server struct {
	// contains filtered or unexported fields
}

Server is a configurable MCP test server

func NewServer

func NewServer(config *ServerConfig) *Server

NewServer creates a new configurable MCP test server

func (*Server) GetServer

func (s *Server) GetServer() *sdk.Server

GetServer returns the underlying SDK server for transport attachment

func (*Server) Start

func (s *Server) Start() error

Start initializes and starts the MCP server with configured tools and resources

func (*Server) Stop

func (s *Server) Stop()

Stop stops the server

type ServerConfig

type ServerConfig struct {
	// Name is the name of the test server
	Name string
	// Version is the version of the test server
	Version string
	// Tools is the list of tools to expose
	Tools []ToolConfig
	// Resources is the list of resources to expose
	Resources []ResourceConfig
}

ServerConfig defines the configuration for a test MCP server

func DefaultServerConfig

func DefaultServerConfig() *ServerConfig

DefaultServerConfig returns a basic server configuration for testing

func (*ServerConfig) WithResource

func (c *ServerConfig) WithResource(resource ResourceConfig) *ServerConfig

WithResource adds a resource to the server configuration

func (*ServerConfig) WithTool

func (c *ServerConfig) WithTool(tool ToolConfig) *ServerConfig

WithTool adds a tool to the server configuration

type TestDriver

type TestDriver struct {
	// contains filtered or unexported fields
}

TestDriver manages test servers and the gateway for integration testing

func NewTestDriver

func NewTestDriver() *TestDriver

NewTestDriver creates a new test driver

func (*TestDriver) AddTestServer

func (td *TestDriver) AddTestServer(serverID string, config *ServerConfig) error

AddTestServer adds a test server with the given ID and configuration

func (*TestDriver) CreateStdioTransport

func (td *TestDriver) CreateStdioTransport(serverID string) (sdk.Transport, error)

CreateStdioTransport creates an in-memory stdio transport to a test server

func (*TestDriver) GetGatewayServer

func (td *TestDriver) GetGatewayServer() *server.UnifiedServer

GetGatewayServer returns the unified server for testing

func (*TestDriver) StartGateway

func (td *TestDriver) StartGateway() error

StartGateway starts the AWMG gateway on top of the test servers

func (*TestDriver) Stop

func (td *TestDriver) Stop()

Stop stops the test driver and all test servers

type ToolConfig

type ToolConfig struct {
	// Name of the tool
	Name string
	// Description of what the tool does
	Description string
	// InputSchema defines the expected input parameters
	InputSchema map[string]interface{}
	// Handler is the function that executes when the tool is called
	Handler func(arguments map[string]interface{}) ([]sdk.Content, error)
}

ToolConfig defines a tool for the test server

func SimpleEchoTool

func SimpleEchoTool(name string) ToolConfig

SimpleEchoTool creates a basic echo tool for testing

type ValidatorClient

type ValidatorClient struct {
	// contains filtered or unexported fields
}

ValidatorClient is a client for validating MCP servers

func NewValidatorClient

func NewValidatorClient(ctx context.Context, transport sdk.Transport) (*ValidatorClient, error)

NewValidatorClient creates a new validator client connected to the given transport

func (*ValidatorClient) CallTool

func (v *ValidatorClient) CallTool(name string, arguments map[string]interface{}) (*sdk.CallToolResult, error)

CallTool calls a tool on the MCP server

func (*ValidatorClient) Close

func (v *ValidatorClient) Close() error

Close closes the validator client connection

func (*ValidatorClient) GetServerInfo

func (v *ValidatorClient) GetServerInfo() *sdk.Implementation

GetServerInfo returns the server information from the initialize handshake

func (*ValidatorClient) ListResources

func (v *ValidatorClient) ListResources() ([]*sdk.Resource, error)

ListResources retrieves the list of resources from the connected MCP server

func (*ValidatorClient) ListTools

func (v *ValidatorClient) ListTools() ([]*sdk.Tool, error)

ListTools retrieves the list of tools from the connected MCP server

func (*ValidatorClient) ReadResource

func (v *ValidatorClient) ReadResource(uri string) (*sdk.ReadResourceResult, error)

ReadResource reads a resource from the MCP server

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL