golemkit
← All posts

July 22, 2026 · 4 min read

Make your SaaS agent-accessible: an MCP server in one route

“Agent-friendly” usually describes a repository: a CLAUDE.md, strict types, clear module boundaries, so coding agents can extend the code. But there’s a second half to it that most products skip — the running product being accessible to agents. Your next user increasingly shows up as someone’s assistant asking “what does this cost?” — and it either answers from your server or from a stale crawl. The Model Context Protocol is how you make it your server, and in this boilerplate the whole thing is one route file.

One route, Streamable HTTP

The server lives at src/app/api/[transport]/route.ts and speaks MCP’s Streamable HTTP transport at /api/mcp, using the mcp-handler package — no separate process, no WebSocket infrastructure, just a Next.js route handler deployed with the rest of the app. Connecting from any MCP client is one line of config:

{ "golemkit": { "url": "https://your-domain/api/mcp" } }

Tools are typed, like everything else

Each capability is registered with registerTool: a name, a description the model reads to decide when to call it, and a zod input schema. The example server ships three tools over the public catalog — list_credit_packs (prices in USD), list_chat_models (the gateway model ids), and get_blog_post (metadata by slug, or all posts). The zod schema isn’t ceremony: it’s what tells the agent that slug is an optional string, so it calls the tool correctly on the first try.

The tools are thin, because the logic already has a home

The interesting design choice is what the tools don’t contain. The credit packs tool returns the same creditPacks array that renders the pricing page. The blog tool reads the same registry that renders /blog and the sitemap. The tools are a few lines each because they’re wrappers around module functions — the same “thin routes, thick modules” rule the rest of the codebase follows. One source of truth serves the UI, the public API, and now agents; when a price changes, all three are right on the next deploy.

Why public-catalog only

The shipped server has no authentication, which is exactly why it only exposes data that is already public on the website. An unauthenticated MCP endpoint is reachable by anyone’s agent — treat it like a public API, because it is one. To expose user data (balances, documents, usage), add token verification first — mcp-handler ships an authorization guide for exactly this — and then let the authenticated tools call the same module functions with a user id, the way the API-key routes already do. The pattern doesn’t change; only step 1 does.

The demo is worth running once: point an MCP client at your deployment and ask it what a credit costs. Watching an agent answer from a tool you wrote in an afternoon makes the case better than any landing page — the product isn’t just built by agents, it’s built for them, on both sides of the deploy.