wingolf-ai-mcp
MCP server integrating Google Search Console, Google Analytics 4, and GitHub, enabling AI clients to query search analytics, traffic data, and repository information.
README
wingolf-ai-mcp
MCP server for wingolf.vn — integrates Google Search Console, Google Analytics 4, and GitHub into a single MCP endpoint for AI clients (Claude, ChatGPT, Cursor, Codex).
Features
- Google Search Console — search analytics, top queries, top pages
- Google Analytics 4 — flexible reports, traffic summary, top pages
- GitHub — code search, file contents, recent commits, pull requests
- Dual transport: stdio (local) and Streamable HTTP (deploy)
- Bearer token auth on HTTP transport
- Read-only by design — no data deletion or modification
Quick Start (local)
1. Prerequisites
- Node.js 20+
- A Google Cloud project with Search Console API and Analytics Data API enabled
- A GitHub fine-grained personal access token
2. Clone and install
cd wingolf-ai-mcp
cp .env.example .env
npm install
3. Configure environment
Edit .env and fill in your credentials (see sections below).
4. Run
# stdio mode (for Claude Desktop / Cursor / Codex)
npm run start:stdio
# HTTP mode (for remote clients or testing)
npm run start:http
# Dev with auto-reload
npm run dev
Google Setup
Create a Google Cloud Project
- Go to Google Cloud Console
- Create a new project (or select existing)
- Note the Project ID
Enable APIs
- Go to APIs & Services → Library
- Search for and enable:
- Google Search Console API
- Google Analytics Data API
Create a Service Account
- Go to IAM & Admin → Service Accounts
- Click Create Service Account
- Give it a name (e.g.,
mcp-server) - Assign role: Viewer (or create a custom role with minimal permissions)
- Click Done
- Click the service account → Keys → Add Key → Create New Key → JSON
- Save the downloaded JSON file to
secrets/google-service-account.json
Never commit this file! The
.env.examplepath is/app/secrets/google-service-account.jsonwhich is mounted read-only via Docker.
Add Service Account to Search Console
- Go to Google Search Console
- Select your property (e.g.,
https://wingolf.vn/) - Go to Settings → Users and permissions
- Click Add user
- Enter the service account email (found in the JSON key file, looks like
name@project.iam.gserviceaccount.com) - Set permission to Restricted (or Full — Restricted is enough for read-only)
- Click Add
Add Service Account to GA4
- Go to Google Analytics
- Select your GA4 property
- Go to Admin → Property Access Management
- Click + → Add users
- Enter the service account email
- Select role: Viewer (or Analyst)
- Click Add
Find your GA4 Property ID
- In GA4 Admin, under Property Settings → Property Details
- Copy the numeric Property ID (e.g.,
123456789) - Set
GA4_PROPERTY_ID=123456789in your.env
GitHub Setup
Create Fine-Grained PAT
- Go to GitHub Settings → Developer settings → Personal access tokens → Fine-grained tokens
- Click Generate new token
- Set:
- Token name:
wingolf-ai-mcp - Expiration: as needed
- Resource owner: your org or user
- Repository access: Only select repositories → choose your repo
- Token name:
- Under Permissions → Repository permissions, set:
- Contents: Read-only
- Metadata: Read-only (auto-selected)
- Pull requests: Read-only
- Click Generate token and copy it
Set in .env:
GITHUB_TOKEN=github_pat_xxx
GITHUB_OWNER=your-org-or-user
GITHUB_REPO=your-repo
Docker Deployment
Build and run
# Build
docker compose build
# Run
docker compose up -d
# View logs
docker compose logs -f
Directory structure on VPS
~/wingolf-ai-mcp/
├── docker-compose.yml
├── .env
└── secrets/
└── google-service-account.json # ro-mounted
Behind Nginx / Cloudflare
For production, put the container behind Nginx or Cloudflare Tunnel with HTTPS:
location /mcp {
proxy_pass http://127.0.0.1:8787;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
Connecting AI Clients
ChatGPT Connector
- Open ChatGPT → Settings → Connectors → Create
- Enter Connector URL:
https://tours.ct14a1.fun/mcp - If connected successfully, the tools list will appear automatically
This server uses anonymous/no-auth for dev mode. For production OAuth 2.1, see OpenAI MCP Auth docs.
Claude Desktop (local stdio)
Add to claude_desktop_config.json:
{
"mcpServers": {
"wingolf-ai-mcp": {
"command": "node",
"args": ["path/to/wingolf-ai-mcp/dist/index.js"],
"env": {
"GOOGLE_APPLICATION_CREDENTIALS": "/path/to/secrets/google-service-account.json",
"GSC_SITE_URL": "https://wingolf.vn/",
"GA4_PROPERTY_ID": "123456789"
}
}
}
}
Cursor / Windsurf / Other MCP Clients
Transport: Streamable HTTP
URL: https://tours.ct14a1.fun/mcp
Testing with curl
# Health (no auth needed)
curl https://mcp.example.com/health
# Ready (needs auth)
curl -H "Authorization: Bearer your-token" https://mcp.example.com/ready
# MCP endpoint
curl -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your-token" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}' \
https://mcp.example.com/mcp
Available Tools
| Tool | Description |
|---|---|
gsc_search_analytics |
Full GSC search analytics query with dimensions, filters, pagination |
gsc_top_queries |
Top search queries by clicks/impressions |
gsc_top_pages |
Top landing pages by clicks/impressions |
ga4_run_report |
Flexible GA4 report with custom dimensions and metrics |
ga4_traffic_summary |
Traffic summary by channel group |
ga4_top_pages |
Top pages by page views |
github_search_code |
Search code in repository |
github_get_file |
Fetch file contents with decoded text |
github_list_recent_commits |
List recent commits |
github_list_pull_requests |
List pull requests by state |
health_check |
Server health and configuration status |
Environment Variables
| Variable | Required | Default | Description |
|---|---|---|---|
PORT |
No | 8787 |
HTTP server port |
MCP_BEARER_TOKEN |
Yes | — | Bearer token for HTTP transport auth |
GOOGLE_APPLICATION_CREDENTIALS |
For GSC/GA4 | — | Path to service account JSON key file |
GSC_SITE_URL |
For GSC | — | Search Console property URL |
GA4_PROPERTY_ID |
For GA4 | — | GA4 property numeric ID |
GITHUB_TOKEN |
For GitHub | — | GitHub fine-grained PAT |
GITHUB_OWNER |
For GitHub | — | GitHub org or username |
GITHUB_REPO |
For GitHub | — | GitHub repository name |
ENABLE_GITHUB_WRITE_TOOLS |
No | false |
Enable GitHub write tools (future) |
MCP_TRANSPORT |
No | stdio |
Transport mode (stdio or http) |
Security Notes
- Rotate tokens regularly — use unique bearer tokens per environment
- Never commit secrets —
.envandsecrets/are excluded from git - Read-only by design — all tools are annotated
readOnlyHint: true - Use HTTPS — put behind Cloudflare, Nginx, or Caddy in production
- IP allowlist — restrict access to known IPs if possible
- GitHub write tools are disabled by default (
ENABLE_GITHUB_WRITE_TOOLS=false) - No shell commands are executed by any tool
- No arbitrary file reading — only the configured service account JSON is read
Project Structure
wingolf-ai-mcp/
├── package.json
├── tsconfig.json
├── Dockerfile
├── docker-compose.yml
├── .env.example
├── README.md
└── src/
├── index.ts # Entry point
├── server.ts # McpServer factory
├── transports/
│ ├── stdio.ts # Stdio transport
│ └── http.ts # HTTP transport with Bearer auth
├── config/
│ └── env.ts # Environment config & validation
├── auth/
│ └── bearer.ts # Bearer token extraction & validation
├── clients/
│ ├── gsc.ts # Google Search Console API client
│ ├── ga4.ts # Google Analytics 4 API client
│ └── github.ts # GitHub API client (Octokit)
├── tools/
│ ├── gsc.tools.ts # GSC tool registrations
│ ├── ga4.tools.ts # GA4 tool registrations
│ ├── github.tools.ts # GitHub tool registrations
│ └── index.ts # Tool registration aggregator + health_check
└── utils/
├── dates.ts # Date parsing & validation
└── errors.ts # Error normalization
Scripts
| Script | Description |
|---|---|
npm run dev |
Watch mode with tsx |
npm run build |
Compile TypeScript to dist/ |
npm run start |
Run compiled server (default: stdio) |
npm run start:stdio |
Force stdio transport |
npm run start:http |
Force HTTP transport |
License
MIT
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.