ExMCP.Testing.MockServer (ex_mcp v0.10.0)
View SourceMock MCP server implementation for testing.
This module provides a comprehensive mock server that can simulate various MCP server behaviors for testing client implementations. It supports all MCP protocol features including tools, resources, prompts, and streaming.
Features
- Full Protocol Support: All MCP methods and notifications
- Configurable Responses: Customize server behavior for testing
- State Management: Stateful behavior for complex scenarios
- Error Simulation: Test error handling and edge cases
- Performance Testing: Latency and throughput simulation
- Transport Agnostic: Works with all transport implementations
Usage
# Simple mock server
MockServer.with_server([], fn client ->
{:ok, result} = ExMCP.Client.list_tools(client)
assert length(result["tools"]) == 0
end)
# Server with predefined tools
MockServer.with_server([
tools: [MockServer.sample_tool()],
resources: [MockServer.sample_resource()]
], fn client ->
# Test with mock data
end)
# Server with custom behavior
MockServer.with_server([
handler: MyCustomHandler,
state: %{custom_data: "test"}
], fn client ->
# Test with custom handler
end)
Summary
Functions
Returns a specification to start this module under a supervisor.
Gets the current call count for a mock server.
Gets the current state of a mock server.
Resets the call count for a mock server.
Creates a sample prompt definition for testing.
Creates a sample resource definition for testing.
Creates a sample tool definition for testing.
Updates the custom state of a mock server.
Starts a mock server and runs a test function with a connected client.
Types
@type mock_config() :: [ tools: [map()], resources: [map()], prompts: [map()], handler: module() | nil, state: map(), latency: pos_integer(), error_rate: float(), capabilities: map() ]
Mock server configuration
@type server_state() :: %{ tools: [map()], resources: [map()], prompts: [map()], handler: module() | nil, custom_state: map(), latency: pos_integer(), error_rate: float(), capabilities: map(), call_count: map(), last_calls: [map()] }
Mock server state
Functions
Returns a specification to start this module under a supervisor.
See Supervisor.
Gets the current call count for a mock server.
Examples
with_server([], fn client ->
ExMCP.Client.list_tools(client)
ExMCP.Client.list_tools(client)
count = MockServer.get_call_count(server_pid)
assert count["tools/list"] == 2
end)
@spec get_server_state(pid()) :: server_state()
Gets the current state of a mock server.
@spec reset_call_count(pid()) :: :ok
Resets the call count for a mock server.
Creates a sample prompt definition for testing.
Examples
prompt = sample_prompt()
# %{"name" => "sample_prompt", "description" => "...", "arguments" => [...]}
prompt = sample_prompt(name: "custom_prompt")
Creates a sample resource definition for testing.
Examples
resource = sample_resource()
# %{"uri" => "file://sample.txt", "name" => "Sample", ...}
resource = sample_resource(uri: "https://api.example.com", name: "API")
Creates a sample tool definition for testing.
Examples
tool = sample_tool()
# %{"name" => "sample_tool", "description" => "...", "inputSchema" => %{...}}
tool = sample_tool(name: "custom_tool", description: "Custom tool")
Updates the custom state of a mock server.
@spec start_link(mock_config()) :: GenServer.on_start()
@spec with_server(mock_config(), (pid() -> any())) :: any()
Starts a mock server and runs a test function with a connected client.
Options
:tools- List of tool definitions to serve:resources- List of resource definitions to serve:prompts- List of prompt definitions to serve:handler- Custom handler module for advanced behavior:state- Initial custom state for the handler:latency- Simulated response latency in milliseconds:error_rate- Probability (0.0-1.0) of returning errors:capabilities- Custom server capabilities
Examples
with_server([], fn client ->
result = ExMCP.Client.list_tools(client)
assert {:ok, %{"tools" => []}} = result
end)
with_server([
tools: [sample_tool()],
latency: 100
], fn client ->
# Test with 100ms latency
end)