Skip to main content
Groundrun

How I picked 4 MCP servers for a Next.js SaaS boilerplate — and why I dropped the official Postgres one

A token-budget framework, the four MCPs that earned a default slot, and a Datadog-disclosed SQL injection that killed the most-downloaded Postgres MCP in the ecosystem.

By Carlos Diaz-Melian12 min read

I'm building Groundrun, a Next.js 16 SaaS boilerplate for developers who use Claude Code daily. When I started, I had eight MCP servers configured in .mcp.json. Six months later I ship four, document a fifth as an opt-in, and have a strong opinion that most other Claude Code-centric templates are getting this wrong.

This piece is the framework I used to pick, the four that earned their default slot, the four I dropped, and the specific reason I removed the official Postgres MCP — which is still pulling 182,000 weekly npm downloads despite being deprecated by Anthropic and carrying an unpatched SQL injection bypass.

Why MCP selection is a marketing-grade decision, not a configuration one

On my first measurement, eight MCPs sent roughly 80,000 tokens of tool and schema definitions into Claude Code's context window before the first prompt. For a 200k-token window, that's 40% gone to setup advertising. Whatever conversation followed had less room than the boilerplate's own boot sequence.

That changed the framing. The question was no longer "what's useful?" but "what's worth a single-digit percentage of the buyer's context budget on session 1?" Most "useful" MCPs are not worth that.

The same logic applies to anyone shipping a Claude Code-centric tool to other developers — every MCP you default-on becomes a tax your users pay every session, forever.

The four criteria I score every MCP on

Before any MCP earns a slot in .mcp.json, it has to pass four checks:

  1. Token budget. Schema definitions cost real context. Measure them with a one-line script before deciding. (npx -y <mcp-package> against a dry-run JSON-RPC handshake gives you the schema; count tokens with tiktoken or a heuristic of ~4 characters per token.)
  2. Attack surface. Every credential the MCP holds is a leak vector. Some MCPs leak via argv (visible in ps auxw and /proc/<pid>/cmdline); some via .mcp.json files committed to public repos; some via the LLM itself being tricked by a malicious prompt into emitting a secret. Score the worst case.
  3. Maintenance health. When was the last commit? Last release? Are issues being responded to? An MCP that breaks under a Node 22 bump is one that takes your users down with it. The bar is higher for a paid template than for personal use — your buyers don't have time to debug your dependency choices.
  4. Redundancy with the existing stack. If prisma/schema.prisma plus a filesystem MCP gives Claude Code the database schema, you don't also need a Postgres MCP just for schema introspection — only for live query execution. Different MCPs that solve the same problem are noise.

Passing all four meant ship by default. Failing two or more meant opt-in only, with a documented trade-off.

The four MCPs that earned a slot in .mcp.json

1. @modelcontextprotocol/server-filesystem

Why it ships: filesystem access is the first thing Claude Code asks for on every project. Without it, every "read this file" turns into a copy-paste exercise. Token cost is low (~3k for the tool definitions), no credentials, official Anthropic package, actively maintained as part of the modelcontextprotocol/servers monorepo.

Scoped to . (repo root) in .mcp.json. A .claudeignore file gates which paths are visible — .env* files are excluded so a malicious prompt can't request a credential file by name.

2. @modelcontextprotocol/server-github

Why it ships: reading issues, opening PRs, and inspecting branch state through the real GitHub API is materially more reliable than prompting Claude to do it via the gh CLI. Token cost (~8k) is the highest of the four defaults — issues, PRs, files, branches, comments — but the substitution payoff (no fuzzy bash sequences when the agent forgets a flag) is worth it for a buyer writing features daily.

Credential: GITHUB_PERSONAL_ACCESS_TOKEN, passed via the env: block in .mcp.json. Never on argv.

3. @stripe/mcp (Stripe's official)

Why it ships: Stripe's official MCP gives Claude Code direct access to the Stripe API (create products, list customers, debug webhooks) AND the Stripe Docs search. For a SaaS boilerplate where the entire billing layer is Stripe, this is the single highest-value MCP per token spent.

Crucially: it's official. When the underlying Stripe API ships a breaking change, the MCP gets updated within days. Compare to community alternatives, which lag months and sometimes never catch up.

Credential: STRIPE_SECRET_KEY, env-only. Test key recommended in .env.example; a restricted key (rk_test_) is recommended once the buyer is shipping anything beyond the local dev loop.

4. @upstash/context7-mcp

Why it ships: this is the one MCP that solves a problem peculiar to a boilerplate ecosystem with fast-moving dependencies. Next.js 16, Auth.js v5, Prisma 7, Stripe SDK, Tailwind v4 — every one of these shipped a breaking change in the six months before this article was written. Most LLMs were trained before those changes existed. Without a docs MCP, Claude Code will confidently write Next 15-era code, Prisma 6-era code, Auth.js v4-era code.

Context7 lets Claude pull current API docs at request time, scoped to the library being asked about. Token cost is variable — light when not queried, expanding only when a specific library is referenced. That's the right shape for a documentation MCP: pay tokens only when you actually need the docs.

Credential: CONTEXT7_API_KEY (the free tier works for most buyers), env-only.

The four MCPs that didn't make the cut

Postgres — @modelcontextprotocol/server-postgres

The interesting one. The official MCP from Anthropic, 182,000 weekly npm downloads as of the week ending 2026-05-12. Most boilerplates I've looked at ship it on by default. Groundrun doesn't — and I'd argue no commercial boilerplate should ship it at all in 2026.

Three reasons:

(a) Anthropic deprecated the package on 2025-07-10 and archived the source repo as modelcontextprotocol/servers-archived. The currently published version on npm hasn't received a security update since.

(b) Datadog Security Labs disclosed an SQL injection on 2025-05-29 that allows arbitrary SQL execution by escaping the package's read-only restriction — for example, smuggling COMMIT; DROP TABLE users; into any executed query. The fix landed in git but was never published to npm. The currently published 0.6.x version is still vulnerable. The full disclosure is worth reading.

(c) The package reads its connection URL from argv only. There is no env-var fallback. Anthropic closed the feature request as "not planned" before deprecating the project. When Claude Code spawns the MCP, the full DATABASE_URL — including password — lands on the child process's argv, readable by any same-UID process via ps auxw or /proc/<pid>/cmdline. On shared-host environments (Replit, Gitpod, Codespaces, multi-tenant CI), this is a real exfiltration vector.

What Groundrun ships instead. The Postgres MCP is opt-in via a documented decision. Two pinned alternatives are in docs/CLAUDE-mcp.md, both env-only credential channel, both still under active maintenance:

  • Path A (Docker, primary): crystaldba/postgres-mcp:0.3.0 with --access-mode=restricted. Python-based, MIT-licensed, 2,700+ stars, 41,000+ weekly PyPI downloads. Strict superset of upstream's features (adds query tuning, index analysis, health checks).
  • Path B (Node, fallback): @zeddotdev/[email protected]. Zed Industries' fork of upstream with the Datadog patch applied, pure env-var credentials, MIT.

The verification step ("did I actually close the leak?") is one command: cat /proc/<mcp-pid>/cmdline | tr '\0' '\n'. The connection string should be absent from cmdline and present in environ.

If you're building a paid boilerplate or starting a new SaaS in 2026, don't ship @modelcontextprotocol/server-postgres on by default. You'd be inheriting an unpatched CVE to every buyer.

Playwright — @playwright/mcp

Token cost: ~14k for browser-automation tool definitions. Value when not actively writing tests: zero. Value when actively writing E2E tests: very high.

Decision: ship as opt-in via a /enable-mcp playwright slash command. The 14k tokens are dead weight in 95% of sessions. Buyers who are writing E2E tests can toggle it on for those sessions only.

Sentry — community MCP

Conditional value. Only useful once you have a Sentry account and a SENTRY_DSN to read from. For a buyer who hasn't decided whether they want Sentry yet, this is configuration friction (sign up, set up a project, paste keys) for a tool they don't yet need.

Decision: not in .mcp.json by default. If you set SENTRY_DSN in .env, copy-paste a snippet from docs/CLAUDE-mcp.md to enable.

Sequential-thinking — @modelcontextprotocol/server-sequential-thinking

The pre-build multi-agent review on Groundrun (April 2026) flagged this one specifically: token-budget cost exceeded signal value. For multi-step reasoning, Claude Code's built-in extended-thinking primitives already do most of the work. The dedicated MCP duplicates that capability with extra tool definitions.

Decision: not in .mcp.json.

What the numbers look like after the cut

ConfigurationTool-definition tokensFirst-prompt context cost
8 MCPs (initial)~80k40% of a 200k window
5 MCPs (post-pre-build-review, with upstream Postgres)~32k16% of window
4 MCPs (current, no Postgres by default)~26k13% of window

For a buyer running a 30k-token feature design conversation, the 4-MCP shape leaves 174k tokens for the actual conversation. The 8-MCP shape would leave 120k. That's the practical difference between "Claude has the full repo in context" and "Claude has half of it and is confidently hallucinating the rest."

The 4-MCP shape is also faster on session boot. Every MCP startup adds 50–200ms of subprocess spawn and stdio handshake. Cutting from 8 to 4 saved approximately 600ms per session, every session, forever — small per session, real per year.

The decision rule, made portable

Default an MCP only if it passes the four criteria (token budget, attack surface, maintenance health, redundancy). For anything that doesn't pass, document the opt-in with the trade-off explained, pin the version, and ship a verification snippet so the buyer can confirm the security posture before enabling.

The corollary: when a widely-shipped MCP becomes unsafe — as happened with the upstream Postgres MCP — shipping it by default makes you complicit in the unpatched CVE landing in your users' boxes. The right answer is to drop it and document why.

Where this lives

Groundrun ships .mcp.json with the four defaults and docs/CLAUDE-mcp.md with the opt-in snippets for Postgres, Playwright, and Sentry. The verification step ("did I close the leak?") is a single shell pipeline against /proc/<pid>/cmdline — runnable by any buyer in 30 seconds.

If you're a daily Claude Code user shipping Next.js SaaS apps and you've been wiring .claude/ from scratch every project, Groundrun is the boilerplate that does it for you. £179 at launch (Mon 6 July 2026), £99 flat for waitlist members — the price holds if you're on the list before launch.