// docs / concepts

MCP sessions vs channels

MCP is one-directional (the client pulls). Channels are bidirectional (the Primeta UI can push). This is why the two feel different in practice.

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_send with 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 call primeta_set_persona (it'll get the new prompt in the tool response).
  • Proactive avatar speech still works — because the LLM chooses to call primeta_send on 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_message frame, the plugin dispatches one turn through your agent, and the reply comes back as a reply frame.
  • 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.sendText sends a send frame 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.