load_ga_export (32nd tool), multi-address entity naming, climate setpoint shift,
suggest_repairs crash fix, CI runs the whole test suite. Details in CHANGELOG.
Pre-release checks: corpus guard no drift on six real projects; twine check PASSED
for wheel and sdist; mcp-name marker present in METADATA; wheel carries ga_export
and no tools/tests/corpus files; sdist has no corpus map or project files; a clean
isolated venv from the wheel imports 0.8.2 and exposes load_ga_export. CHANGELOG
compare links added for 0.8.1 and 0.8.2.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The CI ran tests only. Added a lint job with two narrow gates:
ruff with select = E9,F — syntax errors and pyflakes (undefined names, unused
imports, broken f-strings). Style rules are deliberately off: the full default
set flagged 202 things, almost all cosmetic, and a gate nobody reads is not a
gate. Fixed the 9 findings it did have (8 unused imports, 1 empty f-string).
mypy, clean at 13 errors fixed. None of the 13 was a live bug, so every fix is
an annotation or a local rename: the two accumulators in advanced, the block map
in appprog_parser, a reused loop name in project and in repair, a TypedDict lost
through dict(), a mixed-type summary dict in handover. Two are worth naming.
_CH_TOKEN_RE now captures the letter prefix directly instead of re-matching its
own capture, which removes an unguarded .group() on a possibly-None match; the
regex accepts exactly the same strings. repair's status-DPT lookup now spells out
the None case, which is what dict.get already did since None is not a key there.
Verified the fixes moved nothing: the full suite passes, and the corpus guard
reports no drift across all six real projects, the 3646-GA one included.
Matrix extended to 3.13 and 3.14; both were smoke-tested locally first.
Dependabot config for pip and github-actions, weekly and grouped so a quiet week
is one PR. Dependabot security updates and CodeQL default setup enabled in the
repository settings.
- server.json name fixed to io.github.NickoScope/nickol-knx-mcp (registry permissions are case-sensitive)
- README mcp-name marker in the same case; 0.8.0 had it lowercase, which the registry rejects
- version bumped in pyproject + __init__; CHANGELOG 0.8.1
- registry: io.github.NickoScope/nickol-knx-mcp v0.8.1 active, package pypi/nickol-knx-mcp 0.8.1
Document both new tools in README (tool count 28 -> 30), add a CHANGELOG entry
under Unreleased, and ship the room_templates/*.yaml + SCHEMA.md as package data.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
A .knxproj is a user-supplied ZIP-of-XML — untrusted input. New safexml.py
centralises hardened parsing for every place we open an archive or parse XML
ourselves (load_project, check_device_parameters, app-program parser):
XML - dependency-free reject of DOCTYPE/ENTITY (billion-laughs / XXE;
legitimate ETS XML never carries one) + defusedxml parser-level
blocking when installed (added as a dependency).
ZIP - pre-flight against absolute caps (archive size, entry count, per-member
and total decompressed size, compression ratio) rejects zip-bombs;
member names checked for path-traversal / absolute paths; each member
read through a streaming cap so a lying header can't exhaust memory.
Violations return a normal error dict, not a traceback. Still read-only.
Raised by external security review. tests/test_safexml.py (11/11 suite green).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
From validator to repairer: propose concrete fixes, not just flag problems.
- B1 repair-suggestion engine (repair.py) + suggest_repairs MCP tool: infer a
DPT for a missing-DPT GA, correct a suspect sub-DPT, synthesise a status GA in
a free slot, or add an absolute-brightness GA. Suggestions only; accepted new
GAs feed generate_ets_group_addresses; never writes to ETS or the bus.
- A2 relative-only-dimming detector (analyze.py): 3.007 relative dimmer with no
5.001 absolute-brightness GA in its zone -> HA cannot set a level.
- A3 cover invert/travel-time surfacing (generate_ha.py): verify_cover_invert
review note lists actuator-dependent flags absent from the .knxproj and warns
when position lacks a state address.
- A2/A3/B1 regression tests; CHANGELOG + version bump to 0.5.0.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
A1 — sub-DPT sanity linter: when a GA name implies a specific DPT
sub-type (temperature->9.001, power->14.056, brightness/position->5.001),
flag a wrong sub or wrong main. Multilingual, conservative; surfaced as
the subdpt_suspect finding via check_dpt / analyze_all.
A4 — KNX Data Secure posture: secure_posture() + new check_secure MCP
tool. Report-only summary (secured vs plaintext counts, mixed
secure/plaintext middle groups, keyring handover checklist). Reads only
the per-GA Security flag; no key material touched. Handover pack section
5 rewritten to this posture section.
Version bump to 0.4.0; CHANGELOG updated.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Turn the tool from a .knxproj validator into a design aid.
- device_library.py + decompose_device / list_device_recipes MCP tools:
expand a device (order number / type / alias) into its group-address
recipe — command/status/dimming/position/mode objects with DPTs —
across Zennio + ABB families. Generic vendor facts, typical-wired set.
- docs/spec-to-structure.md: the spec→structure methodology, with a
measured account of what a spec reproduces (~90%) vs the per-device
object count it cannot (2–9× per-project parameterisation).
- Ship alongside the Track B generate_handover_pack and the de-noise
refinements accumulated since 0.2.0.
- CHANGELOG 0.3.0; version bump 0.2.0 → 0.3.0; new device-library tests.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Bump version 0.1.2 -> 0.2.0 (pyproject + __init__). Promote the
Unreleased changelog section to [0.2.0] — 2026-06-30. Scrub a client
city label from two test comments (provenance note only, no PII/topology).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Bump to 0.1.2 and finalize CHANGELOG. Second hardening pass (round-2 public
ETS4/5/6 fixtures): complete dimmable lights, wider shutter detection
(1.001/1.017 + zone-identity guard), and date/time/text DPT routing.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Bump version to 0.1.1 and finalize CHANGELOG. This release bundles the fixes
found by running the tool against real ETS5/ETS6 project files: the critical
load_project recursion, the now-implemented ETS Function role pairing, no-silent
-drops in HA generation, smarter shutter/German classification, venetian slat
tilt handling, and diagnostics alarms as binary_sensors. 5 regression tests added.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Design-time MCP server that reads .knxproj (read-only), validates naming/DPT/status,
and generates Home Assistant KNX YAML + ETS-importable group addresses (XML/CSV).
No live bus access — confined-workspace writes only.
Includes: 12 MCP tools, end-to-end smoke test, MIT license, English-first README
(+ Russian), CONTRIBUTING with a real-project test call, SECURITY policy, CHANGELOG,
GitHub Actions CI (Python 3.10–3.12), and issue/PR templates.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>