Both show up as cards on your dashboard, and both let an agent speak through a Primeta avatar. But they work very differently under the hood — and that difference decides what you can do with each.
MCP sessions are client-pulled (one-directional)
An MCP client (Claude Desktop, Cursor, Claude Code with Token MCP, etc.) talks to Primeta by calling tools. The client decides when to call them.
Client ──tool call──▶ Primeta
◀──result────
Primeta cannot push anything to the client. Every interaction is something the client initiated:
- The LLM wants to speak → it calls
primeta_sendwith the text. - The LLM wants to change persona → it calls
primeta_set_persona. - The LLM wants to know who's installed → it calls
primeta_list_personas.
What this means in practice:
- Typing in the Primeta composer doesn't reach the client. The user's text has nowhere to go — the LLM isn't listening for events. MCP-only conversations hide the composer for this reason.
- Switching persona from the Primeta UI doesn't tell the LLM. The LLM already has the persona's system prompt loaded from when it called
primeta_connect. If you want the LLM to adopt a new persona, ask it to callprimeta_set_persona(it'll get the new prompt in the tool response). - Proactive avatar speech still works — because the LLM chooses to call
primeta_sendon its own turns. That's client-initiated.
Channels are bidirectional (persistent WebSocket)
A channel is a local plugin that opens a WebSocket from your machine to Primeta and keeps it open. The term lines up with OpenClaw's channel SDK — you're registering a Primeta channel inside your agent runtime.
Because both sides hold the socket, either side can send messages at any time.
Channel ◀──chat_message── Primeta (user typed in composer)
──reply──────▶ (agent's response)
◀──persona_update── (user switched persona)
──send──────▶ (agent's proactive speech)
Because Primeta can push into the socket:
- The Primeta composer works. You type, Primeta sends a
chat_messageframe, the plugin dispatches one turn through your agent, and the reply comes back as areplyframe. - Persona switches propagate. The Primeta UI sends
persona_update, the plugin refreshes its cached system-prompt prefix, and the next LLM turn uses the new persona. - The agent can still speak proactively. OpenClaw's
outbound.sendTextsends asendframe back up.
Quick reference
| MCP session | Channel | |
|---|---|---|
| User types in the Primeta composer | Not delivered | Delivered to the agent |
| Persona switch from Primeta UI | UI-only — ask the LLM to switch | Propagates to the agent |
| Proactive speech from the agent | Yes, via primeta_send tool |
Yes, via outbound.sendText (or equivalent) |
| Auth | OAuth or Bearer, per tool call | One-time token on connect |
| Transport | HTTP /mcp |
WebSocket /cable |
| Connection lifetime | Per tool call | Until the plugin stops |
| Integrations | OAuth MCP, Token MCP | OpenClaw |
When to pick which
- Use MCP when your client is a chat app driven by an LLM — Claude Desktop, Cursor, Zed, Claude Code. You want the LLM to call Primeta tools as part of its responses, and you're fine with Primeta being "spoken to" rather than having the Primeta UI drive it.
- Use a channel when you want the Primeta UI to be the front door — typing messages into Primeta, switching personas visually, and having your local agent act as the backend brain.
Nothing stops you from running both at once: your dashboard will show cards for each. They'll usually point at different conversations.