Skip to content

Add ergonomic Client class for testing MCP servers - #1870

Merged
felixweinberger merged 1 commit into
mainfrom
fweinberger/client-v2
Jan 16, 2026
Merged

Add ergonomic Client class for testing MCP servers#1870
felixweinberger merged 1 commit into
mainfrom
fweinberger/client-v2

Conversation

@felixweinberger

@felixweinbergerfelixweinberger commented Jan 15, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds a high-level Client class that provides an ergonomic API for testing MCP servers with in-memory transport.

Motivation and Context

Testing MCP servers currently requires using the verbose create_connected_server_and_client_session function. This PR introduces a simpler API:

frommcpimportClientfrommcp.server.fastmcpimportFastMCPmcp=FastMCP("test")
@mcp.tool()defadd(a: int, b: int) ->int:
returna+basyncwithClient(mcp) asclient:
result=awaitclient.call_tool("add", {"a": 1, "b": 2})

Related issues:

How Has This Been Tested?

  • 24 new tests for Client and InMemoryTransport
  • Migrated existing tests from create_connected_server_and_client_session to new API
  • Full test suite passes

Breaking Changes

  • Removed create_connected_server_and_client_session from mcp.shared.memory (v2 breaking change)

Types of changes

  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

Additional context

New API

High-level (recommended):

frommcpimportClientasyncwithClient(server) asclient:
result=awaitclient.call_tool("my_tool", {"arg": "value"})

Low-level (for advanced use cases):

frommcp.client.transportsimportInMemoryTransportfrommcp.client.sessionimportClientSessiontransport=InMemoryTransport(server)
asyncwithtransport.connect() as (read, write):
asyncwithClientSession(read, write) assession:
awaitsession.initialize()
# Full ClientSession access...

@felixweinberger
felixweinbergerforce-pushed the fweinberger/client-v2 branch 3 times, most recently from e3c2972 to 0b610a8CompareJanuary 16, 2026 09:41
@felixweinberger

Copy link
Copy Markdown
ContributorAuthor

Key files to review:

  • src/mcp/client/client.py (new) - unified Client class
  • src/mcp/client/transports/memory.py (new) - InMemoryTransport
  • src/mcp/client/__init__.py - public exports
  • src/mcp/client/transports/__init__.py - transport exports
  • src/mcp/shared/memory.py (deleted) - replaced by InMemoryTransport

Remainder is tests being updated to use the new interface.

NOTE: This only implements test support. Refactoring Client to support different transports for the end-user API (streamable HTTP, stdio, SSE, etc.) is coming, marked as TODO in the Client docstring.

@felixweinberger
felixweinberger marked this pull request as ready for review January 16, 2026 12:52
Comment threadsrc/mcp/client/client.py
Comment threadsrc/mcp/client/client.py Outdated
Comment threadsrc/mcp/client/client.py
Comment threaddocs/testing.md Outdated
Comment threadsrc/mcp/client/_memory.py
@felixweinberger

felixweinberger commented Jan 16, 2026

Copy link
Copy Markdown
ContributorAuthor

Follow-up tasks

  • Add transport types to Client (StreamableHttpTransport, SSETransport, StdioTransport) + infer_transport() for auto-detection
  • Add lint rule to enforce Google-style docstrings (first line on same line as """) e.g. """Send a ping request."""
  • Audit existing unit tests and as much as possible refactor to use this new Client class instead

Comment threaddocs/testing.md Outdated
Kludex
Kludex previously approved these changes Jan 16, 2026
Comment threadsrc/mcp/client/client.py Outdated
Comment threadsrc/mcp/client/client.py
Comment threadsrc/mcp/client/client.py
Comment threadsrc/mcp/client/client.py
Comment threadsrc/mcp/client/client.py Outdated
Kludex
Kludex previously approved these changes Jan 16, 2026
Add a high-level Client class that wraps ClientSession with transport
management, making it easier to test MCP servers.
Key changes:
- Add Client class with async context manager support
- Add InMemoryTransport for in-memory server connections
- Migrate test files to use new Client(server) API
- Update testing documentation with Client usage examples
Usage:
async with Client(server) as client:
result = await client.call_tool('my_tool', {'arg': 'value'})
@felixweinberger
felixweinberger enabled auto-merge (squash) January 16, 2026 15:48
@felixweinberger
felixweinberger merged commit df039bf into mainJan 16, 2026
26 checks passed
@felixweinberger
felixweinberger deleted the fweinberger/client-v2 branch January 16, 2026 15:49
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add ergonomic test client for testing MCP servers

2 participants

@felixweinberger@Kludex