MCPcopy Index your code
hub / github.com/compassvpn/agent

github.com/compassvpn/agent @main

Chat with this repo
repository ↗ · DeepWiki ↗ · + Follow
54 symbols 219 edges 14 files 23 documented · 43%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

⚠️ Caution: This project is under active development! ⚠️

Compass VPN Agent

A self-contained, Dockerized Xray VPN node. You provision the whole host with one command, and it ships its metrics back to your manager's Grafana.

Requirements

  • A fresh Debian 11+ or Ubuntu 22.04+ server, with root access.
  • The auth values from your manager setup; they go in env_file.

Full requirements are on the website.

Quick start

# 1. Get the code
git clone https://github.com/compassvpn/agent.git
cd agent

# 2. Configure it
cp env_file.example env_file
nano env_file          # paste the values from your manager setup

# 3. Bring it up
./agent.sh start

The first run installs Docker and builds the images, so give it a few minutes. Metrics should appear in your Grafana within 5 to 10 minutes.

Commands

Everything goes through ./agent.sh (run ./agent.sh help to list them):

Command What it does
./agent.sh start Set up, update, or restart everything. Run this first and any time after; it's safe to re-run.
./agent.sh stop Stop and remove the containers, networks, volumes and images.
./agent.sh update Pull the latest code and reconverge.
./agent.sh configs Print the VPN config links.
./agent.sh logs [service] Tail the container logs.
./agent.sh help Show the command list.

How it works

Two files drive everything:

  • agent.sh is the launcher you run. It makes sure uv is installed (Ansible's control side needs Python 3.12+, newer than these releases ship, and uv fetches one on its own, so there's nothing system-wide to manage), then runs the playbook from a pinned toolchain (pyproject.toml plus uv.lock) so every server gets the exact same Ansible and dependency versions.
  • agent.yml is a single Ansible playbook that provisions the host and deploys the stack, in stages.

./agent.sh start runs the playbook top to bottom:

  1. prepare: base packages, DNS and UTC timezone, kernel/network tuning (BBR, conntrack, file limits), the UFW firewall (SSH plus the service ports), and the log files and rotation.
  2. docker: installs Docker if it's missing.
  3. identifier: generates a stable per-node ID once (stored in env_file), used as a metrics label.
  4. cron: schedules the optional hourly auto-update and the periodic re-deploy and cert renewal.
  5. deploy: docker compose up -d --build to (re)start the stack.

It's idempotent, so re-running ./agent.sh start only changes what has drifted (usually just a container rebuild). Each stage is also a tag, so you can run one on its own, for example uv run --frozen ansible-playbook agent.yml --tags deploy.

The Ansible version is pinned in pyproject.toml and locked in uv.lock. To move to a newer Ansible, bump it there and run uv lock; to refresh the pinned dependencies without changing Ansible, run uv lock --upgrade. Commit both files either way.

The stack

Six containers, wired up in docker-compose.yml:

Service Role
xray-config Builds the Xray config, fetches and renews TLS certs (acme.sh and Cloudflare), runs the config self-tests. Internal only.
xray The proxy that handles all the public VPN traffic. Brings up a WireGuard tunnel for egress in warp mode.
nginx Public TLS front plus a decoy site for anything that isn't real proxy traffic.
xray-exporter Turns Xray's access log and stats API into Prometheus metrics on :9550, with GeoIP enrichment.
node-exporter Host metrics (CPU, memory, disk, network). Internal only.
metric-forwarder Runs Grafana Alloy, which scrapes the metrics above and ships them to your manager's Grafana.

Core symbols most depended-on inside this repo

_prom_label_escape
called by 11
xray-config/run.py
exec_command
called by 7
shared_lib/system.py
_river_escape
called by 6
metric-forwarder/common.py
is_debug
called by 5
shared_lib/logger.py
load_env
called by 4
shared_lib/config.py
_interruptible_sleep
called by 4
xray-config/run.py
get_identifier
called by 3
shared_lib/config.py
get_public_ip
called by 3
shared_lib/network.py

Shape

Method 25
Function 20
Route 7
Class 2

Languages

Python100%

Modules by API surface

xray-config/run.py23 symbols
xray-config/config.py15 symbols
shared_lib/xray.py4 symbols
shared_lib/system.py3 symbols
shared_lib/config.py3 symbols
metric-forwarder/common.py3 symbols
shared_lib/network.py1 symbols
shared_lib/logger.py1 symbols
metric-forwarder/alloy.py1 symbols

For agents

$ claude mcp add agent \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact