Welcome — connect your lab
New here? This short guide saves router login, optional VPN provider credentials (same env names as mtk init-site), and mtk-serve URL into ~/.mtk/dashboard-workspace.json on this machine (file mode 0600). You can store multiple named profiles and switch the active one below. Proxy-only testing still works if you skip router fields but set mtk-serve.
1 · What you’ll need
- Router (MikroTik) — LAN IP (often
192.168.88.1), SSH user (usuallyadmin), and password. - mtk-serve — Base URL for the testing API (default
http://127.0.0.1:8765) and token if your server requires auth. - VPN (optional) — Provider username/password for L2TP; used when you bootstrap slots / run
mtkwith site JSON that referencesenv:MTK_VPN_USER.
Already use shell env vars? You can skip this wizard — your environment is left as-is until you save here.
mtk dashboard start (default 8766). Port 8765 is usually mtk-serve, not this dashboard — paths like /api/network/conditions exist only on the dashboard.
2 · Router (SSH)
These map to MTK_HOST, MTK_USER, MTK_PASSWORD, MTK_PORT, MTK_TIMEOUT.
3 · mtk-serve (proxy API)
Maps to MTK_SERVICE_URL and MTK_SERVICE_TOKEN (same names the Python kit reads).
mtk dashboard start, if MTK_SERVICE_URL is a loopback http:// URL and that port is free, the dashboard starts mtk-serve for you in a background process (disable with MTK_DASHBOARD_AUTO_SERVE=0 or --no-auto-serve). If something else already listens on that port, use that instance or change the URL/port. mtk-serve uses MTK_HTTP_PORT (default 8765). Remote MTK_SERVICE_URL hosts are never auto-started.
HTTPS decoding — install CA (like Charles Proxy)
Shows the CA mtk-serve is using (not your full Mac keychain). Pick .p12 or PEM import — only one path is visible at a time. Full mirror under Settings.
CA on mtk-serve now
Loading certificate info…
Install or replace
4 · VPN credentials (optional)
Saved on this profile. Global values map to MTK_VPN_USER, MTK_VPN_PASSWORD, and MTK_VPN_IPSEC_SECRET (same refs as mtk init-site / site JSON). Per-endpoint rows use the same id as a key in your site’s vpn_registry (e.g. US → us.vpn.provider.net); any field you leave blank there inherits the global default. The dashboard exports MTK_VPN_ENDPOINT_CREDENTIALS (JSON) for scripts.
Global defaults
Per-endpoint overrides
Only non-empty override fields replace the global value for that endpoint id. Use Add endpoint for each region that needs its own login.
In Python: from mtk_router_sdk.config import materialize_vpn_env_for_endpoint then materialize_vpn_env_for_endpoint("US") before bootstrap or VPN ops. Sets MTK_VPN_ACTIVE_ENDPOINT when you pick a preference above.
5 · Profile name & save
Profiles are stored locally. Switch active profile here anytime; the dashboard process reapplies env vars after save.
Optional: extra MTK_* for this dashboard
One NAME=value per line (keys must start with MTK_). Applied when this profile is active — affects this dashboard process only. Switching profiles clears these keys before re-applying. mtk-serve uses its own environment at startup.
Profiles on this machine
Load workspace, pick active profile, save. Add more profiles by running the wizard again with a new name or edit JSON carefully.
Live proxy traffic
HTTP requests through mtk-serve (same as proxy log). Shows method, path, status, latency, and whether traffic was mocked or passed through. Filter by client IP in Settings → WebSocket filter.
Quick Actions
⚡ Run Scenario
Execute pre-built test flows like geo-blocking, offline recovery, error resilience
🔴 Start Recording
Capture HTTP traffic for replay testing or golden file comparison
🔗 SDK Connect
Full visibility: pipeline status, tab playbooks, and copy-ready Python / CLI / REST for every action
📖 View Documentation
Interactive guides with animated diagrams and code examples
📋 Traffic & activity
Open Network tab for a full traffic log while you shape links — verify requests still appear
Session activity
Timeline of actions from this session. Expand SDK snippet on any row for copy-ready Python / REST. Open SDK Connect for the full playbook and last mirrored code.
The router applies limits per IP. Each card below can show a different badge — that is how you see different devices on different settings. Pick one device, change it here; others keep their own rules until you reset them.
Conditions load from the dashboard API (same as the All active tab). Use Sync after Reset if the banner lags.
Preset
Profile for the editing device only.
Custom
Bandwidth, latency, loss for this IP.
Timed disconnect
Temporary block (separate from offline preset).
Reset on router
Removes queues and firewall rules for this IP (or everyone). Fixes stuck "offline" if the banner still shows a condition after you expected it cleared.
Link cockpit
Visual summary for the editing device — same data as the API, no extra tab.
Validation (configured vs router)
| Setting | Configured | Router | Status |
|---|---|---|---|
| Apply a profile and start live polling | |||
Generate traffic on the device to see rates move.
Advanced: raw stats & firewall dump
Preset atlas
Cards show each profile. Target is the device selected on Workbench.
All active conditions
Every IP the dashboard sees with shaping. Click an IP to jump back to Workbench.
Session inspector
HTTP transactions recorded by mtk-serve. Device list follows Workbench LAN refresh.
Setup
- Same Wi‑Fi as this machine.
- System proxy: phone → manual proxy → this PC’s IP, port 8888. Trust CA:
http://<PC-IP>:8888/ca.crt - Passthrough:
http://<PC-IP>:8765/v1/proxy/to/<host>/<path> - Health:
curl http://<PC-IP>:8765/healthz
Selected IPs are combined: one stream shows traffic from every checked device.
Session list is empty
Press Fetch or enable Live after the device uses the proxy.
DNS Control
Redirect domains to the proxy for interception, or block them entirely. Supports wildcards like *.example.com.
Active Rules
Create proxy rule
After you add a rule, trigger the app (or curl) against the path. Then scan the proxy log to confirm the response was rewritten.
Rule presets
Save bundles of rules on this browser and apply them in one step — built for recurring test personas (geo mocks, outage paths, slow APIs). Starters work out of the box; use Target device IP for rules that don’t hard-code a client.
Save a bundle — loads current rules from mtk-serve (same as Load rules & logs without filter).
Active rules
Recent HTTP log
Test Scenarios
One-click test flows combining network, DNS, and proxy actions. Perfect for testing app resilience.
Built-in Scenarios
Scenario Execution Log
Traffic Recording
Record HTTP traffic from a device, then replay it to create mock responses.
Recorded Sessions
Replay Session
Create proxy override rules from a recorded session to mock responses for a device.
Configuration Profiles
Profiles from MTK_PROFILES_DIR. Applies network, DNS, proxy, and VPN settings defined in YAML.
Profile Actions
SDK Connect — SQA visibility
Treat this dashboard as a living spec: see what each subsystem is doing, then drop the same calls into pytest, CI, or scripts. Below: live bridge health, per-tab cookbook, mirrored snippets from your last successful action, and how this maps to REST.
Live bridge
Your browser talks to this dashboard (/api/*, /ws). The dashboard uses MtkTestKit, which reaches MikroTik over SSH and mtk-serve over HTTP (/v1/*).
Current tab playbook
Last mirrored action
Interact with controls — successful actions publish copy-ready code here.
pytest fixture shape
Drop mirrored lines inside test_example; keep mtk as your single entry point.
Dashboard API surface
These routes power the UI — equivalent kit calls are in the playbooks. mtk-serve exposes /v1/proxy/*, /v1/network/*, etc.
| Method | Path | Area |
|---|---|---|
| GET | /api/setup/status | First-run / workspace status (no secrets) |
| GET | /api/setup/suggest-router | LAN gateway + SSH probe → suggested router IP |
| GET/POST | /api/setup/workspace | Load or save local credential profiles |
| GET/POST | /api/setup/env-ui | Curated MTK_* toggles (saved as env_ui in workspace) |
| GET | /api/health | Router + mtk-serve probe |
| GET | /api/overview | Counts + proxy snapshot |
| GET | /ws | Live ticks + log lines |
| POST | /api/network/apply | Throttle / profile / latency / loss |
| GET | /api/network/lan-devices | DHCP leases + ARP neighbors (device picker) |
| GET | /api/network/conditions | List active clients |
| GET | /api/network/live-stats?client_ip=... | Real queue/firewall counters from router |
| POST | /api/dns/redirect | Add redirect |
| GET | /api/dns/redirects | List |
| POST | /api/proxy/rule | Override / error / delay |
| GET | /api/proxy/certs/status | mtk-serve MITM CA + leaf metadata |
| POST | /api/proxy/certs/import | Install CA PEM + key on mtk-serve (HTTPS MITM) |
| GET | /api/proxy/logs | HTTP request log |
| POST | /api/scenarios/run | YAML scenario |
| POST | /api/recording/start | Begin HAR capture |
| POST | /api/profiles/apply | YAML bundle apply |
Connection Status
HTTPS decoding (MITM CA)
mtk-serve uses a CA + private key to decrypt TLS for the proxy log (Charles-style). Below is what is installed on mtk-serve today — not your whole macOS keychain. Install the same CA on test devices to trust HTTPS.
CA on mtk-serve now
Loading certificate info from mtk-serve…
Install or replace CA
One bundle file (e.g. Charles root-ca.p12). Enter the export password if the tool set one.
Separate PEM files or paste both blocks — for when you already have ca.crt and ca.key.
Quick Actions
Preferences
Environment
Toggle common MTK_* flags for this dashboard process (saved in your workspace as env_ui).
mtk-serve still uses the environment from how you launched it — restart it after changing server-side variables.