Skip to main content
Glama

Gemini MCP Server

test_ollama_custom_url.pyโ€ข12.8 kB
#!/usr/bin/env python3 """ Ollama Custom URL Test Tests custom API endpoint functionality with Ollama-style local models, including: - Basic chat with custom model via local endpoint - File analysis with local model - Conversation continuation with custom provider - Model alias resolution for local models """ from .base_test import BaseSimulatorTest class OllamaCustomUrlTest(BaseSimulatorTest): """Test Ollama custom URL functionality""" @property def test_name(self) -> str: return "ollama_custom_url" @property def test_description(self) -> str: return "Ollama custom URL endpoint functionality" def run_test(self) -> bool: """Test Ollama custom URL functionality""" try: self.logger.info("Test: Ollama custom URL functionality") # Check if custom URL is configured import os custom_url = os.environ.get("CUSTOM_API_URL") if not custom_url: self.logger.warning("CUSTOM_API_URL not set, skipping Ollama test") self.logger.info("To enable this test, add to .env file:") self.logger.info("CUSTOM_API_URL=http://localhost:11434/v1") self.logger.info("CUSTOM_API_KEY=") return True # Skip gracefully self.logger.info(f"Testing with custom URL: {custom_url}") # Setup test files self.setup_test_files() # Test 1: Basic chat with local model self.logger.info(" 1.1: Basic chat with local model") response1, continuation_id = self.call_mcp_tool( "chat", { "prompt": "Hello! Can you introduce yourself and tell me what model you are? Keep your response brief.", "model": "llama3.2", # Use exact Ollama model name }, ) if not self.validate_successful_response(response1, "local model chat"): return False self.logger.info(f" โœ… Local model responded with continuation_id: {continuation_id}") # Test 2: File analysis with local model using a specific Ollama-related file self.logger.info(" 1.2: File analysis with local model") # Create a simple, clear file that shouldn't require clarification ollama_test_content = '''""" Ollama API Client Test A simple test client for connecting to Ollama API endpoints """ import requests import json class OllamaClient: """Simple client for Ollama API""" def __init__(self, base_url="http://localhost:11434"): self.base_url = base_url def list_models(self): """List available models""" response = requests.get(f"{self.base_url}/api/tags") return response.json() def generate(self, model, prompt): """Generate text using a model""" data = { "model": model, "prompt": prompt, "stream": False } response = requests.post(f"{self.base_url}/api/generate", json=data) return response.json() if __name__ == "__main__": client = OllamaClient() models = client.list_models() print(f"Available models: {len(models['models'])}") ''' # Create the test file ollama_test_file = self.create_additional_test_file("ollama_client.py", ollama_test_content) response2, _ = self.call_mcp_tool( "analyze", { "files": [ollama_test_file], "prompt": "Analyze this Ollama client code. What does this code do and what are its main functions?", "model": "llama3.2", }, ) if not self.validate_successful_response(response2, "local model file analysis", files_provided=True): return False self.logger.info(" โœ… Local model analyzed file successfully") # Test 3: Continue conversation with local model if continuation_id: self.logger.info(" 1.3: Continue conversation with local model") response3, _ = self.call_mcp_tool( "chat", { "prompt": "Thanks for the introduction! I just analyzed an Ollama client Python file. Can you suggest one improvement for writing better API client code in general?", "continuation_id": continuation_id, "model": "llama3.2", }, ) if not self.validate_successful_response(response3, "local model conversation continuation"): return False self.logger.info(" โœ… Conversation continuation with local model working") # Test 4: Test alternative local model aliases self.logger.info(" 1.4: Test alternative local model aliases") response4, _ = self.call_mcp_tool( "chat", { "prompt": "Quick test with alternative alias. Say 'Local model working' if you can respond.", "model": "llama3.2", # Alternative alias }, ) if not self.validate_successful_response(response4, "alternative local model alias"): return False self.logger.info(" โœ… Alternative local model alias working") # Test 5: Test direct model name (if applicable) self.logger.info(" 1.5: Test direct model name") response5, _ = self.call_mcp_tool( "chat", { "prompt": "Final test with direct model name. Respond briefly.", "model": "llama3.2", # Direct model name }, ) if not self.validate_successful_response(response5, "direct model name"): return False self.logger.info(" โœ… Direct model name working") self.logger.info(" โœ… All Ollama custom URL tests passed") return True except Exception as e: self.logger.error(f"Ollama custom URL test failed: {e}") return False finally: self.cleanup_test_files() def validate_successful_response(self, response: str, test_name: str, files_provided: bool = False) -> bool: """Validate that the response indicates success, not an error Args: response: The response text to validate test_name: Name of the test for logging files_provided: Whether actual files were provided to the tool """ if not response: self.logger.error(f"No response received for {test_name}") self._check_server_logs_for_errors() return False # Check for common error indicators error_indicators = [ "OpenRouter API error", "is not a valid model ID", "API key not found", "Connection error", "connection refused", "network is unreachable", "timeout", "error 404", "error 400", "error 401", "error 403", "error 500", "status code 404", "status code 400", "status code 401", "status code 403", "status code 500", "status: error", ] # Special handling for clarification requests from local models if "files_required_to_continue" in response.lower(): if files_provided: # If we provided actual files, clarification request is a FAILURE self.logger.error( f"โŒ Local model requested clarification for {test_name} despite being provided with actual files" ) self.logger.debug(f"Clarification response: {response[:200]}...") return False else: # If no files were provided, clarification request is acceptable self.logger.info( f"โœ… Local model requested clarification for {test_name} - valid when no files provided" ) self.logger.debug(f"Clarification response: {response[:200]}...") return True # Check for SSRF security restriction - this is expected for local URLs if "restricted IP address" in response and "security risk (SSRF)" in response: self.logger.info( f"โœ… Custom URL routing working - {test_name} correctly attempted to connect to custom API" ) self.logger.info(" (Connection blocked by SSRF protection, which is expected for local URLs)") return True response_lower = response.lower() for error in error_indicators: if error.lower() in response_lower: self.logger.error(f"Error detected in {test_name}: {error}") self.logger.debug(f"Full response: {response}") self._check_server_logs_for_errors() return False # Response should be substantial (more than just a few words) if len(response.strip()) < 10: self.logger.error(f"Response too short for {test_name}: {response}") self._check_server_logs_for_errors() return False # Verify this looks like a real AI response, not just an error message if not self._validate_ai_response_content(response): self.logger.error(f"Response doesn't look like valid AI output for {test_name}") self._check_server_logs_for_errors() return False self.logger.debug(f"Successful response for {test_name}: {response[:100]}...") return True def _validate_ai_response_content(self, response: str) -> bool: """Validate that response appears to be legitimate AI output""" if not response: return False response_lower = response.lower() # Check for indicators this is a real AI response positive_indicators = [ "i am", "i'm", "i can", "i'll", "i would", "i think", "this code", "this function", "this file", "this configuration", "hello", "hi", "yes", "sure", "certainly", "of course", "analysis", "analyze", "review", "suggestion", "improvement", "here", "below", "above", "following", "based on", "python", "code", "function", "class", "variable", "llama", "model", "assistant", "ai", ] # Response should contain at least some AI-like language ai_indicators_found = sum(1 for indicator in positive_indicators if indicator in response_lower) if ai_indicators_found < 2: self.logger.warning(f"Response lacks AI-like indicators: {response[:200]}...") return False return True def _check_server_logs_for_errors(self): """Check server logs for any error messages that might explain failures""" try: # Get recent logs from the log file log_file_path = "logs/mcp_server.log" with open(log_file_path) as f: lines = f.readlines() recent_logs = lines[-50:] # Last 50 lines if recent_logs: self.logger.info("Recent server logs:") for line in recent_logs[-10:]: # Last 10 lines if line.strip(): self.logger.info(f" {line.strip()}") except Exception as e: self.logger.debug(f"Failed to check server logs: {e}") def validate_local_model_response(self, response: str) -> bool: """Validate that response appears to come from a local model""" if not response: return False # Basic validation - response should be non-empty and reasonable response_lower = response.lower() # Check for some indicators this might be from a local model # (This is heuristic - local models often mention their nature) local_indicators = ["llama", "local", "assistant", "ai", "model", "help"] # At least response should be meaningful text return len(response.strip()) > 10 and any(indicator in response_lower for indicator in local_indicators)

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/BeehiveInnovations/gemini-mcp-server'

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