Junos MCP について
Junos MCPは、junos-opsによるJuniper Networks機器の操作をAIアシスタントに提供します。機器確認、CLI、設定、アップグレード、診断、複数機器の日次レポートに対応し、破壊的操作はドライランが初期設定です。
主な機能
- 01機器情報と到達性の確認
- 02単一・一括CLIコマンド
- 03ロールバック保護付き設定変更
- 04ファームウェアの更新とロールバック
- 05診断と機器群の日次レポート
活用シーン
- 01機器の状態とJUNOSバージョンの確認
- 02タグ付きルーターでshowコマンドを実行
- 03コミット確認付きで設定を適用
- 04更新準備の確認と診断情報の収集
MCP 対応
STDIOまたはStreamable HTTPで、互換性のあるAIクライアントにjunos-opsの機器操作を公開するMCPサーバーです。Juniper機器の情報、コマンド、設定、更新、診断、各種チェックをツールとして提供します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
26掲載時のツール一覧 · 2 週間前に更新
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| hostname | string | はい | |
| config_path | string | いいえ |
詳細
junos-mcp
English | 日本語
junos-ops 用の MCP(Model Context Protocol)サーバーです。
STDIO トランスポートを介して、Juniper Networks デバイスの操作機能を MCP 対応の AI アシスタント (Claude Desktop、Claude Code、OpenAI Codex など)に提供します。 junos-ops が人間向けの CLI ツールであるのに対し、 junos-mcp は同じ強力なエンジンを利用する AI 向けインターフェースです。
特長
デバイス情報
| ツール | 説明 | 接続 |
|---|---|---|
get_device_facts | 基本的なデバイス情報(モデル、ホスト名、シリアル番号、バージョン)を取得します | はい |
get_version | アップグレード状況を含む JUNOS バージョンを取得します | はい |
get_router_list | config.ini からルーターの一覧を取得します(タグによる絞り込みも可能) | いいえ |
health_check | サーバーバージョンと設定状況(ルーター数、異なるタグの数)を報告します。軽量で、デバイスへの接続は行いません | いいえ |
CLI コマンドの実行
| ツール | 説明 | 接続 |
|---|---|---|
run_show_command | 単一の CLI show コマンドを実行します(output_format: text/json/xml) | はい |
run_show_commands | 1 つのセッションで複数の CLI コマンドを実行します(output_format: text/json/xml) | はい |
run_show_command_batch | 複数のデバイスでコマンドを並列実行します(タグフィルターと grep_pattern に対応) | はい |
設定管理
| ツール | 説明 | 接続 |
|---|---|---|
get_config | デバイス設定を取得します(text/set/xml 形式) | はい |
get_config_diff | ロールバックバージョンとの差分を表示します | はい |
push_config | commit confirmed とヘルスチェックを使って設定をプッシュします | はい |
push_config_start / push_config_result | バックグラウンドジョブとして同じ設定のプッシュを行います。約 60 s で呼び出しを打ち切るホスト型クライアントや、コミットに時間がかかるモデル(SRX ブランチ)向けです。push_config_start はコミットを待たずに差分と job_id を返します。コミットは同じロック済みセッションで実行されます。running でなくなるまで push_config_result をポーリングしてください | はい |
アップグレード操作
| ツール | 説明 | 接続 |
|---|---|---|
check_upgrade_readiness | デバイスがアップグレード可能な状態か確認します | はい |
compare_version | 2 つの JUNOS バージョン文字列を比較します | いいえ |
get_package_info | モデル固有のパッケージファイルとハッシュを取得します | いいえ |
list_remote_files | リモートデバイスのパスにあるファイルを一覧表示します | はい |
copy_package | チェックサムを使って SCP 経由でファームウェアパッケージをコピーします | はい |
install_package | 事前チェックを行ってファームウェアをインストールします(EX2300/EX3400 向けの unlink フラグ) | はい |
rollback_package | 以前のパッケージバージョンにロールバックします | はい |
schedule_reboot | 指定した時刻にデバイスの再起動を予約します | はい |
診断
| ツール | 説明 | 接続 |
|---|---|---|
collect_rsi | モデル固有のタイムアウトで RSI/SCF を収集します | はい |
collect_rsi_batch | 複数のデバイスから RSI/SCF を並列収集します(タグフィルターに対応) | はい |
事前チェック
junos-ops check サブコマンドの各モードと同等です。3 つすべてで、
junos-ops の表示レイヤーを再利用してテーブルを描画します。
| ツール | 説明 | 接続 |
|---|---|---|
check_reachability | ホストごとの NETCONF 接続性と利用可能なディスク容量を調べます(高速:facts の取得なし、5s の TCP プローブ) | はい |
check_local_inventory | config.ini のインベントリに照らしてローカルのファームウェアチェックサムを検証します | いいえ |
check_remote_packages | デバイス上のステージ済みファームウェアのチェックサムと利用可能なディスク容量を検証します(SCP 後の検証) | はい |
日常運用
| ツール | 説明 | 接続 |
|---|---|---|
daily_brief | 複数のデバイスを並行して確認する朝のヘルスチェックです。アラーム、インターフェイスの稼働状態、過去の指定期間内(since_hours、既定値は18時間)のsyslogアラートパターン、REの二重障害([RE_FAULT]。事実情報でREの状態が誤って報告されるSRXシャーシクラスタでは確認をスキップします。クラスタノードの障害はシャーシアラームに表示されます)、および任意のinet.0ルート数ベースライン(route_baseline。例:tags=["main"], route_baseline=152)を確認します。CRITICAL/WARNING/OKのMarkdownサマリーを返します。 | はい |
daily_brief_start / daily_brief_result | 1回の呼び出しでは処理しきれない大規模な機器群向けに、同じ一括チェックをバックグラウンドジョブとして実行します(ホスト型クライアントの1回あたりの制限は約60秒です)。daily_brief_startはすぐにjob_idを返します。doneになるまでdaily_brief_resultをポーリングしてください。同期型のdaily_briefは、現在JUNOS_DEADLINE秒(既定値は45秒。0で無効化)経過後に停止し、未完了のホストをNOT CHECKEDの下に一覧表示します。 | はい |
設計による安全性
すべての破壊的操作(push_config、copy_package、
install_package、rollback_package、schedule_reboot)は、既定でドライランモード(dry_run=True)です。
変更を適用するには、AI アシスタントが明示的にdry_run=Falseを設定する必要があります。
push_configには、他のJunos MCP サーバーにはない追加の安全機能があります。
- タイムアウトを設定できるcommit confirmed(確認されない場合は自動ロールバック)
- コミット後のフォールバックヘルスチェック(ping、NETCONF稼働時間プローブ、または任意のCLIコマンド)
- ヘルスチェックが失敗した場合の自動ロールバック(コミットは確定されず、タイマーが切れるとロールバック)
no_commit=True—commit confirmedを実行しますが、意図的に最終コミットをスキップします。 JUNOSはconfirm_timeout分後に自動ロールバックします。request ...restartコマンドがないサービス(アップグレード後のEX3400のsyslogデーモンなど)の再起動に便利です。
RPCタイムアウトと1回あたりの期限。 すべてのロード/コミットRPCは、ホストのconfig.iniセクションにあるtimeoutを使用します。指定がない場合は、junos-opsモデルの既定値が使われます。SRXブランチモデル(SRX300/320/340/345など。コミットに30秒以上かかることがあります)では180秒、それ以外では120秒です。タイムアウトが短縮されることはありません。JUNOS_DEADLINEを設定すると(既定値は45秒。0で無効化)、push_configはプッシュをバックグラウンドジョブとして実行し、期限直前まで完了を待ちます。完了した場合は期限を設定しなかった場合と同じ結果を返します。完了しない場合はStill runningと、push_config_resultでポーリングするためのjob_idを返します。push_config_startはコミットを待たずに差分とjob_idを返します。ジョブは同じロック済みセッション上で変更をロードして差分を作成した後、コミットするため、コミットされる内容は返された差分と完全に一致します。commit confirmedの送信後に失敗した場合は、confirm_timeout分後にデバイスでロールバックされる可能性のある保留中のコミットとして報告されます。ホストごとに実行できるプッシュは1つだけです。2つ目のプッシュは拒否され、同じホストに対する他のツールは期限まで待機した後、host busyを返します。
必要条件
- Python 3.12+
- 有効な
config.iniを設定したjunos-ops - MCP Python SDK >= 1.0
インストール
pip install junos-mcp
または開発用:
git clone https://github.com/shigechika/junos-mcp.git
cd junos-mcp
python3 -m venv .venv
. .venv/bin/activate
pip install -e ".[test]"
CLI オプション
python -m junos_mcp --help
| オプション | 説明 |
|---|---|
-V, --version | バージョンを表示して終了します |
--check | config.ini を読み込み、ルーターを一覧表示して終了します(エラー時の終了コードは 1) |
--check-host HOSTNAME | --check と併用すると、到達可能性と認証を確認するために NETCONF セッションも開きます |
--transport {stdio,streamable-http} | トランスポートプロトコル(デフォルト:stdio) |
--host HOST / --port PORT | streamable-http 専用:待ち受けるアドレスとポート(デフォルト:127.0.0.1 / 8000)。MCP Python SDK 2.x では読み込まれなくなった FASTMCP_HOST / FASTMCP_PORT ではなく、こちらを使用してください |
--check は、AI アシスタントにサーバーを登録する前に JUNOS_OPS_CONFIG と config.ini にアクセスできることを確認するのに便利です。--check-host rt1 と組み合わせると、実際のデバイスに対して認証情報が正しく認証されることも確認できます。
タグベースのホストフィルタリング
run_show_command_batch、collect_rsi_batch、get_router_list は省略可能な tags 引数を受け取ります。文法は junos-ops --tags CLI フラグと同じです(junos-mcp 0.9.0 / junos-ops 0.16.6 以降)。
- リストの各要素は1 つのタググループです。グループ内でカンマ区切りにしたタグはANDで結合されます。
- 複数のリスト要素は、グループ間でORで結合されます。
- バッチツールで
hostnamesと組み合わせると、結果は共通部分になります(タグでフィルタリングした後、さらに名前で絞り込みます)。共通部分が空の場合はエラーが返されます。
# 1 group, 1 tag — hosts tagged "main"
run_show_command_batch(command="show route summary", tags=["main"])
# 1 group, 2 tags — AND within the group: tokyo AND edge
collect_rsi_batch(tags=["tokyo,edge"])
# 2 groups — OR across groups: main OR backup
get_router_list(tags=["main", "backup"])
# Mixed: (tokyo AND core) OR backup
run_show_command_batch(command="show version", tags=["tokyo,core", "backup"])
# Intersection: among backup-tagged hosts, only rt1/rt2
run_show_command_batch(
command="show version",
hostnames=["rt1.example.jp", "rt2.example.jp"],
tags=["backup"],
)
config.ini のセクションにタグを付ける方法と、一致判定に使われる CLI 文法については、junos-ops のタグに関するドキュメントを参照してください。
構造化出力形式
run_show_command と run_show_commands は省略可能な output_format パラメーターを受け取ります。
| 値 | 説明 |
|---|---|
"text" | デフォルト。プレーンテキストの CLI 出力(コマンドを入力したときと同じです) |
"json" | NETCONF JSON 出力 — デバイスは構造化された辞書を返します |
"xml" | NETCONF XML 出力 — デバイスは整形済み XML を返します |
注: CLI のパイプ処理(| match、| last、| count など)は、output_format にかかわらず無視されます。PyEZ の Device.cli() はコマンドを NETCONF RPC 経由で送信し、JunOS はパイプ処理を行いません。コマンドをパイプなしで実行し、代わりにクライアント側でフィルタリングしてください。単一コマンドの場合、run_show_command_batch の grep_pattern 引数(以下を参照)を使うと、単一ホストに対しても、hostnames に 1 要素のリストを渡すことで、サーバー側のようなフィルタリングを行えます。ただし、内部では常にプレーンテキスト出力を取得するため、output_format="json" / "xml" とは併用できません。また、一度に指定できるコマンドは 1 つだけなので、run_show_commands の複数コマンドの場合にそのまま代用することはできません。
# Get structured BGP summary data
run_show_command("router-a", "show bgp summary", output_format="json")
サーバー側での出力フィルタリング
run_show_command_batch は省略可能な grep_pattern 引数(Python の re パターン)を受け取ります。これを指定すると、各ホストの出力からパターンに一致する行だけが残ります。ヘッダー行(# で始まる行)は常に保持されます。一致する行がないホストには (no match) と表示されます。
この機能により、たとえば 93 台のルーターに対する show route summary のような大規模なバッチ結果を、関連する行だけ抽出して数百 KB から数百バイトに減らせます。
# Extract only the inet.0 destination count from 93 routers
run_show_command_batch(
command="show route summary",
tags=["main"],
grep_pattern=r"inet\.0:\s+\d+ destinations",
)
接続プール
junos-mcp は、ホストごとに NETCONF 接続プールを維持します。アイドル状態の
Device を再利用することで、ツールを呼び出すたびに TCP/NETCONF ハンドシェイクを行う必要がなくなります。プールは、ホストごとのロックを使って同一ホストへの同時操作を直列化します。
| 環境変数 | デフォルト | 説明 |
|---|---|---|
JUNOS_MCP_POOL | 1(有効) | 0 に設定するとプールが無効になり、呼び出しごとに新しい接続を開きます |
JUNOS_MCP_POOL_IDLE | 60 | アイドルタイムアウト(秒)。この時間を超えて使用されていない接続は、次の呼び出し時に閉じられます。退避を無効にするには 0 に設定します |
セキュリティに関する注意: プールされた接続は、長時間維持される SSH セッションです。セッション時間がポリシーで制限される環境では、JUNOS_MCP_POOL_IDLE を非アクティブ時間の上限より短い値に設定するか、JUNOS_MCP_POOL=0 に設定してプール全体を無効にしてください。
設定
このサーバーは junos-ops と同じ config.ini を使用します。詳細については、junos-ops README を参照してください。
各ツールでは、任意の config_path パラメーターを指定できます。省略した場合は、次の順序で検索されます。
- 環境変数
JUNOS_OPS_CONFIG ./config.ini~/.config/junos-ops/config.ini
実際には config.ini は必須です。デバイス接続を開かない get_router_list や health_check を含め、すべてのツールが起動時にこのファイルを読み込みます。また、ファイルが見つからない場合に正常に機能を縮退させる仕組みはありません。MCP クライアントにサーバーを登録する前に、上記3か所のいずれかに動作する config.ini を配置してください。
書き込み操作
5つのツールがデバイスの状態を変更します。それ以外のツールは読み取り専用です。これらは dry_run=True がデフォルトの5つのツールと同じです。dry-run と commit-confirmed の仕組みについては、安全性を考慮した設計を参照してください。この表では、各ツールが呼び出す処理と、それを許可するデバイス側の権限について説明します。
| ツール | API 呼び出し | 権限要件 |
|---|---|---|
push_config(およびバックグラウンド形式の push_config_start) | jnpr.junos.utils.config.Config:lock → load(format="set") → diff → commit_check → commit(confirm=confirm_timeout) → ヘルスチェック → 最終 commit → unlock | 対象ホストの config.ini アカウントには、コンフィグレーションモードと commit を許可する JUNOS ログインクラスが必要です。読み取り専用/オペレータークラスでは実行できません。クラス名は、デバイスごとに config.ini で設定されたものが使用されます。 |
copy_package | junos_ops.upgrade.copy() — チェックサム検証とコピー前のストレージクリーンアップを行い、SCP でファームウェアパッケージをデバイスに転送します | 同じアカウントに、ファイルコピー/ストレージ書き込みのアクセス権(デバイスのフラッシュへの SCP)が必要です。 |
install_package | junos_ops.upgrade.install() — バージョン確認、保留中のロールバック確認、コピーとチェックサム検証、再起動スケジュールの解除、レスキューコンフィグの保存を行った後、PyEZ SW.install() を実行します(またはフラッシュ容量の少ない EX2300/EX3400 では、unlink CLI パスを使って request system software add を実行します) | ソフトウェアのインストール権限が必要です。JUNOS の maintenance クラスまたはスーパーユーザーログインクラスが必要です。 |
rollback_package | junos_ops.upgrade.rollback() — 保留中のバージョンが存在することを確認した後にのみ、request system software rollback 相当の処理を実行します | install_package と同じ、ソフトウェア保守のための昇格権限が必要です。 |
schedule_reboot | request system reboot at <time> をスケジュールします | デバイス上で再起動/保守の権限が必要です。 |
ホストの config.ini アカウントに読み取り専用/オペレーターのログインクラスを設定した場合、この5つのツールはそのホストに対して権限エラーで失敗します。それ以外のすべてのツール(show コマンド、コンフィグの読み取り、診断、daily_brief)は引き続き動作します。このためのプラグインレベルの個別スイッチはありません。権限の境界はすべて、config.ini のアカウントに割り当てられた JUNOS ログインクラスによって決まります。
使い方
Claude Code(プラグイン)
このリポジトリは単一プラグインのマーケットプレイスも兼ねているため、Claude Code からサーバーをインストールできます。
/plugin marketplace add shigechika/junos-mcp
/plugin install junos-mcp@junos-mcp
このプラグインは uvx junos-mcp を起動し、設定で説明しているものと同じ環境変数を読み込みます。Claude Code を起動する前に JUNOS_OPS_CONFIG をエクスポートするか、config.ini を ./config.ini または ~/.config/junos-ops/config.ini に配置してください。
Claude Code を実行するプロセスの PATH に uvx が含まれている必要があります。通常、ログインシェルには含まれていますが、GUI から起動したアプリには含まれないことがあります。プラグインが起動しない場合は、uv をシステム全体にインストールしてください。
Claude Code(手動)
claude mcp add で MCP サーバーを登録します。
claude mcp add junos-mcp \
-e JUNOS_OPS_CONFIG=~/.config/junos-ops/config.ini \
-- python -m junos_mcp
--scope(-s)オプションでは、設定の保存先を指定します。
| スコープ | 説明 | 設定ファイルの場所 |
|---|---|---|
local(デフォルト) | 現在のプロジェクト。現在のユーザーのみ | ~/.claude.json |
project | 現在のプロジェクト。チームと共有 | プロジェクトルートの .mcp.json |
user | すべてのプロジェクト。現在のユーザーのみ | ~/.claude.json |
Claude Desktop
Claude Desktop の設定ファイルに追加します。
| OS | 設定ファイル |
|---|---|
| macOS | ~/Library/Application Support/Claude/claude_desktop_config.json |
| Windows | %APPDATA%\Claude\claude_desktop_config.json |
| Linux | ~/.config/Claude/claude_desktop_config.json |
{
"mcpServers": {
"junos-mcp": {
"command": "python",
"args": ["-m", "junos_mcp"],
"env": {
"JUNOS_OPS_CONFIG": "/path/to/config.ini"
}
}
}
}
編集後、Claude Desktop を再起動してください。
Codex
codex mcp add で MCP サーバーを登録します。
codex mcp add junos-mcp \
--env JUNOS_OPS_CONFIG=~/.config/junos-ops/config.ini \
-- python -m junos_mcp
STDIO サーバーを起動する他の MCP クライアントも同様に使用できます。コマンドに python -m junos_mcp を指定し、環境に JUNOS_OPS_CONFIG を設定してください。
OAuth によるリモートアクセス(mcp-stdio 経由)
junos-mcp は Streamable HTTP トランスポートに対応しており、mcp-stdio を OAuth プロキシとして使用することで、任意の MCP クライアント(Claude Desktop、Claude Code、Codex など)からリモートアクセスできます。
graph TB
A[junos-mcp<br/>remote server] <-- "OAuth 2.1 + HTTPS" --> B[mcp-stdio<br/>proxy]
B <-- "STDIO" --> C[MCP client<br/>Claude / Codex / …]
手順 1:リモートサーバー上で Streamable HTTP を使用して junos-mcp を起動する
JUNOS_OPS_CONFIG=~/.config/junos-ops/config.ini \
python -m junos_mcp --transport streamable-http
デフォルトでは、サーバーは http://localhost:8000/mcp で待ち受けます。
手順 2:ローカルマシン上で mcp-stdio を MCP サーバーとして登録する
# Claude Code
claude mcp add junos-mcp -- mcp-stdio https://your-server:8000/mcp
# Codex
codex mcp add junos-mcp -- mcp-stdio https://your-server:8000/mcp
mcp-stdio は OAuth 2.1 認証(RFC 8414 によるディスカバリー、RFC 7591 による動的クライアント登録、PKCE)を処理し、STDIO と Streamable HTTP 間のリレーを行います。
OAuth プロバイダーのセットアップを含む詳しい設定については、mcp-stdio README を参照してください。
junos-mcp が
mcp-stdio serve(ゲートウェイモード)によって起動され、MCP SDK 2.x で動作する場合は、mcp-stdio 0.43.7 以降を使用してください。古いゲートウェイは 2.x サーバーが拒否するリクエストエンベロープを転送します。その場合はmcp<2をインストールしてください。
MCP Inspector(開発)
mcp dev junos_mcp/server.py
テスト
pytest tests/ -v
23 個のツール、接続プール、ヘルパー関数、エッジケースを網羅する 133 件のテストがあります。
ライブスモークテスト
これらのテストでは PyEZ をモックするため高速ですが、その一方で、ツールが実データを返さなくなっても検知できません。
scripts/smoke_test.py は、登録されているすべてのツールを設定済みデバイスに対して実行し、空の応答、不正な形式の応答、エラー応答があると失敗します。
# uses the same inventory file as the server (JUNOS_OPS_CONFIG)
uv run python scripts/smoke_test.py
uv run python scripts/smoke_test.py --only facts --traceback
- 読み取り専用です。
push_config、push_config_start、copy_package、install_package、rollback_package、schedule_rebootは名前でスキップされ、それを強制するテストもあります。collect_rsi/collect_rsi_batchもスキップされます。これらは変更を加えませんが、アサーションで読み取ることのない応答のために、RE の CPU を数分間使用し、デバイスごとにファイルを作成します。コマンド実行ツールではshow system uptimeを実行します。これらのツールは一般にオペレーションコマンドを受け付けますが、重要なコマンドを入力するのがスモークテストであってはなりません。 - レポートにペイロードを含めません。 ツール名とステータスのみを記録します。これらのツールは対象として指定されたデバイスについてエラーテキストに記載するため、エラーテキストもペイロードと同様に伏せます。
- 仕様に環境固有の情報を含めません。 ホストごとのツールが必要とするデバイスは、実行時に設定済みインベントリから検出されます。
get_package_infoが必要とするハードウェアモデルは、そのデバイス自身のファクトから取得します。この状態を保つために、2 つのテストを用意しています。1 つはこれらのパラメーターをリテラルとして指定することを拒否し、もう 1 つは、このリポジトリが公開されているため、ファイル内のどこにもアドレス形式の値を含めることを禁止します。 - すべてのプローブは、これらのツールが例外を発生させる代わりに返す
Error: .../Connection error: ...の行を拒否します。そうしないと、到達不能なデバイスへの呼び出しが成功したように扱われてしまいます。 - CI では、低コストで実行できる部分を強制します。プローブ仕様なしで登録されたツールがあると、ビルドは失敗します(
tests/test_smoke_probes.py)。そのため、ツールを追加する際に「動作をどう確認するか」という問いが必ず生じます。 scripts/smoke_harness.pyは実行エンジンであり、JUNOS の知識を持ちません。このファイルを共有するサーバー間で同一に保つため、エンジンのバグは一度修正し、このコピーにパッチを適用するのではなく、ファイルを同期してください。
アーキテクチャ
標準出力を安全に保つ設計
junos-ops 0.14.1 以降、コア関数は構造化された dict 値を返し、標準出力には出力しません。MCP ツールは junos_ops.display.format_*() を使って出力を整形します。contextlib.redirect_stdout は不要なため、MCP STDIO JSON-RPC チャネルはクリーンな状態に保たれます。
グローバル状態の初期化
junos-ops は common.args と common.config をグローバル変数として使用します。MCP サーバーは、junos-ops のテストフィクスチャ(conftest.py)と同じパターンでこれらを初期化します。
並列実行
バッチツール(run_show_command_batch、collect_rsi_batch)は、設定可能な max_workers を使用し、junos-ops の common.run_parallel() 経由で ThreadPoolExecutor を利用します。
ライセンス
Apache License 2.0
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。