| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Name | Name | Last commit date | ||
|---|---|---|---|---|
Language / 语言: English | 简体中文
roswire is a lightweight, JSON-first command-line bridge for AI agents and automation scripts that need to operate MikroTik RouterOS devices.
Unlike traditional CLIs designed for human interaction, roswire does not emit colors, spinners, pagers, or interactive prompts. Its contract is simple: successful results go to stdout; structured errors and diagnostics go to stderr.
Project status: MVP / beta candidate. The core JSON-first CLI, configuration, protocol routing, self-description APIs, SSH file transfer, file workflows, and release engineering are in place. Production-stable status is still gated by the real RouterOS / CHR acceptance matrix. See docs/roadmap.md for the milestone roadmap, docs/production-readiness.md for production gates, and docs/develop-plan.md for the development plan.
Prebuilt binaries are published through GitHub Releases, with a checksums.txt file attached to each release.
Linux quick install:
curl -fsSL https://raw.githubusercontent.com/AS153929/roswire/main/scripts/install.sh | shThe installer detects Linux x86_64 / arm64, downloads the matching latest release artifact, verifies checksums.txt, and installs roswire to /usr/local/bin. To install a pinned version or a user-local path:
curl -fsSL https://raw.githubusercontent.com/AS153929/roswire/main/scripts/install.sh | ROSWIRE_VERSION=v0.0.3 ROSWIRE_INSTALL_DIR="$HOME/.local/bin" sh
roswire doctor --jsonIf Rust is already installed, crates.io installation is also supported after the crate is published:
cargo install roswire --lockedThe repository also ships an optional roswire agent skill under skills/roswire. It demonstrates how an AI agent can discover roswire command schemas, run read-only RouterOS evidence collection, and summarize JSON results safely. This installs the skill only; install the roswire binary separately using one of the methods above.
Inspect the skills available in this repository:
npx skills add https://github.com/AS153929/roswire --list --full-depthIf the list shows roswire, install that specific skill:
npx skills add https://github.com/AS153929/roswire --skill roswire --full-depthInstall the roswire skill globally for all supported agents:
npx skills add https://github.com/AS153929/roswire --skill roswire --agent '*' --global --full-depth --yesInstall it for the current project instead:
npx skills add https://github.com/AS153929/roswire --skill roswire --agent '*' --full-depth --yesWhen developing from a local checkout, run this from the repository root:
npx skills add . --skill roswire --agent '*' --global --full-depth --copy --yes--full-depth is needed because the skill lives below skills/roswire/ rather than at the repository root.
For manual installation steps, Cargo installation notes, Windows PowerShell checksum verification, source builds, and uninstall instructions, see docs/installation.md. Maintainer release procedures are documented in docs/release.md.
This path starts with a fresh install, checks the local environment, creates one profile, stores the password outside shell history, and runs the first read-only RouterOS command.
curl -fsSL https://raw.githubusercontent.com/AS153929/roswire/main/scripts/install.sh | sh
roswire doctor --jsondoctor only checks the local machine by default. It does not contact RouterOS unless --include-remote is passed.
roswire config init --jsonroswire config device add studio \
host=192.168.88.1 \
user=admin \
protocol=auto \
routeros_version=auto \
transfer=ssh \
ssh_host_key=SHA256:replace-with-routeros-host-key \
allow_from=203.0.113.10/32 \
--json
roswire config profiles --json
roswire --profile studio config inspect --jsonThe env secret backend stores only the environment variable name in config.toml; the secret value stays in the current process environment.
read -rsp 'RouterOS password: ' ROSWIRE_STUDIO_PASSWORD; echo
export ROSWIRE_STUDIO_PASSWORD
roswire config secret set studio password type=env env=ROSWIRE_STUDIO_PASSWORD --jsonFor production hosts, prefer an OS keychain or encrypted secret backend when available. Store the secret with your platform keychain tool first, then save only the reference in roswire:
roswire config secret set studio password type=keychain service=roswire account=profiles/studio/password --jsonroswire --profile studio interface print --jsonIf API/REST is only reachable through an SSH bastion, set jump_host / jump_user / jump_host_key on the profile (or pass --jump-host). roswire opens direct-tcpip for this process, tears it down on exit, and records the hop in JSONL. It does not leave a local ssh -L listener.
Output (stdout) is structured JSON; errors go to stderr as one structured JSON object.
| Intent | Command |
|---|---|
| Check local setup | roswire doctor --json |
| Create or inspect profiles | roswire config init --json, roswire config profiles --json, roswire --profile studio config inspect --json |
| Store credentials safely | roswire config secret set studio password type=env env=ROSWIRE_STUDIO_PASSWORD --json or type=keychain |
| Inventory interfaces, addresses, routes, and resources | roswire --profile studio interface print --json, roswire --profile studio ip address print --json, roswire --profile studio ip route print --json, roswire --profile studio system resource print --json |
| Run unsupported read-only RouterOS print commands | roswire --profile studio raw /system/resource/print --json |
| Preview file transfers safely | roswire --profile studio file upload ./setup.rsc flash/setup.rsc --dry-run --ssh-host-key SHA256:replace-with-routeros-host-key --allow-from 203.0.113.10/32 --json |
| Reach a private RouterOS through an SSH jump | roswire --profile studio --dry-run ip address print --json after setting jump_host / jump_host_key |
Local diagnostics:
roswire doctor --jsonProfile creation and inspection:
roswire config init --json
roswire config device add studio host=192.168.88.1 user=admin protocol=auto routeros_version=auto transfer=ssh --json
roswire config profiles --json
roswire --profile studio config inspect --jsonSecret setup without command-line password values:
read -rsp 'RouterOS password: ' ROSWIRE_STUDIO_PASSWORD; echo
export ROSWIRE_STUDIO_PASSWORD
roswire config secret set studio password type=env env=ROSWIRE_STUDIO_PASSWORD --json
read -rsp 'SSH key passphrase: ' ROSWIRE_STUDIO_SSH_KEY_PASSPHRASE; echo
export ROSWIRE_STUDIO_SSH_KEY_PASSPHRASE
roswire config secret set studio ssh_key_passphrase type=env env=ROSWIRE_STUDIO_SSH_KEY_PASSPHRASE --json
roswire config secret set studio password type=keychain service=roswire account=profiles/studio/password --jsonCommon read-only RouterOS commands:
roswire --profile studio interface print --json
roswire --profile studio ip address print --json
roswire --profile studio ip route print --json
roswire --profile studio ip firewall filter print stats --json
roswire --profile studio ip firewall connection print count-only --json
roswire --profile studio system resource print --jsonRaw read-only print commands for advanced RouterOS paths:
roswire --profile studio raw /system/resource/print --json
roswire --profile studio raw /interface/print detail --json
roswire --profile studio raw /ip/dhcp-client/print detail --jsonTransfer dry runs with explicit SSH safety inputs:
roswire --profile studio file upload ./setup.rsc flash/setup.rsc \
--dry-run \
--ssh-host-key SHA256:replace-with-routeros-host-key \
--allow-from 203.0.113.10/32 \
--json
roswire --profile studio file download flash/config.rsc ./config.rsc \
--dry-run \
--ssh-host-key SHA256:replace-with-routeros-host-key \
--allow-from 203.0.113.10/32 \
--jsonroswire [global-options] <path...> <action> [key=value ...]
Configuration precedence is intentionally simple:
The local configuration directory is ~/.roswire/ by default. It contains config.toml, local logs under ~/.roswire/logs/, and keeps logs for up to 30 days. Passwords should preferably be stored in the local keychain or referenced through a secret backend; config files should store secret references only.
Device fields map to these profile keys: host, user, protocol, routeros_version, transfer, port, ssh_port, ssh_user, ssh_key, ssh_host_key, and allow_from. These device fields do not come from single-device ROS_* environment variables. Environment variables are process-level settings or secret-backend inputs only.
Process-level environment variables and secret-backend variables:
| Variable | Purpose |
|---|---|
| ROSWIRE_HOME | Override the default ~/.roswire directory, mainly for tests or portable environments. |
| ROSWIRE_DEBUG | Enable redacted debug diagnostics. |
| ROSWIRE_MASTER_KEY | Default master key for encrypted secrets; a secret key_id can point to another variable. |
| Custom variables referenced by profile secrets with type=env | For example ROSWIRE_STUDIO_PASSWORD; read only through the secret backend and never used for device field precedence. |
Passwords and SSH key passphrases use profile secrets: password, ssh_password, and ssh_key_passphrase.
Detailed docs: docs/installation.md, docs/release.md, docs/routeros-acceptance-matrix.md, and docs/production-readiness.md.
roswire is intended for agent use, so all important help and configuration inspection surfaces provide stable JSON. Agents do not need to parse human help text.
Common self-description commands:
roswire help --json
roswire help ip address add --json
roswire commands --json
roswire schema command ip address add --json
roswire schema command ip address add --remote --json
roswire schema discover --remote --json
roswire config inspect --json
roswire config profiles --json
roswire doctor --json
roswire explain-error ROS_API_FAILURE --jsonConventions:
When protocol=auto (the default), roswire performs read-only probing on first connection to determine the RouterOS version and available protocols, then routes the actual command to the best backend.
Fixed precedence:
Probe failure handling is stable: network unreachable or disabled service errors continue to the next candidate; authentication failure is terminal and does not silently retry another protocol, because doing so could hide credential problems.
api-ssl and rest validate the server certificate against the public root store by default. RouterOS ships self-signed certificates, which fail this check. To trust such a device, pin its leaf certificate's SHA-256 fingerprint (mirroring the SSH host-key pin):
When a pin is set, the connection succeeds only if the leaf certificate's SHA-256 matches (CA chain and hostname are intentionally ignored, exactly like the SSH pin). On mismatch the error reports the actual fingerprint so it can be verified out of band and pinned. With no pin set, full root-store verification is unchanged.
RouterOS v6 and v7 both support the native API, but they differ in login flows, menu fields, error returns, and available commands. roswire uses this implementation strategy:
| CLI command | Native API (v6/v7 dialects) | REST API |
|---|---|---|
| roswire ip address print | /ip/address/print | GET /rest/ip/address |
| roswire ip address add address=1.1.1.1 interface=ether1 | /ip/address/add | PUT /rest/ip/address |
| roswire ip address set .id=*1 disabled=true | /ip/address/set | PATCH /rest/ip/address/*1 |
| roswire ip address remove .id=*1 | /ip/address/remove | DELETE /rest/ip/address/*1 |
roswire supports local-client-to-RouterOS file workflows such as uploading .rsc scripts, importing configuration, generating backups, and downloading artifacts. These workflows have two layers:
Target command shapes:
roswire file upload ./setup.rsc flash/setup.rsc --transfer ssh --json
roswire import ./setup.rsc --remote-path flash/setup.rsc --ensure-ssh --allow-from 203.0.113.10/32 --cleanup --json
roswire backup download ./backup.backup --name pre-change --ensure-ssh --allow-from 203.0.113.10/32 --cleanup --json
roswire export download ./config.rsc --compact --ensure-ssh --allow-from 203.0.113.10/32 --cleanup --jsonRecommended strategy:
File transfer uses SSH only. roswire can inspect and configure /ip service ssh through API/REST: enable SSH, set the port, and merge --allow-from or profile allow_from into the service address whitelist. It never opens SSH implicitly; it may modify the device service only when --ensure-ssh is explicitly provided. Transfer cleanup can restore the original SSH service state according to policy.
Note: profile host or --host must be a routable IP address or DNS name. RouterOS MAC addresses are for Layer 2 neighbor discovery and are not supported by the current API, REST, or SSH connection paths.
The SSH transfer backend must validate the actual SSH file-transfer subprotocols supported by the target RouterOS version. Do not assume REST multipart upload support, and do not keep FTP, /tool fetch, or other transfer backends.
flowchart TD
agent[Agent / LLM]
subgraph roswire[roswire]
parser[Argument parser<br/>clap]
context[Context engine<br/>CLI / profile / config loading]
schema[Self-description and schema engine<br/>static catalog / remote overlay / cache]
router[Protocol router<br/>select API / REST from config]
discovery[First-connection probing<br/>version / capability / precedence]
classic[Native API transport<br/>TCP / TLS + sentence codec]
v6[RouterOS v6 dialect]
v7[RouterOS v7 dialect]
transfer[SSH file-transfer layer<br/>upload / download]
sshPrep[SSH service preparation<br/>enable / whitelist / restore]
parser --> context
parser --> schema
parser --> router
context --> router
context --> schema
schema -->|--remote| discovery
router --> discovery
router --> transfer
discovery -->|api / api-ssl| classic
classic --> v6
classic --> v7
transfer --> sshPrep
end
legacy6[RouterOS v6 native API]
legacy7[RouterOS v7 native API]
rest[RouterOS v7 REST API]
ssh[RouterOS SSH service]
agent -->|CLI call<br/>for example roswire ip address print --json| parser
v6 -->|raw TCP / TLS| legacy6
v7 -->|raw TCP / TLS| legacy7
discovery -->|HTTP / JSON| rest
sshPrep -->|API / REST sets /ip service ssh| discovery
transfer -->|SSH / 22| ssh
The implementation plan lives in docs/develop-plan.md. Status of the core milestones:
| Back | FazBrowse Home | New Git URL |