From 729b196c3353b53c9becf345b5f6235f9951c97f Mon Sep 17 00:00:00 2001 From: jtorreggiani Date: Wed, 27 Nov 2024 00:34:59 -0500 Subject: [PATCH 1/2] Add tests for template server. --- src/create_mcp_server/__init__.py | 1 + .../template/test_server.py.jinja2 | 50 +++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 src/create_mcp_server/template/test_server.py.jinja2 diff --git a/src/create_mcp_server/__init__.py b/src/create_mcp_server/__init__.py index b54038d..1c8efb1 100644 --- a/src/create_mcp_server/__init__.py +++ b/src/create_mcp_server/__init__.py @@ -136,6 +136,7 @@ def copy_template( ("__init__.py.jinja2", "__init__.py", target_dir), ("server.py.jinja2", "server.py", target_dir), ("README.md.jinja2", "README.md", path), + ("test_server.py.jinja2", "test_server.py", target_dir), ] pyproject = PyProject(path / "pyproject.toml") diff --git a/src/create_mcp_server/template/test_server.py.jinja2 b/src/create_mcp_server/template/test_server.py.jinja2 new file mode 100644 index 0000000..1388cc7 --- /dev/null +++ b/src/create_mcp_server/template/test_server.py.jinja2 @@ -0,0 +1,50 @@ +import pytest +import os +from mcp import ClientSession, StdioServerParameters +from mcp.client.stdio import stdio_client +from mcp.types import ListResourcesResult, TextContent, TextResourceContents +from pydantic import AnyUrl + + +test_dir = os.path.dirname(os.path.abspath(__file__)) + +@pytest.mark.asyncio(loop_scope='module') +async def test_client_server_interactions(): + """Fixture that starts the actual server and provides a connected session""" + server_params = StdioServerParameters( + command=f"{test_dir}/template_server/src/template_server/server.py", + args=[], + env=None + ) + async with stdio_client(server_params) as (read, write): + async with ClientSession(read, write) as session: + await session.initialize() + + list_resources_result = await session.list_resources() + assert list_resources_result == ListResourcesResult(nextCursor=None, resources=[]) + + list_tools_result = await session.list_tools() + assert list_tools_result.tools[0].name == 'add-note' + + get_prompt_result = await session.get_prompt(name="summarize-notes") + assert get_prompt_result.description == "Summarize the current notes" + + list_prompts_result = await session.list_prompts() + assert list_prompts_result.prompts[0].name == 'summarize-notes' + + call_tool_result = await session.call_tool("add-note", arguments={ + "name": "example_note", + "content": "Example content" + }) + + tool_content = call_tool_result.content[0] + if isinstance(tool_content, TextContent): + assert tool_content.text == "Added note 'example_note' with content: Example content" + + list_resources_result = await session.list_resources() + resource_uri = list_resources_result.resources[0].uri + assert resource_uri == AnyUrl("note://internal/example_note") + + read_resource_result = await session.read_resource(resource_uri) + if isinstance(read_resource_result.contents[0], TextResourceContents): + assert read_resource_result.contents[0].text== 'Example content' \ No newline at end of file From def8f170c89fd98e454d0d5e73ecf52e9a4bec8f Mon Sep 17 00:00:00 2001 From: jtorreggiani Date: Wed, 27 Nov 2024 00:44:05 -0500 Subject: [PATCH 2/2] Add pytest dependency to bootstrap script. --- src/create_mcp_server/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/create_mcp_server/__init__.py b/src/create_mcp_server/__init__.py index 1c8efb1..2b426f4 100644 --- a/src/create_mcp_server/__init__.py +++ b/src/create_mcp_server/__init__.py @@ -182,6 +182,7 @@ def create_project( # Add mcp dependency using uv add try: subprocess.run(["uv", "add", "mcp"], cwd=path, check=True) + subprocess.run(["uv", "add", "pytest", '--dev'], cwd=path, check=True) except subprocess.CalledProcessError: click.echo("❌ Error: Failed to add mcp dependency.", err=True) sys.exit(1)