busware

MCP for TUL

Firmware for the busware TUL that lets an AI agent commission KNX devices — not just talk to them. The stick is its own MCP server.

Need the hardware? busware TUL — TPUART USB module. Pick the ESP32-C6: the C3 runs this firmware but has far less headroom, and it is being phased out. The TUL is a hardware platform for your own projects and ships without firmware; this firmware is free, you install it yourself, and busware provides no support for it.

Flash it right here. Chrome, Edge or Opera. Wi-Fi follows in the same USB session, via Improv — no captive portal, no rebuild.

busware TUL hardware only (shop.busware.de/tul). This page reads the stick first and writes the firmware together with a pass issued for that one device; on anything else the firmware refuses to start. The pass ties this firmware to busware hardware, whose sales fund its development. It also keeps an image off a board it was not built for: the KNX pins differ per product, so an image that drove the wrong ones would drive somebody's bus.

What it does beyond relaying group telegrams

Most gateways relay group telegrams: they talk to devices somebody else configured with ETS. This firmware speaks the connection-oriented management services ETS itself uses. It can give a device its individual address, read and write its memory and properties, drive its Load State Machines, install its address and association tables, restart it so the change takes effect, and change device parameters — from one tool surface an agent can call.

Installing a table is the dangerous part, so it is one operation: open the load session, write in chunks that are each verified by read-back, close the session, restart. Nothing outside can interrupt it half-way, and the close runs even when a write fails. That matters because a device left mid-download is not merely unconfigured — while its table is not loaded it resolves no group address at all, and a power cycle does not reliably get it out of there.

It also reads an installation it did not build: a passive survey of everything it hears, and an active sweep that finds the devices on a line and reads back the identity that maps each one to its product file.

On top of that it publishes what it hears to MQTT, renders Home-Assistant discovery, and answers MCP itself, so an agent talks to the stick directly over your LAN.

After flashing

  1. Provision Wi-Fi in the installer (Improv) — or skip the radio entirely: with the PoE W5500 extension fitted, the stick takes wired network and power over one cable, the natural fit for a distribution cabinet. The firmware uses it without configuration.
  2. Open the stick’s own page: http://busware-knx-<id>.local/ — it shows its mDNS name, both addresses, its hardware identity, and the ready-made command below.
  3. Point your agent at it:
    claude mcp add --transport http busware-knx \
      http://busware-knx-<id>.local/mcp
    Any MCP client works; the endpoint is plain JSON-RPC 2.0 over HTTP POST.
  4. Tell it your MQTT broker (optional — everything else works without one):
    mqtt-set_creds {"broker": "mqtt://<host>:1883"}
    Plain mqtt:// or ws://, with user and pass if the broker wants them; TLS is not supported.

Updating

A stick that already runs this firmware is updated over the network, not through this page: open its own update page, http://busware-knx-<id>.local/update, upload the image for its chip and press Reboot once the upload has finished. Current images (0.25.2): ESP32-C6 · ESP32-C3. The pass and the stored settings stay on the stick. A stick that still runs a version before 0.24.0 answers no_ota_partition and needs one more pass through the flasher above.

The update replaces the firmware; the skill document an agent reads from the stick stays as it was. To bring it in line, upload the skill for 0.25.2 (one file for both chips) — no reboot needed:

curl --data-binary @busware-tul-mcp-0.25.2.SKILL.md \
  "http://busware-knx-<id>.local/api/skill?name=SKILL.md"

What the agent gets

ToolsThe stick’s admin verbs — address assignment, the passive survey and the active sweep, memory and property access, Load State Machines, table build/read and the atomic table install, device restart, group send, datapoint types, Home-Assistant projection, device parameters. Including what a device says about its own properties, so an agent can ask whether a write is permitted instead of finding out by trying it.
A skillresources/read skill://busware-knx-stick/SKILL.md — the commissioning runbook, the Home-Assistant handover, and the device traps worth knowing before the first write.
A safety modelEvery mutating tool defaults to dry run: it performs every read and withholds only the write, so its report is truthful about whether the real thing would work. Danger classes C0–C3 are reported per verb. An admin token gates the mutating set once you set one.

What it will not do

It does not guess product semantics. What a ComObject number means, and where a parameter lives in a device’s memory, is in the manufacturer’s .knxprod — not in this firmware. The stick gives an agent the mechanism; the product file stays your input. A tool that invents a mapping here would move somebody’s blinds for the wrong reason.

Example: a blind, from bare bus to a Home Assistant tile

An actuator is wired to the bus and does nothing yet. There is no ETS project, no knxd, no gateway to configure. What you supply is the manufacturer’s product file; the rest is a conversation.

YouA blind actuator is on the bus. Its product file is in ~/knxprod/. Put channel 1 into Home Assistant.

AgentFrom the product file, channel 1 needs four group objects: move up/down (DPT 1.008), stop/step (1.007), position (5.001) and the position status it sends back (5.001). I’ll use 1/1/1 … 1/1/4 unless you have an address plan. Dry run first — I read the device and show you the writes without performing them.

YouAddresses are fine. Go.

AgentBuilt the address and association tables and wrote them in a load session, then restarted the device. Channel 1 answers. Home Assistant now has a cover tile — up, down, stop, and a position slider.

YouThe slider jumps. It only shows a new height once the blind has stopped.

AgentThat is the actuator: it reports its position at the end of a travel, not during it. The discovery I published accounts for it, so the slider follows your input and corrects itself when the real value arrives. For the travel to be calibrated, the device needs its travel time — a parameter, not a group address.

YouTop to bottom takes 45 seconds.

AgentThe product file puts that parameter at a known memory address, 16 bit, in units of 100 ms. Written in a load session and the device restarted; it now reports intermediate positions. I also exposed it in Home Assistant, so next time you type the number there instead of asking me.

What was not involved: ETS, knxd, a project file, a gateway configuration, or a firmware rebuild. The one input that had to be yours is the manufacturer’s product file — it is where a ComObject number and a parameter address get their meaning, and the stick will not invent them. This sequence is the real one from the session this firmware was developed in, on a Merten 649802 blind actuator; the wrong turns it also contained are left out.