Skip to main content
Glama
test_client.py•14.6 kB
#!/usr/bin/env python3 """ Simple test client for Ultimate MCP Server Tests basic functionality over streamable-HTTP transport """ import asyncio import json from fastmcp import Client async def test_server_connection(): """Test basic server connection and functionality.""" server_url = "http://127.0.0.1:8013/mcp" print(f"šŸ”— Connecting to Ultimate MCP Server at {server_url}") try: async with Client(server_url) as client: print("āœ… Successfully connected to server") # Test 1: List available tools print("\nšŸ“‹ Listing available tools...") tools = await client.list_tools() print(f"Found {len(tools)} tools:") for i, tool in enumerate(tools[:10]): # Show first 10 print(f" {i + 1:2d}. {tool.name}") if len(tools) > 10: print(f" ... and {len(tools) - 10} more tools") # Test 2: List available resources print("\nšŸ“š Listing available resources...") resources = await client.list_resources() print(f"Found {len(resources)} resources:") for resource in resources: print(f" - {resource.uri}") # Test 3: Test echo tool (should be available) print("\nšŸ”Š Testing echo tool...") try: echo_result = await client.call_tool("echo", {"message": "Hello from test client!"}) if echo_result: print(f"āœ… Echo response: {echo_result[0].text}") else: print("āŒ Echo tool returned no response") except Exception as e: print(f"āŒ Echo tool failed: {e}") # Test 4: Test provider status tool print("\nšŸ”Œ Testing provider status...") try: provider_result = await client.call_tool("get_provider_status", {}) if provider_result: provider_data = json.loads(provider_result[0].text) providers = provider_data.get("providers", {}) print(f"āœ… Found {len(providers)} providers:") for name, status in providers.items(): available = "āœ…" if status.get("available") else "āŒ" model_count = len(status.get("models", [])) enabled = status.get("enabled", False) api_key_configured = status.get("api_key_configured", False) status_str = f"{available} {name}: {model_count} models" if not enabled: status_str += " (disabled)" elif not api_key_configured: status_str += " (no API key)" elif status.get("error"): status_str += f" (error: {status['error'][:50]}...)" print(f" {status_str}") except Exception as e: print(f"āŒ Provider status failed: {e}") # Test 5: Read a resource print("\nšŸ“– Testing resource reading...") if resources: try: resource_uri = resources[0].uri resource_content = await client.read_resource(resource_uri) if resource_content: # FastMCP uses 'text' attribute, not 'content' content = resource_content[0].text if hasattr(resource_content[0], 'text') else str(resource_content[0]) preview = content[:200] + "..." if len(content) > 200 else content print(f"āœ… Resource {resource_uri} content preview:") print(f" {preview}") except Exception as e: print(f"āŒ Resource reading failed: {e}") # Test 6: Test a completion tool print("\nšŸ¤– Testing completion tool...") try: completion_result = await client.call_tool( "generate_completion", { "prompt": "Say hello in a creative way", "provider": "ollama", # Using local Ollama since it's available "model": "mix_77/gemma3-qat-tools:27b", "max_tokens": 100, # Increased for better response }, ) if completion_result: result_data = json.loads(completion_result[0].text) response_text = result_data.get('text', '').strip() if response_text: print(f"āœ… Completion response: {response_text}") else: print("āš ļø Completion succeeded but returned empty text") print(f" Model: {result_data.get('model', 'unknown')}") print(f" Processing time: {result_data.get('processing_time', 0):.2f}s") print(f" Tokens: {result_data.get('tokens', {})}") except Exception as e: print(f"āŒ Completion tool failed: {e}") # Try with a different provider try: completion_result = await client.call_tool( "generate_completion", { "prompt": "Say hello in a creative way", "provider": "anthropic", "model": "claude-3-haiku-20240307", "max_tokens": 100, }, ) if completion_result: result_data = json.loads(completion_result[0].text) response_text = result_data.get('text', '').strip() if response_text: print(f"āœ… Completion response (anthropic): {response_text}") else: print("āš ļø Anthropic completion succeeded but returned empty text") except Exception as e2: print(f"āŒ Completion with anthropic also failed: {e2}") print("\nšŸŽ‰ Basic functionality test completed!") except Exception as e: print(f"āŒ Failed to connect to server: {e}") print("Make sure the server is running at the correct address.") async def test_specific_tools(): """Test some specific tools that should be available.""" server_url = "http://127.0.0.1:8013/mcp" print("\nšŸ”§ Testing specific tools...") try: async with Client(server_url) as client: # Test filesystem tools print("\nšŸ“ Testing filesystem tools...") try: # List allowed directories dirs_result = await client.call_tool("list_allowed_directories", {}) if dirs_result: print(f"āœ… Allowed directories: {dirs_result[0].text}") # Try to list current directory ls_result = await client.call_tool("list_directory", {"path": "."}) if ls_result: ls_data = json.loads(ls_result[0].text) files = ls_data.get("files", []) print(f"āœ… Current directory has {len(files)} items") except Exception as e: print(f"āŒ Filesystem tools failed: {e}") # Test Python execution print("\nšŸ Testing Python execution...") try: python_result = await client.call_tool( "execute_python", { "code": "print('Hello from Python!'); result = 2 + 2; print(f'2 + 2 = {result}')" }, ) if python_result: print("āœ… Python execution result:") result_data = json.loads(python_result[0].text) # The field is called 'stdout', not 'output' print(f" Output: {result_data.get('stdout', 'No output')}") print(f" Success: {result_data.get('success', False)}") if result_data.get('result') is not None: print(f" Result: {result_data.get('result')}") except Exception as e: print(f"āŒ Python execution failed: {e}") # Test text processing tools print("\nšŸ“ Testing text processing tools...") try: # Test ripgrep if available - tool expects args_str parameter ripgrep_result = await client.call_tool( "run_ripgrep", { "args_str": "'FastMCP' . -t py", "input_dir": True # Since we're searching in a directory } ) if ripgrep_result: result_data = json.loads(ripgrep_result[0].text) if result_data.get('success'): print("āœ… Ripgrep executed successfully") stdout = result_data.get('stdout', '') if stdout.strip(): print(f" Found matches: {len(stdout.strip().splitlines())} lines") else: print(" No matches found") else: print(f"āŒ Ripgrep failed: {result_data.get('error', 'Unknown error')}") except Exception as e: print(f"āŒ Text processing tools failed: {e}") except Exception as e: print(f"āŒ Failed during specific tool testing: {e}") async def interactive_mode(): """Interactive mode for testing tools manually.""" server_url = "http://127.0.0.1:8013/mcp" print("\nšŸŽ® Entering interactive mode...") print("Type 'list' to see available tools, 'quit' to exit") try: async with Client(server_url) as client: tools = await client.list_tools() tool_names = [tool.name for tool in tools] while True: try: command = input("\n> ").strip() if command.lower() in ["quit", "exit", "q"]: break elif command.lower() == "list": print("Available tools:") for i, name in enumerate(tool_names[:20]): # Show first 20 print(f" {i + 1:2d}. {name}") if len(tool_names) > 20: print(f" ... and {len(tool_names) - 20} more") elif command.lower() == "resources": resources = await client.list_resources() print("Available resources:") for resource in resources: print(f" - {resource.uri}") elif command.startswith("call "): # Parse tool call: call tool_name {"param": "value"} parts = command[5:].split(" ", 1) tool_name = parts[0] params = {} if len(parts) > 1: try: params = json.loads(parts[1]) except json.JSONDecodeError: print("āŒ Invalid JSON for parameters") continue if tool_name in tool_names: try: result = await client.call_tool(tool_name, params) if result: print(f"āœ… Result: {result[0].text}") else: print("āŒ No result returned") except Exception as e: print(f"āŒ Tool call failed: {e}") else: print(f"āŒ Tool '{tool_name}' not found") elif command.startswith("read "): # Read resource: read resource_uri resource_uri = command[5:].strip() try: result = await client.read_resource(resource_uri) if result: # FastMCP uses 'text' attribute, not 'content' content = result[0].text if hasattr(result[0], 'text') else str(result[0]) preview = content[:500] + "..." if len(content) > 500 else content print(f"āœ… Resource content: {preview}") else: print("āŒ No content returned") except Exception as e: print(f"āŒ Resource read failed: {e}") else: print("Commands:") print(" list - List available tools") print(" resources - List available resources") print(" call <tool> <json_params> - Call a tool") print(" read <resource_uri> - Read a resource") print(" quit - Exit interactive mode") except KeyboardInterrupt: break except EOFError: break except Exception as e: print(f"āŒ Interactive mode failed: {e}") async def main(): """Main test function.""" print("šŸš€ Ultimate MCP Server Test Client") print("=" * 50) # Run basic connection test await test_server_connection() # Run specific tool tests await test_specific_tools() # Ask if user wants interactive mode try: response = input("\nWould you like to enter interactive mode? (y/n): ").strip().lower() if response in ["y", "yes"]: await interactive_mode() except (KeyboardInterrupt, EOFError): pass print("\nšŸ‘‹ Test client finished!") if __name__ == "__main__": asyncio.run(main())

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Kappasig920/Ultimate-MCP-Server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server