Building a Channel Through the MCP¶
A model builds a channel through the MCP the way a person builds one in the channel editor, and QIE holds it to the same rules the editor does before it saves. This page lists those rules; the tools that create a channel and add, link and change its nodes are described with them.
The MCP server also serves this guidance to the model as the qie://guide/build-a-channel resource, which ends with every channel rule in the words describe_type uses, so the two never differ. Two more resources, qie://guide/mapping-functions and qie://guide/conditions, explain each kind of mapping function and condition with an example of each (see MCP Field Reference), and qie://guide/zone-objects explains the objects channels share: when to create each, how channels use it and what changing it does.
Creating a channel¶
create_channel creates a channel from a name and a zone other than Global Settings, which holds no channels. The channel is stopped and already passes the rules, so it holds what the console's dialogs give a new channel:
- an HL7 v2 message format;
- an HL7 MLLP server socket, listening on the next port above Next Port in System Configuration that no channel, destination, the engine or the Management API uses, as the Configured Ports dialog offers it;
- one Discard destination that the source feeds;
- the error settings from System Configuration.
The model then changes the source with save_object and the destination with update_node, and adds the rest of the channel. Until the destination is changed, a started channel accepts messages on that port and completes each one without sending it anywhere.
Changing a channel's nodes¶
A whole-channel save through save_object can change settings and scripts but never the nodes or their links. Seven tools change one part of a channel each, and every one reads the channel at the revision the model sent, makes its change, and saves it through the same checks as save_object:
| Tool | Does |
|---|---|
set_script |
Replaces one script, named by its place in the channel as get_object returns it |
update_node |
Changes one node's settings |
add_node |
Adds a mapping, condition or destination node with no links, one grid column past the rightmost node, and returns its id |
remove_node |
Removes a node and every link to and from it |
link_nodes |
Links the source or a node to a node, on the pass branch or, from a condition node, the fail branch |
unlink_nodes |
Removes such a link |
arrange_channel |
Lays the whole channel out on the channel editor's grid, as described in Laying a channel out |
Every change must leave a channel that passes the rules above, so a model adds a node before linking it and links before it unlinks. Linking nodes that are already linked, or unlinking nodes that are not, changes nothing. A link that would form a loop is refused, naming both nodes.
How nodes are numbered¶
QIE numbers a channel's nodes itself, by the same rule the channel editor uses, and ignores any numbers a model sends:
- The source is node 1.
- The nodes the source links to come next, in their current order, each followed by the nodes it links to: pass links before fail links.
- Nodes the source cannot reach follow, in their current order.
- Destinations are numbered last, in the order they were reached.
A new node is placed after every node that already has a number.
Laying a channel out¶
arrange_channel places every node on the channel editor's grid, the same grid nodes snap to when you drag them, as Qvera lays its channels out:
- The path a message takes when every condition passes runs along the top row, left to right.
- A condition's pass branch stays on the condition's row, one column on. Its fail branch goes below it: straight down when it leads to another condition, one column right and one row down otherwise. A long run of conditions, each failing into the next, zig-zags between two columns, half a row at a time.
- A node that several branches feed sits one column past the furthest of them, between their rows. A Discard that several conditions fail into sits half a row below them, so the fail lines run underneath the other nodes.
- A channel with no branches wraps after five columns, each later row starting half a column in.
- No line runs through a node. When a line would, the node it comes from moves down half a row.
- A node the source cannot reach goes in a row below the rest.
The build_channel prompt asks the model to call arrange_channel once every node is in place. Arranging replaces the layout a person made, so on a channel you laid out yourself the model should ask first. Each arrange is saved as one revision, and restore_revision brings the earlier layout back.
A model is also asked to give every condition's fail branch somewhere to go: a Discard destination when nothing else should happen to a message that fails.
What a channel must be to save¶
QIE refuses a save that breaks any of these, naming the rule and the node:
| Rule | What it means |
|---|---|
| A source and a format | The channel has a source kind and a message format, and both pass their own checks, as the source panel and format settings require |
| At least one node | The channel has at least one mapping, condition or destination node |
| Links stay in the channel | Every link points at a node of the same channel |
| No node links to itself | |
| One link per pair of nodes | A node links to another node once, never with both a pass and a fail link |
| Only conditions have fail links | Mapping nodes have pass links only. Destinations have no links at all; a destination ends its path |
| No loops | No path leads back to a node it already passed through |
| A destination is reachable | At least one destination can be reached from the source through pass links |
| Every path ends at a destination | Every mapping or condition node a message can reach has at least one pass link onward |
| Unique endpoint ids | Two destinations do not share an endpoint id |
| Each node passes its own checks | The checks each node's dialog makes, such as a condition node having at least one condition |
While a channel is in a locked package, the source, format and error handler checks are skipped, as they are in the editor, because those settings cannot change.
A node the source cannot reach is allowed, as it is in the editor, which only warns about it.