This page is for developers whose MCP App already renders in Claude. If you don’t have an MCP App yet, start with Add an interactive UI to your MCP server.
Send a message from a view
A view is one rendered instance of your app’s UI in Claude. To send Claude a message, callapp.sendMessage in the view’s script. Claude receives the call as a ui/message request. Pass these fields:
role: set it to"user"content: put the message here astextblocks
<button id="plan"> and an element with id="status" to the view’s HTML.
- Asks you to allow the message
- Places the text in your message box, ready to send
Write a message that the user can agree to
Write the message as a request that the user can read and agree to. Put everything that Claude needs in the message itself.- Caution: when Claude fills the message box with your view’s text, a caution can appear above the box. The caution opens with “Use caution before running this prompt.”
- Existing draft: Claude doesn’t replace a draft that the user already has in the message box unless they agree
Handle the result of app.sendMessage
In the view’s script, handle an error result, a result with no error, and a rejected promise, as the sample does:
isError: true: treat the message as not accepted- A result with no error: you can receive this result before the user agrees, and you can’t learn their decision from it. Don’t treat it as evidence that Claude read the message.
- A rejected promise: when the MCP Apps SDK stops waiting, after 60 seconds by default, the promise rejects. Don’t tell the user that the message wasn’t sent, because Claude can still have it after that time.
isError: true.
Keep the control that sends the message usable, so that the user can try again.
Messages that Claude accepts
If you break a length or character rule, Claude can refuse the message.- Content: send
textblocks that aren’t blank. Claude refuses a blank message, and can refuse a message that contains any other kind of block. - Length: send at most 8,000 characters, counted across all blocks, plus one for each block after the first
- Invisible characters: leave out invisible characters, such as soft hyphens and zero-width spaces, unless Claude recognizes them as part of an emoji or a writing system. Persian, Hindi, and Thai are examples of such writing systems.
- Line breaks: use at most three consecutive line breaks
- Spaces and tabs: use at most 64 consecutive spaces or tabs
- Pace: send a message when the user acts, not on a timer, and don’t retry in code.
- If you send messages quickly one after another, Claude can refuse them.
- After the user declines a message, Claude can refuse later messages for a short time.
Next steps
- Let Claude call tools in your MCP App: let Claude change what the user has open in the view
- Supersede older widget instances: stop an older copy of your app from sending messages
- Design guidelines: decide which interactions belong in the app and which in the conversation
- Troubleshoot MCP Apps: open developer tools to inspect the view’s requests