MTK Router Automation Platform — Python SDK and CLI for MikroTik RouterOS (multi-slot VPN, discovery, bootstrap, optional mtk-serve HTTP API).
Project description
MTK Router Automation Platform
Greenfield product for MikroTik RouterOS: multi-slot Wi‑Fi, per-slot VPN policy routing, discovery-driven configuration, optional AI intent API, and operator dashboard — delivered as a Python library, HTTP service, TypeScript SDK, and CLI.
Normative specification: docs/ROUTER_SDK.md (API semantics, locks, bootstrap, security model).
Documentation map
| Document | Audience |
|---|---|
| docs/README.md | Index of all docs |
| docs/CONFLUENCE_TEAM_PAGE.md | Full team page (Confluence-ready): problem statement, architecture, Python/JS guides, complete feature list, device support — share with anyone |
| docs/QUICK_START.md | 5-minute setup: get running fast |
| docs/EXAMPLES.md | Copy-paste code: Python, TypeScript, CLI |
| docs/GLOSSARY.md | Terms: slots, routing marks, bootstrap, leases |
| docs/CLI_REFERENCE.md | All CLI commands: flags, options, examples |
| docs/TROUBLESHOOTING.md | Fix common issues: connection, VPN, proxy |
| docs/ROUTER_SDK.md | Full product & technical specification |
| docs/USER_GUIDE.md | Operators: install, configure, run |
| docs/USE_CASES.md | Scenario-first: doctor, bootstrap, HTTP, leases, intents, TS client |
| docs/ADOPTION_GUIDE.md | Start here: diagrams, Python + JS snippets, SSH vs HTTP, gaps |
| docs/VPN_SETUP_AND_TEST.md | Live VPN: bootstrap, vpn-debug, slot-vpn, scripts/verify_vpn_live.py |
| docs/PROXY_TESTING.md | API proxy: intercept/modify responses per-client IP, full HTTP logging, HTTPS certs |
| docs/TESTING_SDK.md | Testing toolkit: network simulation, DNS override, profiles, scenarios, test dashboard, pytest |
| docs/PPV_TESTING_AND_MOCKING.md | PPV / entitlement: record-replay & proxy possibilities vs DRM and billing |
| docs/ENVIRONMENT.md | MTK_* env vars (SSH, HTTP service, secrets, bootstrap, strict parsing, dashboard env_ui) |
| docs/ARCHITECTURE.md | System diagram & component boundaries |
| docs/DEVELOPMENT.md | Contributors: repo layout, build, test |
| docs/TESTING_GUIDE.md | How to write and run tests (pytest -m smoke vs full pytest) |
| docs/RELEASE_PROCESS.md | Versioning, tagging, release checklist |
| docs/PUBLISHING_PYPI_AND_NPM.md | PyPI + npm: build, twine / npm publish, tokens, 2FA, errors |
| docs/COMPLIANCE_AND_PRIVACY.md | Logging, capture, AI, data handling |
| docs/AI_LOCAL_ASSISTANT.md | Local LLM (Ollama), guided first-time setup |
| docs/API_REFERENCE.md | OpenAPI, SDK doc entry points |
| docs/FEATURE_LIST.md | Complete feature inventory, gaps, quality metrics |
| docs/ROUTER_OPTIONAL_CAPABILITIES.md | What works without a router (e.g. proxy), what does not, design vs “blocking” |
| docs/ROADMAP_TESTER_FEATURES.md | Future: network simulation, chaos engineering, test scenarios |
| docs/GOVERNANCE.md | Maintainer / decision process |
| docs/rfcs/ | RFC process + templates (big design proposals) |
| docs/adr/ | ADR process + templates (record architecture choices) |
| CONTRIBUTING.md | How to contribute |
| SECURITY.md | Vulnerability reporting |
| CODE_OF_CONDUCT.md | Community standards |
| CHANGELOG.md | Release history |
| SUPPORT.md | How to get help |
| LICENSE | MIT |
Status
- Specification: docs/ROUTER_SDK.md.
- Python SDK (alpha): SSH transport, discovery, JSON site config, bootstrap engine (plan +
--apply), CLI below, pytest suite with fakes, optional HTTP service (mtk-serve), TypeScript HTTP clientclients/typescript/, optional Node.js direct-SSH clientclients/node-ssh/(nobaseUrl). - HTTP / REST (alpha): Spec-style
/v1/*routes onmtk-serve: discovery, dashboard snapshot, wireless/VPN/DHCP/policy tables, PUT/v1/config/slots, POST/v1/bootstrap(+ dry-run), slot leases (rejectorMTK_SLOT_LOCK_MODE=fifo_queue), runtime VPN (POST /v1/slots/{id}/vpn+X-Slot-Lease), per-client block (POST /v1/client/block— firewall DROP, runtime only),POST /v1/ai/intent,WS /v1/stream,GET /readyz,POST/DELETE /v1/session(SSH target override). OptionalMTK_SERVICE_TOKENenforcesAuthorization: Bearer. Static dashboard at/dashboard/. - Bootstrap + wifiwave2: Discovery records
wireless.menu_kind(wireless|wifi); bootstrap uses/interface wifisecurity + VAP menus when the profile reports wifiwave2 (syntax may still need tuning per board — validate on hardware). - OpenAPI + CI:
GET /openapi.jsonmerges core + v1 paths; GitHub Actions runs Python 3.10–3.12 (ruff, mypy, pytest),clients/typescriptnpm run build, andclients/node-sshnpm cismoke load. - Still to build / polish: slot DELETE /
PATCH /v1/config, human-in-the-loop approvals, richer DHCP/slot analytics, sniffer IPv6 / HTTP download of .pcap. CLImtk slot-vpnandmtk sniffer(IPv4 filter, capture file on router) work over SSH withoutmtk-serve. The npm HTTP client stays hand-written for ergonomics;openapi.d.tsis regenerated fromopenapi.json; CI checks drift.
Install the SDK (editable)
Requires Python 3.10 or newer (use a single python/python3 that meets that — do not run python with 3.10+ as if it were a script name).
python3 -m venv .venv && source .venv/bin/activate
python -m pip install -e ".[dev]"
# Optional: Scapy L2 ARP for vendor-agnostic LAN device lists (testing dashboard / `GET /v1/lan/host-peers`; often needs root on Linux): `pip install -e ".[dev,lan-scan]"` — see docs/ENVIRONMENT.md (`MTK_LAN_SCAPY*`).
export MTK_HOST=192.168.88.1 MTK_USER=admin MTK_PASSWORD='your-password'
mtk doctor
mtk doctor only applies to MikroTik RouterOS over SSH; if MTK_HOST points at another device, the CLI explains that instead of a generic failure.
CLI commands
| Command | Purpose |
|---|---|
mtk init-site |
Interactive wizard → writes a site JSON (-o file.json) with connection, vpn_registry, and slots explained step by step |
mtk doctor |
Discovery + human summary + JSON snapshot |
mtk doctor --site FILE |
Same, but SSH target comes from the file’s optional connection block (see below). Do not paste shell comments on the same line in zsh unless setopt INTERACTIVE_COMMENTS is on, or # … is passed as extra arguments. |
mtk interfaces |
/interface … print terse as JSON |
mtk ip |
/ip address … print terse as JSON |
mtk l2tp |
/interface l2tp-client … print terse as JSON (secrets redacted; --show-secrets to print raw) |
mtk vpn-debug [tunnel] |
L2TP print + monitor + ping + log tail — human sections by default; --json for machine output |
mtk vpn-reset [tunnel] |
Disable then enable L2TP client (drop stuck IPsec/L2TP); --pause SEC between steps |
mtk exec '/path …' |
One arbitrary RouterOS command; JSON with exit + stdout/stderr |
mtk bootstrap site.json |
Dry-run: merged plan (no changes). Add --apply to run idempotent scripts on the router (destructive — test on lab gear first). |
mtk slot-vpn --site FILE SLOT_ID GATEWAY |
Set policy-route gateway for that slot’s routing-mark (SSH). Or --ssid SSID instead of SLOT_ID (SSID must match an enabled slot in the site file). |
mtk sniffer start --site FILE --slot N --ip IPv4 |
Start /tool sniffer with filter-ip-address; .pcap on router. Or --ssid SSID instead of --slot. See mtk sniffer stop / status. |
mtk client-resolve --site FILE --ip ADDR |
Print JSON: map client IP → slot (subnets in site; SSH to router for DHCP dhcp_<id> unless --no-ssh). Pairs with HTTP GET /v1/client/resolve and POST /v1/by-client/.... |
mtk sniffer stop / mtk sniffer status |
Stop sniffer or print /tool sniffer print as JSON |
mtk client-block block IP |
Block internet for a client (firewall DROP, runtime only, no persistence) |
mtk client-block unblock IP |
Remove block for a client |
mtk client-block list / status IP |
List all blocked / check one IP |
mtk proxy set IP PATH JSON |
Set mock API response for endpoint (per-client, like Charles Proxy) |
mtk proxy error IP PATH --status 500 |
Simulate error response |
mtk proxy log |
View proxied requests with full HTTP details |
SSH settings: You can put an optional top-level connection object in the site JSON (host, username, password_ref or password, port, timeout). Values may be literals or env:VAR. If both exist, environment variables win (MTK_HOST, MTK_USER, MTK_PASSWORD, MTK_PORT, MTK_TIMEOUT) so production can override a file safely. Full env reference: docs/ENVIRONMENT.md.
Router IP without MTK_HOST: If you omit MTK_HOST and there is no connection.host in the site file, the SDK probes likely LAN routers (gateway, 192.168.88.1, etc.) for SSH. Override with MTK_HOST, or set MTK_AUTO_SSH_PROBE=0 to disable TCP probes, or MTK_SKIP_GATEWAY_DETECT=1 to prefer 192.168.88.1 when not on that subnet.
Bootstrap skips (optional): MTK_BOOTSTRAP_SKIP_SSH_SERVICE=1 skips merging slot subnets into /ip service ssh address; MTK_BOOTSTRAP_SKIP_INPUT_SSH=1 skips the guest/slot input firewall rule for SSH. MTK_BOOTSTRAP_TIMEOUT sets per-step SSH timeout seconds (default 120).
Example site file: examples/site.example.json. It is a template only (REPLACE_WITH_* placeholders, fake hostnames on purpose). Copy it to a local file (e.g. my-site.json, add to .gitignore), put your real VPN endpoints under vpn_registry, your SSIDs under slots, and keep passwords out of the file — use env:MTK_WIFI_PSK, env:MTK_VPN_USER, env:MTK_VPN_PASSWORD (or inline refs only on trusted machines). The _meta block is documentation for humans; the SDK ignores unknown top-level keys.
HTTP service (optional)
After python -m pip install -e ".[dev]" (includes Starlette/Uvicorn):
export MTK_HOST=… MTK_USER=admin MTK_PASSWORD=…
# optional: export MTK_SITE_CONFIG=/path/to/site.json
# optional: export MTK_SERVICE_TOKEN=secret # then send Authorization: Bearer …
mtk-serve # default port 8765, override with MTK_HTTP_PORT
GET /— JSON index (links to OpenAPI, dashboard, health, readyz, v1)GET /dashboard/— minimal operator UI (snapshot, doctor)GET /openapi.json— OpenAPI 3.1 (core +/v1/*)GET /healthz— livenessGET /readyz— readiness (SSH discovery succeeds)GET /v1/version— SDK versionGET /v1/doctor— discovery JSON (503if router error or missing env)/v1/...— see OpenAPI or ROUTER_SDK.md §6.2 (leases, bootstrap, intents, WebSocket stream, …)
TypeScript client
- HTTP (browser / any
fetch):clients/typescript/—MtkHttpClient+baseUrlpointing atmtk-serve(npm install && npm run buildthere). - Node without HTTP:
clients/node-ssh/—MtkSshClientusesMTK_*env and SSH (ssh2); seeclients/node-ssh/README.md.
Legacy GUI
The old CustomTkinter prototype was renamed to legacy_mikrotik_commander.py so pyproject.toml owns packaging. Run it only if you still need that UI: python legacy_mikrotik_commander.py.
Quick orientation
- Python integrators: import
mtk_router_sdk(RouterClient,SshTransport, parsers); CLImtk. - JavaScript/TypeScript integrators: npm
@mtk-router/router-client(MtkClient) → HTTPS → service (not SSH in the browser). - Operators: run
mtk-router-serviceon a trusted LAN host; use dashboard or API with TLS + auth.
License
See LICENSE.
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mtk_router_sdk-0.1.3.tar.gz.
File metadata
- Download URL: mtk_router_sdk-0.1.3.tar.gz
- Upload date:
- Size: 326.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8b55620265cdc04f8b52390a5b0aad437618cc7a196478cd434594a81e9c8a39
|
|
| MD5 |
df64d9d11f0cf2fe4fafec84ece84c69
|
|
| BLAKE2b-256 |
ced9765a944dfdd5c4bdc144ec72093b5ae4fa6c0f9d2de4a647f1a7f156b0af
|
File details
Details for the file mtk_router_sdk-0.1.3-py3-none-any.whl.
File metadata
- Download URL: mtk_router_sdk-0.1.3-py3-none-any.whl
- Upload date:
- Size: 345.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bb114fd6ddbf35b3a35a433686a4d019823ddfacb5ccc4db63023f94b3184672
|
|
| MD5 |
86bcbf9f3a3c43703cd3753c53b37ea4
|
|
| BLAKE2b-256 |
1d8f4be6aaa8f6f3b72e400d272082bb6afd2d01d381a081391501f26ddb6191
|