docs: mcp-ui support (#4049)

Co-authored-by: Angie Jones <jones.angie@gmail.com>
This commit is contained in:
dianed-square
2025-08-12 21:35:28 -07:00
committed by GitHub
parent c5e6916430
commit f055b051ee
7 changed files with 166 additions and 9 deletions
@@ -0,0 +1,8 @@
{
"label": "Rich Interactive Chat",
"position": 6,
"link": {
"type": "doc",
"id": "guides/interactive-chat/index"
}
}
@@ -0,0 +1,46 @@
---
title: Rich Interactive Chat
hide_title: true
description: Transform text-based responses into graphical components and interactive elements
---
import Card from '@site/src/components/Card';
import styles from '@site/src/components/Card/styles.module.css';
<h1 className={styles.pageTitle}>Rich Interactive Chat</h1>
<p className={styles.pageDescription}>
Goose Desktop supports extensions that transform text-only responses into graphical, interactive experiences. Instead of reading through lists and descriptions, you can click, explore, and interact with UI components directly in your conversations.
</p>
<div className="video-container margin-bottom--lg">
<iframe
class="aspect-ratio"
src="https://www.youtube.com/embed/QJHGvsVXhjw"
title="Turn Any AI Chat Into an Interactive Experience | MCP-UI"
frameBorder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
></iframe>
</div>
<div className={styles.categorySection}>
<h2 className={styles.categoryTitle}>📚 Documentation & Guides</h2>
<div className={styles.cardGrid}>
<Card
title="MCP-UI Extensions"
description="Goose transforms text-based responses into engaging graphical and interactive user experiences."
link="/docs/guides/interactive-chat/mcp-ui"
/>
</div>
</div>
<div className={styles.categorySection}>
<h2 className={styles.categoryTitle}>📝 Featured Blog Posts</h2>
<div className={styles.cardGrid}>
<Card
title="MCP UI: Bringing the Browser into the Agent"
description="MCP-UI servers return content that Goose Desktop renders as rich, embeddable UI."
link="/blog/2025/08/11/mcp-ui-post-browser-world"
/>
</div>
</div>
@@ -0,0 +1,86 @@
---
sidebar_position: 1
title: MCP-UI Extensions
sidebar_label: MCP-UI Extensions
description: Learn how Goose can render graphical and interactive UI components from MCP-UI-enabled extensions
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import GooseDesktopInstaller from '@site/src/components/GooseDesktopInstaller';
import CLIExtensionInstructions from '@site/src/components/CLIExtensionInstructions';
import { PanelLeft } from 'lucide-react';
Extensions built on MCP-UI allow Goose Desktop to provide interactive and engaging user experiences. Imagine using a graphical, clickable UI instead of reading text responses and typing all your prompts:
<div style={{ width: '100%', maxWidth: '800px', margin: '0 auto' }}>
<video
controls
playsInline
style={{
width: '100%',
aspectRatio: '2876/2160',
borderRadius: '8px'
}}
>
<source src={require('@site/static/videos/plan-trip-demo.mp4').default} type="video/mp4" />
Your browser does not support the video tag.
</video>
</div>
<br/>
MCP-UI-enabled extensions return content that Goose can render as embedded UI elements for rich, dynamic, and streamlined interactions.
## Try It Out
See how interactive responses work in Goose.
### Add Enabled Extension
For this exercise, we'll add an MCP-UI-enabled extension that connects to [MCP-UI Demos](https://mcp-aharvard.netlify.app/) provided by Andrew Harvard.
<Tabs groupId="interface">
<TabItem value="ui" label="Goose Desktop" default>
1. Click the <PanelLeft className="inline" size={16} /> button in the top-left to open the sidebar
2. Click `Extensions`
3. Click `Add custom extension`
4. On the `Add custom extension` modal, enter the following:
- **Extension Name**: Rich Demo
- **Type**: Streamable HTTP
- **Endpoint**: `https://mcp-aharvard.netlify.app/mcp`
5. Click `Add Extension` to save the extension
6. Navigate to the chat
</TabItem>
<TabItem value="cli" label="Goose CLI">
<CLIExtensionInstructions
name="rich_demo"
type="http"
url="https://mcp-aharvard.netlify.app/mcp"
timeout={300}
/>
</TabItem>
</Tabs>
### Interact in Chat
In Goose Desktop, ask:
- `Help me select seats for my flight`
Instead of just text, you'll see an interactive response with:
- A visual seat map with available and occupied seats
- Real-time, clickable selection capabilities
- A booking confirmation with flight details
Ask questions to try out other demos:
- `Plan my next trip based on my mood`
- `What's the weather in Philadelphia?`
Stay tuned as more extensions build with MCP-UI!
## For Extension Developers
Want to add interactivity to your own extensions? MCP-UI extends the Model Context Protocol to allow MCP servers to return content that agents can render as UI components instead of text-only responses. Learn more:
- [MCP-UI: Bringing the Browser into the Agent](/blog/2025/08/11/mcp-ui-post-browser-world)
- [MCP-UI Documentation](https://mcpui.dev/guide/introduction)
+1 -1
View File
@@ -46,7 +46,7 @@ Note that you'll need [Node.js](https://nodejs.org/) installed on your system to
args={["-y", "@modelcontextprotocol/server-brave-search"]}
envVars={[{ name: "BRAVE_API_KEY", label: "Your Brave Search API Key" }]}
apiKeyLink="https://api-dashboard.search.brave.com/app/keys"
apiKeyLinkText="Get your Brave Search API Key"
apiKeyLinkText="Brave Search API Key"
/>
</TabItem>
<TabItem value="cli" label="Goose CLI">
+2 -2
View File
@@ -41,7 +41,7 @@ You'll need [Docker](https://www.docker.com/) installed on your system. If you w
<GooseDesktopInstaller
extensionId="container-use"
extensionName="Container Use"
extensionDescription="Run container automation with container-use"
description="Run container automation with container-use"
command="npx"
args={["-y", "mcp-remote", "https://container-use.com/mcp"]}
cliCommand="npx -y mcp-remote https://container-use.com/mcp"
@@ -66,7 +66,7 @@ You'll need [Docker](https://www.docker.com/) installed on your system. If you w
<GooseDesktopInstaller
extensionId="container-use"
extensionName="Container Use"
extensionDescription="Run container automation with container-use"
description="Run container automation with container-use"
command="container-use"
args={["stdio"]}
cliCommand="container-use stdio"
@@ -10,12 +10,13 @@ interface GooseDesktopInstallerProps {
extensionId: string;
extensionName: string;
description: string;
type?: 'stdio' | 'sse' | 'http'; // Extension type (http maps to streamable_http)
// Command-line extension props (optional when using url)
command?: string;
args?: string[];
// SSE extension prop (optional when using command+args)
// SSE/HTTP extension prop (optional when using command+args)
url?: string;
envVars?: EnvVar[];
envVars?: EnvVar[]; // For stdio: environment variables, for http: headers
apiKeyLink?: string;
apiKeyLinkText?: string;
customStep3?: string;
@@ -27,6 +28,7 @@ export default function GooseDesktopInstaller({
extensionId,
extensionName,
description,
type,
command,
args,
url,
@@ -38,11 +40,20 @@ export default function GooseDesktopInstaller({
appendToStep3
}: GooseDesktopInstallerProps) {
// Determine extension type with backward compatibility
const extensionType = type || (command ? 'stdio' : url ? 'sse' : 'stdio');
// Build the goose:// URL
const buildGooseUrl = () => {
let urlParts = [];
// Add SSE extension URL or command-line extension command+args first
// Only add type parameter for http extensions (mapped to streamable_http)
// to avoid regressions with existing sse/stdio extensions
if (extensionType === 'http') {
urlParts.push(`type=streamable_http`);
}
// Add SSE/HTTP extension URL or command-line extension command+args
if (url) {
urlParts.push(`url=${encodeURIComponent(url)}`);
} else if (command && args) {
@@ -57,9 +68,11 @@ export default function GooseDesktopInstaller({
`description=${encodeURIComponent(description)}`
);
// Add environment variables (matching TLDR sections encoding)
// Add environment variables/headers
const isHttp = extensionType === 'http';
const paramName = isHttp ? 'header' : 'env';
urlParts.push(...envVars.map(envVar =>
`env=${encodeURIComponent(`${envVar.name}=${envVar.label}`)}`
`${paramName}=${encodeURIComponent(`${envVar.name}=${envVar.label}`)}`
));
return `goose://extension?${urlParts.join('&')}`;
@@ -81,7 +94,11 @@ export default function GooseDesktopInstaller({
if (envVars.length > 0) {
const envVarNames = envVars.map(env => env.name).join(', ');
return `Obtain your ${envVarNames} and paste it in`;
const isHttp = extensionType === 'http';
const variableType = isHttp ? 'header' : 'environment variable';
const variableTypes = isHttp ? 'headers' : 'environment variables';
return `Obtain your ${envVarNames} and paste ${envVars.length > 1 ? `them as ${variableTypes}` : `it as a ${variableType}`}`;
}
return null; // No configuration needed
Binary file not shown.