{
  "markdown": "# mcp-google-search-console-crunchtools\n\n<!-- mcp-name: io.github.crunchtools/google-search-console -->\n\nSecure MCP server for Google Search Console. Query search analytics (clicks, impressions, CTR, position), manage sitemaps, inspect URL indexing status, and manage site properties.\n\n[![CI](https://github.com/crunchtools/mcp-google-search-console/actions/workflows/ci.yml/badge.svg)](https://github.com/crunchtools/mcp-google-search-console/actions/workflows/ci.yml)\n[![PyPI](https://img.shields.io/pypi/v/mcp-google-search-console-crunchtools)](https://pypi.org/project/mcp-google-search-console-crunchtools/)\n[![License: AGPL v3](https://img.shields.io/badge/License-AGPL_v3-blue.svg)](https://www.gnu.org/licenses/agpl-3.0)\n\n## Installation\n\n### uvx (recommended, zero-install)\n\n```bash\nclaude mcp add mcp-google-search-console-crunchtools \\\n    --env GSC_CLIENT_ID=your_client_id \\\n    --env GSC_CLIENT_SECRET=your_client_secret \\\n    --env GSC_REFRESH_TOKEN=your_refresh_token \\\n    -- uvx mcp-google-search-console-crunchtools\n```\n\n### pip\n\n```bash\npip install mcp-google-search-console-crunchtools\n```\n\n### Container (Podman/Docker)\n\n```bash\npodman run -d -p 8017:8017 \\\n    --env-file ~/.config/mcp-env/mcp-google-search-console.env \\\n    quay.io/crunchtools/mcp-google-search-console \\\n    --transport streamable-http --host 0.0.0.0\n```\n\n## OAuth Setup\n\nThis server supports two authentication methods: **browser-based OAuth** (recommended) and **environment variable** (fallback).\n\n### Option A: Browser-Based OAuth (Recommended)\n\nBrowser-based OAuth handles token exchange automatically. When credentials expire, visit the `/auth` URL and click through Google's consent screen — no manual code exchange needed.\n\n#### Step 1: Create a Google Cloud OAuth App\n\n1. Go to [Google Cloud Console](https://console.cloud.google.com/)\n2. Create a new project (or select an existing one)\n3. Navigate to **APIs & Services > Library**\n4. Search for **Google Search Console API** and click **Enable**\n5. Navigate to **APIs & Services > Credentials**\n6. Click **+ CREATE CREDENTIALS > OAuth client ID**\n7. If prompted, configure the OAuth consent screen first:\n   - User type: **External** (or Internal if using Google Workspace)\n   - App name: anything (e.g., \"MCP Search Console\")\n   - Scopes: add `https://www.googleapis.com/auth/webmasters`\n   - Test users: add your Google account email\n8. Back on Create OAuth client ID:\n   - Application type: **Web application**\n   - Name: anything (e.g., \"MCP Search Console\")\n   - Authorized redirect URIs: add your server's callback URL (e.g., `https://mcp-gsc.example.com/oauth2callback`)\n9. Click **Create** — copy the **Client ID** and **Client Secret**\n\n#### Step 2: Configure and Start\n\nCreate an env file:\n\n```bash\ncat > ~/.config/mcp-env/mcp-google-search-console.env << 'EOF'\nGSC_CLIENT_ID=your_client_id\nGSC_CLIENT_SECRET=your_client_secret\nGSC_CREDENTIALS_DIR=/data\nGSC_OAUTH_REDIRECT_URI=https://mcp-gsc.example.com/oauth2callback\nEOF\nchmod 600 ~/.config/mcp-env/mcp-google-search-console.env\n```\n\nStart the server with a persistent volume for credentials:\n\n```bash\npodman run -d -p 8017:8017 \\\n    --env-file ~/.config/mcp-env/mcp-google-search-console.env \\\n    -v mcp-gsc-data:/data:Z \\\n    quay.io/crunchtools/mcp-google-search-console \\\n    --transport streamable-http --host 0.0.0.0\n```\n\n#### Step 3: Authenticate\n\nVisit `https://mcp-gsc.example.com/auth` in your browser. You'll be redirected to Google's consent screen. Grant access and the server will save credentials automatically.\n\nWhen tokens expire, any tool call will return the `/auth` URL. Click it to re-authenticate — no container restart needed.\n\n### Option B: Environment Variable (Fallback)\n\nIf you prefer static credentials or can't expose a callback URL, set `GSC_REFRESH_TOKEN` in your env file. See the [manual OAuth flow](#manual-oauth-flow) below.\n\n<details>\n<summary><strong>Manual OAuth flow</strong></summary>\n\n```bash\nexport GSC_CLIENT_ID=\"your_client_id_here\"\nexport GSC_CLIENT_SECRET=\"your_client_secret_here\"\n\necho \"https://accounts.google.com/o/oauth2/v2/auth?client_id=${GSC_CLIENT_ID}&redirect_uri=http://127.0.0.1&response_type=code&scope=https://www.googleapis.com/auth/webmasters&access_type=offline&prompt=consent\"\n```\n\n1. Open the URL in your browser, sign in, and click **Allow**\n2. Copy the `code=` value from the redirect URL\n3. Exchange the code:\n\n```bash\ncurl -s -X POST https://oauth2.googleapis.com/token \\\n    -d \"client_id=${GSC_CLIENT_ID}\" \\\n    -d \"client_secret=${GSC_CLIENT_SECRET}\" \\\n    -d \"code=PASTE_CODE_HERE\" \\\n    -d \"grant_type=authorization_code\" \\\n    -d \"redirect_uri=http://127.0.0.1\" | python3 -m json.tool\n```\n\n4. Copy the `refresh_token` from the response and add `GSC_REFRESH_TOKEN=...` to your env file.\n\n</details>\n\n### How it works at runtime\n\nThe server checks for credentials in this order:\n1. **File-based credentials** from `GSC_CREDENTIALS_DIR/credentials.json` (written by the browser-based flow)\n2. **Environment variable** `GSC_REFRESH_TOKEN` (fallback)\n\nOn each API call, the server exchanges the refresh token for a short-lived access token (~1 hour), cached in memory and refreshed automatically. Updated tokens are persisted to the credentials file for reuse across container restarts.\n\n## Available Tools (10)\n\n| Category | Count | Tools |\n|----------|------:|-------|\n| Sites | 4 | list_sites, get_site, add_site, delete_site |\n| Search Analytics | 1 | query_search_analytics |\n| Sitemaps | 4 | list_sitemaps, get_sitemap, submit_sitemap, delete_sitemap |\n| URL Inspection | 1 | inspect_url |\n\n## Security\n\n- OAuth2 credentials stored as `SecretStr` (never logged)\n- File-based credentials written with `0o600` permissions (atomic writes)\n- Automatic token scrubbing from error messages\n- Pydantic input validation with `extra=\"forbid\"`\n- No filesystem access, shell execution, or code evaluation\n- TLS certificate validation (httpx default)\n- Request timeouts and response size limits\n- Built on [Hummingbird](https://github.com/hummingbird-project) container images\n\nSee [SECURITY.md](SECURITY.md) for the full security design document.\n\n## Development\n\n```bash\nuv sync --all-extras\nuv run ruff check src tests\nuv run mypy src\nuv run pytest -v\ngourmand --full .\npodman build -f Containerfile .\n```\n\n## License\n\n[AGPL-3.0-or-later](LICENSE)\n",
  "bytes": 6335,
  "sha": "5fda287360c616913336c42d60c09845e474992b845ff397c570851359b5b83c",
  "repo_slug": "crunchtools/mcp-google-search-console",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_crunchtools_google_search_cons_73f2abff/readme"
}