mccimc 2026.6.13__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.
- mccimc-2026.6.13/.gitignore +24 -0
- mccimc-2026.6.13/PKG-INFO +130 -0
- mccimc-2026.6.13/README.md +109 -0
- mccimc-2026.6.13/cimcs.example.toml +24 -0
- mccimc-2026.6.13/pyproject.toml +65 -0
- mccimc-2026.6.13/src/mccimc/__init__.py +10 -0
- mccimc-2026.6.13/src/mccimc/__main__.py +6 -0
- mccimc-2026.6.13/src/mccimc/_cimc.py +522 -0
- mccimc-2026.6.13/src/mccimc/config.py +138 -0
- mccimc-2026.6.13/src/mccimc/docs/api-verbs.md +98 -0
- mccimc-2026.6.13/src/mccimc/docs/firmware-quirks.md +139 -0
- mccimc-2026.6.13/src/mccimc/docs/mo-tree.md +87 -0
- mccimc-2026.6.13/src/mccimc/docs/operations-cookbook.md +148 -0
- mccimc-2026.6.13/src/mccimc/server.py +1300 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# --- Secrets ---
|
|
2
|
+
.env
|
|
3
|
+
.env.*
|
|
4
|
+
*.secret
|
|
5
|
+
|
|
6
|
+
# --- Per-session artifacts (JNLP tokens, cookies) ---
|
|
7
|
+
jnlp/*.jnlp
|
|
8
|
+
jnlp/*.cookie
|
|
9
|
+
*.log
|
|
10
|
+
|
|
11
|
+
# --- Editor / OS junk ---
|
|
12
|
+
.DS_Store
|
|
13
|
+
*~
|
|
14
|
+
.*.swp
|
|
15
|
+
|
|
16
|
+
# Override global gitignore: we want artifacts/ tracked in THIS project.
|
|
17
|
+
# The Avocent JARs we archive there are stable, useful for offline analysis,
|
|
18
|
+
# and small enough (~3 MB total) to commit.
|
|
19
|
+
!artifacts/
|
|
20
|
+
!artifacts/**
|
|
21
|
+
analysis/decompiled/
|
|
22
|
+
|
|
23
|
+
# PNG renders of TUI SVG screenshots are derived (run rsvg-convert on the .svg)
|
|
24
|
+
artifacts/screenshots/*/*.png
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: mccimc
|
|
3
|
+
Version: 2026.6.13
|
|
4
|
+
Summary: MCP server for Cisco UCS CIMC (3.x/4.x firmware) — multi-CIMC registry over HTTP
|
|
5
|
+
Project-URL: Homepage, https://github.com/supported-systems/mccimc
|
|
6
|
+
Project-URL: Source, https://github.com/supported-systems/mccimc
|
|
7
|
+
Author-email: Ryan Malloy <ryan@supported.systems>
|
|
8
|
+
License-Expression: MIT
|
|
9
|
+
Keywords: cimc,cisco,mcp,model-context-protocol,ucs
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
|
+
Classifier: Intended Audience :: System Administrators
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
16
|
+
Classifier: Topic :: System :: Hardware
|
|
17
|
+
Classifier: Topic :: System :: Systems Administration
|
|
18
|
+
Requires-Python: >=3.11
|
|
19
|
+
Requires-Dist: fastmcp>=0.4
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
|
|
22
|
+
# mccimc
|
|
23
|
+
|
|
24
|
+
MCP server for **Cisco UCS C-series CIMC** management. Drive multiple CIMCs from one
|
|
25
|
+
HTTP-served MCP endpoint, configurable as a list of known boxes.
|
|
26
|
+
|
|
27
|
+
## What it does
|
|
28
|
+
|
|
29
|
+
Exposes the CIMC XML API as 20-ish typed MCP tools:
|
|
30
|
+
|
|
31
|
+
- **Discovery** — `cimc_list`, `cimc_ping`
|
|
32
|
+
- **Info / inventory** — `cimc_info`, `cimc_inventory`, `cimc_nics`
|
|
33
|
+
- **Sensors** — `cimc_sensors` (temperature, power)
|
|
34
|
+
- **Power** — `cimc_power_status`, `cimc_power` (on/off/cycle/reset/soft-off/bmc-reset)
|
|
35
|
+
- **Virtual media** — `cimc_vmedia_list`, `cimc_vmedia_mount`, `cimc_vmedia_unmount`
|
|
36
|
+
- **SoL** — `cimc_sol_status`, `cimc_sol_enable`, `cimc_sol_disable`
|
|
37
|
+
- **Convenience** — `cimc_locator_led` (front-panel LED on/off)
|
|
38
|
+
- **KVM** — `cimc_kvm_jnlp` (fetch JNLP for the Java viewer)
|
|
39
|
+
- **Escape hatches** — `cimc_get_mo`, `cimc_get_children`, `cimc_modify_mo` for things no specific tool covers
|
|
40
|
+
|
|
41
|
+
## Install
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
uvx mccimc # one-shot run
|
|
45
|
+
# or
|
|
46
|
+
uv tool install mccimc # persistent install
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Configure
|
|
50
|
+
|
|
51
|
+
Create `~/.config/mccimc/cimcs.toml`:
|
|
52
|
+
|
|
53
|
+
```toml
|
|
54
|
+
[[cimcs]]
|
|
55
|
+
name = "cimc01"
|
|
56
|
+
host = "cimc01.example.net"
|
|
57
|
+
password_env = "CIMC01_PASS"
|
|
58
|
+
cert_path = "~/cimc-certs/cimc01.pem"
|
|
59
|
+
description = "Lab box"
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Then export the password env vars:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
export CIMC01_PASS='...'
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
See `cimcs.example.toml` for the full schema.
|
|
69
|
+
|
|
70
|
+
## Run
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
mccimc # HTTP on 127.0.0.1:7902/mcp
|
|
74
|
+
mccimc --transport stdio # for local Claude Code embedding
|
|
75
|
+
mccimc --host 0.0.0.0 --port 8080 # LAN-accessible
|
|
76
|
+
mccimc --check # validate config and exit
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Connect
|
|
80
|
+
|
|
81
|
+
Add to your Claude Code MCP config:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
claude mcp add cimc --transport http http://127.0.0.1:7902/mcp
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Or for stdio (no need to start `mccimc` separately):
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
claude mcp add cimc --scope user -- uvx mccimc --transport stdio
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Example session (LLM-driven)
|
|
94
|
+
|
|
95
|
+
```
|
|
96
|
+
> Which CIMCs do I have?
|
|
97
|
+
[cimc_list] → [{"name": "cimc01", ...}, {"name": "cimc02", ...}]
|
|
98
|
+
|
|
99
|
+
> Is cimc01 powered on?
|
|
100
|
+
[cimc_power_status cimc="cimc01"] → {"operPower": "on", "adminPower": "policy"}
|
|
101
|
+
|
|
102
|
+
> What's it drawing?
|
|
103
|
+
[cimc_sensors cimc="cimc01"] → {"power": {"consumedPower": "144", ...}}
|
|
104
|
+
|
|
105
|
+
> Mount the installer
|
|
106
|
+
[cimc_vmedia_mount cimc="cimc01" url="http://198.51.100.10/install.iso" name="install"]
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## CIMC firmware compatibility
|
|
110
|
+
|
|
111
|
+
Tested against **CIMC 3.0(4s)** (UCSC-C220-M3S). The MO schema is largely stable
|
|
112
|
+
across 3.x and 4.x C-series firmware — most tools should work unchanged.
|
|
113
|
+
M5/M6 (4.x firmware) adds more sensors and exposes per-port NIC link state;
|
|
114
|
+
tools that read these will just have more data.
|
|
115
|
+
|
|
116
|
+
Known firmware quirks documented in tool docstrings:
|
|
117
|
+
- `commVMediaMap.adminAction` enum only accepts `save-unmapped-volume`
|
|
118
|
+
(so `mount_vmedia` omits `adminAction`, `unmount_vmedia` uses `status="deleted"`)
|
|
119
|
+
- WWW vMedia URLs **must omit explicit ports** on 3.0(4s) (use port 80 or 443
|
|
120
|
+
implicitly, not `:8888`).
|
|
121
|
+
- Java KVM tokens are session-scoped — `cimc_kvm_jnlp` deliberately leaves
|
|
122
|
+
the XML session open.
|
|
123
|
+
|
|
124
|
+
## Author
|
|
125
|
+
|
|
126
|
+
Ryan Malloy <ryan@supported.systems>
|
|
127
|
+
|
|
128
|
+
## License
|
|
129
|
+
|
|
130
|
+
MIT
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# mccimc
|
|
2
|
+
|
|
3
|
+
MCP server for **Cisco UCS C-series CIMC** management. Drive multiple CIMCs from one
|
|
4
|
+
HTTP-served MCP endpoint, configurable as a list of known boxes.
|
|
5
|
+
|
|
6
|
+
## What it does
|
|
7
|
+
|
|
8
|
+
Exposes the CIMC XML API as 20-ish typed MCP tools:
|
|
9
|
+
|
|
10
|
+
- **Discovery** — `cimc_list`, `cimc_ping`
|
|
11
|
+
- **Info / inventory** — `cimc_info`, `cimc_inventory`, `cimc_nics`
|
|
12
|
+
- **Sensors** — `cimc_sensors` (temperature, power)
|
|
13
|
+
- **Power** — `cimc_power_status`, `cimc_power` (on/off/cycle/reset/soft-off/bmc-reset)
|
|
14
|
+
- **Virtual media** — `cimc_vmedia_list`, `cimc_vmedia_mount`, `cimc_vmedia_unmount`
|
|
15
|
+
- **SoL** — `cimc_sol_status`, `cimc_sol_enable`, `cimc_sol_disable`
|
|
16
|
+
- **Convenience** — `cimc_locator_led` (front-panel LED on/off)
|
|
17
|
+
- **KVM** — `cimc_kvm_jnlp` (fetch JNLP for the Java viewer)
|
|
18
|
+
- **Escape hatches** — `cimc_get_mo`, `cimc_get_children`, `cimc_modify_mo` for things no specific tool covers
|
|
19
|
+
|
|
20
|
+
## Install
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
uvx mccimc # one-shot run
|
|
24
|
+
# or
|
|
25
|
+
uv tool install mccimc # persistent install
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Configure
|
|
29
|
+
|
|
30
|
+
Create `~/.config/mccimc/cimcs.toml`:
|
|
31
|
+
|
|
32
|
+
```toml
|
|
33
|
+
[[cimcs]]
|
|
34
|
+
name = "cimc01"
|
|
35
|
+
host = "cimc01.example.net"
|
|
36
|
+
password_env = "CIMC01_PASS"
|
|
37
|
+
cert_path = "~/cimc-certs/cimc01.pem"
|
|
38
|
+
description = "Lab box"
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Then export the password env vars:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
export CIMC01_PASS='...'
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
See `cimcs.example.toml` for the full schema.
|
|
48
|
+
|
|
49
|
+
## Run
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
mccimc # HTTP on 127.0.0.1:7902/mcp
|
|
53
|
+
mccimc --transport stdio # for local Claude Code embedding
|
|
54
|
+
mccimc --host 0.0.0.0 --port 8080 # LAN-accessible
|
|
55
|
+
mccimc --check # validate config and exit
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Connect
|
|
59
|
+
|
|
60
|
+
Add to your Claude Code MCP config:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
claude mcp add cimc --transport http http://127.0.0.1:7902/mcp
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Or for stdio (no need to start `mccimc` separately):
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
claude mcp add cimc --scope user -- uvx mccimc --transport stdio
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Example session (LLM-driven)
|
|
73
|
+
|
|
74
|
+
```
|
|
75
|
+
> Which CIMCs do I have?
|
|
76
|
+
[cimc_list] → [{"name": "cimc01", ...}, {"name": "cimc02", ...}]
|
|
77
|
+
|
|
78
|
+
> Is cimc01 powered on?
|
|
79
|
+
[cimc_power_status cimc="cimc01"] → {"operPower": "on", "adminPower": "policy"}
|
|
80
|
+
|
|
81
|
+
> What's it drawing?
|
|
82
|
+
[cimc_sensors cimc="cimc01"] → {"power": {"consumedPower": "144", ...}}
|
|
83
|
+
|
|
84
|
+
> Mount the installer
|
|
85
|
+
[cimc_vmedia_mount cimc="cimc01" url="http://198.51.100.10/install.iso" name="install"]
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## CIMC firmware compatibility
|
|
89
|
+
|
|
90
|
+
Tested against **CIMC 3.0(4s)** (UCSC-C220-M3S). The MO schema is largely stable
|
|
91
|
+
across 3.x and 4.x C-series firmware — most tools should work unchanged.
|
|
92
|
+
M5/M6 (4.x firmware) adds more sensors and exposes per-port NIC link state;
|
|
93
|
+
tools that read these will just have more data.
|
|
94
|
+
|
|
95
|
+
Known firmware quirks documented in tool docstrings:
|
|
96
|
+
- `commVMediaMap.adminAction` enum only accepts `save-unmapped-volume`
|
|
97
|
+
(so `mount_vmedia` omits `adminAction`, `unmount_vmedia` uses `status="deleted"`)
|
|
98
|
+
- WWW vMedia URLs **must omit explicit ports** on 3.0(4s) (use port 80 or 443
|
|
99
|
+
implicitly, not `:8888`).
|
|
100
|
+
- Java KVM tokens are session-scoped — `cimc_kvm_jnlp` deliberately leaves
|
|
101
|
+
the XML session open.
|
|
102
|
+
|
|
103
|
+
## Author
|
|
104
|
+
|
|
105
|
+
Ryan Malloy <ryan@supported.systems>
|
|
106
|
+
|
|
107
|
+
## License
|
|
108
|
+
|
|
109
|
+
MIT
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# mccimc registry — copy to ~/.config/mccimc/cimcs.toml and edit.
|
|
2
|
+
#
|
|
3
|
+
# Each [[cimcs]] block defines one CIMC the server can talk to.
|
|
4
|
+
# Required: name, host, and one of password or password_env.
|
|
5
|
+
|
|
6
|
+
[[cimcs]]
|
|
7
|
+
name = "cimc01"
|
|
8
|
+
host = "cimc01.example.net" # resolves via /etc/hosts or DNS
|
|
9
|
+
user = "admin" # optional, default "admin"
|
|
10
|
+
password_env = "CIMC01_PASS" # read pw from env var (don't paste literal password if you can avoid)
|
|
11
|
+
cert_path = "~/cimc-certs/cimc01.pem"
|
|
12
|
+
description = "Lab UCSC-C220-M3S"
|
|
13
|
+
|
|
14
|
+
[[cimcs]]
|
|
15
|
+
name = "cimc02"
|
|
16
|
+
host = "cimc02.example.net"
|
|
17
|
+
password_env = "CIMC02_PASS"
|
|
18
|
+
description = "ESXi target, M3 generation"
|
|
19
|
+
|
|
20
|
+
# Inline password (less secure, easier for quick testing)
|
|
21
|
+
# [[cimcs]]
|
|
22
|
+
# name = "test"
|
|
23
|
+
# host = "10.0.0.5"
|
|
24
|
+
# password = "tempPassword123!"
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "mccimc"
|
|
7
|
+
version = "2026.06.13"
|
|
8
|
+
description = "MCP server for Cisco UCS CIMC (3.x/4.x firmware) — multi-CIMC registry over HTTP"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.11"
|
|
11
|
+
authors = [{name = "Ryan Malloy", email = "ryan@supported.systems"}]
|
|
12
|
+
license = "MIT"
|
|
13
|
+
keywords = ["cisco", "ucs", "cimc", "mcp", "model-context-protocol"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Development Status :: 4 - Beta",
|
|
16
|
+
"Intended Audience :: System Administrators",
|
|
17
|
+
"License :: OSI Approved :: MIT License",
|
|
18
|
+
"Programming Language :: Python :: 3.11",
|
|
19
|
+
"Programming Language :: Python :: 3.12",
|
|
20
|
+
"Programming Language :: Python :: 3.13",
|
|
21
|
+
"Topic :: System :: Hardware",
|
|
22
|
+
"Topic :: System :: Systems Administration",
|
|
23
|
+
]
|
|
24
|
+
dependencies = [
|
|
25
|
+
"fastmcp>=0.4",
|
|
26
|
+
]
|
|
27
|
+
|
|
28
|
+
[project.scripts]
|
|
29
|
+
mccimc = "mccimc.server:main"
|
|
30
|
+
|
|
31
|
+
[project.urls]
|
|
32
|
+
Homepage = "https://github.com/supported-systems/mccimc"
|
|
33
|
+
Source = "https://github.com/supported-systems/mccimc"
|
|
34
|
+
|
|
35
|
+
[tool.hatch.build.targets.wheel]
|
|
36
|
+
packages = ["src/mccimc"]
|
|
37
|
+
# Non-.py files under the package (src/mccimc/docs/*.md) ship automatically.
|
|
38
|
+
|
|
39
|
+
[tool.hatch.build.targets.sdist]
|
|
40
|
+
# Belt-and-suspenders PII defense. The unpacked-sdist grep before publish
|
|
41
|
+
# is the authoritative check, but excluding these structurally means new
|
|
42
|
+
# dev artifacts don't accidentally ship.
|
|
43
|
+
exclude = [
|
|
44
|
+
"tests/",
|
|
45
|
+
".env",
|
|
46
|
+
"config.toml",
|
|
47
|
+
"mccimc.toml",
|
|
48
|
+
"*.local.toml",
|
|
49
|
+
".pytest_cache/",
|
|
50
|
+
".ruff_cache/",
|
|
51
|
+
"dist/",
|
|
52
|
+
"build/",
|
|
53
|
+
"*.crt",
|
|
54
|
+
"*.pem",
|
|
55
|
+
"*.key",
|
|
56
|
+
".venv/",
|
|
57
|
+
"uv.lock",
|
|
58
|
+
]
|
|
59
|
+
|
|
60
|
+
[tool.ruff]
|
|
61
|
+
target-version = "py311"
|
|
62
|
+
line-length = 100
|
|
63
|
+
|
|
64
|
+
[tool.ruff.lint]
|
|
65
|
+
select = ["E", "F", "I", "B", "UP"]
|