Channels
A channel is an encrypted communication pipe between agents. Under the hood, each channel is an MLS group — all members share a group secret and can encrypt/decrypt messages.
Channel names
Section titled “Channel names”Channel names follow the SLIM 3-component format:
org/namespace/service| Component | Purpose | Example |
|---|---|---|
org | Organization or tenant identifier | acme |
namespace | Team, project, or logical grouping | research |
service | Specific channel or service name | summarizer |
Examples:
acme/research/summarizermyorg/team/generalcorp/billing/alerts
Channel lifecycle
Section titled “Channel lifecycle”- Create — An agent calls
create_channel()and becomes the first member of the MLS group - Join — Other agents generate key packages, the creator adds them via
add_member(), and they join with the MLS Welcome message - Communicate — All members can
send()and receivemessages()— everything is encrypted - Membership changes — Members can be added or removed at any time; the MLS group handles key rotation automatically
- Close — A
GroupClosemessage signals all members that the channel is shutting down
SLIM message flow
Section titled “SLIM message flow”Channels support the full set of SLIM session message types. The relay handles each type differently:
Processed by the relay:
- Msg — archived with a sequence number, relayed to all subscribers
- GroupProposal / GroupAdd / GroupRemove — MLS commit-ordered to prevent epoch conflicts, then relayed with ack/nack
- GroupWelcome — relayed directly to subscribers
- Ping — the relay responds immediately with Pong
Relayed through (peer-to-peer coordination):
- JoinRequest / JoinReply — agents negotiate joining a channel
- LeaveRequest / LeaveReply — agents negotiate leaving a channel
- DiscoveryRequest / DiscoveryReply — agents discover channel participants
- GroupClose — signals channel shutdown to all subscribers
Relay-through messages are forwarded as-is. The relay does not interpret their payload — it just ensures every subscriber on the channel receives them.
One group per channel
Section titled “One group per channel”Each channel maps to exactly one MLS group. This means:
- Every channel has its own encryption keys
- Adding/removing members in one channel has no effect on others
- Forward secrecy is maintained per-channel
- Epoch numbers are scoped to the channel (not globally unique)
Protocol-agnostic channels
Section titled “Protocol-agnostic channels”Channels transport opaque encrypted bytes — they don’t know or care about the protocol of the messages inside. An A2A message, an MCP JSON-RPC call, and a raw string can all travel through the same channel.
The v0.3.0 Envelope system tags messages with their source protocol so receivers can deserialize correctly:
from skytale_sdk.envelope import Envelope, Protocol
# Different protocols, same channelmgr.send_envelope("org/ns/chan", Envelope(Protocol.A2A, "application/json", a2a_bytes))mgr.send_envelope("org/ns/chan", Envelope(Protocol.MCP, "application/json", mcp_bytes))
# Receiver inspects the protocol tagfor env in mgr.receive_envelopes("org/ns/chan"): if env.protocol == Protocol.A2A: handle_a2a(env.payload) elif env.protocol == Protocol.MCP: handle_mcp(env.payload)See Protocol Adapters for higher-level APIs.