Home / Blog / I Built a Claude Code MCP Connector in 3 Days—And ...

I Built a Claude Code MCP Connector in 3 Days—And Accidentally DDoS'd My Own Database

By CaelLee | | 9 min read

I Built a Claude Code MCP Connector in 3 Days—And Accidentally DDoS'd My Own Database

TL;DR: Built a custom MCP connector that slashed my debugging time by 73% and reduced churn by 0.7%. Also learnt that connection pooling isn't optional, Claude makes very aggressive API calls, and 2 AM coding sessions produce questionable variable names. Open-sourcing the template next week.

Last Tuesday at 2 AM, I was debugging a production database issue with cold pizza in one hand and SELECT * FROM users WHERE churn_probability > 0.7 in the other. Not exactly my finest moment as a founder.

Three days later, I shipped a custom Claude Code MCP connector that cut my debugging time by 70%. Here's the full story—what worked, what broke spectacularly, and why I'm never going back to manual CSV exports.

Actually, before we dive in—when I say "debugging manually," I mean I was literally running queries at 2 AM while my churn rate ticked up to 3.8%. My CAC was already $24 per user. Every hour I spent staring at pgAdmin was an hour I wasn't building features that actually retained customers.

The Problem Nobody Talks About

Most indie hackers I know—shoutout to James over at TinyPilot who warned me about this months ago—rely on pre-built integrations for their AI tools. It makes sense. Why build when you can buy?

Here's the thing, though. When you're bootstrapped and running a SaaS with 200+ paying customers, your database schema is a unique snowflake. Off-the-shelf connectors don't understand your userretentioncohorts table. They've never seen that weird subscriptionstatus enum you added at 3 AM six months ago. (I still don't know why I named it subscriptionstatus instead of just status. Haunts me.)

My setup: PostgreSQL 15.6 on Railway, analytics in BigQuery, and a custom billing system I built because Stripe's default reporting wasn't granular enough for my $10k MRR operation. Every time I wanted Claude to help analyse churn patterns, I had to export CSVs, clean them manually, and paste context into the chat window. It was 2024 and I was working like it was 2015.

Pieter Levels once tweeted something that's stuck with me: "The best tools are the ones you build yourself when you're too lazy to do the manual work." I think about that tweet roughly once a week. It's basically my entire product philosophy at this point.

What the Heck is MCP Anyway?

MCP stands for Model Context Protocol—Anthropic's open standard for connecting AI models to external tools. Think of it as USB-C for AI: instead of every tool having a custom integration, MCP provides a universal protocol.

Claude Code (Anthropic's agentic coding tool, launched late 2024) can connect to any MCP server you build. The magic: Claude doesn't just query your database. It understands the schema, writes optimised SQL, and reasons about the results—all within your security boundary.

Well... mostly within your security boundary. Look, it's complicated. The tool definitions need to follow specific JSON schemas, and Claude Code's tool calling behaviour is—let's say "enthusiastic." It'll hammer your endpoints if you let it. More on that disaster in a bit.

No data leaves your infrastructure. At least in theory. In practice, you need to be really careful about what you expose. I cannot stress this enough.

The Build: 3 Days, 2 Pivots, and 1 "Oh Sh*t" Moment

Day 1: The Naive Approach (1,200 Lines of Garbage)

I started by following Anthropic's MCP Python SDK docs (v0.2.3, latest as of November 2024). The example looked straightforward: define tools, implement handlers, connect to Claude Code. Simple enough, right?

Wrong.

Mistake #1: I tried to build a universal SQL connector that could handle any query. By 6 PM, I had 1,200 lines of unmaintainable code that kept timing out on JOIN queries. The error that broke me:


psycopg2.errors.QueryCanceled: canceling statement due to statement timeout
CONTEXT: SQL function "get_user_analytics" statement 1

Over and over. 47 times in one afternoon. I counted.

Pivot: I scoped down. Dramatically. Instead of "query anything," I built three specific tools:

I probably should've started with just one. But you know how it is at 11 PM when you're in the zone and everything feels obvious.

Day 2: The Architecture That Actually Worked

Here's the architecture I landed on. I had this beautiful Miro board with three clean boxes—Claude Code, MCP Server on Railway, PostgreSQL—with neat arrows showing tool calls and query responses. Then I accidentally closed the tab without saving. Lost the whole thing.

The code, though? That survived.


# Core MCP tool definition (simplified)
@mcp.tool()
async def get_user_churn_risk(user_id: str) -> dict:
 """
 Analyses churn risk for a specific user based on:
 - Login frequency (last 30 days)
 - Feature usage patterns
 - Support ticket history
 - Payment failure count
 """
 # Complex query joining 4 tables
 query = """
 WITH user_activity AS (
 SELECT 
 COUNT(DISTINCT login_date) as active_days,
 AVG(session_duration) as avg_session
 FROM user_sessions
 WHERE user_id = $1 
 AND login_date > NOW() - INTERVAL '30 days'
 ),
 feature_usage AS (...)
 """
 # Returns structured JSON with risk score

Why this worked: Instead of giving Claude raw SQL access—which is terrifying from a security standpoint, I still have nightmares about accidental DROP TABLE statements—I encapsulated business logic in Python functions. Claude reasons about the output, not the query construction. The model never sees a SQL string.

Day 2 metrics:

I went to bed at 3 AM feeling like an absolute genius.

I was wrong.

Day 3: The "Oh Sh*t" Moment (And The Fix)

Deployed to production at 11 AM. By 11:23 AM, my error logs exploded.

The MCP server was opening a new database connection for every single request instead of connection pooling. With Claude making 15+ tool calls per analysis session—and doing them in parallel because it's "efficient"—I hit Railway's connection limit in minutes. The exact error:


FATAL: remaining connection slots are reserved for non-replication superuser connections

My phone started blowing up. Users couldn't log in. I was mid-coffee-pour and nearly dropped the French press. My Apple Watch thought I was having a cardiac event. Not exaggerating—it actually triggered the high heart rate notification.

Fix: Implemented pgBouncer 1.21 connection pooling and added a connection cache with 300-second TTL. Total downtime: 7 minutes. My heart rate: approximately 400 BPM.

Post-fix metrics:

I also added rate limiting. Because Claude will absolutely DDoS your infrastructure if you let it. Ask me how I know. Actually don't—it's embarrassing.

Real Results (With Numbers)

I've been using this connector for 2 weeks now. Here's what changed:

MetricBefore MCPAfter MCPDelta
Debug time per churn case45 min12 min-73%
Weekly DB queries manually written80+12-85%
Time to identify churn patterns3-4 days4 hours-92%

That 0.7% churn reduction translates to roughly $700 more MRR retained each month. The connector cost me literally $0 to build—I used existing Railway infra—and saves me 15+ hours weekly.

Is it sustainable long-term? Honestly, I don't know yet. Two weeks isn't enough data to make grand claims. But the trend line looks promising.

Real example from yesterday: Claude flagged that users on my "Pro" plan who hadn't used the export feature in 14+ days had a 67% churn probability. I built an automated re-engagement email sequence targeting exactly those users in four hours. The sequence went out this morning. Twelve users re-engaged within 3 hours. That's roughly $1,200 in annual revenue that was about to walk out the door.

Four hours of work. Potentially thousands in retained revenue. This is what I mean when I say it's a force multiplier.

What I'd Do Differently

  1. Start with monitoring. I shipped without proper logging. Day 3's outage was entirely preventable. Next time, I'm adding Datadog alerts before deployment. I'm on the free tier right now, which gives you 1-day metric retention. It's not great, but it beats flying completely blind.
  1. Rate limiting from day one. Claude makes aggressive parallel tool calls. Without rate limiting on the MCP server, you'll accidentally DDoS your own database. I cannot believe I have to type this sentence. But here we are.
  1. Open source the template immediately. I'm kicking myself for not building this as a reusable template from the start. Other indie hackers like Sarah over at Paperbell asked for the code. Now I'm retroactively extracting the generic parts into a public repo. ETA: next week? Maybe the week after. I keep finding hardcoded stuff that only works for my specific schema. Classic.
  1. Start smaller. Seriously. My first attempt tried to replicate my entire analytics stack. A single getchurnrisk tool would have validated the approach in 2 hours instead of 3 days. This is a pattern with me. Every. Single. Time.

The Bigger Picture: Why This Matters for Bootstrappers

VC-funded startups can afford dedicated data teams and $2k/month analytics tools. As a bootstrapper, my competitive advantage is speed of learning—how fast I can understand my users and adapt.

This MCP connector isn't just a time-saver. It's a force multiplier. Claude can now reason about my specific business context, not generic SaaS benchmarks. When I ask "why is churn up this week?", it doesn't give me blog-post advice—it queries my actual data and says "three enterprise customers had payment failures because your new billing system doesn't retry ACH transfers."

That's not AI hype. That's a co-founder I can't afford to hire.

I showed this to a mate who runs a $50k MRR SaaS and he just stared at me for like 30 seconds. Then asked if I could build one for him. I said no. But I'll open source the template. Promise.

Want to Build Your Own?

Here's my stack:

I'm planning to open-source the template next week. If you want early access, drop a comment below with your use case. I'm especially curious: what's the one database query you wish Claude could run automatically?

Fair warning: the code is messy. There are comments I wrote at 2 AM that don't make sense anymore. But it works. Mostly.

Product: SaaS Analytics Dashboard — helping bootstrappers understand their metrics

Revenue: $10,200 MRR | 204 customers | 3.1% churn | $24 CAC

Building in public since: January 2024

buildinpublic #ai #mcp #claudecode #bootstrapping #indiehacker #postgresql

P.S. If anyone from Anthropic is reading this—please add native connection pooling to the MCP SDK. I'm begging you. My heart can't take another day like Day 3.

Monthly churn rate3.8%3.1%-0.7%
C

Cael Lee

Full-stack developer with 8+ years of experience. Currently building AI-powered developer tools. I've tested 20+ AI API providers and coding assistants.

Ready to get started?

Get your API key and start building with 180+ AI models.

Get API Key Free