Skip to content

jspv/google_search_mcp

Repository files navigation

Google Search MCP Server

A Model Context Protocol (MCP) server that provides Google Custom Search functionality.

🎯 This repository demonstrates 5 different deployment patterns for the same MCP functionality:

  1. stdio Mode - Standard MCP over stdin/stdout for local development and MCP client integration
  2. HTTP over SSE - MCP HTTP transport using Server‑Sent Events (browser-friendly)
  3. HTTP Streamable - MCP Streamable HTTP transport (non‑SSE)
  4. AWS Lambda + AgentCore Gateway - Serverless deployment with OAuth authentication
  5. Containerized MCP Service - Docker containers deployed to ECS Fargate for scalable cloud deployment

Installation

Clone the repository and install dependencies:

git clone https://github.com/jspv/google-search-mcp.git
cd google-search-mcp
uv sync

Project structure

  • server.py / server_http.py / server_http_stream.py — MCP servers (stdio, HTTP, streaming)
  • lambda_handler.py — AWS Lambda adapter for MCP stdio server
  • Dockerfile.mcp — Container image for HTTP/streaming MCP service
  • deploy/ — legacy deployment assets (use deploy_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 utilities
    • dump_tool_schema.py — dump schema from an MCP server over stdio
  • dist/ — build artifacts and generated outputs
    • schema/tool-schema.json — generated tool schema for AgentCore
    • google_search_mcp_lambda.zip — built Lambda package
  • tests/ — unit and integration tests

Optional Dependencies

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 dev

Configuration

This server uses Dynaconf for configuration management, supporting both .env files and environment variables.

Setup

  1. Copy the example environment file:

    cp .env.example .env
  2. Edit .env and add your Google API credentials:

    GOOGLE_API_KEY=your_actual_api_key_here
    GOOGLE_CX=your_custom_search_engine_id_here

Environment Variable Override

Environment variables will override .env file values when both are present. This allows for flexible deployment scenarios:

  • Development: Use .env file for local development
  • Production: Use environment variables for production deployment
  • CI/CD: Environment variables can override defaults for testing

Example:

If your .env file contains:

GOOGLE_API_KEY=dev_key_from_file

And you set an environment variable:

export GOOGLE_API_KEY=prod_key_from_env

The server will use prod_key_from_env (environment variable takes precedence).

Required Configuration

  • GOOGLE_API_KEY: Your Google Custom Search API key
  • GOOGLE_CX: Your Custom Search Engine ID

Get these from:

Optional Configuration

  • ALLOW_DOMAINS (GOOGLE_ALLOW_DOMAINS env 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).

Usage

This project provides 5 different deployment patterns for the same Google Search MCP functionality:

1. stdio Mode (Default MCP)

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-mcp

Communicates over stdin/stdout using the standard MCP protocol.

2. HTTP over SSE (MCP transport)

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_http

Available MCP endpoints (not a custom REST API):

  • GET /sse — SSE connection for events
  • POST /messages — MCP message handling

Notes:

  • CORS enabled by default (customize with CORS_ORIGINS).
  • Same configuration as stdio mode (GOOGLE_API_KEY, GOOGLE_CX, etc.).

3. HTTP Streamable (non‑SSE)

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_stream

Notes:

  • 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.

4. AWS Lambda + AgentCore Gateway

Prerequisites:

# Install Lambda dependencies
uv sync --extra lambda

# Configure AWS credentials
aws configure

Deploy 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

5. Containerized MCP Service

Prerequisites:

# Install container dependencies (for ECR/ECS deployment)
uv sync --extra container

# Configure Docker and AWS
docker --version
aws configure

Local 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-mcp

Deploy to AWS ECS Fargate:

# Deploy to ECS Fargate
./deploy/deploy_mcp_container.sh google-search-mcp us-east-1 ecs-fargate

Features:

  • 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.

Configuration Notes

All deployment patterns use the same configuration:

  • Set DYNACONF_DOTENV_PATH for .env loading when needed
  • Environment variables override settings.toml values
  • Logging configuration applies across all modes

Quick Start

This project uses httpx with HTTP/2 support enabled. The dependency is declared as httpx[http2] and will install the h2 package automatically.

Using uv (recommended)

# 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.py

Quick Test (no MCP client required)

Test 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.

Logging behavior

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_TEXT is true, it also includes the full q text.

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
    

Testing

Unit Tests

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.py

Testing

Testing

The project includes a comprehensive test suite located in the tests/ directory. All tests use pytest and mock external dependencies for reliable, fast execution.

Unit Tests

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 configuration

Local Testing

Use 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.

AWS Gateway Testing

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.

Deployment Details

AWS Lambda + AgentCore 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.md for detailed instructions (use scripts under deploy_aws_agentcore_auth0/)

AWS AgentCore Runtime

  • 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

About

python mcp server implementing api-based google search

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published