MCP
Cards and card tokens
Why some tools can only be called by the card, and how card tokens bind a click to an action.
The server ships an MCP App: a card the client renders beside the chat. The card is where the human acts. Four tools exist only for it: claim_business, open_session, apply_changeset, undo_changeset.
Visibility
These tools are registered with visibility: ["app"], so a conforming client does not offer them to the model. Even if a model called one, it could not succeed: each requires a card token.
Card tokens
When a tool returns a card, it also returns _meta.cardTokens: one token per click the card may make next, each bound to the signed-in user, one action, and one target.
| Returned by | Token | Lets the card call |
|---|---|---|
find_business | open:<business_id> for each editable match; claim:<business_id> for each claimable one | open_session, claim_business |
claim_business | open:<business_id> | open_session |
propose_changes | apply | apply_changeset |
apply_changeset | undo | undo_changeset |
The server verifies the token against the caller, the action, and the target before forwarding to the Edits API. A token for applying changeset A cannot apply changeset B; a token minted for one user is refused for another.
What the card shows
| View | After |
|---|---|
picker | find_business: the matches, editable or locked, with Open or Claim. |
snapshot | get_snapshot: what needs work, with a link to the console. |
changeset | propose_changes, apply_changeset, undo_changeset: each item with its state and a tick box. |
session | open_session: the business and the session's expiry. |
claimed | claim_business: the claim's expiry. |
structuredContent.view names the view; the card reads the rest of structuredContent for its data.
Without a card
A client with no MCP Apps support still gets the text results. propose_changes includes a console link where the user can apply the staged changeset in Keystone instead.