Skip to main content

Returning rich responses to the Slackbot MCP Client

This feature is still rolling out to developers

To check if you have access to this feature, go to App Settings. For any app, look for an MCP Servers label in the left sidebar under Features.

MCP servers can return rich, interactive UI in one way (for now):

MCP Apps (interactive UI)

MCP Apps are rich, interactive UI experiences returned by MCP servers. Instead of returning plain text that Slackbot renders as a conversational response, your tools can return full interactive interfaces (dashboards, forms, approval flows) that render natively in Slack.

When an MCP tool returns a response containing a _meta.ui.resourceUri field, Slack detects this and renders the UI resource as an interactive block:

  1. A tool is called by Slackbot based on the user's prompt.
  2. The tool returns data plus a _meta.ui.resourceUri pointing to a UI resource.
  3. Slack fetches the UI resource (HTML/JS) from that URI.
  4. The content is rendered as an interactive block in the conversation.

Example response

{
"content": [
{
"type": "text",
"text": "You have 4 pending tasks"
}
],
"_meta": {
"ui": {
"resourceUri": "ui://acme/task-dashboard"
}
}
}

The content field provides a text fallback, while _meta.ui.resourceUri tells Slack where to fetch the interactive UI.

Integration types

Integration typeTool returnsUser experience
Client-only (e.g., tool search, data lookup)Plain data/textConversational text response
Apps-only (e.g., dashboards, analytics)Data + resourceUriRich interactive UI
CombinedEither, depending on contextBoth conversational and rich UI

Your app can support any combination; some tools return plain text while others return interactive UI.

MCP server example

This is an example of an MCP server returning a rich response. The MCP server registers a dice roller tool and serves an interactive HTML resource that renders the result inside Slack. The /mcp route verifies the Slack request signature before forwarding the request to the MCP transport.

The tool uses the readOnlyHint annotation to indicate it doesn't modify any state, and returns structuredContent so the UI resource can render the roll visually.

The examples below use Bolt for JavaScript and Bolt for Python.

ai/slackbot-mcp-client/rich-responses/mcp-apps/src/app.js
loading...

UI resource

When Slackbot invokes the roll_dice tool, it renders this HTML inside an iframe. The page connects to the MCP Apps runtime and displays the structured result visually.

ai/slackbot-mcp-client/rich-responses/mcp-apps/src/dice.html
loading...

Entry point

Start the server on the configured port. Bolt handles the Slack events route automatically, while the custom /mcp route serves your MCP server.

ai/slackbot-mcp-client/no-auth/app.js
loading...