Cisco SD-WAN MCP Server について
Cisco Catalyst SD-WAN Manager(vManage)のファブリック情報をMCPクライアントに公開するサーバーです。デバイス状態、アラーム、経路品質、テンプレートやポリシーを参照でき、設定変更ツールは既定で無効です。
主な機能
- 01デバイスとファブリックのインベントリ
- 02デバイスの稼働状態確認
- 03アラームとイベントの参照
- 04トンネル品質の調査
- 05テンプレートとポリシーの参照
- 06変更ツールの任意有効化と確認
活用シーン
- 01到達不能な拠点デバイスの調査
- 02SD-WANアラームとイベントの確認
- 03劣化したトンネルの特定
- 04設定変更前のテンプレート確認
MCP 対応
MCPサーバーとして、vManageのインベントリ、ヘルス情報、アラーム、経路品質、テンプレート、ポリシーをツールとリソースで提供します。設定変更ツールは有効化した場合も操作ごとにユーザー確認を求めます。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
uvx cisco-sdwan-mcpSDWAN_VMANAGE_URLCisco Catalyst SD-WAN Manager URL, e.g. https://vmanage.example.com:8443SDWAN_USERNAMEvManage username. Use a dedicated read-only account.SDWAN_PASSWORDシークレットvManage password for SDWAN_USERNAME.MCP_TRANSPORTMust be stdio for this install. The server itself defaults to http; set http only when deploying it as a service.SDWAN_VERIFY_SSLVerify the vManage TLS certificate. Prefer SDWAN_CA_BUNDLE over disabling this.SDWAN_CA_BUNDLEPath to a CA bundle for a private-CA or self-signed vManage certificate.SDWAN_ENABLE_WRITESRegister the configuration-changing tools. Read-only when unset.ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。
ツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
Cisco SD-WAN MCP サーバー
cisco-sdwan-mcp は、FastMCP で構築された、
Cisco Catalyst SD-WAN Manager (vManage) 向けの MCP サーバーです。
LLM クライアントに SD-WAN ファブリックの現状を把握させます。インベントリ、 デバイスの健全性、コントロールプレーンとデータプレーンの状態、アラーム、 パス品質、テンプレート、ポリシーを確認できるため、「フランクフルトの 支店がダウンしているのはなぜですか?」と尋ねると、推測ではなく実際の コントローラーデータに基づく回答を得られます。
デフォルトでは読み取り専用です。 設定を変更するツールは、明示的に 有効化しない限り登録されません。有効化した場合でも、すべての呼び出しで 人間による承認が必要です。
目次
- 利用できる機能
- クイックスタート
- 設定
- 書き込み保護
- ツールのリファレンス
- プロンプト
- リソース
- MCP クライアントの接続
- トランスポート
- MCP クライアントの認証
- Docker
- デプロイ
- 独自のツールを追加する
- テスト
- トラブルシューティング
- プロジェクト構成
利用できる機能
| 分野 | ツール |
|---|---|
| インベントリ | list_devices、get_device、get_fabric_summary、list_inventory |
| デバイスの健全性 | check_device_health、get_system_status、get_control_connections、get_bfd_sessions、get_omp_peers、get_interfaces |
| アラームとイベント | get_alarm_summary、list_alarms、list_events |
| パス品質 | find_degraded_tunnels、get_tunnel_statistics、get_interface_statistics |
| テンプレートとポリシー | list_device_templates、get_device_template、list_feature_templates、list_policies、get_template_input_variables |
| 設定グループとプロファイル | list_config_groups、get_config_group、get_device_config_group、get_config_group_device_variables、list_feature_profiles、get_feature_profile、get_parcel、get_parcel_schema、get_device_running_config |
| 設定 (オプトイン) | attach_device_template、activate_vsmart_policy、update_parcel、update_cli_addon_config、deploy_config_group、get_task_status |
さらに、4 つのワークフロー用プロンプトと 3 つのリソースがあります。
すべてのツールに関わる設計上の決定が 3 つあります。あらかじめ把握しておくと便利です。
- レスポンスは必要な項目を抽出したもので、データをそのまま出力するものではありません。 vManage のデバイスレコードには 60 を超えるフィールドがあり、200 台のデバイスがあるファブリックではモデルのコンテキストが埋め尽くされてしまいます。各ツールは質問への回答に必要なフィールドを返し、すべての情報が必要な場合は
detailed=trueを指定できます。 - 結果には必ず件数が付随します。 すべての一覧で、該当した件数を示す
countと、実際に取得した件数を示すreturnedの両方を報告します。これにより、「デバイスが 3 台ダウンしています」と、「確認した最初の 100 台のうちデバイスが 3 台ダウンしています」を混同することがありません。 - 失敗も回答として返されます。 パスワードが間違っている、コントローラーに接続できない、ホスト名が不明といった場合も、例外を発生させるのではなく、読みやすいメッセージを返します。多くの場合、有効な選択肢も提示されます。モデルはその後、自ら修正するか、何を修正すべきかを正確に伝えることができます。
クイックスタート
前提条件
- Python 3.11+
- uv(推奨)または pip
- 接続可能な Cisco Catalyst SD-WAN Manager(vManage)と、そのアカウント
専用の vManage アカウントを作成してください。 まずは読み取り専用のロールを付与します。 アカウントの権限が実質的なセキュリティ境界となります。書き込み保護を参照してください。
インストール
実行のみが目的の場合は、PyPI からインストールします。
uvx cisco-sdwan-mcp # no install, run it straight
pip install cisco-sdwan-mcp
変更する場合は、チェックアウトからインストールします。
git clone https://github.com/pcDamasceno/cisco-sdwan-mcp.git
cd cisco-sdwan-mcp
# with uv (recommended)
uv sync --extra dev
# with pip
pip install -e ".[dev]"
設定
cp .env.example .env
入力が必要な設定は次の 3 つです。
SDWAN_VMANAGE_URL=https://vmanage.example.com:8443
SDWAN_USERNAME=automation-readonly
SDWAN_PASSWORD=...
サーバーは起動時にリポジトリのルートにある .env を読み込みます。別のファイルを読み込むには、SDWAN_ENV_FILE を設定してください。環境変数(compose の env_file、Kubernetes のシークレット)にすでに設定されている値は上書きされません。また、起動ログに使用したファイル名が記録されます。
実行
uv run python -m cisco_sdwan_mcp.server # or: python -m cisco_sdwan_mcp.server
サーバーは 0.0.0.0:8000 で HTTP 経由に起動します。MCP エンドポイントは http://localhost:8000/mcp、ヘルスプローブは http://localhost:8000/healthz、この README は http://localhost:8000/ にあります。
クライアントが接続する前に、起動ログで接続先を確認できます。
INFO cisco_sdwan_mcp.server: vManage controller: vmanage.example.com:8443 (user automation-readonly, TLS verify: True)
INFO cisco_sdwan_mcp.server: Write tools: disabled (read-only)
最初の呼び出し
MCP クライアントを接続し(MCP クライアントの接続を参照)、get_fabric_summary を呼び出してください。1 回のラウンドトリップで、認証、TLS、到達性をまとめて確認できます。
{
"total_devices": 42,
"by_type": {"vedge": 38, "vsmart": 2, "vbond": 1, "vmanage": 1},
"by_reachability": {"reachable": 40, "unreachable": 2},
"unreachable_count": 2,
"unreachable_devices": [{"host-name": "BR2-EDGE1", "system-ip": "10.0.0.12", "site-id": "1002"}]
}
設定
設定はすべて環境変数で行います。.env.example に注釈付きの設定例があります。
vManage 接続
| 変数 | デフォルト | 説明 |
|---|---|---|
SDWAN_VMANAGE_URL | — | コントローラーの URL。例:https://vmanage.example.com:8443。必須(または SDWAN_VMANAGE_HOST を使用) |
SDWAN_VMANAGE_HOST | — | 完全な URL の代わりに指定するホスト名 |
SDWAN_VMANAGE_PORT | 443 | SDWAN_VMANAGE_HOST を使用する場合のポート |
SDWAN_USERNAME | — | vManage のユーザー名。必須 |
SDWAN_PASSWORD | — | vManage のパスワード。必須 |
SDWAN_VERIFY_SSL | true | TLS 証明書の検証 |
SDWAN_CA_BUNDLE | — | CA バンドルへのパス。プライベート CA を使用する場合に適しています |
SDWAN_TIMEOUT | 60 | vManage の応答を待つ秒数 |
SDWAN_PAGE_SIZE | 100 | ツール呼び出しごとのレコード数のデフォルト上限 |
SDWAN_ENABLE_WRITES | false | 設定ツールを登録します。詳細は以下を参照してください |
サーバー
| 変数 | デフォルト | 説明 |
|---|---|---|
MCP_SERVER_NAME | cisco-sdwan-mcp | MCP クライアントに通知する名前 |
MCP_TRANSPORT | http | http または stdio |
MCP_HOST | 0.0.0.0 | バインドアドレス(HTTP のみ) |
MCP_PORT | 8000 | バインドポート(HTTP のみ) |
MCP_AUTH | none | MCP クライアント がこのサーバーに対して認証する方法 |
LOG_LEVEL | INFO | Python のログレベル |
SDWAN_USERNAME/SDWAN_PASSWORDは、このサーバーから vManage への認証に使用します。MCP_AUTHは、クライアントからこのサーバーへの認証方法を制御します。両者は無関係であり、通常はどちらも設定します。
TLS
vManage では、自己署名証明書またはプライベート CA の証明書が使われることがよくあります。推奨度の高い順に、次の方法を検討してください。
SDWAN_CA_BUNDLEにコントローラーの CA を指定します。証明書の検証は有効なままです。- CA を
certificates/に追加します。Docker ビルドによって、コンテナの信頼ストアに自動的にインストールされます。 - 制御下にあるラボ環境で、最後の手段としてのみ
SDWAN_VERIFY_SSL=falseを設定します。この設定では経路上の第三者が認証情報を読み取れるため、サーバーは設定するたびにホスト名を含む警告をログに記録します。
書き込み保護
設定を変更するツールには、2 段階のゲートがあります。
ゲート 1 — 登録時。 SDWAN_ENABLE_WRITES が未設定または false の場合、これらのツールを含むモジュールはインポートされません。ツール一覧にも表示されないため、モデルが誤操作、誤解釈、プロンプトインジェクションによって呼び出すことはありません。このサーバーはポリシーではなく、構造上読み取り専用です。
ゲート 2 — 確認。 書き込みを有効にしても、各呼び出しでは、vManage に何かが送信される前に MCP エリシテーションを通じてユーザーに確認を求め、対象のテンプレートまたはポリシーと影響を受けるデバイスを明示します。エリシテーションを実装していないクライアントが、確認なしに処理を進めることはできません。呼び出し元が confirm=true を渡さない限り呼び出しは拒否されるため、どちらの場合も判断は人間に委ねられます。
SDWAN_ENABLE_WRITES=true uv run python -m cisco_sdwan_mcp.server
WARNING cisco_sdwan_mcp.tools: SDWAN_ENABLE_WRITES=true — configuration-changing tools are registered.
Each one still requires explicit user confirmation before it runs.
実際の境界となるのは vManage アカウントです。
SDWAN_ENABLE_WRITESは、このサーバーで利用できるツールを制御するだけであり、ほかの経路を通じてそのアカウントが実行できる操作には影響しません。変更を確実に不可能にする必要がある場合は、読み取り専用の vManage ロールを使用してください。このフラグだけに頼らないでください。
vManage は設定を非同期で適用します。書き込みが task_id を返すのは、受け付けられたことを意味し、適用されたことを意味するわけではありません。完了と報告されるまで get_task_status(task_id) をポーリングしてください。
途中にレビュー手順を挟む、テンプレートをプッシュする際の想定フローは次のとおりです。
list_device_templates → find the template
get_device_template → see what it configures and who has it
get_template_input_variables → the exact per-device values (read-only preview)
check_device_health → never push to an already-broken device
attach_device_template → asks for approval, returns a task_id
get_task_status → confirm it actually landed
編集とデプロイが別々の手順となる config-group ファブリックの場合は、次のとおりです。
get_device_config_group → which group owns the device
get_feature_profile / get_parcel → find the parcel and its current values
get_parcel_schema → which parcel a setting lives in, and its shape
update_parcel → asks for approval; changes intent only
get_device_running_config → snapshot before the push
deploy_config_group → asks for approval, returns a task_id
get_task_status → confirm it landed, then re-diff the running config
ツールリファレンス
すべてのツールは limit(レコード数の上限)を受け取り、ほとんどのツールは detailed(要約項目ではなく vManage の全フィールドを返す)も受け取ります。
インベントリ
| ツール | 回答する内容 |
|---|---|
get_fabric_summary() | タイプ、到達可能性、バージョン別のデバイス数と、到達不能なすべてのデバイスです。自由形式の質問はまずこれを使用してください。 |
list_devices(device_type, reachability, site_id) | vManage が現在通信しているデバイスです。 |
get_device(device) | 1 台のデバイスの完全なレコードです。ホスト名、システム IP、またはシャーシ番号を指定できます。 |
list_inventory(category, unattached_only) | プロビジョニング済みのすべての項目です。オンボーディングされていないデバイス、無効な証明書を持つデバイス、テンプレートが割り当てられていないデバイスも含みます。 |
デバイスのヘルス
| ツール | 回答する内容 |
|---|---|
check_device_health(device) | 1 回の呼び出しでトリアージできます。システムの状態、コントロール接続、BFD と、問題の内容を示す problems リストを返します。 |
get_system_status(device) | 稼働時間、CPU、メモリ、ディスク、最後の再起動理由です。 |
get_control_connections(device) | vSmart/vBond/vManage への接続です。デバイスが起動しない場合は、まず確認してください。 |
get_bfd_sessions(device, state) | ほかのエッジへのデータプレーン トンネルです。サイトからコントローラーには到達できるものの、サイト間で通信できない場合に確認してください。 |
get_omp_peers(device) | OMP ピアリングです。コントロールがアップしているのに OMP がダウンしている場合、オーバーレイルートはありません。 |
get_interfaces(device, vpn_id, interface_name) | インターフェースの状態、アドレス設定、エラーカウンターです。 |
これらは vManage 経由でデバイスをポーリングするため、ライブ状態を反映しますが、エッジへの往復通信が発生します。3 回に分けて呼び出すより、check_device_health を優先してください。
アラームとイベント
| ツール | 回答する内容 |
|---|---|
get_alarm_summary(hours) | 重大度とコンポーネント別の件数、上位ルール、影響を最も受けているデバイスです。低コストなので、一覧を取得する前に呼び出してください。 |
list_alarms(hours, severity, active_only) | アラームそのものです。 |
list_events(hours, severity, component) | 生のイベントストリームです。ノイズは多くなりますが、アラームにならなかったフラップや状態遷移を確認できます。 |
パス品質
| ツール | 回答する内容 |
|---|---|
find_degraded_tunnels(hours, max_loss_percent, max_latency_ms, max_jitter_ms) | しきい値を超えたトンネルを、悪いものから順に返します。それぞれ、どのしきい値に違反したかも示します。 |
get_tunnel_statistics(device, hours) | トンネルごとの損失、遅延、ジッター、vQoE の生データです。 |
get_interface_statistics(device, hours, interface_name) | スループットとエラーカウンターの履歴です。 |
これらは vManage の統計データベースを読み取るため高速ですが、データの鮮度は最後の収集サイクルに依存します(ほとんどのデプロイでは 30 分ごとです)。ライブ状態を確認するには、デバイスのヘルスツールを使用してください。
テンプレートとポリシー
| ツール | 説明 |
|---|---|
list_device_templates(device_type, attached_only) | テンプレートと、それぞれのアタッチ数。 |
get_device_template(template_id) | 1つのテンプレートの定義と、アタッチされているデバイス。 |
list_feature_templates(template_type) | 構成要素。 |
list_policies(policy_scope) | 集中型(vSmart)またはローカライズされたポリシーと、アクティブなポリシー。 |
get_template_input_variables(template_id, device_ids) | アタッチによって適用される値の読み取り専用プレビュー。 |
Config グループとフィーチャープロファイル
UX-2.0 の構成モデルでは、config グループにフィーチャープロファイル
(system、transport、service、cli、policy-object)がまとめられます。各プロファイルには
実際の構成データであるパーセルが含まれ、デバイスは最大1つの
グループに所属します。この方式で管理されているファブリックでは、テンプレートエンドポイントから
有用な情報は得られません。これらのツールが同等の機能を提供します。vManage は WAN エッジの
インベントリで所属グループを "managed-by": "Config-Group <name>" として報告し、
get_device と list_inventory にも同じ情報が表示されます。
| ツール | 説明 |
|---|---|
list_config_groups() | グループ、各グループのプロファイル、デバイス数、最新状態。 |
get_config_group(group) | 名前または ID で指定した1つのグループと、そのメンバーデバイスおよびデプロイ待ちのデバイス。 |
get_device_config_group(device) | デバイスを管理するグループと、テンプレートを適用してはならないかどうか。 |
get_config_group_device_variables(group, device_ids) | デプロイ時に解決されるデバイスごとの値。get_template_input_variables に相当する config グループ用ツールです。 |
list_feature_profiles(profile_type) | 1種類または5種類すべてのプロファイル。 |
get_feature_profile(profile_type, profile_id) | 各ノードにすぐ使える parcelPath を含むパーセルツリー。 |
get_parcel(profile_type, profile_id, parcel_path, parcel_id) | 1つのパーセルのペイロード、つまり実際の設定項目。 |
get_parcel_schema(profile_type, parcel_path) | パーセルの種類に設定できるすべてのフィールド。編集前に確認してください。 |
get_device_running_config(device) | デプロイ前後の差分を確認するための、デバイスの現在の構成。 |
書き込みが有効な場合、テンプレートのプッシュに相当する config グループ用ツールは、
update_parcel(構造化された設定項目を読み取り・変更・書き戻し)、
update_cli_addon_config(CLI アドオンプロファイル内の生の IOS-XE 行を追加または置換し、差分を返します)、
deploy_config_group(指定したメンバーデバイスにグループをプッシュします。実稼働環境に影響する唯一のステップです)です。
編集後、デプロイされるまでメンバーには configGroupUpToDate: false が設定されます。
attach_device_template は config グループが管理するデバイスへの適用を拒否するため、
2つの構成モデルが同じデバイスを取り合うことはありません。
プロンプト
エンジニアが実際に作業する順序(データプレーンの前にコントロールプレーン、結論の前に証拠)を 反映した、再利用可能なワークフローです。
| プロンプト | 用途 |
|---|---|
troubleshoot_device(device, symptom) | 実際の原因が見つかった時点で停止する、構造化されたデバイスのトリアージ |
fabric_health_report(hours) | デバイス、アラーム、パス品質、推奨事項をまとめたファブリック全体のレポート |
analyse_path_quality(hours, site) | トンネルのパフォーマンスを色/サイト/デバイス別にグループ化し、原因を特定 |
review_template_change(template_id) | 明示的な実施可否判断を含む変更前レビュー。推奨のみを行い、アタッチはしません |
リソース
| URI | 内容 |
|---|---|
sdwan://config | 現在有効な接続設定(コントローラー、ユーザー、TLS モード、書き込みの有効/無効)。パスワードは含まれません。 |
sdwan://devices | デバイスごとのステータスを含む、現在のファブリックインベントリ |
sdwan://device/{identifier} | ホスト名またはシステム IP で指定した、1台のデバイスの完全なレコード |
MCP クライアントの接続
Claude Desktop(claude_desktop_config.json)
{
"mcpServers": {
"cisco-sdwan": {
"url": "http://localhost:8000/mcp"
}
}
}
VS Code(GitHub Copilot)— .vscode/mcp.json
{
"servers": {
"cisco-sdwan": {
"type": "http",
"url": "http://localhost:8000/mcp"
}
}
}
トークン認証を有効にする場合
{
"mcpServers": {
"cisco-sdwan": {
"url": "http://localhost:8000/mcp",
"headers": { "Authorization": "Bearer dev-token" }
}
}
}
OAuth モード(github、google、oauth-proxy、…)ではヘッダーは不要です。
MCP クライアントがフローを検出し、ログイン画面を自動で開きます。
stdio(ローカルサブプロセス)
PyPI からインストールする場合 — クローンは不要です。初回実行時に uvx がパッケージを取得します。
{
"mcpServers": {
"cisco-sdwan": {
"command": "uvx",
"args": ["cisco-sdwan-mcp"],
"env": {
"MCP_TRANSPORT": "stdio",
"SDWAN_VMANAGE_URL": "https://vmanage.example.com:8443",
"SDWAN_USERNAME": "automation-readonly",
"SDWAN_PASSWORD": "..."
}
}
}
}
チェックアウトから実行する場合:
{
"mcpServers": {
"cisco-sdwan": {
"command": "uv",
"args": ["run", "python", "-m", "cisco_sdwan_mcp.server"],
"cwd": "/absolute/path/to/cisco-sdwan-mcp",
"env": {
"MCP_TRANSPORT": "stdio",
"SDWAN_VMANAGE_URL": "https://vmanage.example.com:8443",
"SDWAN_USERNAME": "automation-readonly",
"SDWAN_PASSWORD": "..."
}
}
}
}
トランスポート:HTTP と stdio
- HTTP(デフォルト) — デプロイ用のトランスポートです。多数のクライアントに同時に対応し、ロードバランサーの背後で動作します。また、
MCP_AUTHが適用される唯一のトランスポートです。deploy/内のすべての設定は HTTP を前提としています。 - stdio — デスクトップクライアントがサーバーをサブプロセスとして起動する、ローカルでの単一ユーザー利用向けです。ネットワークリスナーがないため、
MCP_HOST/MCP_PORTとMCP_AUTHは適用されません。プロセスは OS ユーザーによって保護されます。
MCP_TRANSPORT=stdio uv run python -m cisco_sdwan_mcp.server
どこかにデプロイする場合や複数のユーザーにサービスを提供する場合は HTTP を使用してください。自分のマシンで 1 つのクライアントを使う場合は、どちらでも動作します。
MCP クライアントの認証
このサーバーへのクライアントの認証はデフォルトで無効になっており、起動時に MCP_AUTH で選択します。ファクトリーは cisco_sdwan_mcp/auth.py にあり、すべてのモードは FastMCP の組み込みプロバイダーを利用します。
MCP_AUTH | 用途 |
|---|---|
none(デフォルト) | ローカル開発、またはネットワークレベルで保護されている環境(IAM、VPN、mTLS) |
static | 固定ベアラートークン — 簡単なテスト専用。本番環境では使用しないでください |
jwt | JWT を発行する IdP(Keycloak、Okta、Entra ID、Cognito など)をすでに利用している場合 |
introspection | IdP が不透明トークン(RFC 7662)を発行する場合 |
oauth-proxy | 任意の OAuth プロバイダーを介した OAuth 2.1 の完全なログインフロー |
github、google、azure、auth0、workos | ホスト型 ID プロバイダーを介した、事前設定済みの完全なログインフロー |
# Development tokens (never in production — tokens sit in plain env vars)
MCP_AUTH=static MCP_AUTH_STATIC_TOKENS=dev-token uv run python -m cisco_sdwan_mcp.server
# JWT via your IdP's JWKS endpoint
MCP_AUTH=jwt
MCP_AUTH_JWKS_URI=https://idp.example.com/realms/main/protocol/openid-connect/certs
MCP_AUTH_ISSUER=https://idp.example.com/realms/main
MCP_AUTH_AUDIENCE=cisco-sdwan-mcp
すべてのモードの変数リファレンスについては、.env.example をご覧ください。
注意事項:
- 認証が適用されるのは HTTP トランスポートのみ です。
/healthzと/は公開のままです。プローブやユーザーはトークンを持たないためです。有効なトークンがない場合、MCP エンドポイントは401を返します。- 本番環境で OAuth フローを使用するには、公開 URL で HTTPS が必要です。
- 独自の方式を追加するには、
cisco_sdwan_mcp/auth.pyにビルダーを作成し、_BUILDERSに登録してください(プロバイダーのドキュメント)。
WAN トポロジーを公開するサーバーを、到達可能なネットワーク上で
MCP_AUTH=noneにして実行してはいけません。deploy/README.mdをご覧ください。
Docker
cp .env.example .env # fill in vManage URL and credentials
docker compose up -d --build
または、手動で実行します:
docker build -t cisco-sdwan-mcp .
docker run -p 8000:8000 \
-e SDWAN_VMANAGE_URL=https://vmanage.example.com:8443 \
-e SDWAN_USERNAME=automation-readonly \
-e SDWAN_PASSWORD=... \
cisco-sdwan-mcp
ヘルパースクリプトはイメージをビルドし、同じ名前のコンテナーがあれば置き換えて、.env を渡しながら http://localhost:8000/mcp でサーバーを起動します。
bash scripts/run_docker.sh # Linux/macOS
.\scripts\run_docker.ps1 # Windows PowerShell
イメージには /healthz を確認する HEALTHCHECK が含まれているため、docker ps ですぐにコンテナーのヘルス状態を確認できます。
社内 CA 証明書
ルート CA の .crt/.pem ファイルを certificates/ に配置してください。ビルド時にコンテナーの信頼ストアへ追加され、update-ca-certificates が自動的に実行されます。これにより、TLS を傍受するプロキシ と、社内 CA が署名した vManage 証明書 の両方に対応します。不要な場合は、ディレクトリを空のままにしてください。
プロキシを使用する場合、HTTP_PROXY/HTTPS_PROXY/NO_PROXY は Docker のビルド引数としてあらかじめ定義されているため、Dockerfile を編集する必要はありません。
docker build --build-arg HTTPS_PROXY=http://proxy.example.com:8080 -t cisco-sdwan-mcp .
docker run -p 8000:8000 -e HTTPS_PROXY=http://proxy.example.com:8080 cisco-sdwan-mcp
デプロイ
コンテナーは /healthz プローブを備えたポート 8000 の標準的な HTTP サーバーなので、どこでも実行できます。deploy/ には Kubernetes のマニフェスト一式、Helm チャート、Styrmin ドライバー、Cloud Run サービス定義が含まれています。管理ネットワーク上のコントローラーにクラウドから接続する方法、プライベート CA の取り扱い、vManage のアカウントごとのセッション制限など、SD-WAN 固有の内容を含む詳細な手順については、deploy/README.md をご覧ください。
kubectl apply -k deploy/kubernetes
helm install sdwan-mcp oci://ghcr.io/pcdamasceno/charts/cisco-sdwan-mcp \
--set sdwan.vmanageUrl=https://vmanage.example.com:8443
gcloud run services replace deploy/cloud-run-service.yaml --region europe-west3
このリポジトリは Styrmin のアプリケーションドライバーでもあります。ルートにある driver.styrmin.yml と values.j2.yml は、Styrmin がリポジトリをクローンする際に読み込むファイルです。deploy/styrmin.md をご覧ください。
/healthz は意図的に vManage をチェックしません。一時的なコントローラーの停止によってポッドが再起動することはありません。ツールは呼び出しごとに問題を報告し、サーバーは自動的に復旧します。
独自のツールの追加
機能は、関心事ごとに1つのモジュールを含む3つのパッケージに配置されています。各パッケージの
__init__.py はモジュールをインポートしてデコレーターを実行するため、新しいモジュールを追加したら、インポート行を1行追加します。
# cisco_sdwan_mcp/tools/my_tools.py
from cisco_sdwan_mcp.sdwan.client import get_client
from cisco_sdwan_mcp.sdwan.formatting import envelope, project
from cisco_sdwan_mcp.tools._helpers import resolve_device_id, sdwan_tool
@sdwan_tool
async def get_dhcp_leases(device: str, limit: int = 100) -> dict:
"""Show DHCP leases the device is serving.
Args:
device: Hostname, system IP or chassis number.
limit: Maximum leases to return.
"""
system_ip = await resolve_device_id(device)
client = await get_client()
records = await client.get_data(
"/dataservice/device/dhcp/server", {"deviceId": system_ip}
)
fields = ("ifname", "address", "client-id", "state", "expires")
return envelope(project(records, fields), limit=limit, device=device)
次に、cisco_sdwan_mcp/tools/__init__.py のインポート一覧に my_tools を追加します。
@mcp.tool ではなく @sdwan_tool を使用してください。ツールの登録に加えて、
SD-WAN の障害を読みやすい {"error", "message"} の結果に変換します。再実装するのではなく、
共通ヘルパーを利用してください。
| ヘルパー | 目的 |
|---|---|
resolve_device_id(device) | ホスト名/システム IP/シャーシ → vManage のリアルタイムエンドポイントが必要とするシステム IP |
client.get_data(path, params) | vManage の {"data": [...]} エンベロープを取得して展開する |
project(records, fields) | 幅の広いレコードを重要な情報に絞り込む |
envelope(records, limit=...) | count/returned/切り捨てに関する注記を追加する |
build_query(hours=..., rules=...) | アラーム/イベント/統計に必要な JSON の query パラメーターを構築する |
count_by(records, field) | フィールドの値を集計して要約する |
モデルがツールを呼び出すかどうかを判断する際に参照するのは docstring です。
アクセスするエンドポイントだけでなく、そのツールがどのような質問に答えるのかを記述してください。書き込み
操作は config_tools.py にまとめ、登録ゲートで引き続き制御できるようにしてください。
テスト
uv run pytest # or: pytest
テストスイートは実際のコントローラーではなく、偽の vManage(httpx.MockTransport)を使って実行されるため、
現場で実際に問題となるケースを網羅できます。
- ログインハンドシェイク。vManage が HTTP 200 と HTML 本文で失敗したログインに応答する場合も含みます
- CSRF トークンの処理と、トークンのエンドポイントがない 19.2 より古いコントローラー
- セッション中の有効期限切れ → 透過的に1回再ログインして再試行
- エラーの変換:到達不能なホスト、タイムアウト、403、JSON 以外の応答
- すべての読み取りツールのフィルタリング、射影、切り捨て
- 書き込みゲート。新しいインタープリターで検証し、
SDWAN_ENABLE_WRITES=trueがない場合は構成ツールが 使用できず、設定した場合は使用できることを確認します - 書き込みの確認:確認を拒否した場合、または確認を求められないクライアントの場合、vManage への HTTP 呼び出しは 発生しません
tests/conftest.py に偽のコントローラーがあります。独自のツールを作成する際の例として使用してください。
トラブルシューティング
| 症状 | 原因と対処法 |
|---|---|
ConfigurationError: No controller configured | SDWAN_VMANAGE_URL(または SDWAN_VMANAGE_HOST)が設定されていません。 |
AuthenticationError: rejected the credentials | ユーザー名またはパスワードが間違っているか、アカウントがロックされています。パスワードが間違っている場合、vManage はログインページを HTTP 200 で返します。クライアントはこれを検知し、認証エラーとして報告します。 |
AuthenticationError: may lack the required role | 認証には成功しましたが、そのアカウントには対象のエンドポイントを利用する権限がありません。テンプレートとポリシーのエンドポイントには、基本的な読み取り専用ロールよりも強い権限が必要です。 |
AuthenticationError: issued no JSESSIONID cookie | URL が vManage 自体ではなく、Cookie を除去するプロキシを指しています。 |
APIError: cannot reach <host> | DNS、ルーティング、ファイアウォール、またはポートの誤りが原因です。vManage は通常、443 ではなく 8443 で待ち受けます。 |
APIError: timed out after 60s | リアルタイムエンドポイントは、デバイス自体をポーリングします。SDWAN_TIMEOUT の値を増やすか、クエリの対象を 1 台のデバイスに絞ってください。 |
| TLS /証明書の検証に失敗する | プライベート CA が原因です。SDWAN_CA_BUNDLE を設定するか、CA を certificates/ に追加してください。SDWAN_VERIFY_SSL=false は、ラボ環境でのみ使う最後の手段です。 |
APIError: response was not valid JSON | 対象のエンドポイントがこのバージョンの vManage に存在しません。API パスはリリースによって異なります。 |
| 書き込みツールが「存在しない」 | 想定される動作です。SDWAN_ENABLE_WRITES が true ではありません。 |
書き込みが applied: false を返し、confirm=True を案内する | クライアントは MCP のエリシテーションに対応していないため、承認を求めることができません。 |
| エラーはないのに、どこでも結果が空 | アカウントの対象範囲が、デバイスのないテナントまたはデバイスグループに限定されている可能性があります。sdwan://config を確認し、list_inventory を試してください。 |
詳細を確認するには、LOG_LEVEL=DEBUG を設定してください。vManage のエラー本文は詳細な場合があります。共有環境でデバッグログを有効にする前に、実際に返される内容を確認してください。
プロジェクト構成
.
├── cisco_sdwan_mcp/
│ ├── mcp.py ← Shared FastMCP instance, auth wiring, /healthz
│ ├── auth.py ← MCP client authentication factory (MCP_AUTH)
│ ├── server.py ← Entry point: transport selection, startup logging
│ ├── sdwan/ ← vManage integration layer (no MCP knowledge)
│ │ ├── config.py ← SDWAN_* settings
│ │ ├── client.py ← Async client: login, CSRF, session recovery
│ │ ├── formatting.py ← Projection, envelopes, vManage query builder
│ │ └── errors.py ← Exception hierarchy
│ ├── tools/
│ │ ├── _helpers.py ← @sdwan_tool, device resolution
│ │ ├── inventory_tools.py ← Devices and fabric summary
│ │ ├── monitoring_tools.py ← Control plane, BFD, OMP, interfaces, health
│ │ ├── alarm_tools.py ← Alarms and events
│ │ ├── statistics_tools.py ← Tunnel and interface statistics
│ │ ├── template_tools.py ← Templates and policies (read-only)
│ │ ├── config_group_tools.py ← Config groups, feature profiles, parcels (read-only)
│ │ ├── config_tools.py ← Template/policy writes — imported only when enabled
│ │ └── config_group_write_tools.py ← Parcel/CLI/deploy writes — same gate
│ ├── resources/sdwan_resources.py
│ └── prompts/sdwan_prompts.py
├── tests/
│ ├── conftest.py ← Fake vManage (httpx.MockTransport)
│ ├── sample_data.py ← Representative vManage payloads
│ ├── test_client.py ← Login, session recovery, error translation
│ ├── test_formatting.py ← Projection, envelopes, query building
│ ├── test_tools.py ← Read tools via the in-memory MCP client
│ ├── test_config_tools.py ← The write confirmation gate
│ ├── test_config_group_tools.py← Config-group reads, writes and the template guardrail
│ ├── test_server.py ← Registration, the write gate, public routes
│ └── test_auth.py ← MCP client auth factory
├── deploy/ ← Kubernetes + Cloud Run
├── scripts/ ← Docker helper scripts (bash / PowerShell)
├── certificates/ ← Drop-in CA certificates for Docker builds
├── .env.example ← Annotated reference of every variable
├── docker-compose.yml
├── Dockerfile
└── pyproject.toml
リソース
ライセンス
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。