Channels reference
A channel lets a connected MCP server push a message into a running interactive session. A chat bridge, a webhook relay or a CI watcher can then hand the agent new work without you typing it. This page is the contract for server authors and the rules that decide which messages get through. For a walkthrough, see Channels.
How a message flows
- Your MCP server declares the channel capability when it connects.
- Whenever it has something to say, it sends a
notifications/syntic/channelnotification. - Syntic Code queues the message in a small per-server inbox.
- Between screen updates, the session drains each inbox and checks every message against the rules below.
- An accepted message shows as a one-line notice (
⇠ server: first words…) and is queued as a user turn, wrapped so the agent can tell it apart from something you typed. If the agent is idle, it starts working on it right away.
Channels run in interactive sessions only. -p runs do not read them.
Server side
Declare the capability
Add the syntic/channel key to the experimental capabilities your server returns from initialize:
{
"capabilities": {
"tools": {},
"experimental": { "syntic/channel": {} }
}
}A server that never declares it cannot push, even if you trust it.
Send a message
{
"jsonrpc": "2.0",
"method": "notifications/syntic/channel",
"params": {
"content": "Build #812 failed on main: 3 tests in api/orders.",
"meta": { "chat_id": "C024", "sender": "ci-bot" }
}
}| Param | Type | Rules |
|---|---|---|
content | string | Required. Blank content is ignored. Text past 16 KB is cut, with a note giving the full size. |
meta | object | Optional flat key/value pairs. String, number and boolean values are kept as text; nested values are skipped. Up to 16 fields. |
What the agent sees
The message reaches the agent wrapped in a channel element. The server name becomes the source attribute and each meta field becomes another attribute:
<channel source="ci-watch" chat_id="C024" sender="ci-bot">
Build #812 failed on main: 3 tests in api/orders.
</channel>Attribute values are escaped. A meta key is only used when it starts with a letter or _ and holds only letters, digits and _; other keys are dropped.
Limits
| Limit | Value |
|---|---|
| Message body | 16 KB |
meta fields per message | 16 |
| Messages waiting per server between drains | 32. Extra messages are counted, dropped, and reported to you. |
Who may push
Every message must pass all of these checks, in order. The first one that fails decides the note you see.
| Check | Passes when | Note when it fails |
|---|---|---|
| Channels are on | At least one trusted server, and no "channelsEnabled": false in your user settings or managed policy | channels are off for this session |
| The server is trusted | It is named in --channels, or in the channels list of your user settings | it is not listed in —channels |
| Organization list | Managed policy has no allowedChannelServers list, or the list names the server | your organization’s channel list does not include it |
| Capability | The server declared syntic/channel | the server did not declare the channel capability |
| Permission rules | No deny rule covers the server (mcp__<server> or a wildcard) | a permission deny rule covers this server |
When channels are off altogether and a server was never trusted, its messages are dropped silently.
Project and local settings cannot trust a server or turn channels on. A repository you clone can never open a channel into your session.
In bypass permission mode, accepted messages are held back with a warning instead of being run, so a pushed message can never act without any checks.
Turn channels on
For one run:
syntic --channels ci-watch
syntic --channels ci-watch,chatbridge--channels can be repeated and takes comma-separated names. The names are MCP server names from your configuration.
Every session, in ~/.syntic/settings.json:
{ "channels": ["ci-watch"] }Settings keys
| Key | Where it counts | Meaning |
|---|---|---|
channels | User settings | Servers trusted to push, added to --channels. |
channelsEnabled | User settings, managed policy | false turns channels off. |
allowedChannelServers | Managed policy | When set, only these servers may push, even if trusted. |
Troubleshooting
| You see | Do |
|---|---|
| Nothing at all | Check the server is connected in /mcp, and that you started with --channels <name> or listed it in user settings. |
| ”did not declare the channel capability” | Add syntic/channel to the server’s experimental capabilities. |
| ”not listed in —channels” | The name must match the server name in your MCP configuration exactly. |
| ”were dropped” | The server sent more than 32 messages between drains. Batch them into fewer messages. |
| ”Held back … while permissions are bypassed” | Leave bypass mode to let pushed messages run. |
Related: MCP servers, Permission rules, Managed settings, CLI reference.