iframe

Loading "Iframe S6mai"
πŸ‘¨β€πŸ’Ό When users interact with our AI assistant, they expect rich, interactive experiences that go beyond simple text responses. Whether they're viewing a detailed project dashboard or exploring a complex data visualization, they want to see and interact with full-featured interfaces that feel like native applications. The problem is: how do we provide these sophisticated UI experiences within the constraints of MCP?
The solution is iframe-based UI components - embedding full web applications as UI resources that can leverage entire frameworks and provide rich, interactive experiences while maintaining secure communication with the host application.
// Create an iframe-based UI resource for a project dashboard
const resource = createUIResource({
	uri: `ui://project-dashboard/${Date.now()}`,
	content: {
		type: 'externalUrl',
		iframeUrl: 'https://myapp.com/dashboard/project-123',
	},
	encoding: 'text',
})
To make this happen, we use the externalUrl content type in MCP UI. This allows us to embed complete web applications that can handle complex state management, rich interactions, and responsive design - all while communicating securely with the host through a standardized protocol.
The key advantage is that instead of building everything from scratch with raw HTML or struggling with the limitations of Remote DOM, we can leverage the full ecosystem of web technologies. Users get interfaces that feel like they belong in a modern application, not a basic chat interface.

Request Info

In the MCP TypeScript SDK, tools can receive two arguments:
  1. args - the arguments passed to the tool
  2. extra - extra information about the request
If the tool does not have an inputSchema, the first argument will be the "extra" object which includes the requestInfo object.
When constructing iframe URLs, we need to use the origin from the request headers.
Here's how to access the origin from the request headers in the tool handler:
agent.server.registerTool(
	'get_dashboard',
	{
		title: 'Get Dashboard',
		description: 'Get the dashboard for a project',
		// no inputSchema means the first argument to our tool handler will be the "extra" object which includes the requestInfo object
	},
	// In your tool handler, the requestInfo object contains the request headers
	async ({ requestInfo }) => {
		const origin = requestInfo.headers['x-origin']
		// origin would be something like https://example.com
		// ...
	},
)
We need to add a custom x-origin header to the MCP request so our tool handler knows where to set the full iframe URL. This header is added in the worker's fetch handler before forwarding the request to the MCP server.
The worker sets up the custom header like this:
// In worker/index.ts
if (url.pathname === '/mcp') {
	// clone the request headers
	const headers = new Headers(request.headers)
	// add the custom header
	headers.set('x-origin', url.origin)
	// clone the request with the new headers
	const newRequest = new Request(request, { headers })

	return EpicMeMCP.serve('/mcp', {
		binding: 'EPIC_ME_MCP_OBJECT',
		// pass the newRequest instead of request
	}).fetch(newRequest, env, ctx)
}
This ensures that when our tool handler receives the request, it has access to the origin information needed to construct the proper iframe URL.

Please set the playground first

Loading "iframe"
Loading "iframe"
Login to get access to the exclusive discord channel.
  • πŸ’»MCP UI
    MCP use case for average AI user
    hasan ⚑:
    Hey @Kent C. Dodds β—† πŸš€πŸ†πŸŒŒβš‘ while working with MCPs one concern keeps comint to me. Do you feel ave...
    • βœ…1
    3 Β· 4 hours ago
  • ⚑General
    Epic MCP Server
    Fede:
    Given the amount of questions around deployment and getting started, it would be cool to have an Epi...
    • βœ…1
    2 Β· 20 hours ago
  • ⚑General
    Cloudflare deployment
    Aaron Schwartz:
    Do you have any resources on deploying to a live cloudflare instance? I haven't dug through the work...
    • πŸ‘1
    • βœ…1
    4 Β· 21 hours ago
  • πŸ’»MCP UI
    MCP-UI UIResourceRenderer
    js.nz ⚑:
    Any comments on using UIResourceRenderer from @mcp-ui/client when building a client UI?
    • βœ…1
    1 Β· 19 hours ago
  • πŸ’»MCP UI
    Render data use cases
    Aaron Schwartz:
    I'm still wrapping my head around the Auth section, but I was confused during the UI render data sec...
    • βœ…1
    1 Β· 21 hours ago
  • πŸ’ͺAdv. MCP Features
    ⚑General
    Understanding Session and State Management for Remote MCP Server
    Kusten ⚑:
    I just completed the Advanced Features workshop, and the notifications/tools/list_changed section le...
    • βœ…1
    1 Β· a day ago
  • πŸ’»MCP UI
    nanobot questions
    Jangla ⚑:
    Anyone know how to change the db location? I've followed the idea of adding nanobot config to an ign...
    • βœ…1
    4 Β· 3 days ago
  • πŸ’»MCP UI
    nanobot fails to connect to mcp server in exercise MCP UI 3.1
    Dan:
    Had nanobot connecting successfully in previous exercises but I get the following error since moving...
    • βœ…1
    14 Β· 3 days ago
  • ⚑General
    Epic MCP server not initializing
    steve ⚑:
    I am attempting to configure the Epic MCP Server per Kent's instructions here: https://www.epicai.pr...
    • βœ…2
    3 Β· 4 days ago
  • πŸ’»MCP UI
    Issue: Goose not detecting MCP extension in UI Workshop exercise
    Nhalillo ⚑:
    Hi everyone! πŸ‘‹ Has anyone managed to properly configure Goose for the first exercise (Simple Raw H...
    • βœ…1
    5 Β· 5 days ago
  • πŸ’»MCP UI
    Issue: Goose not displaying HTML (remote DOM exercise)
    okram ⚑:
    Hi πŸ‘‹ Goose is not displaying the HTML. I have no diff between problem and solution and I enabled t...
    • βœ…1
    1 Β· 4 days ago
  • ⚑General
    What will tomorrows MCP hosts look like?
    Paul πŸš€:
    Hi Kent,

Thanks for putting together the course, I’m really enjoying it. Im interested if you have...
    • βœ…1
    2 Β· 5 days ago
  • πŸ’»MCP UI
    MCP UI repository - Unexpected option passed to `new Miniflare()` constructor?
    mark:
    So when I run the MCP UI repository and try start the first exercise I receive an error: "Unexpecte...
    • βœ…1
    11 Β· 5 days ago
  • ⚑General
    VS Code Copilot and Epic Workshop MCP Server
    Alexandre πŸš€:
    I might have missed something, but how do we install the Epic Workshop MCP Server so we can ask Copi...
    • βœ…1
    3 Β· 6 days ago
  • 🐣MCP Fundamentals
    πŸ’ͺAdv. MCP Features
    πŸ”MCP Auth
    πŸ’»MCP UI
    What about the usage of MCP Servers for some kind of chat interacting with a local LLM?
    frankfullstack ⚑:
    I would like to raise a general question about the usage of MCP Servers and how we could interact fr...
    • βœ…1
    5 Β· 11 days ago
  • 🐣MCP Fundamentals
    ⚑General
    It'd be really cool to have a basic deployment guide.
    BeyondLimits99 ⚑:
    The course has been amazing so far! I'd love to have a basic deployment guide just so I can practice...
    • βœ…2
    3 Β· 8 days ago
  • ⚑General
    non-related question: how do you rollout updates?
    mark:
    I'm very curious to hear: How do you roll-out new updates? do you use some kind of libary?
    • βœ…1
    5 Β· 13 days ago
  • 🐣MCP Fundamentals
    ⚑General
    How do you teach the LLMs to use ResourceTemplates and ResourceTemplatesList?
    frontendwizard:
    I'm playing around with building an mcp with claude and he has a tendency to go for json for everyth...
    • βœ…1
    8 Β· 11 days ago