The original 2026.04.27 was published-then-deleted from PyPI within
hours after a stricter audit (against the unpacked sdist, not just
curated source paths) found cluster-fingerprint content that the
pre-publish grep had missed. This release supersedes the deleted one;
no functional differences.
Issues found in 2026.04.27 that this fixes:
1. docs/query-patterns/sip-trunk-report.md — "Live result snapshot"
section (38 lines) contained the live cluster's actual SIP trunk
inventory: real hostnames (exp-c-p.binghammemorial.org), real
internal IPs (172.20.6.99, .104, .105, .114, .120, .222, plus
172.20.2.22, 172.20.14.105, 172.24.10.10), real trunk-name +
description rows. Section removed entirely. The query-pattern doc
itself still ships — schema/SQL guidance is generic and useful.
One inline FQDN example (`exp-c-p.binghammemorial.org`) replaced
with `exp-c-p.example.com`. Status line that named the specific
maintenance release (`Validated against CUCM 15.0.1.12900-234 on
2026-04-25.`) genericized to `Validated against CUCM 15.`
2. .mcp.json shipping in sdist with `/home/rpm/bingham/axl` as the
`--directory` argument. Local filesystem path = hostname leak.
Added to `[tool.hatch.build.targets.sdist] exclude`. File stays
in the source repo for development; no longer ships.
3. pyproject.toml comment about the audit workflow ironically
contained the literal word "bingham" as the example grep token.
Rewritten to use "site-specific tokens" generically.
Audit verification (against the unpacked sdist this time):
tar -xzf dist/mcaxl-2026.4.27.1.tar.gz -C /tmp/sdist-inspect
grep -rnEi 'bingham|binghammemorial|10\.[0-9]+\.[0-9]+\.[0-9]+|
172\.(1[6-9]|2[0-9]|3[01])\.[0-9]+\.[0-9]+|
192\.168\.[0-9]+\.[0-9]+|SupportedSystems|CCX-AXL|
CER-AXL|CUC-AXL|TabSync|variphy|15\.0\.1\.12900|
production cluster|/home/rpm|cucm-pub\.bingham'
/tmp/sdist-inspect/
→ returns empty (verified)
Tests still 155/155.
Lesson encoded for next time: the pre-publish audit MUST run against
the unpacked sdist, not just the four explicitly-named paths in the
python.md rule (src/, tests/, README.md, pyproject.toml, .env.example).
The sdist also pulls in docs/, top-level dotfiles, and uv.lock.
CHANGELOG.md spells this out in the post-release note for next time.
98 lines
4.1 KiB
Markdown
98 lines
4.1 KiB
Markdown
# Changelog
|
|
|
|
This project uses [CalVer](https://calver.org/) — version numbers
|
|
encode the date the package was tested against the upstream Cisco APIs
|
|
and published. Format: `YYYY.MM.DD` with optional `.N` post-release
|
|
suffix for same-day fixes.
|
|
|
|
## 2026.04.27.1 — same-day PII scrub
|
|
|
|
Post-release fix per the python.md immutability rule. The original
|
|
`2026.04.27` was published-then-deleted from PyPI after a stricter
|
|
audit found cluster-fingerprint content in the shipped sdist that the
|
|
pre-publish audit had missed:
|
|
|
|
- `docs/query-patterns/sip-trunk-report.md` contained a "Live result
|
|
snapshot" section with the test cluster's actual SIP trunk inventory
|
|
(real hostnames, real internal IPs). The query-pattern doc itself
|
|
still ships; the snapshot section has been removed and one inline
|
|
FQDN example replaced with `.example.com`.
|
|
- `.mcp.json` was shipping in the sdist with a local filesystem path.
|
|
Added to `[tool.hatch.build.targets.sdist] exclude`. The file
|
|
remains in the source repo for development; it no longer ships.
|
|
|
|
Lesson encoded for next time: **the pre-publish PII audit must run
|
|
against the unpacked sdist, not just curated source paths.** The
|
|
sdist also pulls in `docs/`, top-level dotfiles like `.mcp.json`, and
|
|
`uv.lock`. The python.md rule's example grep covers fewer paths than
|
|
the actual sdist blast surface; the durable fix is `tar -xzf
|
|
dist/*.tar.gz -C /tmp/inspect && grep -rnE 'site-token' /tmp/inspect`
|
|
before every publish.
|
|
|
|
No functional changes between 2026.04.27 and 2026.04.27.1 — just
|
|
metadata and shipped-doc content.
|
|
|
|
## 2026.04.27 — initial public release (deleted)
|
|
|
|
> Yanked-and-deleted from PyPI on the publish date due to a sdist
|
|
> PII leak. Superseded by `2026.04.27.1`. Retained here as a marker.
|
|
|
|
First public release on PyPI as `mcaxl`. Renamed from the internal
|
|
working name `mcp-cucm-axl` to fit the operator's `mc<interface>`
|
|
naming convention.
|
|
|
|
### Tools (19 total)
|
|
|
|
**Foundational**: `axl_version`, `axl_sql`, `axl_list_tables`,
|
|
`axl_describe_table`, `cache_stats`, `cache_clear`, `health`.
|
|
|
|
**Route plan**: `route_partitions`, `route_calling_search_spaces`,
|
|
`route_patterns`, `route_inspect_pattern`, `route_lists_and_groups`,
|
|
`route_translation_chain`, `route_digit_discard_instructions`,
|
|
`route_device_pool_route_groups`, `route_devices_using_css`,
|
|
`route_filters`.
|
|
|
|
**Real-time registration (RisPort70)**: `device_registration_status`,
|
|
`device_registration_summary`.
|
|
|
|
### Prompts (10 total)
|
|
|
|
Schema-grounded conversation seeds: `route_plan_overview`,
|
|
`investigate_pattern`, `audit_routing`, `cucm_sql_help`,
|
|
`sip_trunk_report`, `phone_inventory_report`, `user_audit`,
|
|
`inbound_did_audit`, `hunt_pilot_audit`, `whoami`.
|
|
|
|
### Engineering rigor
|
|
|
|
- **Read-only by structural guarantee**: no AXL write methods are
|
|
registered; the SQL validator rejects non-SELECT/WITH queries as
|
|
defense-in-depth.
|
|
- **Hamilton-style review closed**: 7 findings (2 Critical, 3 Major,
|
|
2 Minor) addressed during pre-release hardening, each with a
|
|
regression test.
|
|
- **Live-cluster verified**: every tool path verified against a
|
|
live CUCM 15 cluster before release.
|
|
- **155 unit tests**, schema drift guard for all 71 known
|
|
`fkcallingsearchspace_*` columns (via
|
|
`test_complete_schema_coverage_against_known_columns`).
|
|
|
|
### Known limitations
|
|
|
|
- `route_translation_chain` evaluates CUCM wildcards (`X`, `!`,
|
|
`[0-9]`, `@`, `\\+`) but does not model route-filter constraints on
|
|
`@` patterns — use as guidance, not authoritative.
|
|
- AXL WSDL must be supplied externally (Cisco-licensed; not bundled).
|
|
See `README.md` for bootstrap instructions.
|
|
- RisPort `state_info` cursor pagination is implemented but not yet
|
|
stress-tested on clusters with > 1000 devices in a single class.
|
|
|
|
### Acknowledgments
|
|
|
|
Borrowed two ideas from
|
|
[`@calltelemetry/cisco-cucm-mcp`](https://github.com/calltelemetry/cisco-cucm-mcp)
|
|
(MIT licensed): the RisPort70 SOAP envelope shape and the
|
|
exponential-backoff retry policy on HTTP 503. Their tool covers
|
|
operational debugging (logs, perfmon, packet capture) — install both
|
|
side-by-side for compound questions like *"audit found CSS X
|
|
unreferenced AND RisPort confirms zero phones registered against it."*
|