Before you start
For larger changes or new features, open an issue first to discuss the approach. This avoids duplicate effort and ensures the change is aligned with the project direction. For small fixes (typos, docs, minor bugs) you can go straight to a pull request.Getting started
Install dependencies
You need:
| Tool | Version | Notes |
|---|---|---|
| Rust toolchain | 1.76+ | Install via rustup |
pkg-config | any | Required by reqwest (TLS) |
libssl-dev | any | On Debian/Ubuntu: apt install libssl-dev |
| Node.js + npm | 18+ | Only needed to rebuild the dashboard UI |
| Docker | any | Required to run the test database |
Install git hooks
Run this once after cloning to activate the pre-push quality gate:Every
git push will automatically run cargo fmt checks and cargo clippy before the push is allowed.Local development
Build
Run the server locally
Generate a self-signed certificate for local testing:Run the client locally
With the server running, expose a local service:--insecure skips TLS verification — required when using the self-signed cert. Never use it against a production server.Running tests
The integration test suite spins up a real server on random ports and exercises auth, HTTP tunnels, TCP tunnels, and reconnection logic. It requires a running PostgreSQL instance.Code quality
Before opening a PR, make sure these pass:Opening a pull request
- Push your branch to your fork and open a PR against
main. - Write a clear description of what changed and why.
- Make sure CI is green — format, Clippy, and all tests.
- A maintainer will review and merge.
PR guidelines
- Keep PRs focused — one logical change per PR. Avoid bundling unrelated fixes.
- Add or update tests for any new behaviour. The integration test suite in
tests/integration/is the right place for end-to-end scenarios. - Follow existing code style —
cargo fmtis enforced by CI. - Update documentation if you change user-facing behaviour (flags, config keys, API endpoints).
Project structure
| Path | Purpose |
|---|---|
crates/rustunnel-protocol/ | Shared ControlFrame types and serialization |
crates/rustunnel-server/ | Server: control plane, HTTP/TCP edges, dashboard, TLS |
crates/rustunnel-client/ | CLI client with auto-reconnect and local port forwarding |
crates/rustunnel-mcp/ | MCP server for AI agent integration |
dashboard-ui/ | Next.js dashboard frontend |
deploy/ | Dockerfiles, compose files, systemd unit, config templates |
tests/integration/ | End-to-end tests (real server + real PostgreSQL) |
docs/ | Public documentation source |
Useful make targets
| Target | Description |
|---|---|
make build | Debug build of all workspace crates |
make release | Optimized release build |
make check | cargo fmt check + cargo clippy |
make test | Full test suite (requires make db-start) |
make db-start | Start the local PostgreSQL container |
make db-stop | Stop the local PostgreSQL container |
make install-hooks | Install the pre-push git hook |
make docker-build | Build the server Docker image |
License
By contributing you agree that your work will be licensed under the GNU AGPLv3 License.Contact
João Henrique Machado Silva- GitHub: @joaoh82
- Issues & feature requests: GitHub Issues

