How to Expose Local Servers with AI Agents: MCP, Claude Code, and OpenClaw
Let Claude Code, Cursor, or any MCP-compatible agent manage your tunnels. A practical guide to rustunnel's MCP server, Claude Code plugin, and OpenClaw skill — with diagrams and real terminal output.
AI coding agents are changing how developers work. You describe what you need in natural language, and the agent writes code, runs commands, and interacts with external tools on your behalf.
But there's a gap: agents can't reach your local machine. When Claude Code needs to test a webhook from Stripe, or Cursor wants to preview a Next.js app for a client, the agent has no way to make your localhost:3000 reachable from the internet.
That's exactly what rustunnel's MCP server solves. Let's walk through how it works and how to set it up.
Why AI Agents Need Tunnels
There are three scenarios where an AI agent benefits from a tunnel:
-
Webhook testing — You ask Claude to integrate Stripe payments. Claude writes the endpoint, starts your server, and needs a public URL to test the webhook flow. Without a tunnel, the test can't complete.
-
Preview sharing — You're working in Cursor on a design review. The agent finishes the frontend, starts the dev server, and you need to share the result with a stakeholder. A tunnel gives you an instant shareable link.
-
CI/CD and automation — An agent in a GitHub Actions workflow spins up a preview environment and needs to expose it for integration tests or visual regression checks.
In all three cases, the agent needs to programmatically create a tunnel, get a public URL, use it, and clean up afterward. That's what the MCP protocol enables.
How rustunnel's MCP Server Works
The rustunnel-mcp binary implements the Model Context Protocol (MCP) over stdio. It's a thin bridge between AI agents and the rustunnel API.
The flow is straightforward:
- You ask the agent something like "Expose my local server on port 3000."
- The agent sends a JSON-RPC call to
rustunnel-mcpover stdio, calling thecreate_tunneltool. - The MCP server spawns the
rustunnelCLI as a subprocess, which establishes a WebSocket connection to the edge relay. - The MCP server polls the REST API until the new tunnel appears (up to 15 seconds).
- The agent gets back a public URL like
https://abc123.eu.edge.rustunnel.com.
When you're done, the agent calls close_tunnel — the MCP server kills the subprocess and deletes the tunnel via the API. No orphaned processes, no manual cleanup.
Three Ways to Connect
rustunnel offers three paths for AI agent integration, each suited to a different workflow.
Option 1: Claude Code Plugin (Recommended)
The fastest path if you're using Claude Code. One command, zero config.
/plugin install rustunnelYou'll be prompted for three values:
| Setting | Hosted example | Self-hosted example |
|---|---|---|
| Server address | eu.edge.rustunnel.com:4040 | localhost:4040 |
| Dashboard API URL | https://eu.edge.rustunnel.com:8443 | http://localhost:4041 |
| API token | rt_live_abc123... | your admin token |
The plugin bundles the MCP server configuration and a skill definition (212 lines of agent instructions that teach Claude how to use all 6 tools). The token is stored securely by Claude Code's plugin system and persists across sessions.
After installation, just talk to Claude:
> Expose my local server on port 3000.
Claude: I'll create an HTTP tunnel to your local port 3000.
→ create_tunnel(local_port=3000, protocol="http")
Your tunnel is live: https://abc123.eu.edge.rustunnel.com
Option 2: Manual MCP Configuration
For Claude Desktop, Cursor, VS Code, or any MCP-compatible client, add this to your config:
{
"mcpServers": {
"rustunnel": {
"command": "rustunnel-mcp",
"args": [
"--server", "eu.edge.rustunnel.com:4040",
"--api", "https://eu.edge.rustunnel.com:8443"
],
"env": {
"RUSTUNNEL_TOKEN": "your-token-here"
}
}
}
}The rustunnel-mcp binary is installed automatically when you install rustunnel via Homebrew:
brew tap joaoh82/rustunnel
brew install rustunnelThe Homebrew formula installs both rustunnel (the CLI client) and rustunnel-mcp (the MCP server) in a single step.
Option 3: OpenClaw Skill
If you use an OpenClaw-compatible agent, the skill is published at openclaw.dev/skills/rustunnel. It reads your credentials from ~/.rustunnel/config.yml and handles first-time setup automatically — if the config file doesn't exist, the agent asks you for your token and creates it.
The 6 MCP Tools
The MCP server exposes six tools that cover the full tunnel lifecycle:
| Tool | Auth | Description |
|---|---|---|
create_tunnel | yes | Open a tunnel and get a public URL |
close_tunnel | yes | Close a tunnel by UUID |
list_tunnels | yes | List all active tunnels |
list_regions | no | Show available server regions |
get_tunnel_history | yes | View past tunnel activity |
get_connection_info | yes | Get the CLI command string (for cloud sandboxes) |
The last one, get_connection_info, is worth highlighting. Some AI agents run in cloud sandboxes where they can't spawn subprocesses. In that case, the agent calls get_connection_info, which returns the CLI command to run locally. You paste it into your terminal, and the agent uses list_tunnels to confirm it's live.
Example Workflow: Webhook Integration
Here's a real scenario. You're building a Stripe integration and need to test webhooks.
Step 1: Ask Claude Code to set up the project:
> Set up a Stripe webhook endpoint on my Next.js app running on port 3000.
When you're done, expose it with rustunnel so I can test.
Step 2: Claude creates the endpoint, then calls the MCP tool:
→ create_tunnel(token, local_port=3000, protocol="http", subdomain="stripe-test")
Step 3: The MCP server spawns the CLI and polls the API:
# MCP server spawns this in the background:
rustunnel http 3000 --server eu.edge.rustunnel.com:4040 \
--token rt_live_abc123 --subdomain stripe-testStep 4: After ~2 seconds, the API returns the tunnel:
{
"public_url": "https://stripe-test.eu.edge.rustunnel.com",
"tunnel_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"protocol": "http"
}Step 5: Claude configures the Stripe webhook:
Claude: Your webhook endpoint is live at:
https://stripe-test.eu.edge.rustunnel.com/api/stripe/webhook
I've configured Stripe to send events to this URL.
Run a test payment to verify it works.
Step 6: When you're done testing:
> Close the tunnel.
→ close_tunnel(token, tunnel_id="a1b2c3d4-...")
The subprocess is killed, the tunnel is deleted from the relay, and the URL stops working. Clean.
What's Next
The MCP server is production-ready today, but we're thinking about what comes next:
- x402 USDC micropayments — autonomous agents that need tunnels could purchase their own credits via a crypto payment rail, eliminating the need for human-provided API tokens entirely.
- Remote MCP server — a Streamable HTTP transport that lets cloud agents connect to the MCP server without running it locally.
Getting Started
brew tap joaoh82/rustunnel
brew install rustunnelThen either install the Claude Code plugin (/plugin install rustunnel) or configure MCP manually. Check out the MCP server documentation and Claude Code plugin guide for full setup instructions.
The source code for everything — MCP server, Claude Code plugin, and OpenClaw skill — is open source on GitHub under AGPL.