Skip to main content

Google Discover API and MCP server, self-hosted

A Google Discover API and a Google Discover MCP server you run on your own computer, in Python. It reads the Discover feed that Chrome for Android shows on its New Tab page to someone not signed in to Google, and gives you every card as JSON: position, title, publisher, URL, domain, article or video, age and image. The same 3 tools we run in production at Cotlet.

Google has no API for the Discover feed. The Discover report in Search Console counts clicks on your own site; it does not say which cards a country sees or in what order. This repo gives you:

  • MCP server for Claude Code, Claude Desktop, Cursor, Codex and any MCP client, over stdio or HTTP. Setup
  • REST API on http://127.0.0.1:8787/api/v1/google-discover, with OpenAPI docs at /docs. Setup
  • Python: call("check_domain_in_feed", domain="example-news.com"), plus 7 ready scripts in examples/.

No Google account and no browser. It is for technical people who want to run it themselves, for noncommercial use only (license). If you want the feed of any country without a proxy of your own, on a schedule in the cloud, for a team or a business, use the hosted version at cotlet.dev.

Google Discover MCP server Python 3.11+ License: PolyForm Noncommercial 1.0.0

pip install "git+https://github.com/cotletdev/google-discover-api-mcp-server.git@v1.0.1"
apkeep -a com.android.chrome -d apk-pure -o 'acknowledge_dangers=true,arch=arm64-v8a' .   # or any Chrome APK
google-discover-mcp setup --apk "com.android.chrome@arm64-v8a.xapk"
google-discover-mcp call get_discover_feed limit=10
claude mcp add google-discover -- google-discover-mcp mcp

Contents

How it works

AI agent (MCP) / script (REST, Python) ──▶ google-discover-mcp on your computer ──protobuf──▶ discover-pa.googleapis.com
                                                     ▲
             google-discover-mcp setup --apk ────────┘ reads Chrome's API key from a Chrome for Android APK, once
  1. Chrome for Android asks discover-pa.googleapis.com for its New Tab feed with one gzipped protobuf request. Signed out, it adds Chrome's own API key. The code that builds this request is open source in Chromium (components/feed).
  2. This server sends the same request, as Chrome 155 on an Android phone, and reads the cards out of the answer. One read holds about 31 cards. No headless browser runs.
  3. Google picks the feed's region from the IP the request comes from, and its language from the request. From your own connection you get the feed of your country. A proxy gets you other countries.

The API key is not in this repo. It belongs to Chrome, and Google could switch it off once it sits on GitHub. setup reads it from a Chrome for Android APK you download, tests it against the feed and saves it on your computer.

Requirements

  • Python 3.11 or newer.
  • A Chrome for Android APK or XAPK (com.android.chrome), downloaded once. How.
  • macOS, Linux or Windows.
  • For countries other than yours: a proxy with exits in those countries. Details.

Install

pip install "git+https://github.com/cotletdev/google-discover-api-mcp-server.git@v1.0.1"
google-discover-mcp --version

From source:

git clone https://github.com/cotletdev/google-discover-api-mcp-server.git
cd google-discover-api-mcp-server
python3 -m venv .venv
. .venv/bin/activate              # Windows: .venv\Scripts\activate
pip install -e .
google-discover-mcp --version

With uv: uv venv && uv pip install -e ., then uv run google-discover-mcp ....

Setting it up with an AI agent (Claude Code, Codex, Cursor)? Open it in this folder and ask it to set up the repo: AGENTS.md tells it every step.

To update: pip install -U "git+https://github.com/cotletdev/google-discover-api-mcp-server.git", from source git pull && pip install -e .. We copy every change of the hosted tools into this repo.

Set up: Chrome's API key

  1. Download Chrome for Android. With apkeep from APKPure:

    apkeep -a com.android.chrome -d apk-pure -o 'acknowledge_dangers=true,arch=arm64-v8a' .
    

    APKPure is a mirror of Google Play, not Google. setup only reads strings out of the file and runs nothing from it. An APK you pulled from your own Android phone (adb shell pm path com.android.chrome, then adb pull) works too.

  2. Run:

    google-discover-mcp setup --apk "com.android.chrome@arm64-v8a.xapk"
    
    Found 4 API keys in com.android.chrome@arm64-v8a.xapk, Chrome 155.0.8059.84
    Testing each key with one read of the DE feed ...
    Saved 2 working keys of Chrome 155.0.8059.84 to /Users/you/.config/google-discover-api-mcp/settings.json
    Feed country: DE
    

    It finds the AIzaSy... keys in Chrome's native libraries and the Chrome version in the manifest, tries each key with one read of the feed and keeps those Google takes. It also asks Cloudflare's trace page (cloudflare.com/cdn-cgi/trace) once which country your IP is in.

  3. Check at any time:

    google-discover-mcp status
    

Already have a key? google-discover-mcp setup --key --chrome-version 155.0.8059.84 asks for it with hidden input. When Google stops taking the keys (every call ends in target_error with HTTP 403), download the newest APK and run setup again.

Countries and proxies

Without a proxy every read comes from your IP, so the feed is the one of your country. country may be left out; another country gives invalid_input.

For other countries, set a proxy whose URL holds {country} (US) or {country_lower} (us). Most residential proxy providers put the country in the user name:

export GOOGLE_DISCOVER_PROXY='http://user-{country}-1:password@proxy.example.com:80'
google-discover-mcp call get_discover_feed country=GB

Or save it: google-discover-mcp setup --apk <file> --proxy '<url>'. A proxy without a placeholder sends everything through one exit; set GOOGLE_DISCOVER_COUNTRY to its country.

Any IP gets a feed, but a home IP gives the local news a person there sees. The feed of one country changes with the city of the IP.

MCP server

The MCP server lists the 3 tools with their input schemas and descriptions written for agents. All are read-only.

Claude Code

claude mcp add google-discover -- google-discover-mcp mcp
# without installing first:
claude mcp add google-discover -- uvx --from "git+https://github.com/cotletdev/google-discover-api-mcp-server.git@v1.0.1" google-discover-mcp mcp

Run setup once before the first call.

Claude Desktop

~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):

{
  "mcpServers": {
    "google-discover": {
      "command": "uvx",
      "args": [
        "--from",
        "git+https://github.com/cotletdev/google-discover-api-mcp-server.git@v1.0.1",
        "google-discover-mcp",
        "mcp"
      ]
    }
  }
}

Cursor

~/.cursor/mcp.json, the same block as Claude Desktop. A ready copy is in mcp.json.

Codex

~/.codex/config.toml:

[mcp_servers.google-discover]
command = "uvx"
args = ["--from", "git+https://github.com/cotletdev/google-discover-api-mcp-server.git@v1.0.1", "google-discover-mcp", "mcp"]

Over HTTP

google-discover-mcp serve also serves MCP over streamable HTTP at http://127.0.0.1:8787/mcp, for clients that take a URL:

google-discover-mcp serve
claude mcp add --transport http google-discover http://127.0.0.1:8787/mcp

Then ask your agent things like:

Is example-news.com in the Discover feed right now? Give the position, title and age of each card.

Which publishers have the most cards in Discover today?

List the video cards in the feed with their positions.

Collect 200 Discover cards and tell me which topics most of them are about.

REST API

google-discover-mcp serve          # http://127.0.0.1:8787, MCP at /mcp, docs at /docs

Each tool has its own route under /api/v1/google-discover, the same paths as the hosted API at cotlet.dev, so code written against one works with the other. Path parts and the query string are arguments.

curl 'http://127.0.0.1:8787/api/v1/google-discover/feed?limit=10'
curl 'http://127.0.0.1:8787/api/v1/google-discover/feed/domains/example-news.com'
curl 'http://127.0.0.1:8787/api/v1/google-discover/feed/cards?cards=150'

Any tool by name, body as its arguments:

curl -X POST http://127.0.0.1:8787/api/v1/google-discover/tools/check_domain_in_feed -d '{"domain": "example-news.com"}'
  • GET /api/v1/google-discover/tools: every tool with its route, input schema and an example answer.
  • GET /docs: interactive OpenAPI docs, GET /openapi.json the schema, for n8n, Postman or a generated client.

The server listens on 127.0.0.1 only. To reach it from another device of yours, set a token, and every request then needs Authorization: Bearer <token>:

GOOGLE_DISCOVER_MCP_TOKEN=$(openssl rand -hex 24) google-discover-mcp serve --host 0.0.0.0

Python and the example scripts

Straight from Python, no server needed:

from google_discover_api_mcp import call
from google_discover_api_mcp.scripting import write_rows

feed = call("get_discover_feed")
write_rows(feed["cards"], "discover.csv")
print(call("check_domain_in_feed", domain="example-news.com")["in_feed"])

Or one tool from the shell: google-discover-mcp call check_domain_in_feed domain=example-news.com, or with a JSON object.

Ready scripts in examples/. Each prints JSON, takes --out file.csv or --out file.json where it makes sense, and --help:

Script What it does
read_feed.py The feed, every card with position, title, publisher, URL, type and age. --limit.
top_publishers.py Publishers with the most cards in the feed.
check_domain.py Whether a site is in the feed now, and where.
watch_domain.py A site's cards that entered or dropped out of the feed since the last run. For cron.
compare_domains.py Cards, positions and titles of your site and its competitors.
video_cards.py The video cards of the feed.
collect_cards.py Up to 300 different cards from many reads, with how often each appeared.
python examples/check_domain.py --domain example-news.com
python examples/collect_cards.py --cards 200 --out discover.csv

On a schedule, cron on your own computer works while it is on: 0 * * * * cd ~/google-discover-api-mcp-server && .venv/bin/python examples/watch_domain.py --domain example-news.com.

All 3 tools

country is an ISO 3166-1 alpha-2 code (US, GB, DE). Leave it out for your own country. language is BCP 47 (en-US, de-DE), by default the country's main language. google-discover-mcp tools prints this list, google-discover-mcp tools --json adds the input schemas.

Tool Access REST route What it does
get_discover_feed read GET /feed The cards Google Discover shows right now in a country, in feed order, with no Google account.
check_domain_in_feed read GET /feed/domains/{domain} Whether cards from a domain are in a country's Discover feed now, and at which positions.
collect_discover_cards read GET /feed/cards Up to 300 different cards Discover shows in a country, from many reads, with how often each appeared.

A read of one country and language is reused for 15 minutes while the server runs. collect_discover_cards reads the feed up to 150 times, 8 at a time, for at most 70 seconds, and merges the cards by URL. From one IP the pool runs dry sooner than from many: 40 reads from one IP gave about 210 different US cards in our tests.

Never built, on purpose: follow, hide or "Not interested" on a card, and the personal feed of a Google account. Those need a signed-in account.

Configuration

Variable Default What it does
GOOGLE_DISCOVER_MCP_HOME ~/.config/google-discover-api-mcp Folder of settings.json.
GOOGLE_DISCOVER_API_KEY Chrome API keys, comma-separated, instead of setup.
GOOGLE_DISCOVER_CHROME_VERSION 155.0.8059.84 The Chrome version the keys came from.
GOOGLE_DISCOVER_COUNTRY found by setup The country of your IP, or of a proxy without a placeholder.
GOOGLE_DISCOVER_PROXY Proxy for every request, e.g. http://user-{country}:pass@host:port.
GOOGLE_DISCOVER_MCP_READ_ONLY 1 is the same as --read-only. Every tool already only reads.
GOOGLE_DISCOVER_MCP_TOKEN Bearer token required by serve; needed to listen beyond 127.0.0.1.
GOOGLE_DISCOVER_MCP_HOST, GOOGLE_DISCOVER_MCP_PORT 127.0.0.1, 8787 Address of serve.

Security

  • No account. Nothing here signs in to Google, and no cookie or password is read.
  • One host. Tools reach only discover-pa.googleapis.com. setup also asks www.cloudflare.com/cdn-cgi/trace once for your country.
  • Local by default. serve binds to 127.0.0.1 and refuses another address without GOOGLE_DISCOVER_MCP_TOKEN.
  • The settings file (settings.json, mode 0600) holds the keys and your proxy URL, which may carry the proxy's password. Keep it out of git.
  • Google's terms. This reads a Google service with Chrome's key, outside Chrome. Keep the volume to what you need; you answer for how you use it.

Errors

The REST API answers {"error": "<code>", "message": "..."}. The MCP server returns the same code and message as a tool error.

Status Code What to do
401 auth_required No API key saved. Run google-discover-mcp setup --apk <file>.
422 invalid_input An argument is wrong, or country is not yours and no proxy has {country}. The message says which.
429 rate_limited Google is limiting your IP. Wait a minute.
502 target_error Google refused the key (HTTP 403: take the newest APK and run setup again), answered with an error, or changed the feed's layout. git pull for the latest tools, or open an issue.
504 timeout Google or the proxy did not answer in time. Retry.

Self-hosted or hosted

This repo Cotlet, hosted
Tools the same 3 the same 3
Runs on your computer, while it is on in the cloud, 24/7
Countries yours, others through your own proxy any country per call, from a fresh home IP there
API key from a Chrome APK you download, renewed by you kept working for you, the feed tested daily
collect_discover_cards reads from your IP or proxy each read from another home IP in the country
Works with MCP clients on your machine, local scripts Claude.ai and ChatGPT connectors, n8n, Make, any HTTP client
Who may use it you, for noncommercial use teams, businesses, agencies
Price free free 7-day trial with 2,000 credits, no card; then one-time packs from $29 for 5,000 credits

On the hosted version a successful read uses 10 credits, failed calls are free, and there is no Cloud Browser or account to pay for. collect_discover_cards makes many reads and costs more. Full pricing.

FAQ

Does Google Discover have an API? No. Google has no API for the Discover feed. The only official Discover data is the Discover report in Search Console, with clicks and impressions for sites you own. Details: cotlet.dev/integrations/google-discover-api-mcp-server.

Is there a Google Discover MCP server for Claude, ChatGPT or Cursor? Yes, this one runs on your machine: google-discover-mcp mcp for Claude Code, Claude Desktop, Cursor and Codex. ChatGPT and Claude.ai connectors need a public HTTPS URL, which the hosted Google Discover MCP server gives you.

Is this my personal Discover feed? No. No Google account is involved, so your searches do not shape it. It is the default feed of a country and language, the one a phone that is not signed in gets. People who are signed in see feeds tuned to them.

Is this a Google Discover scraper? It does what people want a scraper for, the cards of the feed as rows, but it parses no HTML and drives no phone or emulator. It sends the request Chrome sends and reads the protobuf answer.

Is it the same data as DiscoverSnoop or another Discover panel? No. A panel collects the personal feeds of many users who run its software and sells totals and history. This reads one signed-out feed per call and keeps no history; watch_domain.py on a schedule builds your own.

Why does the feed change between calls? Discover changes through the day, and each read draws its 31 cards from a larger pool. Calls inside 15 minutes reuse the last read of that country and language.

Why is the API key not in the repo? It is Chrome's key, not ours. Google can switch off a key it finds on GitHub, and every copy of this repo would stop at once. Reading it from the APK keeps each install on its own.

Can it run on a VPS or in Docker? Yes. Run setup there, or set GOOGLE_DISCOVER_API_KEY. The feed then follows the server's IP; a proxy gets you the countries you want.

Can I use it at work or for my clients? No, the license allows noncommercial use only. For a team, a company or client work, use Cotlet or write to contact@cotlet.dev.

Is it open source? The source is public, the license is not an open source license: noncommercial use only, no business use.

A tool broke or I need another one. Open an issue with the tool name and the error message.

License

PolyForm Noncommercial License 1.0.0. In short:

  • Allowed: noncommercial use: you, for your own personal purposes, or a charity, school, public research or government body. Changing the code, and sharing it under the same license.
  • Not allowed: any commercial use, your own business included; client work; selling or offering it, or a service built on it.

Cotlet

Maintained by Cotlet (@cotletdev). Google, Google Discover and Chrome are trademarks of Google LLC. This project is unofficial and not affiliated with, endorsed or sponsored by Google.

Metadata

Release files for google-discover-api-mcp 1.0.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for google-discover-api-mcp 1.0.2
File Size Uploaded Provenance
google_discover_api_mcp-1.0.2.tar.gz 92.8 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for google-discover-api-mcp 1.0.2
File Interpreter ABI Platform
google_discover_api_mcp-1.0.2-py3-none-any.whl Python 3 none any Details

Total release size: 140.1 kB

Release files / google_discover_api_mcp-1.0.2.tar.gz

Download URL google_discover_api_mcp-1.0.2.tar.gz
Size 92.8 kB
Tags Source
SHA-256 checksum
How to use checksums
e3a808528a97ff262dc3e2e018dbad67fc52c1e74ae99a85b4a77d33b8d803ef
BLAKE2b-256 checksum
How to use checksums
3f61553c6f6f871ca28b2a1d69ce8e4a49cd1b1bd48c320c35eecb5348f9ebb8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 27, 2026.

Transparency log

Release files / google_discover_api_mcp-1.0.2-py3-none-any.whl

Download URL google_discover_api_mcp-1.0.2-py3-none-any.whl
Size 47.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
7c56b50d490dfc1799c3f5bc15177e476fe384b601907520b31183b02e9b974e
BLAKE2b-256 checksum
How to use checksums
cdfd7b3455fba88409af53d6716aaf25eb9f4385735287a6520e28d0de50f339
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 27, 2026.

Transparency log

Security for google-discover-api-mcp 1.0.2

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for google_discover_api_mcp-1.0.2.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 27, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

1.0.2 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page