A remote MCP connector that gives Claude access to Google Gemini — for what Claude can't do (image & video generation) and as an independent second opinion and auditor on important work.

Gemini Sidekick — a Gemini MCP connector for Claude

A remote MCP connector that gives Claude access to yourGoogle Gemini models, deployed as a single stateless Cloudflare Worker on the free tier.It works everywhere your Claude account goes: claude.ai web, the mobile app, Claude Desktop,and every Claude Code project.

The rule this whole thing is built around:Gemini is a gap-filler and a verifier, never an author. Claude writes every answer itself —its own reasoning, creativity, brainstorming, and judgment, from start to finish. Thisconnector exists only to (a) do things Claude cannot do at all (generate and edit images,reach exotic models) and (b) make Claude's own answers better through independentverification and contrasting perspectives. Never use it to outsource Claude's thinking,writing, ideation, or analysis. Critique-then-refine, not merge-two-drafts.

This rule is sent to Claude on every connection, and it's also in the two paste-blocks below(claude-profile-instructions.md andclaude-code-config.md). Keep it in all three.

What it gives Claude

Tool What it's for
list_gemini_models Live model discovery + recommended defaults. Nothing is hardcoded; the live list is the source of truth, so new models on your key appear automatically.
generate_image Generate (Imagen-class quality, or a fast/cheap draft) and iteratively edit — feed a result's URL back in to refine "add a red bandana / warmer light / bigger logo" indefinitely, branching whenever you want.
gemini_audit Independent, structured cross-model audit of important output Claude produced (issues with severity + location + suggested fix + a confidence) so Claude can surgically fix only what's wrong.
ask_gemini A genuine second opinion to contrast with Claude's own answer. Multi-turn.
gemini_disagree Asks a fast and a strong model the same thing and surfaces only where they diverge — divergence is the signal.
gemini_digest Offloads a very large input (big PDF, whole codebase, long transcript, YouTube URL) to Gemini's huge context window and returns a compact structured summary.
gemini_grounded Gemini with Google Search grounding as a second, independent search engine to cross-check facts.
gemini_raw Escape hatch to any model/method on your key (music, robotics, video, TTS, embeddings, future models), including polling long-running video jobs to completion.

Every generated/edited image is hosted at a stable, unguessable URL and returned both as amarkdown image and as a plain clickable link — because many clients (claude.ai web/mobile)won't render an inline image from a connector.

Deploy

Prerequisites: a Cloudflare account (free) and aGoogle AI Studio API key with billing enabled. The onlyvalue you generate yourself is one random string — your connector secret:

openssl rand -hex 24

Forking this for your own use? Your src/ code needs no changes. The one fork-specificvalue is the KV namespace id: a KV namespace belongs to a single Cloudflare account, so theid committed here (the original author's) won't work in yours. Set yours — no CLI required:

  1. Fork the repo on GitHub.
  2. Cloudflare dashboard → Storage & Databases → KV → Create a namespace (any name) → copyits Namespace ID.
  3. In your fork on GitHub, open wrangler.jsonc, replace the id on the MEDIA binding withthat value, and commit.

(Original author: already set — skip this.)

Option A — Connect the repo to Cloudflare (recommended; no local tooling)

After this one-time setup, every push to main auto-builds and deploys (edit → update.sh → live).

  1. Create the application. Dashboard → Workers & Pages → Create applicationImport a repositoryGitHub → install/authorize the Cloudflare GitHub app → pick your repo.

  2. On the "Set up your application" screen (open Advanced settings to see everything):

    • Build command: npm install
    • Deploy command: npx wrangler deploy
    • Non-production branch deploy command: npx wrangler versions upload (the default — leave it)
    • Path: / · API token: leave the auto-created one
    • Variable name / Variable value → leave BLANK. ⚠️ This box adds build variables; secretsentered here never reach the running worker. The real secrets go in step 3.
    • Click Deploy and let the first build finish.
  3. Add the two secrets to the WORKER (runtime — not the build). Open the worker →Settings → Variables and secrets → + Add, each as type Secret (encrypted):

    • GEMINI_API_KEY — your AI Studio key
    • CONNECTOR_SECRET — the random string from above (the secret in your URL)

    Save. (DAILY_CALL_CAP and IMAGE_TTL_SECONDS are already listed as plaintext — they come fromwrangler.jsonc.) Until the secrets are set, the URL returns a clean "Server not configured."

  4. Get your connector URL. On the worker's page the address is shown at the top and behind theVisit button:

    https://gemini-mcp.<your-subdomain>.workers.dev
    

    gemini-mcp is the worker name from wrangler.jsonc; <your-subdomain> is your account'sworkers.dev subdomain (the same across all your workers). That bare URL should say "Gemini Sidekickconnector is running." Your connector URL is it plus /<CONNECTOR_SECRET>/mcp:

    https://gemini-mcp.<your-subdomain>.workers.dev/<CONNECTOR_SECRET>/mcp
    

Verify with npm run smoke (see "Verify it works"), then add it inclaude.ai. Push future changes — which auto-deploy — with:

bash scripts/update.sh "what you changed"     # macOS / Linux / Git Bash
scripts\update.bat "what you changed"         # Windows

Option B — Deploy from your machine with the CLI (alternative)

Needs Node 18+.

npm install
npx wrangler login

# Forkers: create your KV namespace, then put the printed id in wrangler.jsonc (kv_namespaces[0].id),
# replacing the committed value. Say NO if wrangler offers to "add it on your behalf".
npx wrangler kv namespace create MEDIA

npx wrangler deploy                          # creates the worker and prints its URL
npx wrangler secret put GEMINI_API_KEY       # your AI Studio key
npx wrangler secret put CONNECTOR_SECRET     # the random string from above

Connect it to claude.ai (web + mobile + Desktop share this)

Settings → ConnectorsAdd custom connector → paste the full connector URL above →save. Because connectors live on your account, it's immediately available in the web app, themobile app, and Claude Desktop. Then paste claude-profile-instructions.mdinto Settings → Profile → "Instructions for Claude."

Custom connectors require a Claude plan that supports them (Pro/Max/Team/Enterprise).

Connect it to Claude Code (every project, automatically)

claude mcp add --scope user --transport http gemini \
  "https://gemini-mcp.<your-subdomain>.workers.dev/<CONNECTOR_SECRET>/mcp"

--scope user makes it available in every project. Then add the philosophy + usage blockfrom claude-code-config.md to your global ~/.claude/CLAUDE.md.

Verify it works (after deploy)

Automated smoke test — speaks MCP straight to your deployed Worker and exercises each toolagainst real Gemini, with no Claude in the loop (so it's deterministic and scriptable). It makesa few cents of real calls.

GEMINI_MCP_URL="https://gemini-mcp.<your-subdomain>.workers.dev/<CONNECTOR_SECRET>/mcp" npm run smoke
  • npm run smoke -- --cheap — protocol + model list + one flash call only (near-free).
  • npm run smoke -- --no-image — skip the (priciest) image generate/edit calls.
  • npm run smoke -- --full — also run gemini_disagree (3 calls) and gemini_digest.

Exit code is 0 only if every step passed. The secret stays in the env var — it's never writtento the repo.

Then a 2-minute manual check in claude.ai web or mobile — the one thing the script can'tverify is client-side rendering. Ask it to "generate an image of a fox, then make it wear a hat,"and confirm you get a working clickable link at each step (the inline image won't render there —that's expected, and exactly why the link matters).

Troubleshooting

  • Deploys fine, but every call errors or returns "Server not configured": your secrets are setas Build variables, not runtime. Move GEMINI_API_KEY and CONNECTOR_SECRET to the worker →Settings → Variables and secrets (encrypted), then redeploy.
  • First build fails on the KV namespace: the id in wrangler.jsonc isn't in your account.Create your own with npx wrangler kv namespace create MEDIA and replace it.
  • "MEDIA assigned to multiple KV Namespace bindings": there are two MEDIA entries — wranglerappended one when you accepted its "add it on your behalf" prompt. Keep a single binding.
  • 404 on the connector URL: the secret in the path doesn't match CONNECTOR_SECRET. The bareworker URL (no path) should say "Gemini Sidekick connector is running."

Configuration (optional)

Set in wrangler.jsonc under vars, then redeploy:

  • DAILY_CALL_CAP — a circuit breaker. "0" (default) disables it; "200" refusesbillable Gemini calls after 200 in a UTC day. Approximate (counted in KV), meant to stop arunaway loop, not to do accounting. Listing models and polling operations don't count.
  • IMAGE_TTL_SECONDS — how long hosted images live in KV (default 2592000 = 30 days).Images must outlive an editing session so you can keep refining a result across turns.

Free-tier KV allows ~1,000 writes/day. Each generated/edited image is one write (and,if DAILY_CALL_CAP is on, each billable call is one more). That's plenty for personal use,but it's the limit you'd hit first if something loops.

Billing safety — read this

Billing is on, so a runaway loop costs money, not just quota. The DAILY_CALL_CAP above isa guard rail. Your real safety net is a budget alert: in theGoogle Cloud Console → Billing → Budgets &alerts, create a budget on the project behind your AI Studio key with email alerts at, say,50% / 90% / 100%. Do this — the connector secret lives in the URL, so if it ever leaks, abudget alert is what tells you.

Security notes

  • Auth is an unguessable secret as the first URL path segment (claude.ai's connector UIcan't send static auth headers, so this is what actually works). It's compared inconstant time, and the Gemini key is stored as a Cloudflare secret, never in the URL.
  • Image links are decoupled from the connector secret. Images are served from/img/<id> where <id> is its own 144-bit unguessable token — so sharing an image linknever leaks your connector secret.
  • The image route can't become an XSS vector. Only safe raster types (PNG/JPEG/WebP/GIF)are served inline; anything else (e.g. SVG) is forced to download, under a strictContent-Security-Policy and X-Content-Type-Options: nosniff.
  • Model names and API methods are validated against allow-lists before they're ever placed inan API URL path (injection protection).
  • Stored image bytes are copied into an exact-length buffer, so no pooled/shared memory canleak into a stored image or a subsequent edit.

Publishing this repo (it's public-safe)

Nothing secret is committed, so this repo is safe to make public:

  • GEMINI_API_KEY and CONNECTOR_SECRET are never in the repo. They live as encryptedCloudflare Worker secrets; .dev.vars (local only) is gitignored.
  • The KV namespace id in wrangler.jsonc is not a secret — it's an account-scoped resourcehandle that does nothing without your Cloudflare credentials.

If someone forks this, they create their own KV namespace, replace that one id, and set their owntwo secrets — see Deploy. Nothing tied to you exposes anything sensitive.

Local development & tests

cp .dev.vars.example .dev.vars   # fill in a fake key + a test secret
npm run dev                       # wrangler dev (local workerd + local KV)
npm test                          # unit + integration tests (transport, security, defaults)
npm run typecheck                 # tsc --noEmit over src/
npm run build                     # dry-run bundle, no deploy

Should there be a text-to-speech tool? (the open question)

Decision: no dedicated TTS tool — it's covered by the gemini_raw escape hatch, whose audiooutput is auto-hosted at a link. Reasoning:

  • TTS is a real capability gap (Claude can't synthesize speech), so it belongs somewhere.But unlike image editing, it has no iterative loop and no model-shape juggling that abespoke tool would simplify — it's a single generateContent call with a speechConfig,which gemini_raw already expresses directly.
  • Audio can't render inline in Claude's clients anyway, so it needs the same "host it andreturn a link" treatment images get. gemini_raw already does that automatically for anyinline media in a response, so TTS audio comes back as a clickable URL with zero extrasurface.
  • You removed TTS once already, which signals it's low-frequency for you. A leaner tool listalso serves the "proactive but never naggy" goal: fewer tools means Claude routes to theright one more reliably.
  • If you find yourself reaching for it constantly, promoting it to a first-class tool later isa small change (it would mostly be the hosting wiring, which already exists).

So it's available today via gemini_raw (model + generateContent + a speechConfig body),just not as its own tool.

MCP Server · Populars

MCP Server · New

    amith-vp

    Indian Railway MCP

    MCP server for Indian Railway data. Search trains, check seat availability, get live statuses, delay info, station/train codes, and more — all via a simple Claude Desktop integration.

    Community amith-vp
    woraphol-j

    LINE Shopping API MCP Server

    Model Context Protocol (MCP) server for the LINE SHOPPING API. Enables AI agents and tools to manage products, inventory, orders, and settlements on LINE SHOPPING via auto-generated MCP tools from the official OpenAPI spec.

    Community woraphol-j
    tianyilt

    qzcli - 启智平台任务管理 CLI

    启智平台任务管理 CLI:资源查询、任务提交、日志查看和 MCP/agent workflow

    Community tianyilt
    WorkingMem

    jurisd

    MCP server for Australian and New Zealand legal research. Searches AustLII for case law and legislation, retrieves full-text judgements with paragraph numbers preserved, and supports OCR for scanned PDFs.

    Community WorkingMem
    mesh

    Clay MCP Server

    A simple Model Context Protocol (MCP) server for Clay.

    Community mesh