Skip to content

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.