A Model Context Protocol (MCP) server that provides Google Custom Search functionality.
🎯 This repository demonstrates 5 different deployment patterns for the same MCP functionality:
- stdio Mode - Standard MCP over stdin/stdout for local development and MCP client integration
- HTTP over SSE - MCP HTTP transport using Server‑Sent Events (browser-friendly)
- HTTP Streamable - MCP Streamable HTTP transport (non‑SSE)
- AWS Lambda + AgentCore Gateway - Serverless deployment with OAuth authentication
- Containerized MCP Service - Docker containers deployed to ECS Fargate for scalable cloud deployment
Clone the repository and install dependencies:
git clone https://github.com/jspv/google-search-mcp.git
cd google-search-mcp
uv syncserver.py/server_http.py/server_http_stream.py— MCP servers (stdio, HTTP, streaming)lambda_handler.py— AWS Lambda adapter for MCP stdio serverDockerfile.mcp— Container image for HTTP/streaming MCP servicedeploy/— legacy deployment assets (usedeploy_aws_agentcore_auth0/)deploy_aws_agentcore_auth0/— canonical Auth0 + AgentCore Gateway deploy scripts and templates-
build_zip.sh— build Lambda ZIP -
deploy_lambda.sh— deploy Lambda via CloudFormation -
AGENTCORE_GATEWAY_CHECKLIST.md— complete Gateway (Lambda + Cognito) integration checklist -
deploy_gateway.sh— attempt AgentCore setup via CLI -
gen_tool_schema.sh— generate MCP tool schema (uses Python stdio client) -
cloudformation-*.yaml— infrastructure templates -
README-*.md— deployment-specific docs
-
scripts/— developer/CI utilitiesdump_tool_schema.py— dump schema from an MCP server over stdio
dist/— build artifacts and generated outputsschema/tool-schema.json— generated tool schema for AgentCoregoogle_search_mcp_lambda.zip— built Lambda package
tests/— unit and integration tests
Install additional dependencies based on your deployment needs:
# For HTTP/streaming modes
uv sync --extra http
# For AWS Lambda deployment
uv sync --extra lambda
# For containerized deployments (ECS/Fargate)
uv sync --extra container
# For AWS (both Lambda and container)
uv sync --extra aws
# For development
uv sync --extra dev
# Install multiple extras
uv sync --extra http --extra aws --extra devThis server uses Dynaconf for configuration management, supporting both .env files and environment variables.
-
Copy the example environment file:
cp .env.example .env
-
Edit
.envand add your Google API credentials:GOOGLE_API_KEY=your_actual_api_key_here GOOGLE_CX=your_custom_search_engine_id_here
Environment variables will override .env file values when both are present. This allows for flexible deployment scenarios:
- Development: Use
.envfile for local development - Production: Use environment variables for production deployment
- CI/CD: Environment variables can override defaults for testing
If your .env file contains:
GOOGLE_API_KEY=dev_key_from_fileAnd you set an environment variable:
export GOOGLE_API_KEY=prod_key_from_envThe server will use prod_key_from_env (environment variable takes precedence).
GOOGLE_API_KEY: Your Google Custom Search API keyGOOGLE_CX: Your Custom Search Engine ID
Get these from:
- API Key: Google Cloud Console
- Search Engine ID: Google Custom Search
-
ALLOW_DOMAINS(GOOGLE_ALLOW_DOMAINSenv var): Comma-separated list of allowed domains (e.g.,example.com, docs.python.org). When set, results outside these domains are filtered out. -
Logging:
LOG_QUERIES(GOOGLE_LOG_QUERIES): Enable logging of query hash, timing, and key params.LOG_QUERY_TEXT(GOOGLE_LOG_QUERY_TEXT): Also log full query text (off by default).LOG_LEVEL(GOOGLE_LOG_LEVEL): Set logging level (e.g.,INFO,DEBUG).LOG_FILE(GOOGLE_LOG_FILE): Optional path to also write logs to a file (stderr remains enabled).
This project provides 5 different deployment patterns for the same Google Search MCP functionality:
Standard MCP server for local development and integration with MCP clients:
# Run via uv (recommended)
uv run python -m server
# Or direct execution
python server.py
# Run via uvx (no activation, from any folder)
uvx --from /Users/justin/src/google_search_mcp google-search-mcp
# Run via pipx (isolated, globally available)
pipx install /Users/justin/src/google_search_mcp
google-search-mcpCommunicates over stdin/stdout using the standard MCP protocol.
MCP over HTTP using Server‑Sent Events (SSE). This exposes the standard MCP HTTP endpoints used by browser clients.
# Install HTTP extras and run
uv sync --extra http
uv run python -m server_http
# Or via console script (if installed)
uv run google-search-mcp-http
# With custom host/port
HOST=0.0.0.0 PORT=8000 uv run python -m server_httpAvailable MCP endpoints (not a custom REST API):
GET /sse— SSE connection for eventsPOST /messages— MCP message handling
Notes:
- CORS enabled by default (customize with
CORS_ORIGINS). - Same configuration as stdio mode (
GOOGLE_API_KEY,GOOGLE_CX, etc.).
MCP Streamable HTTP transport for clients that don’t use SSE.
# Start the Streamable HTTP MCP server
uv sync --extra http
uv run python -m server_http_stream
# Or via console script (if installed)
uv run google-search-mcp-stream
# Custom host/port
HOST=0.0.0.0 PORT=8000 uv run python -m server_http_streamNotes:
- Not a REST interface. Use an MCP client that supports the Streamable HTTP transport.
- CORS behavior matches the SSE app and is configurable via
CORS_ORIGINS.
Prerequisites:
# Install Lambda dependencies
uv sync --extra lambda
# Configure AWS credentials
aws configureDeploy to AWS Lambda with Bedrock AgentCore Gateway integration:
# Build and deploy
./deploy_aws_agentcore_auth0/build_zip.sh # Cross-platform build
./deploy_aws_agentcore_auth0/deploy_lambda.sh # Deploy via CloudFormation
./deploy_aws_agentcore_auth0/deploy_gateway.sh # Setup AgentCore Gateway
# Test the deployment
python3 deploy_aws_agentcore_auth0/test_gateway_auth0.py https://your-gateway-url.amazonaws.com client-id client_secret https://your-domain.auth0.com [audience]Features:
- JSON-RPC 2.0 protocol with OAuth authentication
- Serverless execution with environment variable inheritance
- Integrated with AWS Bedrock AgentCore ecosystem
Prerequisites:
# Install container dependencies (for ECR/ECS deployment)
uv sync --extra container
# Configure Docker and AWS
docker --version
aws configureLocal Testing:
# Build container
docker build -f Dockerfile.mcp -t google-search-mcp .
# Run locally
docker run -p 8000:8000 --env-file .env -e MCP_MODE=http-stream google-search-mcpDeploy to AWS ECS Fargate:
# Deploy to ECS Fargate
./deploy/deploy_mcp_container.sh google-search-mcp us-east-1 ecs-fargateFeatures:
- Multi-mode container supporting stdio, HTTP, and streaming
- Scalable deployment via ECS Fargate
- Environment variable configuration
- Health checks and monitoring
Note: AgentCore Runtime uses preview SDK and requires manual configuration as APIs are not publicly available.
All deployment patterns use the same configuration:
- Set
DYNACONF_DOTENV_PATHfor .env loading when needed - Environment variables override settings.toml values
- Logging configuration applies across all modes
This project uses httpx with HTTP/2 support enabled. The dependency is declared as httpx[http2] and will install the h2 package automatically.
# Install dependencies
uv sync
# Create and configure environment
cp .env.example .env
$EDITOR .env
# Run tests (optional sanity check)
uv run pytest -q
# Start the MCP server (stdio mode)
uv run python server.pyTest the search function directly:
uv run python -c 'import asyncio, server; print(asyncio.run(server.search("site:python.org httpx", num=2, safe="off")))'Note: safe must be off or active, and num is clamped to maximum of 10 per Google CSE limits.
If LOG_QUERIES is enabled, the server will write a single line per request to stdout containing:
- q_hash (short, non-reversible hash of the query), dt_ms (latency), num, start, safe, and endpoint (cse/siterestrict)
- If
LOG_QUERY_TEXTis true, it also includes the fullqtext.
Example log line:
2025-09-27T12:34:56+0000 INFO google_search_mcp: search q_hash=1a2b3c4d dt_ms=123 num=5 start=1 safe=off endpoint=cse q="site:python.org httpx"
When a client spawns the server via uvx, logs go to the server process’s stderr by default (safe for MCP stdio). To persist logs regardless of the client’s stderr handling:
- Set a file path (absolute recommended):
GOOGLE_LOG_QUERIES=true GOOGLE_LOG_FILE=/var/log/google_search_mcp.log - Or redirect stderr in the launch command:
uvx --from /path/to/repo google-search-mcp 2>> /tmp/google_search_mcp.log
Run the test suite to validate functionality:
# Run all tests
uv run pytest
# Run with quiet output
uv run pytest -q
# Run specific test files
uv run pytest tests/test_server.py
uv run pytest tests/test_server_http.pyThe project includes a comprehensive test suite located in the tests/ directory. All tests use pytest and mock external dependencies for reliable, fast execution.
Run the comprehensive test suite to validate functionality:
# Run all tests
uv run pytest
# Run with quiet output
uv run pytest -q
# Run specific test modules
uv run pytest tests/test_server.py # Core MCP server functionality
uv run pytest tests/test_server_http.py # HTTP endpoint testing
uv run pytest tests/test_server_http_stream.py # HTTP streaming testing
uv run pytest tests/test_client.py # Client integration
uv run pytest tests/test_logging.py # Logging configurationUse an MCP client (e.g., Inspector or your app) that supports SSE or Streamable HTTP transports. There is no custom REST list_tools/call_tool in this server.
For AWS AgentCore Gateway deployments, use the dedicated test script:
# Test gateway with authentication
python3 deploy_aws_agentcore_auth0/test_gateway_auth0.py \
"https://your-gateway.amazonaws.com/mcp" \
"client-id" \
"client-secret" \
"https://your-domain.auth0.com" \
"https://your-gateway.amazonaws.com/mcp" # audience (optional depending on IdP)This validates authentication, tool listing, and tool execution through the gateway.
- Uses JSON-RPC 2.0 protocol with OAuth authentication
- Cognito client credentials flow required
- Manual console configuration for compute targets and MCP providers (APIs not publicly available)
- See
deploy/README-lambda-zip.mdfor detailed instructions (use scripts underdeploy_aws_agentcore_auth0/)
- Uses preview AgentCore SDK (placeholder implementation)
- Requires manual configuration as APIs are not publicly available
- Container-based deployment via ECR integration
- Provides persistent sessions with microVM isolation