Metadata-Version: 2.4
Name: tunnex
Version: 26.10.10.22
Summary: Expose localhost over HTTPS, WebSocket, TCP and UDP — built for developers and their AI agents
Home-page: https://tunnex.org
Author: Tunnex
Author-email: dev@tunnex.org
License: MIT
Project-URL: Source, https://gitlab.com/homycoder/tunnex
Project-URL: Console, https://connect.tunnex.org
Classifier: Programming Language :: Python :: 3
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Topic :: Internet :: Proxy Servers
Classifier: Topic :: Software Development
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: click>=8.1
Requires-Dist: rich>=13.0
Requires-Dist: websockets>=15.0
Requires-Dist: httpx>=0.27
Requires-Dist: fastapi>=0.115
Requires-Dist: uvicorn>=0.30
Requires-Dist: sqlalchemy[asyncio]>=2.0.30
Requires-Dist: aiosqlite>=0.19
Requires-Dist: pydantic>=2.6
Requires-Dist: pyyaml>=6.0
Requires-Dist: anthropic>=1.0
Requires-Dist: mcp<3,>=2.0
Requires-Dist: uvloop>=0.19; sys_platform != "win32"
Dynamic: author
Dynamic: author-email
Dynamic: classifier
Dynamic: description
Dynamic: description-content-type
Dynamic: home-page
Dynamic: license
Dynamic: license-file
Dynamic: project-url
Dynamic: requires-dist
Dynamic: requires-python
Dynamic: summary

# Tunnex

**The tunnel built for developers and their AI agents.** Expose localhost over HTTPS, WebSocket, TCP and
UDP in one command — then let your agent drive it over MCP, share local LLMs and MCP servers behind keys,
and understand your traffic with an AI-assisted inspector.

```bash
pip install tunnex
tunnex http 3000          # → https://<random>.tunnex.org
```

[Website](https://tunnex.org) · [Console](https://connect.tunnex.org) · [Product](docs/PRODUCT.md) ·
[APIs](docs/API.md) · [Protocol](docs/PROTOCOL.md) · [Architecture](ARCHITECTURE.md) · [Benchmarks](docs/BENCHMARKS.md)

## What you can do

| | Command |
|---|---|
| Public HTTPS URL for a local app (WebSockets, SSE and large uploads stream end to end) | `tunnex http 3000` |
| Sign in: your own subdomains, TCP/UDP, email SSO | `tunnex login` |
| Pick a subdomain (auto-reserved to your account) | `tunnex http 3000 --subdomain myapp` |
| Private demo | `--basic-auth demo:secret` · `--allow-email @company.com` · `--allow-ip 203.0.113.0/24` |
| Protect an API with keys | `tunnex http 8000 --key auto` |
| Let Claude Code / Cursor drive Tunnex | `claude mcp add tunnex -- tunnex mcp serve` |
| Share a local model (Ollama, LM Studio, vLLM, llama.cpp) | `tunnex llm` |
| Publish a stdio MCP server as a remote MCP URL | `tunnex mcp expose -- npx -y @modelcontextprotocol/server-filesystem ~/docs` |
| Raw TCP / UDP (SSH, Postgres, game servers) | `tunnex tcp 5432` · `tunnex udp 27015` |
| Your addresses | `tunnex domains` · `tunnex domains reserve myapp` |
| What's running locally | `tunnex status` |

Every tunnel records its traffic in the local **inspector** at `http://127.0.0.1:4040`:
replay and edit requests, export them as curl/Python/JS/pytest, *Explain with AI*, search in plain English,
infer an OpenAPI spec from real traffic, and serve mocks — including an offline mock that answers from
recorded traffic when your backend is down.

## For AI agents (MCP)

`tunnex mcp serve` is an MCP server with tools `start_tunnel`, `stop_tunnel`, `list_tunnels`,
`list_requests`, `get_request`, `wait_for_request`, `replay_request`, `send_request`, `set_mock`,
`clear_mock`, `set_offline_mock`, `explain_request`, `get_openapi`. The canonical loop — *"fix the Stripe
webhook handler"*: start a tunnel → give the URL to Stripe → `wait_for_request` → read the 500 → fix the
code → `replay_request` → 200. Traffic of tunnels started in other terminals is visible too.

## Sharing local AI safely

**Why not just tunnel Ollama's port?** Model servers have no authentication, expose admin endpoints
(`/api/pull`, `/api/delete` — a stranger can fill your disk or delete models), give you no per-user
accounting, and naive tunnels buffer streaming responses. `tunnex llm` adds edge-enforced API keys, an
inference-only path allowlist, per-key rate limits, true token streaming and per-key/model token usage:

```python
from openai import OpenAI
client = OpenAI(base_url="https://myllm.tunnex.org/v1", api_key="sk-tnx-...")
```

`tunnex mcp expose` bridges stdio MCP servers to Streamable HTTP (one subprocess per MCP session), behind
a secret URL (works with claude.ai / ChatGPT connectors) or a bearer key.

## AI provider for the inspector

Claude (`claude-opus-5-5`) when `ANTHROPIC_API_KEY` is set, or a local model through Ollama so traffic never
leaves your machine: `tunnex ai --provider ollama --model qwen2.5:7b`. Secrets (authorization, cookies, API
keys, password/token fields) are redacted before any prompt.

## Plans

| | Anonymous | Free account |
|---|---|---|
| Subdomain | random, sticky per machine | your choice, reserved (3) |
| Browser interstitial | yes | no |
| Edge policies | basic auth, keys, IP/path allowlists | + email SSO |
| TCP / UDP | — | yes, stable ports |
| Rate limit | 120 req/min | 1200 req/min |
| Concurrent tunnels | 3 per IP | 10 |

## Architecture in one picture

```
 browser / webhook / agent
          │ HTTPS, WSS, TCP, UDP
          ▼
 ┌──────────────── edge: <sub>.tunnex.org ────────────────┐      ┌─ control: connect.tunnex.org ─┐
 │ policies (IP, path, keys, basic, SSO) · rate limits     │      │ console · accounts · tokens   │
 │ interstitial · identity headers · streaming proxy       │      │ device login · SSO · usage    │
 └──────────────┬──────────────────────────────────────────┘      └──────────────┬────────────────┘
                │ protocol v2: binary frames, multiplexed streams, flow control   │ PostgreSQL
                ▼                                                                  ▼
 ┌──────────── tunnex client (your machine) ─────────────┐
 │ HTTP/WS/TCP/UDP → localhost · capture → ~/.tunnex     │──▶ inspector :4040 · MCP server · AI
 └───────────────────────────────────────────────────────┘
```

Details: [ARCHITECTURE.md](ARCHITECTURE.md).

## Self-hosting

Requirements: a host with a public IP, a domain with a wildcard DNS record (`*.example.com`) and a wildcard
TLS certificate, Docker with Compose.

```bash
CF_API_TOKEN=<cloudflare token with Zone:DNS:Edit> ./deploy/bootstrap-server.sh root@<host>
```

The bootstrap installs Nginx (TLS termination, streaming proxy), certbot (wildcard certificate via DNS-01),
ufw, and `/opt/tunnex/` with [docker-compose.yml](deploy/docker-compose.yml) — Tunnex server, PostgreSQL,
Prometheus and Grafana — plus a `.env` with generated secrets. Migrations run on container start. Server
settings: [server_/config.yaml.example](server_/config.yaml.example); every value can be overridden with
`TUNNEX_*` environment variables. Optional: a GitHub OAuth app
(`https://connect.<domain>/auth/github/callback`) adds "Sign in with GitHub" and enables email SSO for tunnels.

Point the client at your server with `TUNNEX_SERVER=wss://connect.example.com` (or `--server`).

Metrics are served on `127.0.0.1:9101/metrics`; the Grafana dashboard is provisioned automatically
(`ssh -L 3000:127.0.0.1:3000 <host>`).

## Development

```bash
uv venv .venv --python 3.10 && uv pip install -e . -r server_/requirements.txt pytest pytest-asyncio
.venv/bin/python -m pytest -q                       # end-to-end suite (SQLite)
TUNNEX_TEST_DATABASE_URL=postgresql+asyncpg://... .venv/bin/python -m pytest -q   # against PostgreSQL
TUNNEX_CONFIG=server_/config.yaml.example .venv/bin/python -m server_            # run a server
```

The suite starts real servers, clients and upstream apps in-process and covers streaming, flow control,
policies, accounts, SSO, TCP/UDP, MCP, LLM publishing and the AI features (with fake providers).

| Path | What |
|---|---|
| `shared/` | protocol v2 frames ([protocol.py](shared/protocol.py)) and the stream multiplexer ([mux.py](shared/mux.py)) |
| `server_/` | edge proxy, control plane API, accounts, policies, PostgreSQL models + Alembic migrations, metrics, web console |
| `client/` | CLI, tunnel client, inspector API + UI, MCP server and bridge, LLM publishing, AI features |
| `deploy/` | bootstrap script, Nginx, Compose stack, monitoring |
| `landing/` | tunnex.org |
| `bench/` | benchmark harness |

CI (GitLab): tests on every change → server image → deploy with Compose; client → PyPI; landing → rsync.

## Contact

dev@tunnex.org · MIT License
