https://github.com/1999azzar/mcp-server-google-search
MCP server proxy for Google Programmable Search Engine
https://github.com/1999azzar/mcp-server-google-search
mcp-server microservice
Last synced: 4 months ago
JSON representation
MCP server proxy for Google Programmable Search Engine
- Host: GitHub
- URL: https://github.com/1999azzar/mcp-server-google-search
- Owner: 1999AZZAR
- License: mit
- Created: 2025-04-28T12:24:15.000Z (6 months ago)
- Default Branch: master
- Last Pushed: 2025-04-29T11:52:32.000Z (5 months ago)
- Last Synced: 2025-06-19T01:39:06.516Z (4 months ago)
- Topics: mcp-server, microservice
- Language: TypeScript
- Homepage:
- Size: 153 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# 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
```bash
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:
```ini
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
```bash
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
```bash
npm run build
npm start
```### API Usage Examples
**Health Check**
```bash
curl http://localhost:3000/health
```**Readiness**
```bash
curl http://localhost:3000/ready
```**Search**
```bash
curl "http://localhost:3000/search?q=openai&safe=active"
```**Filters**
```bash
curl http://localhost:3000/filters
```**Tools**
```bash
curl http://localhost:3000/tools
```**Search by file type**
```bash
curl "http://localhost:3000/search-file-type?q=openai&fileType=pdf"
```**Extract**
```bash
curl "http://localhost:3000/extract?url=https://example.com"
```**Metrics**
```bash
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)**
```bash
curl http://localhost:3000/graphql/schema
```**GraphQL (Query)**
```bash
curl -X POST http://localhost:3000/graphql \
-H "Content-Type: application/json" \
-d '{"query":"{ search(q:\"openai\") }"}'
```### Testing & Linting
```bash
npm run lint
npm test
```### Docker
**Dockerfile**
```dockerfile
FROM node:16-alpine
WORKDIR /app
COPY . .
RUN npm install --production
CMD ["npm", "start"]
```**Build & Run**
```bash
docker build -t mcp-google-search .
docker run -d -p 3000:3000 --env-file .env mcp-google-search
```## Environment Variables
| Variable | Description | Default |
|--------------------------|--------------------------------------------|-----------------------------|
| `GOOGLE_API_KEY` | Google API key | (required) |
| `GOOGLE_CSE_ID` | Custom Search Engine ID | (required) |
| `PORT` | HTTP port | `3000` |
| `REDIS_URL` | Redis connection URL | `redis://localhost:6379` |
| `CACHE_TTL` | Redis cache TTL (seconds) | `3600` |
| `LRU_CACHE_SIZE` | Fallback LRU cache max entries | `500` |
| `RATE_LIMIT_WINDOW_MS` | Rate limit window (ms) | `60000` |
| `RATE_LIMIT_MAX` | Max requests per window | `30` |
| `CB_TIMEOUT_MS` | Circuit breaker timeout (ms) | `5000` |
| `CB_ERROR_THRESHOLD` | Circuit breaker error threshold (%) | `50` |
| `CB_RESET_TIMEOUT_MS` | Circuit breaker reset timeout (ms) | `30000` |
| `LOG_LEVEL` | Pino log level | `info` |## 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.
```json
{
"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": "" }` and returns JSON response.
## Testing
Run unit tests and coverage:
```bash
npm test
```Coverage report in `coverage/`.
## License
MIT