This is ridiculous. We’ve spent decades building firewalls, hardening systems, and generally doing everything humanly possible to keep unauthorized access out of our networks. And then what do we do? We pry open a gaping hole for a specific service. Madness. Caddy-mcp, however, offers a different approach. It’s a Caddy plugin designed to tunnel private MCP servers out to the world, not invite the world in. It’s a subtle but vital distinction. The private box dials out. Over QUIC. Caddy then serves it like any other HTTPS endpoint. Brilliant. No inbound ports. No third party dictating terms. Just your private server, speaking to the internet on its own terms.
The Architecture: A Secure Dial-Out
Here’s the diagram. It’s elegant. A public Caddy instance at the front. It handles the usual TLS, routing, and middleware jazz. But the magic happens in the caddy-mcp plugin itself. This isn’t just a simple proxy. It’s listening on a QUIC port (4443, because why not?) and acts as a tunnel registry and policy engine. Think of it as a bouncer with a very specific guest list for your private services. It manages tokens, enforces policies, and even keeps an audit log of everything that’s happening.
The real trick is the dial-out. The rift client, running on your private network, initiates a QUIC connection. It uses --protocol mcp. This means your MCP server, chugging away happily on localhost:9090, doesn’t have to be exposed. It’s shielded. The connection is encrypted using TLS 1.3 and multiplexed streams. This isn’t just about accessibility; it’s about security architecture.
Modes of Operation: Transparent vs. Aware
Caddy-mcp offers two distinct modes for these tunnels. The first is Transparent. In this mode, Caddy is essentially a dumb pipe. It forwards bytes. Your MCP server handles its own session management and authentication. It’s the simplest setup, if you’ve already got that locked down.
The second mode, Aware, is where things get interesting. Caddy doesn’t just pass traffic; it parses the JSON-RPC calls. This allows for granular policy enforcement before anything even hits your upstream server. The example configuration shows this beautifully:
reverse_proxy mcp-tunnel {
transport mcp {
tunnel code-server
mode aware
allow_tools read_file list_files search
deny_tools execute_command shell_exec
allow_resources "file:///repo/*"
}
}
This snippet demonstrates how you can precisely control what tools and resources are accessible. You can allow_tools like read_file or list_files but deny_tools like execute_command. It’s fine-grained access control at the protocol level. No more granting broad access and hoping for the best.
Denied calls get a JSON-RPC error back. There’s per-user ACLs via a policy file (effective permissions are the intersection of tunnel and user ACLs), and a structured audit log of every call — token, user, tool, resource, decision, latency.
This level of visibility and control is what’s been missing. The audit logs are a godsend for security and debugging. You see exactly who did what, when, and whether it was allowed. The intersection of tunnel and user ACLs adds another layer of complexity that can be both powerful and, for the uninitiated, a bit daunting. But that’s the point, isn’t it? Security shouldn’t be a free-for-all.
The Beta Blues and Future Prospects
Right now, caddy-mcp is in beta. It’s designed for a single Caddy instance and doesn’t yet support high availability. This means it’s perfect for personal projects or small teams who need a secure way to access internal services without exposing their entire network. Forget about massive enterprise deployments for now. This is about sensible, secure access.
The project lives on GitHub. The code is open-source, which is, of course, the only way anything in this space should be. The creator, Venkat Krishna, has built something genuinely useful here. It tackles a common problem with an elegant, secure, and modern solution. The reliance on QUIC is a smart move, taking advantage of modern networking protocols that are designed for performance and resilience. It’s a step away from the legacy of port forwarding and NAT traversal headaches that have plagued sysadmins for decades.
Why does this matter for developers? Because it means less time fighting with firewalls and more time building things. It means secure remote access to development environments, internal tools, and databases without becoming a security vulnerability yourself. It’s about reducing the attack surface. For anyone who’s ever had to tell a stakeholder, “Just open port 8080 on your router,” this plugin is a revelation. It’s the quiet revolution in how we connect to our own infrastructure.
🧬 Related Insights
- Read more: Warden v2.0: Free CLI That Sniffs Out Malicious npm Packages in Seconds
- Read more: Zoxide: The Shell Ally That Ends Wrong-Directory Nightmares
Frequently Asked Questions
What does caddy-mcp do? Caddy-mcp is a Caddy plugin that allows private MCP servers to be exposed to the internet by initiating a secure QUIC connection from the private network to a public Caddy instance, avoiding the need for inbound firewall ports.
Is caddy-mcp suitable for large enterprises? Currently, caddy-mcp is in beta and supports a single Caddy instance without high availability features, making it best suited for personal or small-team setups, not large enterprise deployments.
How does caddy-mcp improve security? It enhances security by eliminating the need to open inbound ports on firewalls, reducing the attack surface. Additionally, the ‘Aware’ mode allows for granular policy enforcement and detailed audit logging of all service access.