Last week I stood up a remote MCP server for this blog. It exposes ten tools — search my posts, list drafts, moderate comments, pull traffic stats — so I can manage the site by talking to an agent instead of clicking around an admin panel. It works, I'm happy with it, and I want to start by telling you that I didn't need to build it.
That sounds like a confession of wasted effort. It isn't. The reason I didn't need it is the same reason you might, and the gap between those two situations is the whole point.
The over-engineering reflex
When you build something that touches the public internet and handles credentials, there's a gravitational pull toward doing it "properly." For an MCP server, "properly" sounds like OAuth — discovery endpoints, dynamic client registration, short-lived tokens, the works. I spent a good chunk of an afternoon convincing myself I needed it.
I didn't. I'm one person. The server sits behind HTTPS, and a single 32-byte random bearer token in an Authorization header is genuinely sufficient. It's not a shortcut or a security smell — it's the right amount of mechanism for one user with one secret. The lesson I keep relearning: match the auth to the threat model, not to the most impressive thing the spec supports.
When you actually need one
So when is an MCP server worth it? Not when you want to save yourself a few local installs. The honest trigger is sharing.
Imagine you write a data-profiling tool. It needs a Python runtime, a Node install, an ODBC driver, a configured DSN, and — the part people forget — network line-of-sight to the warehouse, which usually means being inside a VPC or on the VPN. If that lives as a local script, every coworker who wants it has to reproduce all of that. Five teammates, five environments that drift, five copies of the database password sitting on laptops.
Move it behind an MCP server and the math changes. The dependencies, the drivers, and the network access live in one place — the place that already has them. Your coworkers connect over HTTPS with a token and call the tools. They don't need Python, Node, ODBC, or a VPN route to the database, because the server has all of that.
The framing that finally clicked for me: the win isn't "no local installs." The win is centralizing execution where the credentials, dependencies, and network access already live, then exposing it to agents with auth and audit in one spot. Installs are the least interesting part. Reachability and credential containment are the real payoff.
How it actually goes together
The implementation is less exotic than it sounds. Mine is a small Python container speaking MCP's Streamable HTTP transport, sitting behind the same nginx that already serves the site. The tools don't reimplement any logic — they're thin clients that call the API endpoints the website already exposes, reusing the machine-auth token pattern that was already in the codebase. New surface area was deliberately small.
A couple of things to know going in:
- Put the server behind your existing reverse proxy. You get TLS and routing for free.
- Don't duplicate business logic in the tools. Call the endpoints you already have.
- One gotcha cost me twenty minutes: the MCP SDK ships DNS-rebinding protection that only trusts localhost. Behind nginx, the proxied Host header gets rejected with a bare HTTP 421. The fix is allow-listing your real hostname — but the symptom looks nothing like the cause.
The auth flow, for when you do need it
If you outgrow the bearer token and need real per-user identity, MCP leans on OAuth 2.1, and the flow is specific: the client hits your server, gets a 401 pointing at discovery metadata, dynamically registers itself, runs an authorization-code exchange with PKCE, and comes back with a short-lived token your server validates on every call. That dynamic registration step is load-bearing — and it's exactly why you can't drop in just any identity provider. Google, for instance, won't work directly, because it doesn't support dynamic client registration; you'd have to run a small broker in front of it.
That's the upgrade path. The point is that it's a path, not a prerequisite. Start with the token. Add OAuth the day you have a second user — and not a day sooner.
0 Comments
Leave a Comment