I use Claude at work every day, and for good reason. It’s great at what it does, and Anthropic’s ecosystem makes wiring up third-party tools as simple as clicking a button. But for my personal setup, I’m a complete Google fanboy. I use Gemini Spark constantly because I love that it can run unattended in the background and has deep, native ties into the rest of my Google life (Gmail, Calendar, Drive, and Docs).
The problem is that once you step outside of Google’s walled garden, connecting external services to Gemini Spark gets frustrating fast.
Like most things on this blog, this whole project came down to scratching a very specific personal itch: I wanted my personal AI assistant to talk to the tools I actually use, and I flatly refused to pay a monthly subscription fee just to make two APIs talk to each other.
Fair warning up front: I am a hobbyist with a big toolchest, not a DevOps engineer. What follows is what worked for me on a weekend, not a reference architecture.
What is Model Context Protocol?
If you haven’t run into it yet, the Model Context Protocol (MCP) is an open standard designed to act like a universal USB port for AI models. Instead of building bespoke API integrations for every single combination of LLM and external service, MCP gives models a standardized way to discover tools, pull context, and take action across databases and APIs.
Why won’t Spark just connect to an existing MCP server?
Claude lets you click a pre-built connector or point at a local command, and it just works. Spark is a different animal:
- Almost no built-in connectors: Spark has practically zero out-of-the-box integrations for third-party tools compared to Claude’s catalog.
- Strict HTTPS and OAuth 2.0 requirements: Gemini Spark only connects to remote MCP servers over public HTTPS endpoints protected by OAuth 2.0.
That second requirement is the real roadblock. It immediately rules out standard local stdio MCP servers (the kind that run locally on your laptop for desktop apps). Worse, it also breaks a lot of hosted community MCP servers that “ought to” work out of the box, because they don’t implement the exact OAuth flow Spark expects.
How do you connect your own tools without paying for a connector service?
If you search around for ways to solve this, the internet will happily point you toward connector clearinghouses like Composio. Those services work fine if you’re an enterprise with a company card, but for personal use, paying a $20-$50/month middleman tax just to let an AI model check a repository or run a script on a Saturday afternoon makes zero sense.
I wanted something lightweight, fully under my own control, and free (or at most a few pennies a month).
The sweet spot turns out to be hosting custom FastMCP servers on Google Cloud Run, backed by Google Cloud Firestore for persistent token storage.
Cloud Run gives you an instant HTTPS endpoint with automatic SSL and scales all the way down to zero instances when idle. The always-free tier covers 2 million requests a month, and it stays pretty cheap as you ramp up past that. A personal MCP server that only runs when you ask it a question sits comfortably inside the free tier. When you aren’t chatting with Spark, you pay literally $0.
What does it take to make Cloud Run and FastMCP actually work?
Deploying a basic FastMCP container to Cloud Run sounds simple on paper, but getting Gemini Spark to actually talk to it means solving four sneaky architectural gotchas:
- The PKCE vs. Basic Auth loop: FastMCP advertises
client_secret_basicsupport in its metadata by default. When Spark sees this, it tries to use HTTP Basic Auth instead of PKCE (none), resulting in an infinite “Account linking required” loop. The fix is monkeypatching FastMCP’s metadata generator at startup to strip the basic auth methods. - Dynamic Client ID loss on scale-to-zero: Gemini Spark registers dynamic client IDs during setup. But when Cloud Run scales down to zero, that in-memory registration disappears. When a new container boots, it rejects Spark with “Client ID not found.” To solve this, a custom
ResilientGoogleProvidersynthesizes valid client records on the fly whenever a cold container starts. - Lost tokens on ephemeral disks: FastMCP writes OAuth refresh tokens to local disk by default. On Cloud Run, container filesystems are ephemeral and vanish on restarts or new deploys. Backing FastMCP with an encrypted Firestore collection keeps tokens alive across container lifecycles without paying for a persistent virtual disk.
- Acting as the user, not the service account: By default, Cloud Run executes API calls using its default machine service account, which has access to none of your personal data. Instead, it pulls the caller’s OAuth bearer token out of the incoming request, so tools run with your real permissions.
I’ve packaged up the entire boilerplate, Dockerfile, and deployment scripts in the spark-cloud-run-mcp repo on GitHub, complete with step-by-step setup instructions. If you want to review the code before trusting it, that’s the place to do it.
Is it secure?
Reasonably, in that it runs on your own OAuth permissions rather than some third party’s. But it was all vibe-coded on a weekend, so be careful before you point an MCP server at anything that touches your wallet. Start with things where the worst case is embarrassing rather than expensive.
What can you do with it?
Once you have this bridge in place, you can hook Gemini Spark into pretty much anything without ongoing overhead. A few ways I’m using it today:
- Analytics and data diagnostics: Custom tools that pull reporting and run checks for some personal projects.
- A real GitHub integration: Gemini is inexplicably missing a built-in GitHub integration (and hopefully one they’ll fix, since it’s seamless in with Antigravity), so I wired up my own MCP server to search repos, pull commits, inspect PRs, and review diffs directly from chat.
- Adding new tools on the fly: Whenever I need a new capability, I just add a Python function decorated with
@mcp.tool()to the server and redeploy.
If you want to scratch your own itch and plug the gaps in Spark’s external tool support without paying SaaS middleman fees, check out the end-to-end instructions in the repository.
This blog’s been empty for years because my blogging has mostly shown up at McGaw.io instead.
