← MCP / Code presence

Rendering an object that has no Code

Under DEC-025 a Code is minted only when someone deliberately hands context over, so most objects an MCP tool returns will not have one. Both harness tiers need a second rendering, and the plain tier needs it most: in a text transcript, any stand-in character is indistinguishable from a truncation artifact.

Companion to the app surfaces in concepts/code-presence-v1. Per-harness config lives in relay-platform docs/DESIGN-NOTE.mcp-rich-display.md; components in src/relay/mcp/ui/.

DEC-025 · identity-and-codes relay AJA9TN proposal · 2026-08-01
L1
Mark presence, never absence

A Code line is emitted or it is not. No dash, no (no code), no empty bracket pair. In plain text a placeholder cannot be distinguished from a broken render.

L2
One accent moment per card

Rich: the Code when shared, the share action when not. Plain: the Code token is the only styled run in the block; an unshared object has no styled run at all.

L3
The title never changes rank

Same line, same position, same emphasis in both states. The title is what the agent uses to talk about the object; it is not a substitute identifier.

L4
Bracketed labels, never glyphs, in plain

[Relay] A3BF72KQ. The prefix belongs to the rich tier only, where it can be marked decorative.

A single object, both states

relay_context · relay_search hit

The shared object leads with its Code. The unshared object leads with its title and simply has one fewer line. Nothing moves up to take the vacated position, which is what keeps the two renderings comparable when an agent prints them back to back.

relay_contextshared · Code present
State 1 — in circulation
Rich
Relay Context
--- Relay AJA9TN Q3 pricing model, assumptions and open questions Shared 2 days ago · claimed once ---
Plain
Relay Context
[Relay] AJA9TN Q3 pricing model, assumptions and open questions Shared 2 days ago · claimed once
The carries aria-hidden plus a visually hidden “Relay” label, so assistive tech reads “Relay AJA9TN” and never the Unicode character name. The plain tier gets the same words from the bracket instead.
relay_contextunshared · no Code
State 2 — never left
Rich
Relay Context
--- Onboarding copy, second pass Yours · edited 2 days ago Share this relay ---
Plain
Relay Context
Onboarding copy, second pass Yours · edited 2 days ago Share it to give it a Code.
One line fewer, not one line blanked. The rich tier moves its accent to the action; the plain tier states the capability in words, since a text transcript has no button to carry it.

A list with both kinds in it

relay_search · relay_sessions

Alignment does the work. Codes sit in a fixed leading column so the eye reads circulation straight down; rows without one start at the title column. The trailing summary is what makes absence countable, and it describes the rows returned, never the workspace.

relay_search6 results · mixed
Rich
Relay Search
---
Relay AJA9TNQ3 pricing model
Onboarding copy, second pass
Notes from the Thursday sync
Relay KTVANVCustody journey handoff
Scratch: residency region wiring
Relay PMHUK3Launchpad extraction scope
--- 3 of 6 shown have been shared
Plain
Relay Search
[Relay] AJA9TN Q3 pricing model Onboarding copy, second pass Notes from the Thursday sync [Relay] KTVANV Custody journey handoff Scratch: residency region wiring [Relay] PMHUK3 Launchpad extraction scope 3 of 6 shown have been shared.
Leading whitespace is padding, not a placeholder: it holds the column without asserting anything. If a harness collapses whitespace, drop to one object per line rather than substituting a character.

The moment a Code exists

relay_send · relay_session package

This is the one response where the Code is the subject rather than a field, so it gets the full hero weight in rich and its own line in plain. Copy stays at capability level: what the Code lets someone do, never how it comes to exist.

relay_sendcreated
Rich
Send Relay
--- Relay AJA9TN Q3 pricing model Anyone with this Code can claim the context. ---
Plain
Send Relay
[Relay] AJA9TN Q3 pricing model Anyone with this Code can claim the context.
RCTX-1073 gate: capability language clears it, mechanism language does not. “Anyone with this Code can claim the context” is fine. Any sentence explaining how or when a Code comes into being is not, in either tier.

What not to emit

plain tier

Every one of these was written to be helpful. In a transcript that an agent may re-read, quote, or summarise, each of them creates a fact that is not true.

[Relay] —————— Onboarding copy, second pass
A dash where the Code would be

Reads as a redaction or a failed lookup. An agent summarising the transcript later has no way to tell whether the Code was withheld or never existed, and will hedge in its own output.

[Relay] (not shared) Onboarding copy, second pass
A parenthetical state stamp

Spends the line on a non-event, and repeated down a list of twenty results it becomes the loudest thing in the block. Absence belongs in the summary line, once, where it can be counted.

⇄ AJA9TN Q3 pricing model
The glyph in plain text

The prefix is a visual device. Emitted as raw text it reaches screen readers as “left right arrow with double vertical stroke”, survives copy-paste into places that cannot render it, and gives the agent a token it may try to reproduce. Plain uses the bracket.

[Relay] r7f3a91c04d2e Onboarding copy, second pass
The internal ID standing in

IDs are lowercase hex machine handles, not a display surface. Their narrow alphabet keeps them shape-disjoint from uppercase Codes, which is exactly what lets one resolver dispatch on shape; printing one into a chat invites a person to try claiming it.

App surfaces: concepts/code-presence-v1 Brief: BRIEF.code-presence.md Upstream: relay-platform DESIGN-NOTE.mcp-rich-display.md · RCTX-1066