-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Description
Question
There isn't much documentation on testing and it isn't clear what the recommended and supported way of unit testing MCP endpoints are?
As a unit test it shouldn't involve a sub-process or actually opening an port. But it should test enough of the MCP integration to ensure the endpoint would work, and wouldn't hit unexpected serialization issues etc.
Currently I have something like this:
server.py
from mcp.server.fastmcp import FastMCP
mcp = FastMCP(name='Example MCP Server')
@mcp.tool()
async def add_numbers(a: int, b: int) -> int:
"""Add two numbers."""
return a + b
test_server.py
import pytest
from mcp.types import TextContent
from server import mcp
class TestMcp:
@pytest.mark.asyncio
async def test_should_add_two_numbers(self):
result = await mcp.call_tool(
"add_numbers",
arguments={"a": 1, "b": 2}
)
assert result
assert isinstance(result[0], TextContent)
assert result[0].text == '3'
i.e. on the FastMCP
instance I am calling call_tool
. That code is for version 1.9.4
and would need to be slightly adjusted due to changes in what call_tool
returns (see also #1251).
However, I am not sure whether call_tool
is properly supported as a public function given the change in a minor version.
What should I actually be using for unit tests?
Additional Context
The fastmcp
library has Client
object for testing, with a similar call_tool
function:
test_server.py for fastmcp
from fastmcp import Client
from mcp.types import TextContent
import pytest
from server import mcp
class TestMcp:
@pytest.mark.asyncio
async def test_should_add_two_numbers(self):
async with Client(mcp) as client:
result = await client.call_tool(
"add_numbers",
arguments={"a": 1, "b": 2}
)
assert isinstance(result[0], TextContent)
assert result[0].text == '3'
FastAPI
has fastapi.testclient.TestClient
dedicated for testing.