Config generator for proxy tools. Medusa fetches subscription URLs, decodes their contents, parses proxy URLs (ss://, trojan://, anytls://, vmess://, vless://), and renders a backend config file. Currently the Glider backend is fully wired; it also produces a companion .rule file with DNS nameserver policies extracted from Clash-format subscriptions.
pip install -e .
# with dev tools
pip install -e ".[dev]"Python 3.8+ required.
medusa -o glider.conf
medusa -o glider.conf --backend glider --verbose
medusa -o glider.conf --config my_config.ymlFlags:
-o, --output— output file path (required). A<output>.rulefile is written alongside it.--backend— target backend (default:glider).--config— config file name or absolute path (default:config.yml).-v, --verbose— verbose logging.
Config files are resolved from medusa/configs/ unless an absolute path is given. Minimal config.yml:
subscriptions:
- https://example.com/subscription1
- https://example.com/subscription2Each subscription URL is fetched, decoded (Gzip → Base64 → URL-safe Base64 → plain text), and the resulting proxy URLs are converted using the selected backend.
Running medusa -o glider.conf produces:
glider.conf— the backend template (frommedusa/templates/<backend>_template.conf) followed by arulefile=glider.conf.ruledirective and oneforward=...line per deduplicated proxy.glider.conf.rule—dnsserver=/domain=entries built fromdns.nameserver-policyin the Clash YAML variant of each subscription (when available).
| Backend | Shadowsocks | Trojan | AnyTLS | VMess | VLESS |
|---|---|---|---|---|---|
| Glider | ✅ | ✅ | ✅ | not implemented | not implemented |
Pipeline: CLI → ConfigLoader → URLFetcher → ContentDecoder → URLParser → ProxyConverter → output file (with RulesExtractor producing the rules file in parallel).
medusa/
├── cli/ # argparse + GenerateCommand orchestrator
├── core/ # fetcher, decoder, parser, converter, rules
├── backends/ # BackendConverter ABC + per-backend handlers
├── config/ # Pydantic config model + loader
├── configs/ # default config.yml lives here
├── templates/ # <backend>_template.conf files
└── utils/ # logging, exceptions
- New backend — subclass
BackendConverterinmedusa/backends/, register it inConverterRegistry._register_default_converters(), and drop a<name>_template.confinmedusa/templates/. - New protocol — subclass
ProxyHandlerand add it to the backend's_handlersdict.
pytest # run tests
pytest --cov=medusa --cov-report=html # with coverage
black medusa/ tests/
ruff check medusa/ tests/
mypy medusa/MIT