Production-Ready testing for MCP

Test MCP Servers with confidence — fast, reliable, type-safe

A lightweight Java framework to write maintainable MCP tests, track performance, and assert on exchanges.

6 modules
Java 17+
Javadoc ready

Built for Developers

Everything you need to test MCP servers effectively

Type-Safe API

Strongly typed domain models eliminate runtime errors. No raw JSON handling.

Fluent Assertions

Chainable methods make tests readable and maintainable.

Modular Design

Clean separation with 6 specialized modules. Import only what you need.

Performance Tracking

Built-in latency monitoring with percentile calculations.

Complete Abstraction

Internal details never leak to your test code.

Extensible

Custom transport implementations supported.

Quick Installation

Get started in minutes with Maven or Gradle

<dependency>
    <groupId>io.github.abhiramrathod</groupId>
    <artifactId>mcp-test-api</artifactId>
    <version>1.0.3</version>
    <scope>test</scope>
</dependency>
testImplementation 'io.github.abhiramrathod:mcp-test-api:1.0.3'
Only add mcp-test-api - all modules are included transitively

Your First Test

import mcp.toolkit.testing.framework.api.*;
import mcp.toolkit.testing.framework.api.model.*;

public class MyFirstTest {
    @Test
    public void testMcpServer() {
        // Connect to MCP server
        McpClient client = McpClient.connectTo("http://localhost:8080")
                .config(McpClientConfig.builder()
                        .timeout(Duration.ofSeconds(30))
                        .build())
                .initializeOnBuild()
                .build();

        // Test tool invocation
        McpToolResult result = client.tools()
                .callTool("calculator", Map.of("operation", "add", "a", 5, "b", 3))
                .assertSuccess()
                .assertTextContains("8");

        // Verify performance
        client.exchanges().assertAverageLatencyBelow(McpMethod.TOOLS_CALL, 500);
        
        client.close();
    }
}

Configuration

Control client behavior via McpClientConfig

Key Options

  • timeout (Duration) — request timeout for connections and RPC calls. Default: 10s.
  • protocolVersion (String) — MCP protocol version advertised during initialize. Default: 2024-11-05.
  • sseEndpointPath — default SSE endpoint path: /sse.
McpClientConfig config = McpClientConfig.builder()
        .timeout(Duration.ofSeconds(30))
        .protocolVersion("2024-11-05")
        .build();

McpClient client = McpClient.connectTo("http://localhost:8080")
        .config(config)
        .build();

Components (Modules)

Overview of each module in the project, coordinates, key classes and notes for maintainers and users.

mcp-test-api

Coordinates: io.github.abhiramrathod:mcp-test-api:1.0.3

Purpose: Public API surface exported to tests. Import this artifact in your test scope to use the client, models and assertions.

Key packages / classes: mcp.toolkit.testing.framework.apiMcpClientConfig, factory classes (connect/build), models and assertion helpers.

Source: McpClientConfig.java

Notes: This module re-exports functionality implemented in internal modules; use only this artifact in test code.

Built artifact (if built locally): mcp-test-api target jar

mcp-test-client

Coordinates: io.github.abhiramrathod:mcp-test-client:1.0.3

Purpose: Internal client implementation used by the public API. Handles initialization, component wiring and high-level helpers.

Key classes: McpTestClient (connection lifecycle), client directories: tools/resources/prompts, and exchange tracking (performance APIs).

Source: McpTestClient.java

mcp-test-transport

Coordinates: io.github.abhiramrathod:mcp-test-transport:1.0.3

Purpose: Transport implementations for communicating with MCP servers.

Key classes: McpSseTransport — SSE-based transport that opens a streaming connection and posts messages to the MCP message endpoint.

Source: McpSseTransport.java

Notes: Transport is pluggable — you can implement mcp.toolkit.testing.framework.interfaces.McpTransport to provide custom wiring.

mcp-test-core

Coordinates: io.github.abhiramrathod:mcp-test-core:1.0.3

Purpose: Core utilities, codecs and constants shared by client and transport implementations.

Key packages: mcp.toolkit.testing.framework.core — JSON codec, constants and common helpers.

mcp-test-interfaces

Coordinates: io.github.abhiramrathod:mcp-test-interfaces:1.0.3

Purpose: Public interfaces used by internal modules and custom extensions.

Key interfaces: mcp.toolkit.testing.framework.interfaces.McpTransport — transport abstraction for sending/receiving MCP JSON-RPC messages.

mcp-test-examples

Purpose: Example tests demonstrating usage patterns and integration scenarios. Not published; useful for learning and CI tests.

How to run: mvn -pl mcp-test-examples test

Build & Javadocs: The parent POM attaches javadocs during the build. To build and create attached javadocs for publishable artifacts run:

mvn -T 1C clean install
# javadocs attached automatically by parent POM; to produce only javadocs:
mvn javadoc:jar -pl mcp-test-api

Publishing: Distribution is configured to publish to GitHub Packages via https://maven.pkg.github.com/${env.GITHUB_REPOSITORY}. Set appropriate credentials (GITHUB_TOKEN or personal access token) in your CI or settings.xml when deploying.

Javadocs (local): If an aggregated Javadoc has been generated and placed under docs/javadoc, view it here: API Javadocs.

Core Capabilities

Comprehensive testing for all MCP features

Tools Testing

Discover and invoke MCP tools with strongly-typed results

List<McpTool> tools = client.tools().listTools();

McpToolResult result = client.tools()
        .callTool("calculator", Map.of("op", "add", "a", 5, "b", 3))
        .assertSuccess()
        .assertTextContains("8");

Resources Testing

List and read MCP resources with content validation

List<McpResource> resources = client.resources().listResources();

McpResourceContent content = client.resources()
        .readResource("file://config.json")
        .assertNotEmpty();

Prompts Testing

Retrieve and inspect MCP prompts with arguments

List<McpPrompt> prompts = client.prompts().listPrompts();

McpPromptResult prompt = client.prompts()
        .getPrompt("translate", Map.of("lang", "en"))
        .assertNotEmpty();

Performance Monitoring

Track RPC exchanges and assert on latency

client.exchanges()
        .assertAverageLatencyBelow(McpMethod.TOOLS_CALL, 500);

long p99 = client.exchanges()
        .latencyPercentile(McpMethod.TOOLS_CALL, 99);

Clean Architecture

Modular design with clear separation of concerns

Public API
mcp-test-api
Internal
mcp-test-client
Transport
mcp-test-transport
Core
mcp-test-interfaces mcp-test-core
Users only import mcp-test-api - all other modules are internal