Skip to main content
Glama

Google Search MCP Server

by meaigood001
main.py6.19 kB
""" Google Search MCP Server A FastMCP server that provides Google Custom Search functionality. This server exposes a tool for performing Google searches and returning formatted results. It requires Google API Key and Custom Search Engine ID stored in environment variables. Features: - Streamable HTTP transport support for real-time communication - Configurable host and port via environment variables - Google Custom Search API integration - Error handling and formatted result responses Environment Variables: - GOOGLE_API_KEY: Your Google API key (required) - GOOGLE_CSE_ID: Your Custom Search Engine ID (required) - HTTP_HOST: Server host (default: 127.0.0.1) - HTTP_PORT: Server port (default: 9000) - ENABLE_AUTH: Enable authentication (default: false) - API_TOKEN: Bearer token for API authentication (required when ENABLE_AUTH=true) Usage: 1. Copy .env.example to .env and configure your API keys 2. For production use, enable authentication by setting ENABLE_AUTH=true and API_TOKEN 3. Run: python main.py 4. Server will start at http://127.0.0.1:9000/mcp/ 5. When authentication is enabled, clients must include Authorization header: Authorization: Bearer your_api_token_here """ import os from typing import Dict, Any, Optional from mcp.server.fastmcp import FastMCP from mcp.server.auth.provider import TokenVerifier, AccessToken from mcp.server.auth.settings import AuthSettings from googleapiclient.discovery import build from googleapiclient.errors import HttpError from dotenv import load_dotenv # Load configuration from .env load_dotenv() GOOGLE_API_KEY = os.getenv('GOOGLE_API_KEY') GOOGLE_CSE_ID = os.getenv('GOOGLE_CSE_ID') # HTTP Stream server configuration HTTP_HOST = os.getenv('HTTP_HOST', '127.0.0.1') HTTP_PORT = int(os.getenv('HTTP_PORT', '9000')) # Authentication configuration API_TOKEN = os.getenv('API_TOKEN') ENABLE_AUTH = os.getenv('ENABLE_AUTH', 'false').lower() == 'true' class SimpleTokenVerifier(TokenVerifier): """ Simple token verifier that checks if the token matches a predefined API token. """ def __init__(self, api_token: str): self.api_token = api_token async def verify_token(self, token: str) -> Optional[AccessToken]: """ Verify the token against the predefined API token. Args: token: The bearer token to verify Returns: AccessToken if valid, None otherwise """ if token == self.api_token: return AccessToken( token=token, client_id="api-client", scopes=["api.access"] ) return None # Initialize FastMCP with authentication if enabled if ENABLE_AUTH and API_TOKEN: # Create token verifier only when authentication is properly enabled token_verifier = SimpleTokenVerifier(API_TOKEN) # Create auth settings with required URLs # Using the server's own URL as both issuer and resource server for simplicity server_url = f"http://{HTTP_HOST}:{HTTP_PORT}" auth_settings = AuthSettings( issuer_url=f"{server_url}/", resource_server_url=f"{server_url}/mcp/" ) mcp = FastMCP("GoogleSearch", token_verifier=token_verifier, auth=auth_settings, host=HTTP_HOST, port=HTTP_PORT) else: mcp = FastMCP("GoogleSearch", host=HTTP_HOST, port=HTTP_PORT) @mcp.tool() async def search_google(query: str, num_results: int = 5) -> Dict[str, Any]: """ Perform a Google search and return formatted results. This function uses Google Custom Search API to search the web based on the provided query. It formats the results into a consistent structure and handles potential errors. Args: query (str): The search query string num_results (int, optional): Number of search results to return. Defaults to 5. Returns: Dict[str, Any]: A dictionary containing: - success (bool): Whether the search was successful - results (list): List of dictionaries with title, link, and snippet - total_results (str): Total number of results found (when successful) - error (str): Error message (when unsuccessful) """ try: # Initialize Google Custom Search API service = build("customsearch", "v1", developerKey=GOOGLE_API_KEY) # Execute the search # pylint: disable=no-member result = service.cse().list( q=query, cx=GOOGLE_CSE_ID, num=num_results ).execute() # Format the search results formatted_results = [] if "items" in result: for item in result["items"]: formatted_results.append({ "title": item.get("title", ""), "link": item.get("link", ""), "snippet": item.get("snippet", "") }) return { "success": True, "results": formatted_results, "total_results": result.get("searchInformation", {}).get("totalResults", "0") } except HttpError as error: return { "success": False, "error": f"API Error: {str(error)}", "results": [] } except Exception as error: # pylint: disable=broad-exception-caught return { "success": False, "error": str(error), "results": [] } if __name__ == "__main__": # 使用Streamable HTTP模式启动服务,支持环境变量配置 print(f"Starting Google Search MCP server with Streamable HTTP transport...") print(f"Server will be available at: http://{HTTP_HOST}:{HTTP_PORT}/mcp/") if ENABLE_AUTH: print(f"Authentication: ENABLED (Bearer Token required)") if API_TOKEN: print(f"API Token: {'*' * len(API_TOKEN)}") else: print("WARNING: Authentication enabled but no API_TOKEN configured!") else: print("Authentication: DISABLED (insecure mode)") # 使用 FastMCP 的 run 方法启动服务器 mcp.run(transport="streamable-http")

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/meaigood001/google-search-mcp'

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