helpers

package
v0.6.7 Latest Latest
Warning

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

Go to latest
Published: Nov 25, 2025 License: Apache-2.0 Imports: 23 Imported by: 0

Documentation

Overview

Package helpers provides test utilities for vMCP integration tests.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AssertTextContains

func AssertTextContains(tb testing.TB, text string, expected ...string)

AssertTextContains asserts that text contains all expected substrings. This is a variadic helper for checking multiple content expectations in tool results.

The function uses assert (not require), so multiple failures can be reported together.

Example:

text := helpers.AssertToolCallSuccess(t, result)
helpers.AssertTextContains(t, text, "user_id", "username", "email")

func AssertTextNotContains

func AssertTextNotContains(tb testing.TB, text string, forbidden ...string)

AssertTextNotContains asserts that text does not contain any of the forbidden substrings. This is a variadic helper for checking that certain content is absent from tool results.

The function uses assert (not require), so multiple failures can be reported together.

Example:

text := helpers.AssertToolCallSuccess(t, result)
helpers.AssertTextNotContains(t, text, "password", "secret", "api_key")

func AssertToolCallSuccess

func AssertToolCallSuccess(tb testing.TB, result *mcp.CallToolResult) string

AssertToolCallSuccess asserts that a tool call succeeded (IsError=false) and returns the concatenated text content from all content items.

The function uses require assertions, so it will fail the test immediately if the tool call was an error.

Example:

result := client.CallTool(ctx, "get_user", map[string]any{"id": 123})
text := helpers.AssertToolCallSuccess(t, result)
assert.Contains(t, text, "username")

func CreateBackendServer

func CreateBackendServer(tb testing.TB, tools []BackendTool, opts ...BackendServerOption) *httptest.Server

CreateBackendServer creates an MCP backend server using the mark3labs/mcp-go SDK. It returns an *httptest.Server ready to accept streamable-HTTP connections.

The server automatically registers all provided tools with proper closure handling to avoid common Go loop variable capture bugs. Each tool's handler is invoked when the tool is called via the MCP protocol.

The server uses the streamable-HTTP transport, which is compatible with ToolHive's vMCP server and supports both streaming and non-streaming requests.

The returned httptest.Server should be closed after use with defer server.Close().

Example:

// Create a simple echo tool
echoTool := testkit.NewBackendTool(
    "echo",
    "Echo back the input message",
    func(ctx context.Context, args map[string]any) string {
        msg := args["message"].(string)
        return fmt.Sprintf(`{"echoed": %q}`, msg)
    },
)

// Start backend server
backend := testkit.CreateBackendServer(t, []BackendTool{echoTool},
    testkit.WithBackendName("echo-server"),
    testkit.WithBackendEndpoint("/mcp"),
)
defer backend.Close()

// Use backend URL to connect MCP client
client := testkit.NewMCPClient(ctx, t, backend.URL+"/mcp")
defer client.Close()

func GetHTTPHeadersFromContext

func GetHTTPHeadersFromContext(ctx context.Context) http.Header

GetHTTPHeadersFromContext retrieves HTTP headers from the context. Returns nil if headers are not present in the context.

func GetToolNames

func GetToolNames(result *mcp.ListToolsResult) []string

GetToolNames extracts tool names from a ListToolsResult. This is a convenience function for common test assertions.

Example:

tools := client.ListTools(ctx)
names := helpers.GetToolNames(tools)
assert.ElementsMatch(t, []string{"tool1", "tool2"}, names)

func NewBackend

func NewBackend(id string, opts ...func(*vmcptypes.Backend)) vmcptypes.Backend

NewBackend creates a test backend with sensible defaults. Use functional options to customize.

func NewVMCPServer

func NewVMCPServer(
	ctx context.Context, tb testing.TB, backends []vmcptypes.Backend, opts ...VMCPServerOption,
) *vmcpserver.Server

NewVMCPServer creates a vMCP server for testing with sensible defaults. The server is automatically started and will be ready when this function returns. Use functional options to customize behavior.

Example:

server := testkit.NewVMCPServer(ctx, t, backends,
    testkit.WithPrefixConflictResolution("{workload}_"),
)
defer server.Shutdown(ctx)

func WithAuth

func WithAuth(strategy string, metadata map[string]any) func(*vmcptypes.Backend)

WithAuth configures authentication.

func WithMetadata

func WithMetadata(key, value string) func(*vmcptypes.Backend)

WithMetadata adds a metadata key-value pair.

func WithURL

func WithURL(url string) func(*vmcptypes.Backend)

WithURL sets the backend URL.

Types

type BackendServerOption

type BackendServerOption func(*backendServerConfig)

BackendServerOption is a functional option for configuring a backend server.

func WithBackendName

func WithBackendName(name string) BackendServerOption

WithBackendName sets the backend server name. This name is reported in the server's initialize response.

Default: "test-backend"

func WithCaptureHeaders

func WithCaptureHeaders() BackendServerOption

WithCaptureHeaders enables capturing HTTP request headers in the context. When enabled, tool handlers can access request headers via GetHTTPHeadersFromContext(ctx). This is useful for testing authentication header injection.

Default: false

type BackendTool

type BackendTool struct {
	// Name is the unique identifier for the tool
	Name string

	// Description explains what the tool does
	Description string

	// InputSchema defines the expected input structure using JSON Schema.
	// The schema validates the arguments passed to the tool.
	InputSchema mcp.ToolInputSchema

	// Handler processes tool calls and returns results.
	// The handler receives the tool arguments as a map and should return
	// a string representation of the result (typically JSON).
	Handler func(ctx context.Context, args map[string]any) string
}

BackendTool defines a tool for MCP backend servers. It provides a simplified interface for creating tools with handlers in tests.

The handler function receives a context and arguments map, and returns a string result. The result should typically be valid JSON matching the tool's output schema.

func NewBackendTool

func NewBackendTool(name, description string, handler func(ctx context.Context, args map[string]any) string) BackendTool

NewBackendTool creates a new BackendTool with sensible defaults. The default InputSchema is an empty object schema that accepts any properties.

Example:

tool := testkit.NewBackendTool(
    "create_issue",
    "Create a GitHub issue",
    func(ctx context.Context, args map[string]any) string {
        title := args["title"].(string)
        return fmt.Sprintf(`{"issue_id": 123, "title": %q}`, title)
    },
)

type MCPClient

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

MCPClient wraps the mark3labs MCP client with test-friendly methods. It automatically handles initialization and provides semantic assertion helpers that integrate with Go's testing.TB interface.

Example usage:

ctx := context.Background()
mcpClient := helpers.NewMCPClient(ctx, t, serverURL)
defer mcpClient.Close()

tools := mcpClient.ListTools(ctx)
toolNames := helpers.GetToolNames(tools)
assert.Contains(t, toolNames, "create_issue")

func NewMCPClient

func NewMCPClient(ctx context.Context, tb testing.TB, serverURL string, opts ...MCPClientOption) *MCPClient

NewMCPClient creates and initializes a new MCP client for testing. It automatically starts the transport and performs the MCP handshake.

The client is configured with sensible defaults suitable for testing:

  • Protocol version: Latest (mcp.LATEST_PROTOCOL_VERSION)
  • Client name: "testkit-client"
  • Client version: "1.0.0"
  • Transport: streamable-http (vMCP only supports streamable-http)

The function fails the test immediately if initialization fails.

Example:

client := helpers.NewMCPClient(ctx, t, "http://localhost:8080/mcp")
defer client.Close()

tools := client.ListTools(ctx)
assert.NotEmpty(t, helpers.GetToolNames(tools))

func (*MCPClient) CallTool

func (c *MCPClient) CallTool(ctx context.Context, name string, args map[string]any) *mcp.CallToolResult

CallTool calls the specified tool with the given arguments. The method logs the operation and fails the test if the request fails.

Example:

result := client.CallTool(ctx, "create_issue", map[string]any{
    "title": "Bug report",
    "body": "Description",
})
text := helpers.AssertToolCallSuccess(t, result)
assert.Contains(t, text, "issue_id")

func (*MCPClient) Close

func (c *MCPClient) Close() error

Close closes the MCP client connection. This should typically be deferred immediately after client creation.

func (*MCPClient) ListTools

func (c *MCPClient) ListTools(ctx context.Context) *mcp.ListToolsResult

ListTools lists all available tools from the MCP server. The method logs the operation and fails the test if the request fails.

Example:

tools := client.ListTools(ctx)
toolNames := helpers.GetToolNames(tools)
assert.Contains(t, toolNames, "expected_tool")

type MCPClientOption

type MCPClientOption func(*mcpClientConfig)

MCPClientOption is a functional option for configuring an MCPClient.

type VMCPServerOption

type VMCPServerOption func(*vmcpServerConfig)

VMCPServerOption is a functional option for configuring a vMCP test server.

func WithPrefixConflictResolution

func WithPrefixConflictResolution(format string) VMCPServerOption

WithPrefixConflictResolution configures prefix-based conflict resolution.

Jump to

Keyboard shortcuts

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