Skip to main content

A2UI chat surfaces

When the MCP host supports A2UI, signal-mcp serves read-only chat-surface resources that render Signal conversations as native UI — two-sided message bubbles, sender names, human-readable timestamps, attachment lines, and emoji reactions on their target bubbles.

Resources

Four resource URIs are registered (two schemes × two surfaces):

URIWhat it renders
signal://conversations/a2ui{?w}Index of buffered conversations
mcp://signal/conversations/a2ui{?w}(same)
signal://conversation/{id}/a2ui{?w}One conversation thread
mcp://signal/conversation/{id}/a2ui{?w}(same)

{id} is a phone number (E.164) or a Signal group id. Group ids are base64 and may contain / and =, so they must be percent-encoded in the URI.

{?w} is the optional width hint A2UI hosts append uniformly to any /a2ui URI (?w=112). Both surfaces accept it and currently ignore it; the bare URI works identically. Declaring it makes every URI a template, so all four advertise under resourceTemplates/list rather than resources/list.

All resources declare MIME application/a2ui+json and audience: ["user"]. The model's programmatic tools (receive_message, sends, reactions, mark_read) are unchanged — resources are purely additive.

Scope and limitations

History is in-memory, instance-local, and cleared on restart. The buffer covers only traffic this server process observed during its own lifetime, plus its own outbound sends. The phone is the only complete record — this is not a message archive. Two concurrently running instances will legitimately show different things.

Configuration

Three configurable caps bound memory use:

FlagEnv varDefaultSemantics
--history-message-capSIGNAL_MCP_HISTORY_MESSAGE_CAP200Messages per conversation (FIFO eviction)
--history-conversation-capSIGNAL_MCP_HISTORY_CONVERSATION_CAP50Total conversations (LRU eviction)
--history-text-capSIGNAL_MCP_HISTORY_TEXT_CAP4096Stored text bytes per message (truncation with marker)

Reference