routeros-command-tree
RouterOS command tree introspection via /console/inspect API. Use when: building tools that parse RouterOS commands, generating API schemas from RouterOS, working with /console/inspect, mapping CLI commands to REST verbs, traversing the RouterOS command hierarchy, or when the user mentions inspect, command tree, RAML, or OpenAPI generation for RouterOS.
下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o routeros-command-tree.zip https://jpskill.com/download/20950.zip && unzip -o routeros-command-tree.zip && rm routeros-command-tree.zip
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/20950.zip -OutFile "$d\routeros-command-tree.zip"; Expand-Archive "$d\routeros-command-tree.zip" -DestinationPath $d -Force; ri "$d\routeros-command-tree.zip"
完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。
💾 手動でダウンロードしたい(コマンドが難しい人向け)
- 1. 下の青いボタンを押して
routeros-command-tree.zipをダウンロード - 2. ZIPファイルをダブルクリックで解凍 →
routeros-command-treeフォルダができる - 3. そのフォルダを
C:\Users\あなたの名前\.claude\skills\(Win)または~/.claude/skills/(Mac)へ移動 - 4. Claude Code を再起動
⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。
🎯 このSkillでできること
下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。
📦 インストール方法 (3ステップ)
- 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
- 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
- 3. 展開してできたフォルダを、ホームフォルダの
.claude/skills/に置く- · macOS / Linux:
~/.claude/skills/ - · Windows:
%USERPROFILE%\.claude\skills\
- · macOS / Linux:
Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。
詳しい使い方ガイドを見る →- 最終更新
- 2026-05-18
- 取得日時
- 2026-05-18
- 同梱ファイル
- 1
📖 Skill本文(日本語訳)
※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。
[Skill 名] routeros-command-tree
RouterOS コマンドツリーと /console/inspect
概要
RouterOS は、すべての設定とコマンドを階層ツリーに整理しています。CLI のすべてのパス(/ip/address/add など)は、このツリー内のノードに対応しています。/console/inspect REST エンドポイントを使用すると、ツリー全体をプログラムで探索できます。restraml(RAML/OpenAPI スキーマジェネレーター)や rosetta(MCP コマンドルックアップ)のようなツールは、この方法でデータベースを構築しています。
コマンドツリーの構造
RouterOS のコマンド階層には、4つのノードタイプがあります。
| ノードタイプ | 意味 | 例 |
|---|---|---|
dir |
ディレクトリ — 子パスを含みます | /ip, /system |
path |
パス — ナビゲート可能なレベル(多くの場合、コマンドを持ちます) | /ip/address, /interface/bridge |
cmd |
コマンド — 実行可能なアクション | add, set, print, remove, get, export |
arg |
引数 — コマンドのパラメーター | address=, interface=, disabled= |
ツリーの例
/ (root dir)
├── ip/ (dir)
│ ├── address/ (path)
│ │ ├── add (cmd)
│ │ │ ├── address (arg) — "IP address"
│ │ │ ├── interface (arg) — "Interface name"
│ │ │ └── disabled (arg) — "yes | no"
│ │ ├── set (cmd)
│ │ ├── remove (cmd)
│ │ ├── get (cmd)
│ │ ├── print (cmd)
│ │ └── export (cmd)
│ ├── route/ (path)
│ │ └── ...
│ └── dns/ (path)
│ ├── set (cmd)
│ ├── cache/ (path)
│ │ ├── print (cmd)
│ │ └── flush (cmd)
│ └── ...
├── interface/ (dir)
│ └── ...
├── system/ (dir)
│ └── ...
└── ...
/console/inspect API
エンドポイント
POST /rest/console/inspect
基本認証が必要です。すべての RouterOS 7.x バージョンで利用可能です。
リクエストタイプ
| リクエスト | 目的 | 戻り値 |
|---|---|---|
child |
パスの子をリスト表示します | {type: "child", name, "node-type"} の配列 |
syntax |
ノードのヘルプテキストを取得します | {type: "syntax", text} の配列 |
highlight |
構文ハイライトデータ | トークン化された出力(めったに使用されません) |
completion |
タブ補完の候補 | 補完候補 |
子のリスト表示
// /ip の子をリスト表示します
const children = await fetch(`${base}/console/inspect`, {
method: "POST",
headers: { ...authHeaders, "Content-Type": "application/json" },
body: JSON.stringify({
request: "child",
path: "ip",
}),
}).then(r => r.json());
// レスポンス:
// [
// { "type": "child", "name": "address", "node-type": "path" },
// { "type": "child", "name": "arp", "node-type": "path" },
// { "type": "child", "name": "cloud", "node-type": "path" },
// { "type": "child", "name": "dhcp-client", "node-type": "path" },
// { "type": "child", "name": "dns", "node-type": "path" },
// { "type": "child", "name": "route", "node-type": "path" },
// ...
// ]
構文ヘルプの取得
// /ip/address/add → address 引数の説明を取得します
const syntax = await fetch(`${base}/console/inspect`, {
method: "POST",
headers: { ...authHeaders, "Content-Type": "application/json" },
body: JSON.stringify({
request: "syntax",
path: "ip,address,add,address", // カンマ区切りのパス
}),
}).then(r => r.json());
// レスポンス:
// [{ "type": "syntax", "text": "IP address" }]
パス形式
path フィールドは、スラッシュではなくカンマ区切りのセグメントを使用します。
- ルート:
""(空文字列) /ip:"ip"/ip/address:"ip,address"/ip/address/add:"ip,address,add"/ip/address/add → address arg:"ip,address,add,address"
JavaScript の Array.toString() メソッドを使用すると、このカンマ区切り形式は配列から自然に生成されます。["ip", "address", "add"].toString() → "ip,address,add"。
ツリー走査パターン
ツリー全体を再帰的に走査するには、次の手順を実行します。
async function walkTree(path = [], tree = {}) {
const children = await fetchInspect("child", path.toString());
for (const child of children) {
if (child.type !== "child") continue;
const childPath = [...path, child.name];
tree[child.name] = { _type: child["node-type"] };
// 引数の場合、構文の説明を取得します — ただし、危険なサブツリー内では取得しません
if (child["node-type"] === "arg") {
if (DANGEROUS_PATHS.some(p => childPath.includes(p))) continue;
const syntax = await fetchInspect("syntax", childPath.toString());
if (syntax.length === 1 && syntax[0].text.length > 0) {
tree[child.name].desc = syntax[0].text;
}
}
// この子に再帰します (子の列挙は危険なサブツリー内でも安全です)
await walkTree(childPath, tree[child.name]);
}
return tree;
}
危険なパス — スキップ必須
これらのパスセグメントは、/console/inspect を介して arg ノードの構文が照会されると、RouterOS REST サーバーをクラッシュさせます。これらの名前のいずれかを含むサブツリー内の引数については、常に構文ルックアップをスキップしてください。
where, do, else, rule, command, on-error
これらは RouterOS スクリプトの構成要素です。具体的には、これらのサブツリー内の arg ノードタイプに対する fetchSyntax() は、HTTP サーバープロセスを終了させます。子の列挙(child リクエスト)は、これらのパス内でも安全です。引数の構文/説明ルックアップのみがクラッシュを引き起こします。
保守的なアプローチ(上記の例で使用されているもの)は、祖先のいずれかが危険なパスと一致する場合、引数全体をスキップします。実際の rest2raml.js 実装はこのパターンと一致しています。
const DANGEROUS_PATHS = ["where", "do", "else", "rule", "command", "on-error"];
CLI コマンド → REST 動詞マッピング
RouterOS CLI コマンドは、REST API の HTTP 動詞にマッピングされます。
| CLI コマンド | HTTP 動詞 | REST URL パターン | 注記 |
|---|---|---|---|
get (print) |
GET |
/rest/ip/address |
すべてのエントリの配列を返します |
get (single) |
GET |
/rest/ip/address/*1 |
ID による単一エントリ |
add |
PUT |
/rest/ip/address |
新しいエントリを作成します (POST ではありません!) |
set |
PATCH |
/rest/ip/address/*1 |
既存のエントリを更新します |
remove |
DELETE |
/rest/ip/address/*1 |
ID でエントリを削除します |
print |
`PO |
📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開
RouterOS Command Tree & /console/inspect
Overview
RouterOS organizes all configuration and commands in a hierarchical tree. Every path in the CLI
(like /ip/address/add) corresponds to a node in this tree. The /console/inspect REST endpoint
lets you programmatically explore the entire tree — this is how tools like restraml (RAML/OpenAPI
schema generator) and rosetta (MCP command lookup) build their databases.
The Command Tree Structure
RouterOS's command hierarchy has four node types:
| Node Type | Meaning | Example |
|---|---|---|
dir |
Directory — contains child paths | /ip, /system |
path |
Path — a navigable level (often has commands) | /ip/address, /interface/bridge |
cmd |
Command — an executable action | add, set, print, remove, get, export |
arg |
Argument — a parameter to a command | address=, interface=, disabled= |
Tree Example
/ (root dir)
├── ip/ (dir)
│ ├── address/ (path)
│ │ ├── add (cmd)
│ │ │ ├── address (arg) — "IP address"
│ │ │ ├── interface (arg) — "Interface name"
│ │ │ └── disabled (arg) — "yes | no"
│ │ ├── set (cmd)
│ │ ├── remove (cmd)
│ │ ├── get (cmd)
│ │ ├── print (cmd)
│ │ └── export (cmd)
│ ├── route/ (path)
│ │ └── ...
│ └── dns/ (path)
│ ├── set (cmd)
│ ├── cache/ (path)
│ │ ├── print (cmd)
│ │ └── flush (cmd)
│ └── ...
├── interface/ (dir)
│ └── ...
├── system/ (dir)
│ └── ...
└── ...
/console/inspect API
Endpoint
POST /rest/console/inspect
Requires basic authentication. Available on all RouterOS 7.x versions.
Request Types
| Request | Purpose | Returns |
|---|---|---|
child |
List children of a path | Array of {type: "child", name, "node-type"} |
syntax |
Get help text for a node | Array of {type: "syntax", text} |
highlight |
Syntax highlighting data | Tokenized output (rarely used) |
completion |
Tab-completion suggestions | Completion candidates |
Listing Children
// List children of /ip
const children = await fetch(`${base}/console/inspect`, {
method: "POST",
headers: { ...authHeaders, "Content-Type": "application/json" },
body: JSON.stringify({
request: "child",
path: "ip",
}),
}).then(r => r.json());
// Response:
// [
// { "type": "child", "name": "address", "node-type": "path" },
// { "type": "child", "name": "arp", "node-type": "path" },
// { "type": "child", "name": "cloud", "node-type": "path" },
// { "type": "child", "name": "dhcp-client", "node-type": "path" },
// { "type": "child", "name": "dns", "node-type": "path" },
// { "type": "child", "name": "route", "node-type": "path" },
// ...
// ]
Getting Syntax Help
// Get description for /ip/address/add → address argument
const syntax = await fetch(`${base}/console/inspect`, {
method: "POST",
headers: { ...authHeaders, "Content-Type": "application/json" },
body: JSON.stringify({
request: "syntax",
path: "ip,address,add,address", // comma-separated path
}),
}).then(r => r.json());
// Response:
// [{ "type": "syntax", "text": "IP address" }]
Path Format
The path field uses comma-separated segments (not slashes):
- Root:
""(empty string) /ip:"ip"/ip/address:"ip,address"/ip/address/add:"ip,address,add"/ip/address/add → address arg:"ip,address,add,address"
When using the JavaScript Array.toString() method, this comma-separated format is produced
naturally from an array: ["ip", "address", "add"].toString() → "ip,address,add".
Tree Traversal Pattern
To walk the entire tree recursively:
async function walkTree(path = [], tree = {}) {
const children = await fetchInspect("child", path.toString());
for (const child of children) {
if (child.type !== "child") continue;
const childPath = [...path, child.name];
tree[child.name] = { _type: child["node-type"] };
// For args, fetch the syntax description — but NOT inside dangerous subtrees
if (child["node-type"] === "arg") {
if (DANGEROUS_PATHS.some(p => childPath.includes(p))) continue;
const syntax = await fetchInspect("syntax", childPath.toString());
if (syntax.length === 1 && syntax[0].text.length > 0) {
tree[child.name].desc = syntax[0].text;
}
}
// Recurse into this child (child enumeration is safe even in dangerous subtrees)
await walkTree(childPath, tree[child.name]);
}
return tree;
}
Dangerous Paths — Must Skip
These path segments crash the RouterOS REST server when their arg nodes are queried
for syntax via /console/inspect. Always skip syntax lookups for args inside subtrees
containing any of these names:
where, do, else, rule, command, on-error
These are RouterOS scripting constructs. Specifically, fetchSyntax() on arg node-types
within these subtrees terminates the HTTP server process. Enumerating children (child request)
is safe even inside these paths — only the syntax/description lookup for arguments crashes.
The conservative approach (used in the example above) skips the entire arg when any ancestor
matches a dangerous path. The actual rest2raml.js implementation matches this pattern.
const DANGEROUS_PATHS = ["where", "do", "else", "rule", "command", "on-error"];
CLI Command → REST Verb Mapping
RouterOS CLI commands map to HTTP verbs in the REST API:
| CLI Command | HTTP Verb | REST URL Pattern | Notes |
|---|---|---|---|
get (print) |
GET |
/rest/ip/address |
Returns array of all entries |
get (single) |
GET |
/rest/ip/address/*1 |
Single entry by ID |
add |
PUT |
/rest/ip/address |
Creates new entry (not POST!) |
set |
PATCH |
/rest/ip/address/*1 |
Updates existing entry |
remove |
DELETE |
/rest/ip/address/*1 |
Deletes entry by ID |
print |
POST |
/rest/ip/address/print |
Action-style (also works as GET) |
| Other commands | POST |
/rest/path/command |
Action — reboot, flush, etc. |
Key insight: REST PUT = create, PATCH = update. This is the opposite of many REST API conventions where PUT is idempotent update and POST is create.
RAML/OpenAPI Schema Generation
When generating API schemas from the command tree:
- Walk the tree to collect all paths, commands, and arguments
- For each
cmdnode:get→ generates bothGET /path(list) andGET /path/{id}(single)add→ generatesPUT /pathwith arg-based request bodyset→ generatesPATCH /path/{id}with arg-based request bodyremove→ generatesDELETE /path/{id}- Other commands →
POST /path/command
- For each
argunder a command, generate request body properties or query parameters - The
descfield from syntax lookups becomes the description
The .proplist and .query Parameters
All POST-based command endpoints accept two special parameters:
.proplist— selects which properties to return (like SQL SELECT).query— filter expression array (like SQL WHERE)
These are RouterOS REST API conventions, not standard REST patterns.
Output Formats
The inspect tree can be converted to multiple schema formats:
inspect.json (Raw Output)
The raw tree as returned by recursive /console/inspect calls. Each node has:
{
"address": {
"_type": "path",
"add": {
"_type": "cmd",
"address": { "_type": "arg", "desc": "IP address" },
"interface": { "_type": "arg", "desc": "Interface name" }
},
"set": { "_type": "cmd", ... },
"print": { "_type": "cmd", ... }
}
}
RAML 1.0 (schema.raml)
Converted to RAML 1.0 resource/method notation:
/ip:
/address:
get:
queryParameters: ...
responses: ...
put:
body:
application/json:
properties:
address: { type: any, description: "IP address" }
/{id}:
get: ...
patch: ...
delete: ...
OpenAPI 3.0 (openapi.json)
Standard OpenAPI 3.0 schema generated from the same inspect tree (7.21.1+).
The inspect.json Data Model
Each version's inspect.json is the canonical source of truth for that RouterOS version's
command tree. It captures:
- Every navigable path in the CLI hierarchy
- Every executable command at each path level
- Every argument (parameter) for each command
- Syntax descriptions for arguments
Tools can parse inspect.json offline without needing a live router — set INSPECTFILE env var
and the schema generator will use the cached file instead of querying a router.
Common Patterns for Working with the Tree
Finding Commands at a Path
// Given an inspect.json node for /ip/address
const node = inspectData.ip.address;
// Commands are children with _type === "cmd"
const commands = Object.entries(node)
.filter(([key, val]) => val._type === "cmd")
.map(([key]) => key);
// → ["add", "set", "remove", "get", "print", "export", ...]
Finding Arguments for a Command
// Arguments of /ip/address/add
const addCmd = inspectData.ip.address.add;
const args = Object.entries(addCmd)
.filter(([key, val]) => val._type === "arg")
.map(([key, val]) => ({ name: key, description: val.desc }));
// → [{name: "address", description: "IP address"}, ...]
Traversing Directories
// Directories and paths (navigable children)
const children = Object.entries(node)
.filter(([key, val]) => val._type === "dir" || val._type === "path")
.map(([key]) => key);
Performance Notes
- Full tree traversal takes many minutes against a live router (thousands of HTTP requests,
each a separate POST to
/console/inspect). With KVM acceleration the CHR responds quickly, but the sheer number of sequential requests adds up. - Each
/console/inspectcall is a separate HTTP request — no batch API - Use
INSPECTFILEfor development/testing to avoid repeated live queries - The tree is version-specific — different RouterOS versions have different command sets
- Extra packages (container, iot, zerotier, etc.) add additional command tree branches
Additional Resources
- For REST API details: see
routeros-fundamentalsskill → REST API patterns - For running a CHR to query: see the
routeros-qemu-chrskill - For /app YAML format (a feature visible in the tree under 7.22+): see the
routeros-app-yamlskill