No chat client lets an MCP server register a mention. claude.ai has no @ for connectors. Claude Code's @ lists resources, and its slash commands are prompts — RelayLink exposes both for contacts, but the conversational shorthand is still not a registered mention.
It works because the instructions the server sends at connect time teach the model what the word means. Those instructions are a function of this host's handle, so a sandbox teaches a different word than production. /docs and the landing page show whichever this host uses. Do not copy a spelling from a guide and assume it is universal.
Draft, never send
"@relaylink Priya — the deck is ready, can she review it by Friday?" means: resolve Priya against accepted contacts, open a draft with that ask, stop for approval. The short form — @rl where the handle derives it, or the sandbox-shaped alias on a sandbox — means the same.
There is no path from the shorthand to a send without you. The review step is the product.
How a name resolves
draft_package takes a contact name alongside an email address. Resolution runs against accepted contacts only:
- Nickname first — the word you chose
- Then whole name, then a word of the name, then prefixes — stop at the first tier with any match, so an exact "Richard" beats "Richard Hale"
- A name that is not an accepted contact fails exactly like an unknown one. Pending, blocked, and stranger included. The resolver will not tell you whether someone has an account
- A tie is refused with the candidates named. A guess is a package to the wrong person
- Name and email together, disagreeing, are refused for the same reason
Tool descriptions do not name the handle, because a description baked into the code would be wrong on a sandbox. Only the instructions do.
Resources and the send-to prompt
In Claude Code, accepted contacts appear under @ as resources, and send-to is a prompt. Both stop at preview-and-approve. They are instructions, not a send button. When the prompt cannot resolve the person, it carries the server's own message so the model asks rather than guesses.
The list is yours. A contact resource for anyone but an accepted contact of this caller answers not-found — the same not-found, so the picker cannot be used to learn who else has an account.
A stale list is not the server
Assistants cache. You set a nickname, or someone accepts, and the model still answers from the list it fetched earlier — "that person is not a contact" — without calling again.
The instructions, the list_contacts description, and the resolver's own refusal all say the same thing: try the name against the server, and re-read the list before saying no. If your assistant still answers from memory, say it: check my RelayLink contacts again.
Connect, try the short form once, and approve what it drafts. That is the loop the shorthand exists to start.