mcp-server-google-search

mcp-server-google-search

0

The Google Search MCP Server is a microservice designed for Google Custom Search. It offers features such as caching, rate limiting, and error handling, and supports REST and GraphQL endpoints.

Google Search MCP Server

A microservice for Google Custom Search with caching, rate-limiting, metrics, and robust error handling.

Features

  • Centralized error handling middleware
  • Config validation via Zod (fail-fast)
  • Redis + LRU caching with stale-while-revalidate
  • Prometheus metrics endpoint (/metrics)
  • Rate limiting via express-rate-limit
  • Swagger UI documentation (/docs)
  • REST endpoints: /health, /ready, /, /search, /search-file-type, /extract, /filters, /tools, /metrics
  • Unit tests with Jest + Supertest
  • ESLint + TypeScript linting
  • GraphQL endpoint (/graphql) with Apollo Server Sandbox UI

Quickstart

Prerequisites

  • Node.js >= v14
  • npm >= v6
  • Google API Key with Custom Search API enabled
  • Google CSE ID
  • Redis instance (optional)

Installation

git clone https://github.com/azzar/mcp-server-google-search.git
cd mcp-server-google-search
npm install
cp .env.example .env

Configuration

Edit .env to set:

GOOGLE_API_KEY=your_api_key
GOOGLE_CSE_ID=your_cse_id
PORT=3000
REDIS_URL=redis://localhost:6379
CACHE_TTL=3600
LRU_CACHE_SIZE=500
RATE_LIMIT_WINDOW_MS=60000
RATE_LIMIT_MAX=30
CB_TIMEOUT_MS=5000
CB_ERROR_THRESHOLD=50
CB_RESET_TIMEOUT_MS=30000
LOG_LEVEL=info

Alternatively, adjust settings directly in config.ts for advanced use.

Running in Development

npm run dev
  • Live reload with ts-node
  • Swagger UI available at http://localhost:3000/docs
  • GraphQL Sandbox UI available at http://localhost:3000/graphql

Running in Production

npm run build
npm start

API Usage Examples

Health Check

curl http://localhost:3000/health

Readiness

curl http://localhost:3000/ready

Search

curl "http://localhost:3000/search?q=openai&safe=active"

Filters

curl http://localhost:3000/filters

Tools

curl http://localhost:3000/tools

Search by file type

curl "http://localhost:3000/search-file-type?q=openai&fileType=pdf"

Extract

curl "http://localhost:3000/extract?url=https://example.com"

Metrics

curl http://localhost:3000/metrics

Swagger UI Visit http://localhost:3000/docs

GraphQL (UI) Visit Apollo Sandbox at http://localhost:3000/graphql

GraphQL Schema (SDL)

curl http://localhost:3000/graphql/schema

GraphQL (Query)

curl -X POST http://localhost:3000/graphql \
  -H "Content-Type: application/json" \
  -d '{"query":"{ search(q:\"openai\") }"}'

Testing & Linting

npm run lint
npm test

Docker

Dockerfile

FROM node:16-alpine
WORKDIR /app
COPY . .
RUN npm install --production
CMD ["npm", "start"]

Build & Run

docker build -t mcp-google-search .
docker run -d -p 3000:3000 --env-file .env mcp-google-search

Environment Variables

VariableDescriptionDefault
GOOGLE_API_KEYGoogle API key(required)
GOOGLE_CSE_IDCustom Search Engine ID(required)
PORTHTTP port3000
REDIS_URLRedis connection URLredis://localhost:6379
CACHE_TTLRedis cache TTL (seconds)3600
LRU_CACHE_SIZEFallback LRU cache max entries500
RATE_LIMIT_WINDOW_MSRate limit window (ms)60000
RATE_LIMIT_MAXMax requests per window30
CB_TIMEOUT_MSCircuit breaker timeout (ms)5000
CB_ERROR_THRESHOLDCircuit breaker error threshold (%)50
CB_RESET_TIMEOUT_MSCircuit breaker reset timeout (ms)30000
LOG_LEVELPino log levelinfo

API Reference

GET /health

Liveness probe. Returns 200 OK.

GET /ready

Readiness probe. Checks Redis & Google API reachability. Returns 200 OK or 503 Service Unavailable with JSON { checks: {...} }.

GET /

Root endpoint. Returns JSON { status: 'ok' }.

GET /search

Perform a Google Custom Search.

Query Parameters:

  • q (string, required): search query
  • Optional filters: searchType, fileType, siteSearch, dateRestrict, safe, exactTerms, excludeTerms, sort, gl, hl, num, start

Response: JSON from Google API.

GET /search-file-type

Search only specific file types.

Query Parameters:

  • q (string, required): search query
  • fileType (string, required): file type

Response: JSON from Google API.

GET /extract

Extract main content and sentiment from a URL.

Query Parameters:

  • url (string, required): URL to extract

Response: JSON with extracted content and sentiment.

GET /filters

List supported filters.

GET /tools

List available tool descriptions.

{
  "tools": [
    {
      "name": "search",
      "method": "GET",
      "path": "/search",
      "description": "Perform a Google Custom Search with optional filters",
      "parameters": {
        "q": "string",
        "searchType": "string",
        "fileType": "string",
        "siteSearch": "string",
        "dateRestrict": "string",
        "safe": "string",
        "exactTerms": "string",
        "excludeTerms": "string",
        "sort": "string",
        "gl": "string",
        "hl": "string",
        "num": "string",
        "start": "string"
      }
    },
    {
      "name": "searchFileType",
      "method": "GET",
      "path": "/search-file-type",
      "description": "Search only specific file types",
      "parameters": { "q": "string", "fileType": "string" }
    },
    {
      "name": "extract",
      "method": "GET",
      "path": "/extract",
      "description": "Extract main content and sentiment from a URL",
      "parameters": { "url": "string" }
    }
  ]
}

GET /metrics

Prometheus metrics in plain text.

GET /graphql

GraphQL interactive UI (Apollo Server Sandbox).

POST /graphql

GraphQL endpoint. Accepts JSON { "query": "<GraphQL Query>" } and returns JSON response.

Testing

Run unit tests and coverage:

npm test

Coverage report in coverage/.

License

MIT