contributes block is how it adds surfaces to Mission
Control. The GCS half declares them under gcs.contributes; the agent
half declares its own (services, shared_topics, drivers, vision
and the MCP lists) under agent.contributes, described in the
manifest reference. This page is the
reference for the GCS-side keys.
Every contribution is declarative. You name what you want in
manifest.yaml, request the matching capability, and the host mounts
it. There is no runtime “register this panel” call.
Each visual contribution needs the matching
ui.slot.* capability under
gcs.permissions. A contribution whose slot capability was not granted
is not mounted: the slot skips it and shows the operator a notice naming
the missing grant. See Permissions.The shape of contributes
missionTemplates,
mapOverlays and targetActions, but the agent’s validator (and so
ados plugin lint, sign and test) rejects the camelCase spelling.
Omit the arrays you do not need. Mission Control parses each array
independently and drops a malformed entry with a console warning rather
than failing the whole plugin. The tools, resources and prompts
lists are covered in the
manifest reference.
Slot and capability map
The slot taxonomy
There are 13 slots. Each maps one-to-one to its capability by replacing dots with dashes:node.detail.tab needs ui.slot.node-detail-tab.
A per-drone contribution is bound to the selected drone: its capability
token names that drone, and it is torn down and re-mounted when the
operator switches drone. The node-scoped slots are the six marked per
drone; the other seven are fleet-level.
skills
A Skill is a flight behavior that surfaces in the cockpit Skill Bar. It can be bound to a hotkey or a gamepad button, toggled or fired once, and gated on arm state. Built-in commands and plugin behaviors such as Follow-Me are the same Skill shape. What it does. Registers an entry in the Skill Bar. Activation writes a key in the plugin’s per-drone config (activation.via: config); the
plugin’s agent half reads that key and starts or stops the behavior. The
Skill’s live state is read back from an event topic (state.via: event), so the bar shows what the plugin reports rather than an
optimistic guess.
ui.slot.flight-skill.
target_actions
A target action is an action a plugin offers on a detection the operator clicks in the cockpit video. It appears in the same popup as the built-in actions, and can be fired on the selected target with a key. What it does. When the operator picks the action, Mission Control optionally designates the clicked box to the drone’s vision tracker, then writes one key of the plugin’s per-drone config so the agent half reacts.config_key as one of the plugin’s
skills inherits that skill’s confirm and arm gates, so the two surfaces
cannot bypass each other. An action that writes false is a stop and is
not gated. A default_key that collides with a chord Mission Control
owns is ignored.
Where it renders. The cockpit target popup on a clicked detection.
Capability. None on the GCS half: Mission Control performs the
designation and the config write itself. The agent half needs the
vision capabilities to see detections (vision.detection.subscribe)
and its flight capabilities to act on them.
tabs
A node-detail tab mounts on a node’s detail panel. It works on any node profile. Use it for a configuration or status surface that belongs to one node. What it does. Adds a tab to the selected node’s detail panel, rendered as a sandboxed iframe scoped to that node. An optionalprofile list narrows which node profiles offer the tab.
profile the tab is offered on every
profile.
Capability. ui.slot.node-detail-tab.
The entry accepts
id or key as its stable id. A tabs entry always
resolves to the node.detail.tab slot; any slot field on it is
ignored.parameters
A parameter is a native, schema-driven form field Mission Control renders itself, with no iframe. The plugin declares the field’s type, bounds and widget; the host renders the control, validates and clamps the value, and writes it to the binding you name.ui.group
and ordered by ui.order.
Capability. No ui.slot.* for the native form itself. A parameter
bound to engine.detector switches the shared vision detector.
The schema, the widget set, visible_if and the bindings are on the
parameter schema reference.
settings
A settings section groups native parameters under a heading. Use it when a plugin has more than a handful of parameters.order.
Capability. ui.slot.settings-section.
panels
A panel mounts the plugin’s iframe bundle into the slot each entry names. Unliketabs, which always resolve to node.detail.tab, a panel
can target any iframe slot.
fc.tab (a tab in a drone’s Setup tab), hardware.tab,
settings.section (an iframe section; use settings for a native
one), cockpit.panel and cockpit.widget (default zone
bottom-left).
Capability. The ui.slot.* capability of the slot you name, for
example ui.slot.fc-tab or ui.slot.cockpit-widget.
overlays
A video overlay draws on top of the live video. Use it for detection boxes or a HUD. What it does. Mounts the plugin’s iframe above the video player, letterbox-corrected so plugin geometry lines up with the video pixels. For vector marks (boxes, reticles, labels) the bridge’scockpit.marks
method composites them into one shared layer instead.
overlays entry implies the video.overlay slot.
Where it renders. Above the live video in the cockpit.
Capability. ui.slot.video-overlay.
notifications
A notification channel lets the plugin push alerts into Mission Control. What it does. Registers a named channel. The GCS half publishes into it withctx.notifications.publish; messages appear as toasts.
notifications entry implies the notification.channel slot.
Mission Control reads only id, title, icon and order from the
entry. Severity is set per message on the ctx.notifications.publish
payload (info, warning, error, success or critical).
Capability. ui.slot.notification-channel.
mission_templates
A mission template adds an entry to the planner’s pattern editor.ui.slot.mission-template.
A template only registers the entry. A mission built from it goes
through the normal pre-upload validation and operator approval before it
reaches the aircraft.
map_overlays
A map overlay draws on the map: polygons, markers or heatmaps.ui.slot.map-overlay.
models
A model registration adds a vision model to the catalog the agent’s vision engine selects from, with per-board variants. Use it when a plugin ships its own detector rather than relying on the built-in catalog. What it does. Registers a model id for a vision task with one or more per-board variants. The agent selects the variant whoseboard_match fits the running board, downloads it from source, and
verifies it against sha256. A model parameter then lets the operator
switch the active detector.
model parameter renders, and feeds the agent’s vision engine.
Capability. None on the GCS half. The agent half needs the vision
capabilities that consume it (vision.frame.read,
vision.detection.subscribe), and a model parameter must bind to
engine.detector to switch the active detector.
agent_pages and node_surfaces
These two put a plugin’s pages where the built-in node pages live, rather than in a generic plugin tab. Both are rendered from the GCS bundle, so they needgcs.entrypoint.
agent_pages[]:
node_surfaces[]:
Next steps
Parameter schema
Widgets, bindings and validation for native fields.
Scaffolder walkthrough
A plugin with a skill, a tab, parameters and a target action.
Permissions
The
ui.slot.* capabilities and the rest of the catalog.Manifest
Every manifest field in dependency order.