I needed a way to interact with my app through AI clients without locking myself into a single provider. That's how this whole thing started.
I'd been hearing about the Model Context Protocol (MCP) for a while but never actually dived in. When I finally did, I had a small epiphany: MCP is just a standardized protocol for exposing tools to LLMs (Anthropic, Nov 2024). It's essentially the same function calling I'd been building all along. So what was actually different?
For my earlier apps, every time I swapped LLM providers I had to rewrite the tool-calling glue. Everything was tightly coupled to whichever model I happened to be using that week. MCP promised to decouple my application logic from the model — and to solve the broader M×N problem of wiring M models to N tools without writing M×N integrations (InfoQ). So I gave it a shot.
From local stdin to a public endpoint
Implementing it was embarrassingly straightforward. I lifted the tool suite straight out of my Vela app, reshaped the schemas to match the MCP spec, and fired up a test through the Cline plugin. It worked on the first try, talking over local stdin and stdout - a fun throwback to first-year CS.
The next challenge was reaching the server from outside my machine. I wanted my host tools available to remote clients like Claude, so I exposed the MCP over HTTP, routed it through Nginx, and bolted on auth for multi-tenancy.

My server exposes real tools against real infra. Here it lists my active projects, then blocks Eric's the second I ask - no dashboard, no SSH.
The "wow" moment
Once it was live, the thing that sold me wasn't the architecture. It was sending a message from my phone and watching a remote model drive my actual machines.
It starts small. "Show me my data usage for this month, my battery status, and the network I'm connected to - and send me a push notification reminding me to sleep."

One prompt, four tools across my laptop, zero context-switching.
Then you get greedy. Imagine sending this to a remote model and watching it execute cleanly:
"Investigate why my Ubuntu Server is showing nearly 80% RAM usage. Determine whether this memory is actively consumed by processes and Docker containers, or safely allocated to the Linux buffer/cache. Identify the highest memory-consuming entities and evaluate whether there is an immediate risk of Out-Of-Memory (OOM) exhaustion or swapping. Execute any necessary read-only system and container inspection tools concurrently where possible. Strict constraint: do not restart, kill, stop, or modify any processes, containers, or services. Provide a clear diagnosis citing the evidence gathered in a formatted PDF."

It pulled live memory stats, top processes, and Docker usage concurrently, reasoned about OOM risk, and handed me a formatted PDF - combining my host tools with its own report generation.
You can be on the beach and have Claude pull a Docker image, deploy it, configure Nginx, and hand you a live service. The more tools you expose, the more absurdly capable it gets.
The real takeaway
The magic of MCP isn't reinventing function calling - it's composability. My server brings remote execution against my infra; the client model brings reasoning and capabilities I never wrote, like rendering that PDF. Combined, you get an agent tailored to your exact stack, portable across any MCP-speaking client.
If you've been putting it off because it sounds over-engineered, don't. It's simpler than you think, and the decoupling alone is worth the weekend. At the very least, you'll have something new for the CV. 😉
One note: I'm deliberately leaving the server's language/framework out of this post - this one's about the why, not the wiring. If you want the implementation details (tool-schema mapping, the HTTP transport, the multi-tenant auth), drop a comment and I'll do a follow-up.
Have you shipped an MCP server yet? What's the most unhinged thing you've let a model do to your infra? 👇
Top comments (0)