fabric-aiops 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. fabric_aiops-0.1.0/.github/workflows/publish.yml +26 -0
  2. fabric_aiops-0.1.0/.gitignore +7 -0
  3. fabric_aiops-0.1.0/CHANGELOG.md +55 -0
  4. fabric_aiops-0.1.0/LICENSE +21 -0
  5. fabric_aiops-0.1.0/PKG-INFO +123 -0
  6. fabric_aiops-0.1.0/README.md +107 -0
  7. fabric_aiops-0.1.0/RELEASE_NOTES.md +51 -0
  8. fabric_aiops-0.1.0/SECURITY.md +80 -0
  9. fabric_aiops-0.1.0/fabric_aiops/__init__.py +10 -0
  10. fabric_aiops-0.1.0/fabric_aiops/cli/__init__.py +9 -0
  11. fabric_aiops-0.1.0/fabric_aiops/cli/_common.py +81 -0
  12. fabric_aiops-0.1.0/fabric_aiops/cli/_root.py +64 -0
  13. fabric_aiops-0.1.0/fabric_aiops/cli/client.py +65 -0
  14. fabric_aiops-0.1.0/fabric_aiops/cli/device.py +75 -0
  15. fabric_aiops-0.1.0/fabric_aiops/cli/doctor.py +21 -0
  16. fabric_aiops-0.1.0/fabric_aiops/cli/health.py +47 -0
  17. fabric_aiops-0.1.0/fabric_aiops/cli/init.py +99 -0
  18. fabric_aiops-0.1.0/fabric_aiops/cli/network.py +72 -0
  19. fabric_aiops-0.1.0/fabric_aiops/cli/org.py +75 -0
  20. fabric_aiops-0.1.0/fabric_aiops/cli/overview.py +16 -0
  21. fabric_aiops-0.1.0/fabric_aiops/cli/remediate.py +195 -0
  22. fabric_aiops-0.1.0/fabric_aiops/cli/secret.py +103 -0
  23. fabric_aiops-0.1.0/fabric_aiops/config.py +151 -0
  24. fabric_aiops-0.1.0/fabric_aiops/connection.py +214 -0
  25. fabric_aiops-0.1.0/fabric_aiops/doctor.py +84 -0
  26. fabric_aiops-0.1.0/fabric_aiops/governance/__init__.py +40 -0
  27. fabric_aiops-0.1.0/fabric_aiops/governance/audit.py +377 -0
  28. fabric_aiops-0.1.0/fabric_aiops/governance/budget.py +225 -0
  29. fabric_aiops-0.1.0/fabric_aiops/governance/decorators.py +474 -0
  30. fabric_aiops-0.1.0/fabric_aiops/governance/paths.py +23 -0
  31. fabric_aiops-0.1.0/fabric_aiops/governance/patterns.py +378 -0
  32. fabric_aiops-0.1.0/fabric_aiops/governance/policy.py +411 -0
  33. fabric_aiops-0.1.0/fabric_aiops/governance/sanitize.py +39 -0
  34. fabric_aiops-0.1.0/fabric_aiops/governance/undo.py +218 -0
  35. fabric_aiops-0.1.0/fabric_aiops/ops/__init__.py +1 -0
  36. fabric_aiops-0.1.0/fabric_aiops/ops/_util.py +74 -0
  37. fabric_aiops-0.1.0/fabric_aiops/ops/clients.py +62 -0
  38. fabric_aiops-0.1.0/fabric_aiops/ops/devices.py +93 -0
  39. fabric_aiops-0.1.0/fabric_aiops/ops/health.py +283 -0
  40. fabric_aiops-0.1.0/fabric_aiops/ops/networks.py +82 -0
  41. fabric_aiops-0.1.0/fabric_aiops/ops/organizations.py +93 -0
  42. fabric_aiops-0.1.0/fabric_aiops/ops/overview.py +41 -0
  43. fabric_aiops-0.1.0/fabric_aiops/ops/remediation.py +145 -0
  44. fabric_aiops-0.1.0/fabric_aiops/platform.py +148 -0
  45. fabric_aiops-0.1.0/fabric_aiops/secretstore.py +302 -0
  46. fabric_aiops-0.1.0/mcp_server/__init__.py +1 -0
  47. fabric_aiops-0.1.0/mcp_server/_shared.py +100 -0
  48. fabric_aiops-0.1.0/mcp_server/server.py +35 -0
  49. fabric_aiops-0.1.0/mcp_server/tools/__init__.py +1 -0
  50. fabric_aiops-0.1.0/mcp_server/tools/clients.py +67 -0
  51. fabric_aiops-0.1.0/mcp_server/tools/devices.py +83 -0
  52. fabric_aiops-0.1.0/mcp_server/tools/health.py +104 -0
  53. fabric_aiops-0.1.0/mcp_server/tools/networks.py +75 -0
  54. fabric_aiops-0.1.0/mcp_server/tools/organizations.py +101 -0
  55. fabric_aiops-0.1.0/mcp_server/tools/remediation.py +310 -0
  56. fabric_aiops-0.1.0/pyproject.toml +59 -0
  57. fabric_aiops-0.1.0/server.json +21 -0
  58. fabric_aiops-0.1.0/skills/fabric-aiops/SKILL.md +106 -0
  59. fabric_aiops-0.1.0/skills/fabric-aiops/references/capabilities.md +84 -0
  60. fabric_aiops-0.1.0/skills/fabric-aiops/references/cli-reference.md +75 -0
  61. fabric_aiops-0.1.0/skills/fabric-aiops/references/setup-guide.md +82 -0
  62. fabric_aiops-0.1.0/smithery.yaml +9 -0
  63. fabric_aiops-0.1.0/tests/test_health.py +138 -0
  64. fabric_aiops-0.1.0/tests/test_platform.py +142 -0
  65. fabric_aiops-0.1.0/tests/test_reads.py +169 -0
  66. fabric_aiops-0.1.0/tests/test_secretstore.py +99 -0
  67. fabric_aiops-0.1.0/tests/test_smoke.py +262 -0
  68. fabric_aiops-0.1.0/uv.lock +962 -0
@@ -0,0 +1,26 @@
1
+ name: Publish to PyPI
2
+
3
+ # Trusted Publishing (OIDC) — publishes from GitHub's runners with no API token,
4
+ # sidestepping the local-IP / account new-project rate limit. Configure a matching
5
+ # "trusted publisher" for this package on PyPI (see the repo release notes).
6
+ on:
7
+ release:
8
+ types: [published]
9
+ workflow_dispatch:
10
+
11
+ permissions:
12
+ contents: read
13
+
14
+ jobs:
15
+ publish:
16
+ runs-on: ubuntu-latest
17
+ permissions:
18
+ id-token: write # required for PyPI Trusted Publishing (OIDC)
19
+ steps:
20
+ - uses: actions/checkout@v4
21
+ - name: Set up uv
22
+ uses: astral-sh/setup-uv@v5
23
+ - name: Build sdist + wheel
24
+ run: uv build
25
+ - name: Publish to PyPI (Trusted Publishing)
26
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,7 @@
1
+ .venv/
2
+ dist/
3
+ __pycache__/
4
+ *.pyc
5
+ .pytest_cache/
6
+ .ruff_cache/
7
+ *.egg-info/
@@ -0,0 +1,55 @@
1
+ # Changelog
2
+
3
+ All notable changes to fabric-aiops are documented here. Format loosely follows
4
+ [Keep a Changelog](https://keepachangelog.com/); this project uses semantic
5
+ versioning (currently 0.x preview — the API may change).
6
+
7
+ ## [0.1.0] — 2026-07-13
8
+
9
+ Initial preview release: governed AI-ops for network fabrics managed through the
10
+ **Cisco Meraki Dashboard API** (organizations → networks → devices) with a
11
+ bundled governance harness. **Mock-validated only — not verified against a live
12
+ Meraki organization.** Community-maintained; not affiliated with Cisco/Meraki.
13
+
14
+ ### Added
15
+
16
+ - **Multi-platform connection layer** — a `platform` registry (`fabric_aiops.platform`)
17
+ keyed by name so future controllers (Catalyst Center, Arista CVP) can register a
18
+ descriptor without touching the ops/CLI/MCP layers. Only **meraki** is
19
+ registered in v0.1. Handles `Authorization: Bearer` / `X-Cisco-Meraki-API-Key`
20
+ auth, `Link`-header pagination, and injection-safe response normalisation.
21
+ - **32 governed MCP tools**, every one wrapped with `@governed_tool`:
22
+ - **Overview** — `overview` (org networks + device status/product rollup).
23
+ - **Organizations** — `org_list`, `org_get`, `org_licensing`, `org_admins`,
24
+ `org_device_statuses`, `org_api_requests`.
25
+ - **Networks** — `network_list`, `network_get`, `network_vlans`,
26
+ `network_alerts`, `network_traffic`.
27
+ - **Devices** — `device_inventory` (by model MX/MS/MR/MV/MG), `device_status`,
28
+ `device_uplinks`, `switch_ports`, `wireless_ssids`.
29
+ - **Clients** — `client_list`, `client_get`, `client_usage`,
30
+ `client_connectivity`.
31
+ - **Health (flagship)** — `uplink_loss_and_latency_rca`, `network_health_score`,
32
+ `config_template_drift`.
33
+ - **Remediation (writes)** — `reboot_device` (high), `blink_device_leds` (low),
34
+ `update_device` (medium), `update_network_vlan` (medium),
35
+ `claim_devices_into_network` (high), `remove_device_from_network` (high),
36
+ `bind_network_to_template` (high), `unbind_network_from_template` (high).
37
+ - **Guarded writes** — every write supports a `dry_run` preview and (at the CLI)
38
+ double confirmation. Mutating/reversible writes fetch the **real before-state**
39
+ and record a faithful inverse undo descriptor.
40
+ - **Bundled governance harness** (`fabric_aiops.governance`) — audit log, policy
41
+ engine, token/runaway budget guard, undo-token recording, graduated risk tiers,
42
+ prompt-injection `sanitize`. State under `~/.fabric-aiops/` (relocatable via
43
+ `FABRIC_AIOPS_HOME`).
44
+ - **Encrypted secret store** — Meraki API keys in `~/.fabric-aiops/secrets.enc`
45
+ (Fernet + scrypt); legacy `FABRIC_<TARGET>_APIKEY` env fallback + `secret
46
+ migrate`.
47
+ - **CLI** — `init` wizard, `overview`, `org`, `network`, `device`, `client`,
48
+ `health`, `remediate`, `secret`, `doctor`, `mcp`.
49
+
50
+ ### Known limitations
51
+
52
+ - Preview / mock-only: Dashboard API paths need live verification.
53
+ - Coverage is a curated subset of the Dashboard API; open an issue/PR for gaps.
54
+
55
+ [0.1.0]: https://github.com/AIops-tools/Fabric-AIops/releases/tag/v0.1.0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 wei <zhouwei008@gmail.com>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,123 @@
1
+ Metadata-Version: 2.4
2
+ Name: fabric-aiops
3
+ Version: 0.1.0
4
+ Summary: Governed AI-ops for Cisco Meraki network fabrics: uplink RCA, health scoring & config-drift with a built-in governance harness (audit, budget, undo, risk tiers)
5
+ Author-email: wei <zhouwei008@gmail.com>
6
+ License-Expression: MIT
7
+ License-File: LICENSE
8
+ Requires-Python: >=3.11
9
+ Requires-Dist: cryptography>=42.0
10
+ Requires-Dist: httpx<1.0,>=0.27
11
+ Requires-Dist: mcp[cli]<2.0,>=1.10
12
+ Requires-Dist: pyyaml<7.0,>=6.0
13
+ Requires-Dist: rich<16.0,>=13.0
14
+ Requires-Dist: typer<1.0,>=0.12
15
+ Description-Content-Type: text/markdown
16
+
17
+ <!-- mcp-name: io.github.AIops-tools/fabric-aiops -->
18
+
19
+ # Fabric AIops (preview)
20
+
21
+ > **Disclaimer**: Community-maintained open-source project. **Not affiliated with, endorsed by, or sponsored by Cisco, Meraki, or any network-controller vendor.** "Cisco" and "Meraki" and all product/trademark names belong to their respective owners. MIT licensed.
22
+
23
+ Governed AI-ops for **network fabrics** managed through a cloud controller —
24
+ starting with the **Cisco Meraki Dashboard API** (organizations → networks →
25
+ devices) — with a **built-in governance harness**: unified audit log, policy
26
+ engine, token/runaway budget guard, undo-token recording, and graduated-autonomy
27
+ risk tiers. **Multi-platform by construction**: a registry keyed by `platform`
28
+ means Catalyst Center or Arista CVP can be added later as additional platforms
29
+ without touching the ops/CLI/MCP layers — **Meraki is the one platform shipped in
30
+ v0.1**. **Preview — mock-validated only, not verified against a live Meraki org.**
31
+
32
+ ## What it does
33
+
34
+ Three flagship signature analyses, plus the guarded reads and writes around them:
35
+
36
+ - **Uplink loss & latency RCA** — pull MX WAN uplink loss + latency across an
37
+ org, rank the worst uplinks by a composite of average loss and latency, and
38
+ map each degraded uplink to a likely cause + recommended action. Every ranking
39
+ carries its numbers, not a black-box verdict.
40
+ - **Network health score** — a composite 0-100 score per network from device
41
+ online %, uplink health %, and an alert-severity penalty (weighted 0.5/0.3/0.2),
42
+ with every component returned so the number is explainable.
43
+ - **Config template drift** — for networks bound to a config template, list the
44
+ settings that have drifted from the template (expected vs actual).
45
+
46
+ ## What works
47
+
48
+ - **CLI** (`fabric-aiops ...`): `init`, `overview`, `org`, `network`, `device`, `client`, `health`, `remediate`, `secret`, `doctor`, `mcp`.
49
+ - **MCP server** (`fabric-aiops mcp` or `fabric-aiops-mcp`): **32 tools** (24 read, 8 write), every one wrapped with the bundled `@governed_tool` harness.
50
+ - **Encrypted credentials**: the Meraki API key lives in an encrypted store `~/.fabric-aiops/secrets.enc` (Fernet + scrypt) — **never plaintext on disk**. Unlock with a master password from `FABRIC_AIOPS_MASTER_PASSWORD` (MCP/CI) or an interactive prompt (CLI).
51
+ - **Reversibility**: mutating writes fetch the **real before-state first** and record a faithful inverse (`update_device`/`update_network_vlan` restore prior values; `claim`↔`remove`; `bind`↔`unbind`/rebind). Irreversible ops (`reboot_device`, `blink_device_leds`) record the prior state for audit but declare no undo.
52
+ - **Safety**: every state-changing CLI op supports `--dry-run` and requires double confirmation; every write MCP tool takes a `dry_run` preview.
53
+
54
+ ## Capability matrix (32 MCP tools)
55
+
56
+ | Domain | Tools | Count | R/W |
57
+ |--------|-------|:-----:|:---:|
58
+ | **Overview** | `overview` | 1 | read |
59
+ | **Organizations** | `org_list`, `org_get`, `org_licensing`, `org_admins`, `org_device_statuses`, `org_api_requests` | 6 | read |
60
+ | **Networks** | `network_list`, `network_get`, `network_vlans`, `network_alerts`, `network_traffic` | 5 | read |
61
+ | **Devices** | `device_inventory`, `device_status`, `device_uplinks`, `switch_ports`, `wireless_ssids` | 5 | read |
62
+ | **Clients** | `client_list`, `client_get`, `client_usage`, `client_connectivity` | 4 | read |
63
+ | **Health (flagship)** | `uplink_loss_and_latency_rca`, `network_health_score`, `config_template_drift` | 3 | read |
64
+ | **Remediation** | `reboot_device`, `claim_devices_into_network`, `remove_device_from_network`, `bind_network_to_template`, `unbind_network_from_template` | 5 | write (high) |
65
+ | | `update_device`, `update_network_vlan` | 2 | write (medium) |
66
+ | | `blink_device_leds` | 1 | write (low) |
67
+
68
+ `network_health_score` and `config_template_drift` are injected-only (they score
69
+ data you already hold); `uplink_loss_and_latency_rca` accepts injected `records`
70
+ for offline analysis or pulls live from a configured target. Device models carry
71
+ a product-type prefix: **MX** appliance, **MS** switch, **MR** wireless AP, **MV**
72
+ camera, **MG** cellular gateway.
73
+
74
+ ## Quick start
75
+
76
+ ```bash
77
+ uv tool install fabric-aiops # or: pipx install fabric-aiops
78
+ fabric-aiops init # wizard: add a target + store the Meraki API key (encrypted)
79
+ fabric-aiops doctor # verify config, secrets, connectivity
80
+ fabric-aiops overview # one-shot fabric fleet health
81
+ fabric-aiops health uplink-rca # rank worst MX WAN uplinks + cause/action
82
+ fabric-aiops device inventory --model MS # switches in the org
83
+ ```
84
+
85
+ Run as an MCP server (stdio):
86
+
87
+ ```bash
88
+ export FABRIC_AIOPS_MASTER_PASSWORD=... # unlock secrets non-interactively
89
+ fabric-aiops-mcp
90
+ ```
91
+
92
+ ## Governance
93
+
94
+ Every MCP tool passes through the bundled `@governed_tool` harness:
95
+
96
+ - **Audit** — every call (params, result, status, duration, risk tier, approver,
97
+ rationale) is logged to `~/.fabric-aiops/audit.db` (relocatable via
98
+ `FABRIC_AIOPS_HOME`).
99
+ - **Budget / runaway guard** — token and call budgets trip a circuit breaker.
100
+ - **Risk tiers** — graduated autonomy; high-risk ops can require a named approver
101
+ (`ENDPOINT_AUDIT_APPROVED_BY` / `ENDPOINT_AUDIT_RATIONALE` — the env-var names
102
+ the bundled harness reads).
103
+ - **Undo recording** — reversible writes record an inverse descriptor built from
104
+ the fetched before-state.
105
+
106
+ ## Scope
107
+
108
+ This is the **network-fabric / controller** member of the AIops-tools family
109
+ (governed AI-ops with audit + budget + undo + risk tiers). Do **NOT** use it for
110
+ OT / industrial edge (Modbus, OPC-UA, PROFINET) — see the separate
111
+ `industrial-aiops` line — nor for device-level CLI/SSH network automation.
112
+
113
+ ## Missing a capability?
114
+
115
+ Coverage is intentionally a curated subset of the Meraki Dashboard API. Missing a
116
+ call, a device family, or want another controller platform (Catalyst Center,
117
+ Arista CVP)? **Open an issue or PR** — contributions welcome.
118
+
119
+ ## Status
120
+
121
+ **Preview — mock-validated only, not verified against a live Meraki org.** The
122
+ Dashboard API paths are modelled from the public API shape and need live
123
+ verification. `fabric-aiops doctor` is the fastest live check.
@@ -0,0 +1,107 @@
1
+ <!-- mcp-name: io.github.AIops-tools/fabric-aiops -->
2
+
3
+ # Fabric AIops (preview)
4
+
5
+ > **Disclaimer**: Community-maintained open-source project. **Not affiliated with, endorsed by, or sponsored by Cisco, Meraki, or any network-controller vendor.** "Cisco" and "Meraki" and all product/trademark names belong to their respective owners. MIT licensed.
6
+
7
+ Governed AI-ops for **network fabrics** managed through a cloud controller —
8
+ starting with the **Cisco Meraki Dashboard API** (organizations → networks →
9
+ devices) — with a **built-in governance harness**: unified audit log, policy
10
+ engine, token/runaway budget guard, undo-token recording, and graduated-autonomy
11
+ risk tiers. **Multi-platform by construction**: a registry keyed by `platform`
12
+ means Catalyst Center or Arista CVP can be added later as additional platforms
13
+ without touching the ops/CLI/MCP layers — **Meraki is the one platform shipped in
14
+ v0.1**. **Preview — mock-validated only, not verified against a live Meraki org.**
15
+
16
+ ## What it does
17
+
18
+ Three flagship signature analyses, plus the guarded reads and writes around them:
19
+
20
+ - **Uplink loss & latency RCA** — pull MX WAN uplink loss + latency across an
21
+ org, rank the worst uplinks by a composite of average loss and latency, and
22
+ map each degraded uplink to a likely cause + recommended action. Every ranking
23
+ carries its numbers, not a black-box verdict.
24
+ - **Network health score** — a composite 0-100 score per network from device
25
+ online %, uplink health %, and an alert-severity penalty (weighted 0.5/0.3/0.2),
26
+ with every component returned so the number is explainable.
27
+ - **Config template drift** — for networks bound to a config template, list the
28
+ settings that have drifted from the template (expected vs actual).
29
+
30
+ ## What works
31
+
32
+ - **CLI** (`fabric-aiops ...`): `init`, `overview`, `org`, `network`, `device`, `client`, `health`, `remediate`, `secret`, `doctor`, `mcp`.
33
+ - **MCP server** (`fabric-aiops mcp` or `fabric-aiops-mcp`): **32 tools** (24 read, 8 write), every one wrapped with the bundled `@governed_tool` harness.
34
+ - **Encrypted credentials**: the Meraki API key lives in an encrypted store `~/.fabric-aiops/secrets.enc` (Fernet + scrypt) — **never plaintext on disk**. Unlock with a master password from `FABRIC_AIOPS_MASTER_PASSWORD` (MCP/CI) or an interactive prompt (CLI).
35
+ - **Reversibility**: mutating writes fetch the **real before-state first** and record a faithful inverse (`update_device`/`update_network_vlan` restore prior values; `claim`↔`remove`; `bind`↔`unbind`/rebind). Irreversible ops (`reboot_device`, `blink_device_leds`) record the prior state for audit but declare no undo.
36
+ - **Safety**: every state-changing CLI op supports `--dry-run` and requires double confirmation; every write MCP tool takes a `dry_run` preview.
37
+
38
+ ## Capability matrix (32 MCP tools)
39
+
40
+ | Domain | Tools | Count | R/W |
41
+ |--------|-------|:-----:|:---:|
42
+ | **Overview** | `overview` | 1 | read |
43
+ | **Organizations** | `org_list`, `org_get`, `org_licensing`, `org_admins`, `org_device_statuses`, `org_api_requests` | 6 | read |
44
+ | **Networks** | `network_list`, `network_get`, `network_vlans`, `network_alerts`, `network_traffic` | 5 | read |
45
+ | **Devices** | `device_inventory`, `device_status`, `device_uplinks`, `switch_ports`, `wireless_ssids` | 5 | read |
46
+ | **Clients** | `client_list`, `client_get`, `client_usage`, `client_connectivity` | 4 | read |
47
+ | **Health (flagship)** | `uplink_loss_and_latency_rca`, `network_health_score`, `config_template_drift` | 3 | read |
48
+ | **Remediation** | `reboot_device`, `claim_devices_into_network`, `remove_device_from_network`, `bind_network_to_template`, `unbind_network_from_template` | 5 | write (high) |
49
+ | | `update_device`, `update_network_vlan` | 2 | write (medium) |
50
+ | | `blink_device_leds` | 1 | write (low) |
51
+
52
+ `network_health_score` and `config_template_drift` are injected-only (they score
53
+ data you already hold); `uplink_loss_and_latency_rca` accepts injected `records`
54
+ for offline analysis or pulls live from a configured target. Device models carry
55
+ a product-type prefix: **MX** appliance, **MS** switch, **MR** wireless AP, **MV**
56
+ camera, **MG** cellular gateway.
57
+
58
+ ## Quick start
59
+
60
+ ```bash
61
+ uv tool install fabric-aiops # or: pipx install fabric-aiops
62
+ fabric-aiops init # wizard: add a target + store the Meraki API key (encrypted)
63
+ fabric-aiops doctor # verify config, secrets, connectivity
64
+ fabric-aiops overview # one-shot fabric fleet health
65
+ fabric-aiops health uplink-rca # rank worst MX WAN uplinks + cause/action
66
+ fabric-aiops device inventory --model MS # switches in the org
67
+ ```
68
+
69
+ Run as an MCP server (stdio):
70
+
71
+ ```bash
72
+ export FABRIC_AIOPS_MASTER_PASSWORD=... # unlock secrets non-interactively
73
+ fabric-aiops-mcp
74
+ ```
75
+
76
+ ## Governance
77
+
78
+ Every MCP tool passes through the bundled `@governed_tool` harness:
79
+
80
+ - **Audit** — every call (params, result, status, duration, risk tier, approver,
81
+ rationale) is logged to `~/.fabric-aiops/audit.db` (relocatable via
82
+ `FABRIC_AIOPS_HOME`).
83
+ - **Budget / runaway guard** — token and call budgets trip a circuit breaker.
84
+ - **Risk tiers** — graduated autonomy; high-risk ops can require a named approver
85
+ (`ENDPOINT_AUDIT_APPROVED_BY` / `ENDPOINT_AUDIT_RATIONALE` — the env-var names
86
+ the bundled harness reads).
87
+ - **Undo recording** — reversible writes record an inverse descriptor built from
88
+ the fetched before-state.
89
+
90
+ ## Scope
91
+
92
+ This is the **network-fabric / controller** member of the AIops-tools family
93
+ (governed AI-ops with audit + budget + undo + risk tiers). Do **NOT** use it for
94
+ OT / industrial edge (Modbus, OPC-UA, PROFINET) — see the separate
95
+ `industrial-aiops` line — nor for device-level CLI/SSH network automation.
96
+
97
+ ## Missing a capability?
98
+
99
+ Coverage is intentionally a curated subset of the Meraki Dashboard API. Missing a
100
+ call, a device family, or want another controller platform (Catalyst Center,
101
+ Arista CVP)? **Open an issue or PR** — contributions welcome.
102
+
103
+ ## Status
104
+
105
+ **Preview — mock-validated only, not verified against a live Meraki org.** The
106
+ Dashboard API paths are modelled from the public API shape and need live
107
+ verification. `fabric-aiops doctor` is the fastest live check.
@@ -0,0 +1,51 @@
1
+ # Fabric AIops v0.1.0 — preview
2
+
3
+ Governed AI-ops for **network fabrics** managed through the **Cisco Meraki
4
+ Dashboard API** (organizations → networks → devices) for AI agents, with a
5
+ built-in governance harness (audit, policy, token/runaway budget, undo-token
6
+ recording, graduated risk tiers) and an encrypted credential store. Standalone —
7
+ no external skill-family dependency. Multi-platform by construction; Meraki is
8
+ the one platform shipped in v0.1.
9
+
10
+ > **Preview / mock-only.** All behaviour is validated against mocked Dashboard
11
+ > API responses; it has not been run against a live Meraki organization. The
12
+ > fastest live check is `fabric-aiops doctor`.
13
+ >
14
+ > Community-maintained; **not affiliated with or endorsed by Cisco/Meraki.**
15
+ > Trademarks belong to their owners.
16
+
17
+ ## Highlights
18
+
19
+ - **32 MCP tools** (24 read, 8 write), every one wrapped with `@governed_tool`.
20
+ - Read: fleet `overview`; organizations (6); networks (5); devices (5);
21
+ clients (4); and three flagship analyses.
22
+ - Write: `reboot_device`/`claim_devices_into_network`/`remove_device_from_network`/
23
+ `bind_network_to_template`/`unbind_network_from_template` (high),
24
+ `update_device`/`update_network_vlan` (medium, capture before-state),
25
+ `blink_device_leds` (low).
26
+ - **Three signature analyses** — `uplink_loss_and_latency_rca` (rank worst MX WAN
27
+ uplinks + cause/action), `network_health_score` (composite per-network health),
28
+ and `config_template_drift` (settings drifted from a bound template).
29
+ - **Encrypted API key store** (`~/.fabric-aiops/secrets.enc`, Fernet + scrypt) —
30
+ never plaintext on disk; legacy `FABRIC_<TARGET>_APIKEY` env fallback.
31
+ - **CLI** with an `init` onboarding wizard, `secret` management, and `doctor`.
32
+ - **Multi-platform connection layer** — a `platform` registry (`Authorization:
33
+ Bearer` or `X-Cisco-Meraki-API-Key` auth, `Link`-header pagination) with
34
+ teaching error translation (`FabricApiError`); only Meraki registered in v0.1.
35
+
36
+ ## Install
37
+
38
+ ```bash
39
+ uv tool install fabric-aiops
40
+ fabric-aiops init
41
+ fabric-aiops doctor
42
+ ```
43
+
44
+ ## Caveats
45
+
46
+ - The Dashboard API paths are modelled from the public API shape and need live
47
+ verification against a real organization.
48
+ - Out of scope by design: full org/network provisioning workflows, firmware
49
+ upgrade orchestration, and any bulk destructive operation.
50
+ - Missing a capability or want another controller platform (Catalyst Center,
51
+ Arista CVP)? Open an issue or PR.
@@ -0,0 +1,80 @@
1
+ # Security Policy
2
+
3
+ ## Disclaimer
4
+
5
+ Community-maintained open-source project. **Not affiliated with, endorsed by, or
6
+ sponsored by Cisco, Meraki, or any network-controller vendor.** "Cisco",
7
+ "Meraki", and all product/trademark names belong to their respective owners.
8
+ Source is publicly auditable under the MIT license.
9
+
10
+ ## Reporting Vulnerabilities
11
+
12
+ Report privately via a GitHub Security Advisory on
13
+ [github.com/AIops-tools/Fabric-AIops](https://github.com/AIops-tools/Fabric-AIops/security/advisories)
14
+ or email zhouwei008@gmail.com. Please do not open public issues for security
15
+ reports.
16
+
17
+ ## Security Design
18
+
19
+ ### Credential Management
20
+ - Per-target Meraki API keys live **encrypted** in `~/.fabric-aiops/secrets.enc`
21
+ (Fernet/AES-128 + scrypt-derived key; chmod 600), never in `config.yaml` and
22
+ never in source. The master password is never stored — only a per-store random
23
+ salt and the ciphertext are on disk.
24
+ - A legacy plaintext env var `FABRIC_<TARGET_NAME_UPPER>_APIKEY` is still honoured
25
+ as a fallback with a deprecation warning (migrate with `fabric-aiops secret
26
+ migrate`).
27
+ - The API key is sent in the platform auth header (`Authorization: Bearer` by
28
+ default, or `X-Cisco-Meraki-API-Key`) at request time and held only in memory.
29
+ Keys are never logged or echoed; the config file holds only platform, base URL,
30
+ default org id, and TLS settings.
31
+
32
+ ### Governed Operations
33
+ Every MCP tool runs through the bundled `@governed_tool` harness
34
+ (`fabric_aiops.governance`):
35
+ - **Audit** — every call logged to a local SQLite DB under `~/.fabric-aiops/`
36
+ (relocatable via `FABRIC_AIOPS_HOME`), agent-attributed, secret-redacted.
37
+ - **Token/runaway budget** — hard ceilings (`ENDPOINT_MAX_TOOL_CALLS` /
38
+ `ENDPOINT_MAX_TOOL_SECONDS` — the env-var names the bundled harness reads) plus
39
+ an on-by-default guard that trips a tight poll/retry loop, preventing unbounded
40
+ Dashboard API consumption (and the associated rate-limit exposure).
41
+ - **Graduated risk tiers** — `~/.fabric-aiops/rules.yaml` `risk_tiers` gate writes
42
+ by environment/tag; the highest tiers require a recorded approver
43
+ (`ENDPOINT_AUDIT_APPROVED_BY` / `ENDPOINT_AUDIT_RATIONALE`).
44
+ - **Undo-token recording** — mutating/reversible writes fetch the **real
45
+ before-state first** and record a faithful inverse descriptor (e.g.
46
+ `update_device` restores the prior attributes; `bind`↔`unbind`; `claim`↔`remove`).
47
+
48
+ ### State-Changing Operations
49
+ Every write supports `--dry-run` (CLI) / `dry_run=True` (MCP) and requires double
50
+ confirmation at the CLI layer. Destructive or fleet-affecting ops (`reboot_device`,
51
+ `claim_devices_into_network`, `remove_device_from_network`,
52
+ `bind_network_to_template`, `unbind_network_from_template`) are `risk_level=high`;
53
+ mutating reversible ops (`update_device`, `update_network_vlan`) are `medium`;
54
+ `blink_device_leds` (a locator aid, no config change) is `low`. Irreversible ops
55
+ capture the before-state for the audit record but record no undo token.
56
+
57
+ ### SSL/TLS Verification
58
+ `verify_ssl` defaults to true; disable only for a self-signed on-prem controller
59
+ proxy.
60
+
61
+ ### Prompt-Injection Protection
62
+ All controller-returned text (network names, device names, client descriptions,
63
+ tags, settings) is passed through a `sanitize()` truncate + control-character
64
+ strip before reaching the agent.
65
+
66
+ ### Network Scope
67
+ No webhooks, no telemetry, no outbound calls beyond the configured controller REST
68
+ API base URL. No post-install scripts or background services.
69
+
70
+ ## Static Analysis
71
+
72
+ ```bash
73
+ uvx bandit -r fabric_aiops/ mcp_server/
74
+ uv run ruff check .
75
+ ```
76
+
77
+ ## Supported Versions
78
+
79
+ The latest released version receives security fixes. This is a preview (0.x);
80
+ pin a version in production.
@@ -0,0 +1,10 @@
1
+ """fabric-aiops — governed Cisco Meraki network-fabric operations for AI agents.
2
+
3
+ Standalone and self-contained: the governance harness (audit, token budget,
4
+ undo-token recording, graduated risk tiers, prompt-injection sanitize) is
5
+ bundled under ``fabric_aiops.governance`` — this package has no external
6
+ skill-family dependency. Multi-platform by construction (see
7
+ ``fabric_aiops.platform``); v0.1 ships Meraki. Preview: not yet full-coverage.
8
+ """
9
+
10
+ __version__ = "0.1.0"
@@ -0,0 +1,9 @@
1
+ """CLI package for fabric-aiops.
2
+
3
+ Re-exports ``app`` so the pyproject entry point
4
+ ``fabric-aiops = "fabric_aiops.cli:app"`` works unchanged.
5
+ """
6
+
7
+ from fabric_aiops.cli._root import app
8
+
9
+ __all__ = ["app"]
@@ -0,0 +1,81 @@
1
+ """Shared helpers for fabric-aiops CLI sub-modules."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import functools
6
+ from collections.abc import Callable
7
+ from pathlib import Path
8
+ from typing import Annotated, Any
9
+
10
+ import typer
11
+ from rich.console import Console
12
+
13
+ console = Console()
14
+
15
+ # ─── Shared Option types ───────────────────────────────────────────────────
16
+
17
+ TargetOption = Annotated[
18
+ str | None, typer.Option("--target", "-t", help="Target name from config")
19
+ ]
20
+ OrgOption = Annotated[
21
+ str | None, typer.Option("--org-id", "-o", help="Meraki organization id (else target default)")
22
+ ]
23
+ DryRunOption = Annotated[
24
+ bool, typer.Option("--dry-run", help="Print the API call without executing")
25
+ ]
26
+
27
+
28
+ def _cli_error_types() -> tuple[type[BaseException], ...]:
29
+ """Exceptions translated to a one-line teaching error instead of a traceback."""
30
+ from fabric_aiops.connection import FabricApiError
31
+
32
+ return (FabricApiError, KeyError, OSError, ValueError)
33
+
34
+
35
+ def cli_errors(fn: Callable) -> Callable:
36
+ """Translate known exceptions into one red line + exit code 1."""
37
+
38
+ @functools.wraps(fn)
39
+ def wrapper(*args: Any, **kwargs: Any) -> Any:
40
+ try:
41
+ return fn(*args, **kwargs)
42
+ except (typer.Exit, typer.Abort):
43
+ raise
44
+ except _cli_error_types() as e:
45
+ message = str(e)
46
+ if isinstance(e, KeyError):
47
+ message = f"Missing required key or environment variable: {message}"
48
+ console.print(f"[red]Error: {message}[/]")
49
+ raise typer.Exit(1) from e
50
+
51
+ return wrapper
52
+
53
+
54
+ def get_connection(target: str | None, config_path: Path | None = None):
55
+ """Return a (conn, config) tuple for the given target."""
56
+ from fabric_aiops.config import load_config
57
+ from fabric_aiops.connection import ConnectionManager
58
+
59
+ cfg = load_config(config_path)
60
+ mgr = ConnectionManager(cfg)
61
+ return mgr.connect(target), cfg
62
+
63
+
64
+ def dry_run_print(*, operation: str, api_call: str, parameters: dict | None = None) -> None:
65
+ """Print a dry-run preview of the API call that would be made."""
66
+ console.print("\n[bold magenta][DRY-RUN] No changes will be made.[/]")
67
+ console.print(f"[magenta] Operation: {operation}[/]")
68
+ console.print(f"[magenta] API Call: {api_call}[/]")
69
+ for k, v in (parameters or {}).items():
70
+ console.print(f"[magenta] Param: {k} = {v}[/]")
71
+ console.print("[magenta] Run without --dry-run to execute.[/]\n")
72
+
73
+
74
+ def double_confirm(action: str, resource: str) -> None:
75
+ """Require two confirmations for a destructive operation."""
76
+ console.print(f"[bold yellow]⚠️ About to: {action} '{resource}'[/]")
77
+ typer.confirm(f"Confirm 1/2: {action} '{resource}'?", abort=True)
78
+ typer.confirm(
79
+ f"Confirm 2/2: really {action} '{resource}'? This may be irreversible.",
80
+ abort=True,
81
+ )
@@ -0,0 +1,64 @@
1
+ """Top-level Typer app: assembles sub-apps and top-level commands."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import typer
6
+
7
+ from fabric_aiops.cli._common import cli_errors
8
+ from fabric_aiops.cli.client import client_app
9
+ from fabric_aiops.cli.device import device_app
10
+ from fabric_aiops.cli.doctor import doctor_cmd
11
+ from fabric_aiops.cli.health import health_app
12
+ from fabric_aiops.cli.init import init_cmd
13
+ from fabric_aiops.cli.network import network_app
14
+ from fabric_aiops.cli.org import org_app
15
+ from fabric_aiops.cli.overview import overview_cmd
16
+ from fabric_aiops.cli.remediate import remediate_app
17
+ from fabric_aiops.cli.secret import secret_app
18
+
19
+ app = typer.Typer(
20
+ name="fabric-aiops",
21
+ help="Governed AI-ops for Cisco Meraki network fabrics (organizations / networks / devices).",
22
+ no_args_is_help=True,
23
+ )
24
+
25
+ app.add_typer(org_app, name="org")
26
+ app.add_typer(network_app, name="network")
27
+ app.add_typer(device_app, name="device")
28
+ app.add_typer(client_app, name="client")
29
+ app.add_typer(health_app, name="health")
30
+ app.add_typer(remediate_app, name="remediate")
31
+ app.add_typer(secret_app, name="secret")
32
+ app.command("init")(init_cmd)
33
+ app.command("overview")(overview_cmd)
34
+ app.command("doctor")(doctor_cmd)
35
+
36
+
37
+ @app.command("mcp")
38
+ @cli_errors
39
+ def mcp_cmd() -> None:
40
+ """Start the MCP server (stdio transport).
41
+
42
+ Single-command entry point for MCP clients (does not go through uvx/PyPI
43
+ resolution at launch):
44
+ fabric-aiops mcp
45
+ """
46
+ import sys
47
+
48
+ if sys.version_info < (3, 11):
49
+ typer.echo(
50
+ f"ERROR: fabric-aiops requires Python >= 3.11 "
51
+ f"(got {sys.version_info.major}.{sys.version_info.minor}).\n"
52
+ f"Fix: uv python install 3.12 && "
53
+ f"uv tool install --python 3.12 --force fabric-aiops",
54
+ err=True,
55
+ )
56
+ raise typer.Exit(2)
57
+
58
+ from mcp_server.server import main as _mcp_main
59
+
60
+ _mcp_main()
61
+
62
+
63
+ if __name__ == "__main__":
64
+ app()