A channel is the route that connects a person to Metnos. Web chat and Telegram have different interfaces, but both deliver requests to the same runtime. The medium and available features change; the rules governing actions do not.
The channel handles transport. It recognises the sender through an existing pairing, gathers text and attachments, calls the runtime, and returns the answer. It does not choose executors, bypass Vaglio, or decide which powers to grant.
| Part | Responsibility |
|---|---|
| Channel | Receives and sends messages and keeps the identifiers required by the transport. |
| Runtime | Understands the request, prepares the work, and coordinates executors. |
| Controls | Check identity, authority, policy, placement, and required confirmations. |
For example, “send Lucia the meeting summary on Telegram” does not require the requester to know her technical chat number. Metnos finds Lucia's paired Telegram channel and, if the action is allowed, delivers the message there.
Each request is attributed using authenticated channel data. A name written in the message or displayed by Telegram cannot assign a role, switch users, or claim somebody else's resources.
Conversations, pending dialogues, approvals, and notices are scoped to the recognised user. Even a button click is checked again: knowing or forwarding a button's internal code does not authorise the linked action.
Browser and Telegram pairing are described in Pairing and identity.
The browser takes a direct path. The page sends the request to the HTTP server, which authenticates the session and calls the runtime. It can return a complete JSON response or stream progress updates while the turn is running.
Web chat does not implement the polling cycle in the Channel
contract: HTTP already has its natural request-and-response model. This is a
transport difference, not a governance difference. Policy, Vaglio, executors,
and user separation remain the same.
Available routes and methods are documented in HTTP API.
Telegram uses a small service process and the official Bot API. Metnos opens outbound connections to Telegram, so a home server does not need to expose an incoming port or configure a webhook.
The channel is enabled during installation when a bot token is provided. Metnos looks for that token, in order, in explicit configuration, environment variables, the encrypted credential store, and the legacy compatibility file. A normal installation uses the encrypted store.
The Telegram service is optional. On systems using systemd, it
runs as the Metnos user's service, starts with the rest of the instance, and
restarts after a failure.
/start and /pair commands are the exception because
their purpose is to create that pairing.The identifier of the latest acknowledged update is stored atomically. If handling or storage fails, the identifier does not advance, and Telegram may redeliver the message on the next pass. This reduces the risk of losing a request during an abrupt shutdown.
| Content | Behaviour |
|---|---|
| Text | It becomes a request or a reply to an already open dialogue. |
| Photos | They are downloaded only after the sender has been recognised. Closely timed album items are collected into one request, and every file remains subject to configured limits. |
| Location | It may answer a location prompt or update the authenticated user's location. Sharing is always initiated by the user in Telegram. |
| Buttons | They support choices, cancellation, and approval. Button data is accepted only while the matching state is valid and belongs to the same user. |
| Unsupported content | It is acknowledged at transport level without being arbitrarily reinterpreted as a request. |
Long replies are split to respect Telegram's limits. Formatting is adapted to the channel; if Telegram rejects formatted text, Metnos retries in plain text. A partial or uncertain delivery is reported as such, because retrying the whole response could duplicate the part already received.
A reply normally returns through the channel that originated the turn. A different destination must be declared in the request and authorised. Metnos does not silently move a conversation between users or channels.
Some work finishes after the original turn has timed out, such as a remote executor waiting for its computer to return. Metnos then places the result in the user's private queue, and the Telegram service attempts delivery in later cycles without running the action again.
For polling-based transports, Metnos defines a very small Python contract:
class Channel(Protocol):
name: str
def poll(self) -> list[InboundMessage]: ...
def send(self, recipient: str, message: OutboundMessage) -> dict: ...
InboundMessage keeps the sender, text, identifier, timestamp,
and transport metadata. OutboundMessage contains text, an optional
message to reply to, and buttons. Received objects are immutable: an arrived
message is a fact to record, not a workspace to alter.
The contract separates transport mechanics from request semantics. A new adapter may normalise its own messages, but it must deliver them to the same runtime and honour the same identity checks.
To learn how to open the web interface, continue with Open and use Metnos. For server details, continue with HTTP API.