Plugin: Command Response MQTT

Audience: Integrators building a plugin that receives commands over MQTT and publishes responses — a bidirectional pattern suitable for request-driven components like bridges, proxies, and action dispatchers.
The minimal plugin examples show a plugin that only publishes outbound. This example adds the inbound side: the plugin subscribes to a Commands/+ topic, processes each command, and publishes results to a corresponding Responses/+ topic. A separate Status topic provides a channel for health signals. This is a cross-platform JSON — the same file covers Windows, Linux, and macOS.
Read Plugin: Minimal Windows first if you have not already. This page focuses on the command/response topic layout and does not repeat the field-by-field explanation from that page.
The Plugin JSON
What to Change
id
A stable, unique identifier matching the filename. All topic paths below derive from this ID by convention — change them together.
executablePath
Path to your binary. For Linux and macOS, remove the .exe extension and confirm the install root. See the Minimal Linux and Minimal macOS pages for platform-specific path and permission details.
supportedPlatforms
Remove any platforms you do not ship for.
Subscription.Topic
The primary MQTT topic for this plugin. By convention, use the plugin id.
metadata.mqttTopics.publish
Replace MyWorker throughout with your plugin id. Add or remove topics as your design requires.
metadata.mqttTopics.subscribe
Replace MyWorker with your plugin id. Tighten the wildcard if your command space is bounded — see below.
startupPriority
50 starts this plugin slightly earlier than the default 60. Lower only if your plugin has dependencies that must start first.
How This Works
The topic layout. The three topic patterns form a conventional command/response structure:
MyWorker/Commands/+
Subscribe
Inbound commands. The + wildcard matches one level — MyWorker/Commands/scan, MyWorker/Commands/reset, and so on. Each command type gets its own sub-topic.
MyWorker/Responses/+
Publish
Outbound results, mirroring the command sub-topic. A response to MyWorker/Commands/scan publishes to MyWorker/Responses/scan. Callers subscribe to the response topic they care about.
MyWorker/Status
Publish
Health signals, heartbeats, or state changes. Subscribers use this to monitor whether the plugin is alive and what state it is in without sending a command.
The primary Subscription topic is separate. MyWorker (the Subscription.Topic) is the orchestrator-level identifier for the plugin. It is listed separately from the command/response topics in metadata.mqttTopics.subscribe — both are subscribed, but they serve different purposes. The primary subscription is how the agent knows the plugin is connected; the command topics are how callers drive it.
Tighten wildcards in production. Commands/+ permits any single-level subtopic. If your plugin only handles a known set of commands, restrict the subscription to explicit topic strings rather than a wildcard:
And restrict publications to explicit response topics:
Wildcards are convenient during development but give the broker less to enforce. Explicit topic lists are a tighter security posture for production.
Correlating commands and responses. The topic naming convention handles routing, but your payload should also carry a correlation ID so callers can match a response to the command that triggered it — especially when multiple callers may issue commands concurrently. This is a design responsibility in your binary, not something the plugin JSON or broker enforces.
startupPriority: 50 starts this plugin slightly earlier than plugins at the default 60. Use a lower priority only if something that starts before you needs to be ready first, or if callers expect the plugin to be available shortly after agent startup. Avoid racing to start as early as possible — earlier priority means fewer other components are ready when yours starts.
Before You Deploy
Sign the binary for each platform you support. On Windows, use Authenticode. On macOS, sign with Apple Developer ID and notarize. On Linux, align with your deployment's signing enforcement.
Ship platform-specific binaries under the correct paths. For a cross-platform plugin,
bin/MyWorker/MyWorker.exeis the Windows binary. Linux and macOS binaries atbin/MyWorker/MyWorker(no extension) should live at the same relative path under their respective agent roots.Set executable permissions on Linux and macOS with
chmod +x.Place the JSON file at
{AgentRoot}/Plugins/MyWorker.jsonon each endpoint.Confirm that any component subscribing to
MyWorker/Responses/+orMyWorker/Statushas MQTT subscribe permission for those topics before going live.Restart the agent so the orchestrator picks up the registration.
Verify
After the agent restarts, confirm the plugin connected by checking that its primary subscription topic is active in the agent logs. Then publish a test command from a trusted process and verify the response arrives on the expected topic. If the response does not arrive, check:
That the command topic string matches exactly what the plugin subscribes to
That the response topic is in
metadata.mqttTopics.publish— a missing entry causes a silently denied publish, not an error visible to the callerThat the calling process has permission to publish to the command topic and subscribe to the response topic
Last updated

