# MCP Tests
Shared test utilities for testing MCP servers across all API packages.
## Overview
This package provides reusable testing utilities built on the official MCP Python SDK with SSE transport support. It eliminates the need for manual JSON-RPC request handling and SSE parsing.
## Features
- **MCP Client Session**: Easy-to-use async context manager for MCP connections
- **Environment Handling**: Utilities for loading and validating environment variables
- **Tool Discovery**: Helper functions for finding tools by name
## Installation
Add to your API package's dev dependencies:
```toml
[project.optional-dependencies]
dev = [
"mcp-tests",
]
```
## Usage
### Basic Example
```python
import pytest
from pathlib import Path
from mcp_tests import (
create_mcp_session,
load_environment_from_dotenv,
validate_required_env_var,
find_tool_by_name,
)
# Load environment variables
load_environment_from_dotenv(Path(__file__).parent / '.env')
@pytest.fixture
async def mcp_session():
"""Create an authenticated MCP session."""
url = validate_required_env_var("MCP_SERVER_URL")
async with create_mcp_session(url) as session:
yield session
@pytest.mark.asyncio
async def test_list_tools(mcp_session):
"""Test listing available tools."""
# When: Requesting the list of tools
tools_response = await mcp_session.list_tools()
# Then: The response contains tools
assert len(tools_response.tools) > 0
print(f"Found {len(tools_response.tools)} tools")
@pytest.mark.asyncio
async def test_call_tool(mcp_session):
"""Test calling a tool."""
# Given: A list of available tools
tools_response = await mcp_session.list_tools()
user_tool = find_tool_by_name(tools_response.tools, "get_current_user")
assert user_tool is not None
# When: Calling the tool
result = await mcp_session.call_tool(user_tool.name, {})
# Then: The tool returns valid data
assert len(result.content) > 0
```
## API Reference
### `create_mcp_session(url, headers=None)`
Create an MCP client session using SSE transport.
**Parameters:**
- `url` (str): The MCP server SSE endpoint URL
- `headers` (dict, optional): HTTP headers to include in requests
**Returns:**
- `ClientSession`: An initialized MCP client session
**Example:**
```python
async with create_mcp_session("https://api.example.com/mcp") as session:
tools = await session.list_tools()
```
### `validate_required_env_var(var_name)`
Validate that a required environment variable is set.
**Parameters:**
- `var_name` (str): Name of the environment variable
**Returns:**
- `str`: The value of the environment variable
**Raises:**
- `pytest.fail`: If the variable is not set
### `find_tool_by_name(tools, tool_name)`
Find a tool by exact name match.
**Parameters:**
- `tools` (list[Tool]): List of Tool objects from `list_tools()` response
- `tool_name` (str): Exact name of the tool to find
**Returns:**
- `Tool | None`: The Tool object if found, None otherwise
### `load_environment_from_dotenv(file_path)`
Load environment variables from a .env file.
**Parameters:**
- `file_path` (Path, optional): Path to .env file
## Benefits
✅ **Official SDK**: Uses the official MCP Python SDK
✅ **Type Safety**: Full type hints and IDE autocomplete
✅ **Async Native**: Built on modern async/await patterns
✅ **Reusable**: Share code across all API test suites
✅ **Maintainable**: Changes to MCP protocol handled by SDK updates
## License
Apache-2.0