Skip to main content

Control AI coding agents from your phone — Claude Code, Codex, and Antigravity. Self-hosted, E2E encrypted, open source.

Project description

CorvusTunnel

Control your AI coding agents from your phone, tablet, or any other computer. CorvusTunnel runs on the machine where your code lives, shows a QR code, and lets you drive Claude Code, Codex, or Antigravity from a browser anywhere.

License: MIT Python 3.10+ PyPI


What this is

CorvusTunnel is a small, self-hosted tool. You install it next to your project, start it, and scan the QR code it prints. From then on your phone (or any browser) is a terminal into the agent running on your machine. You can step away from your desk and still review diffs, answer prompts, and keep work moving.

It is free and open source, and it is run as a community project rather than a business. There is no paid plan, no account to create, no analytics, and nothing about your sessions is sold or shared. Your code and the agent's output stay on your machine; everything that leaves it is end-to-end encrypted. The project is not run for profit, and it never will be.

Quick start

pip install corvustunnel

cd /path/to/your/project
corvustunnel start

Scan the QR code that appears, and you are connected. You can also point it at a specific folder instead of the current one:

corvustunnel start --workspace /path/to/your/project

The QR code is one-time use. If nobody connects within 60 seconds the server shuts down on its own, so a stale link cannot linger — just run the command again for a fresh code.

How it works

   Your device                 Relay                 Your computer
  ┌────────────┐          ┌────────────┐          ┌────────────────┐
  │  browser   │◄────────►│  forwards  │◄────────►│  CorvusTunnel  │
  │  (xterm)   │   wss     │ ciphertext │   wss     │  FastAPI + PTY │
  └────────────┘          └────────────┘          │  agent (claude │
        ▲                                          │  / codex / agy)│
        │            end-to-end encrypted          └────────────────┘
        └──────────────────────────────────────────────────►

The browser and the server perform an ephemeral key exchange and encrypt every terminal frame. The relay in the middle only ever forwards opaque bytes; it cannot read anything that passes through it.

Features

  • Works with Claude Code, Codex CLI, and Antigravity.
  • End-to-end encryption with NaCl (X25519 key agreement, XSalsa20-Poly1305), with fresh keys per connection.
  • Connect by scanning a QR code — no URLs to copy.
  • Live terminal streaming over WebSocket, rendered with xterm.js.
  • Works on phones, tablets, and desktop browsers alike.
  • Installable as a PWA, with optional push notifications for agent events.
  • Quick-action chips and pinned favorite commands for one-tap replies.
  • Audit and forensic logging of every session, kept on your machine.
  • Hardened by default: IP bans, rate limiting, body-size limits, security headers, and spoof-resistant client-IP handling.

Connecting from outside your network

By default CorvusTunnel registers a session with a hosted relay (roost.corvustunnel.com) so your phone can reach your machine without any port forwarding. The relay is a free convenience that the project runs; because traffic is end-to-end encrypted, it only sees ciphertext.

If you would rather not use the hosted relay, you have options:

corvustunnel start --no-relay              # use a cloudflared Quick Tunnel
corvustunnel start --no-relay --no-tunnel  # LAN only, reachable on your network
corvustunnel start --host https://your.domain   # front it with your own proxy

The public port binds to 127.0.0.1 by default in relay and tunnel modes. Use --bind 0.0.0.0 to expose it on your network directly. If you put your own reverse proxy in front, set TRUSTED_PROXIES so its X-Forwarded-For header is honored — otherwise that header is ignored and the real socket address is used for bans and rate limiting.

Security

  • Every terminal frame is encrypted end to end with NaCl Box (crypto_box: X25519 plus XSalsa20-Poly1305). Only the browser and your machine hold keys.
  • Forward secrecy: both sides use ephemeral keypairs that are never written to disk and are discarded when the connection closes.
  • Access starts with a one-time boot token delivered in the QR code, which is exchanged for a session token bound to the connecting IP.
  • WebSocket connections use one-time, IP-bound tickets with a 30-second life.
  • Repeated failed attempts get the source IP rate-limited and then banned.

Found a security problem? Please email admin@kalai-tech.com privately rather than opening a public issue.

Configuration

Settings are read from the environment:

Variable Default Description
AGENT_TOKEN Auto-generated Bearer token used for authentication
ALLOWED_DIRS Home + current dir Comma-separated folders the browser may open
AUDIT_LOG_DIR ./logs Where audit logs are written
PUBLIC_PORT 8000 Public port
INTERNAL_PORT 8001 Internal, localhost-only admin port
TRUSTED_PROXIES (none) Extra IPs whose X-Forwarded-For is trusted

Useful flags: --workspace, --bind, --no-relay, --no-tunnel, --host, --claim-timeout (seconds before an unused QR expires; 0 disables), and --verbose.

Project layout

corvustunnel/
├── cli.py            command-line entry point: servers, relay, the QR code
├── boot.py           renders the QR code in the terminal
├── version.py        single source of the version string
├── apps/
│   ├── public.py     public app (port 8000): web UI and API, via the relay
│   └── internal.py   internal app (port 8001): localhost-only admin views
├── auth/             boot/session tokens, IP binding, WebSocket tickets
├── crypto/           end-to-end encryption (X25519 + NaCl Box)
├── executor/         the PTY session that runs the agent
├── routers/          HTTP and WebSocket route handlers
├── middleware/       client-IP trust, IP bans, rate limits, security headers
├── audit/            audit and forensic logging
├── config/           settings loaded from the environment
├── history/          reads past Claude / Codex / Antigravity sessions
└── static/           the built web UI
frontend/             web UI source (Svelte + Vite)
tests/                test suite

Development

git clone https://github.com/maliozturk/CorvusTunnel.git
cd CorvusTunnel
pip install -e ".[dev]"

AGENT_TOKEN=dev-token corvustunnel start --verbose
python -m pytest

The web UI lives in frontend/ (Svelte + Vite). Build it with npm install && npm run build, which writes the bundle into corvustunnel/static/.

Contributing

Contributions are welcome. See CONTRIBUTING.md for how to get set up and what to expect.

License

MIT. See LICENSE.

Links

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

corvustunnel-1.1.2.tar.gz (812.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

corvustunnel-1.1.2-py3-none-any.whl (815.2 kB view details)

Uploaded Python 3

File details

Details for the file corvustunnel-1.1.2.tar.gz.

File metadata

  • Download URL: corvustunnel-1.1.2.tar.gz
  • Upload date:
  • Size: 812.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.9

File hashes

Hashes for corvustunnel-1.1.2.tar.gz
Algorithm Hash digest
SHA256 5dccc1647cd02f400ec6b02080af7912239f029d0b5f03a0164fe9a6f6b1f539
MD5 1e7b5ef3299e7f879b0e197ec1ab5bc0
BLAKE2b-256 60f4e4172320377d38a9982b383c1b8a934c3713314c5d96328029ff3cc8f200

See more details on using hashes here.

File details

Details for the file corvustunnel-1.1.2-py3-none-any.whl.

File metadata

  • Download URL: corvustunnel-1.1.2-py3-none-any.whl
  • Upload date:
  • Size: 815.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.9

File hashes

Hashes for corvustunnel-1.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 a2048d9d6f4653a0f20712b2112b6d196a934e8b09998ba9ad87b5239d00caad
MD5 5a3c6580a6e42a9fa13b09240cfae380
BLAKE2b-256 fd28a89c9643e43abdac5aa3036b08c4659de38f5b4e17e4515faf60f33d743f

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page