fix: Address formatting and type checking issues

This commit is contained in:
David Soria Parra
2025-01-03 15:23:58 +00:00
parent 79ec8dccdb
commit 2d8f08d648
5 changed files with 56 additions and 41 deletions

View File

@@ -8,7 +8,10 @@ from mcp.server.fastmcp import FastMCP
mcp = FastMCP() mcp = FastMCP()
@mcp.tool(description="🌟 A tool that uses various Unicode characters in its description: á é í ó ú ñ 漢字 🎉") @mcp.tool(
description="🌟 A tool that uses various Unicode characters in its description: "
"á é í ó ú ñ 漢字 🎉"
)
def hello_unicode(name: str = "世界", greeting: str = "¡Hola") -> str: def hello_unicode(name: str = "世界", greeting: str = "¡Hola") -> str:
""" """
A simple tool that demonstrates Unicode handling in: A simple tool that demonstrates Unicode handling in:
@@ -31,29 +34,31 @@ def list_emoji_categories() -> list[str]:
"🌍 Travel & Places", "🌍 Travel & Places",
"💡 Objects", "💡 Objects",
"❤️ Symbols", "❤️ Symbols",
"🚩 Flags" "🚩 Flags",
] ]
@mcp.tool(description="🔤 Tool that returns text in different scripts") @mcp.tool(description="🔤 Tool that returns text in different scripts")
def multilingual_hello() -> str: def multilingual_hello() -> str:
"""Returns hello in different scripts and writing systems.""" """Returns hello in different scripts and writing systems."""
return "\n".join([ return "\n".join(
"English: Hello!", [
"Spanish: ¡Hola!", "English: Hello!",
"French: Bonjour!", "Spanish: ¡Hola!",
"German: Grüß Gott!", "French: Bonjour!",
"Russian: Привет!", "German: Grüß Gott!",
"Greek: Γεια σας!", "Russian: Привет!",
"Hebrew: !שָׁלוֹם", "Greek: Γεια σας!",
"Arabic: !مرحبا", "Hebrew: !שָׁלוֹם",
"Hindi: नमस्ते!", "Arabic: !مرحبا",
"Chinese: 你好!", "Hindi: नमस्ते!",
"Japanese: こんにちは!", "Chinese: 你好!",
"Korean: 안녕하세요!", "Japanese: こんにちは!",
"Thai: สวัสดี!", "Korean: 안녕하세요!",
]) "Thai: สวัสดี!",
]
)
if __name__ == "__main__": if __name__ == "__main__":
mcp.run() mcp.run()

View File

@@ -1,6 +1,5 @@
import json import json
import subprocess import subprocess
from pathlib import Path
from unittest.mock import patch from unittest.mock import patch
import pytest import pytest
@@ -15,42 +14,39 @@ def temp_config_dir(tmp_path):
config_dir.mkdir() config_dir.mkdir()
return config_dir return config_dir
@pytest.fixture @pytest.fixture
def mock_config_path(temp_config_dir): def mock_config_path(temp_config_dir):
"""Mock get_claude_config_path to return our temporary directory.""" """Mock get_claude_config_path to return our temporary directory."""
with patch('mcp.cli.claude.get_claude_config_path', return_value=temp_config_dir): with patch("mcp.cli.claude.get_claude_config_path", return_value=temp_config_dir):
yield temp_config_dir yield temp_config_dir
def test_command_execution(mock_config_path): def test_command_execution(mock_config_path):
"""Test that the generated command can actually be executed.""" """Test that the generated command can actually be executed."""
# Setup # Setup
server_name = "test_server" server_name = "test_server"
file_spec = "test_server.py:app" file_spec = "test_server.py:app"
# Update config # Update config
success = update_claude_config( success = update_claude_config(
file_spec=file_spec, file_spec=file_spec,
server_name=server_name, server_name=server_name,
) )
assert success assert success
# Read the generated config # Read the generated config
config_file = mock_config_path / "claude_desktop_config.json" config_file = mock_config_path / "claude_desktop_config.json"
config = json.loads(config_file.read_text()) config = json.loads(config_file.read_text())
# Get the command and args # Get the command and args
server_config = config["mcpServers"][server_name] server_config = config["mcpServers"][server_name]
command = server_config["command"] command = server_config["command"]
args = server_config["args"] args = server_config["args"]
test_args = [command] + args + ["--help"] test_args = [command] + args + ["--help"]
result = subprocess.run( result = subprocess.run(test_args, capture_output=True, text=True, timeout=5)
test_args,
capture_output=True,
text=True,
timeout=5
)
assert result.returncode == 0 assert result.returncode == 0
assert "usage" in result.stdout.lower() assert "usage" in result.stdout.lower()

View File

@@ -3,25 +3,32 @@ from mcp.server.fastmcp import FastMCP
pytestmark = pytest.mark.anyio pytestmark = pytest.mark.anyio
async def test_list_tools_returns_all_tools(): async def test_list_tools_returns_all_tools():
mcp = FastMCP("TestTools") mcp = FastMCP("TestTools")
# Create 100 tools with unique names # Create 100 tools with unique names
num_tools = 100 num_tools = 100
for i in range(num_tools): for i in range(num_tools):
@mcp.tool(name=f"tool_{i}") @mcp.tool(name=f"tool_{i}")
def dummy_tool_func(): def dummy_tool_func():
f"""Tool number {i}""" f"""Tool number {i}"""
return i return i
globals()[f'dummy_tool_{i}'] = dummy_tool_func # Keep reference to avoid garbage collection
globals()[f"dummy_tool_{i}"] = (
dummy_tool_func # Keep reference to avoid garbage collection
)
# Get all tools # Get all tools
tools = await mcp.list_tools() tools = await mcp.list_tools()
# Verify we get all tools # Verify we get all tools
assert len(tools) == num_tools, f"Expected {num_tools} tools, but got {len(tools)}" assert len(tools) == num_tools, f"Expected {num_tools} tools, but got {len(tools)}"
# Verify each tool is unique and has the correct name # Verify each tool is unique and has the correct name
tool_names = [tool.name for tool in tools] tool_names = [tool.name for tool in tools]
expected_names = [f"tool_{i}" for i in range(num_tools)] expected_names = [f"tool_{i}" for i in range(num_tools)]
assert sorted(tool_names) == sorted(expected_names), "Tool names don't match expected names" assert sorted(tool_names) == sorted(
expected_names
), "Tool names don't match expected names"

View File

@@ -35,7 +35,9 @@ class TestServer:
"""Test that FastMCP handles non-ASCII characters in descriptions correctly""" """Test that FastMCP handles non-ASCII characters in descriptions correctly"""
mcp = FastMCP() mcp = FastMCP()
@mcp.tool(description="🌟 This tool uses emojis and UTF-8 characters: á é í ó ú ñ 漢字 🎉") @mcp.tool(
description="🌟 This tool uses emojis and UTF-8 characters: á é í ó ú ñ 漢字 🎉"
)
def hello_world(name: str = "世界") -> str: def hello_world(name: str = "世界") -> str:
return f"¡Hola, {name}! 👋" return f"¡Hola, {name}! 👋"
@@ -43,6 +45,7 @@ class TestServer:
tools = await client.list_tools() tools = await client.list_tools()
assert len(tools.tools) == 1 assert len(tools.tools) == 1
tool = tools.tools[0] tool = tools.tools[0]
assert tool.description is not None
assert "🌟" in tool.description assert "🌟" in tool.description
assert "漢字" in tool.description assert "漢字" in tool.description
assert "🎉" in tool.description assert "🎉" in tool.description

View File

@@ -18,8 +18,12 @@ from mcp.types import (
@pytest.mark.anyio @pytest.mark.anyio
async def test_server_session_initialize(): async def test_server_session_initialize():
server_to_client_send, server_to_client_receive = anyio.create_memory_object_stream[JSONRPCMessage](1) server_to_client_send, server_to_client_receive = anyio.create_memory_object_stream[
client_to_server_send, client_to_server_receive = anyio.create_memory_object_stream[JSONRPCMessage](1) JSONRPCMessage
](1)
client_to_server_send, client_to_server_receive = anyio.create_memory_object_stream[
JSONRPCMessage
](1)
async def run_client(client: ClientSession): async def run_client(client: ClientSession):
async for message in client_session.incoming_messages: async for message in client_session.incoming_messages: