Mirror of https://github.com/modelcontextprotocol/conformance — Conformance Tests for MCP
  • TypeScript 98.1%
  • JavaScript 1.9%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Paul Carleton 753f1240d1
Add client credentials support to everything-client (#89)
* Add client credentials support to everything-client

- Add ConformanceContextSchema with discriminated union for auth contexts
- Add runClientCredentialsJwt and runClientCredentialsBasic handlers
- Update runner to include scenario name in context for discriminated union parsing
- Update test helpers to set env vars for inline client runners
- Fix JWT audience validation to match SDK behavior (no trailing slash)
- Remove client credentials scenarios from skip list

* Accept both trailing slash forms for JWT audience per RFC 3986

Per RFC 3986, URLs with and without trailing slash are equivalent.
The MCP spec recommends (SHOULD) the form without trailing slash, but
since it's not a MUST, the conformance test should accept both forms
for interoperability with clients like Pydantic that normalize URLs.

* Remove .vscode from tracking and add to gitignore

* Address review feedback

- Remove unused issuerUrl variable and comment
- Simplify audience array to exactly 2 values with clearer naming
- Add comment explaining strip-then-add-back logic
- Rename ConformanceContextSchema to ClientConformanceContextSchema

* Remove dist from tracking and add to gitignore

* Fix .gitignore formatting

* Add getHandler to everything-client for cleaner test imports

Instead of importing individual handlers, tests can now import getHandler
and look up handlers by scenario name.

* Use getHandler exclusively, remove goodClient import

- Add CIMD support to runAuthClient in everything-client
- Add auth fallback to getHandler for unregistered auth/* scenarios
- Remove goodClient import from test file

* Remove runAuthClient fallback, register all auth scenarios explicitly
2026-01-05 17:48:53 +00:00
.github Bump actions/checkout from 4 to 6 (#68) 2026-01-05 14:02:06 +00:00
examples Add client credentials support to everything-client (#89) 2026-01-05 17:48:53 +00:00
src Add client credentials support to everything-client (#89) 2026-01-05 17:48:53 +00:00
.gitattributes chore: enforce LF line endings for x-plat consistency (#74) 2025-12-04 17:32:07 +00:00
.gitignore Add client credentials support to everything-client (#89) 2026-01-05 17:48:53 +00:00
.prettierrc.json chore: enforce LF line endings for x-plat consistency (#74) 2025-12-04 17:32:07 +00:00
eslint.config.mjs adjust prettier to use more defaults (#8) 2025-11-04 15:34:27 +00:00
lefthook-local.example.yml Add sep-835 limit retry scenario, add suite options to server command and update pending scenarios (#49) 2025-11-21 16:49:38 +00:00
lefthook.yml Add sep-835 limit retry scenario, add suite options to server command and update pending scenarios (#49) 2025-11-21 16:49:38 +00:00
LICENSE Add publish step (#16) 2025-11-11 12:05:12 +00:00
package-lock.json Add token endpoint auth method conformance tests (#48) 2026-01-05 14:32:35 +00:00
package.json Add token endpoint auth method conformance tests (#48) 2026-01-05 14:32:35 +00:00
README.md Refactor client testing to use 'everything' client with scenario routing (#54) 2026-01-05 14:16:21 +00:00
tsconfig.json move to vitest (#18) 2025-11-13 13:32:07 +00:00
vitest.config.ts feat: add conformance tests for SEP-1699 SSE polling (#47) 2025-11-24 18:34:28 +00:00

MCP Conformance Test Framework

A framework for testing MCP (Model Context Protocol) client and server implementations against the specification.

[!WARNING] This repository is a work in progress and is unstable. Join the conversation in the #conformance-testing-wg in the MCP Contributors discord.

Quick Start

Testing Clients

# Using the everything-client (recommended)
npx @modelcontextprotocol/conformance client --command "tsx examples/clients/typescript/everything-client.ts" --scenario initialize

# Run an entire suite of tests
npx @modelcontextprotocol/conformance client --command "tsx examples/clients/typescript/everything-client.ts" --suite auth

Testing Servers

# Run all server scenarios (default)
npx @modelcontextprotocol/conformance server --url http://localhost:3000/mcp

# Run a single scenario
npx @modelcontextprotocol/conformance server --url http://localhost:3000/mcp --scenario server-initialize

List Available Scenarios

npx @modelcontextprotocol/conformance list

Overview

The conformance test framework validates MCP implementations by:

For Clients:

  1. Starting a test server for the specified scenario
  2. Running the client implementation with the test server URL
  3. Capturing MCP protocol interactions
  4. Running conformance checks against the specification
  5. Generating detailed test results

For Servers:

  1. Connecting to the running server as an MCP client
  2. Sending test requests and capturing responses
  3. Running conformance checks against server behavior
  4. Generating detailed test results

Usage

Client Testing

npx @modelcontextprotocol/conformance client --command "<client-command>" --scenario <scenario-name> [options]

Options:

  • --command - The command to run your MCP client (can include flags)
  • --scenario - The test scenario to run (e.g., "initialize")
  • --suite - Run a suite of tests in parallel (e.g., "auth")
  • --timeout - Timeout in milliseconds (default: 30000)
  • --verbose - Show verbose output

The framework appends <server-url> as an argument to your command and sets the MCP_CONFORMANCE_SCENARIO environment variable to the scenario name. For scenarios that require additional context (e.g., client credentials), the MCP_CONFORMANCE_CONTEXT environment variable contains a JSON object with scenario-specific data.

Server Testing

npx @modelcontextprotocol/conformance server --url <url> [--scenario <scenario>]

Options:

  • --url - URL of the server to test
  • --scenario <scenario> - Test scenario to run (e.g., "server-initialize". Runs all available scenarios by default

Test Results

Client Testing - Results are saved to results/<scenario>-<timestamp>/:

  • checks.json - Array of conformance check results with pass/fail status
  • stdout.txt - Client stdout output
  • stderr.txt - Client stderr output

Server Testing - Results are saved to results/server-<scenario>-<timestamp>/:

  • checks.json - Array of conformance check results with pass/fail status

Example Clients

  • examples/clients/typescript/everything-client.ts - Single client that handles all scenarios based on scenario name (recommended)
  • examples/clients/typescript/test1.ts - Simple MCP client (for reference)
  • examples/clients/typescript/auth-test.ts - Well-behaved OAuth client (for reference)

Available Scenarios

Client Scenarios

  • initialize - Tests MCP client initialization handshake
    • Validates protocol version
    • Validates clientInfo (name and version)
    • Validates server response handling
  • tools-call - Tests tool invocation
  • auth/basic-dcr - Tests OAuth Dynamic Client Registration flow
  • auth/basic-metadata-var1 - Tests OAuth with authorization metadata

Server Scenarios

Run npx @modelcontextprotocol/conformance list --server to see all available server scenarios, including:

  • server-initialize - Tests server initialization and capabilities
  • tools-list - Tests tool listing endpoint
  • tools-call-* - Various tool invocation scenarios
  • resources-* - Resource management scenarios
  • prompts-* - Prompt management scenarios

Architecture

See src/runner/DESIGN.md for detailed architecture documentation.

Key Components

  • Runner (src/runner/) - Orchestrates test execution and result generation
    • client.ts - Client testing implementation
    • server.ts - Server testing implementation
    • utils.ts - Shared utilities
    • index.ts - Public API exports
  • CLI (src/index.ts) - Command-line interface using Commander.js
  • Scenarios (src/scenarios/) - Test scenarios with expected behaviors
  • Checks (src/checks/) - Conformance validation functions
  • Types (src/types.ts) - Shared type definitions

Adding New Scenarios

  1. Create a new directory in src/scenarios/<scenario-name>/
  2. Implement the Scenario interface with start(), stop(), and getChecks()
  3. Register the scenario in src/scenarios/index.ts

See src/scenarios/initialize/ for a reference implementation.