mirror of
https://github.com/block/goose.git
synced 2026-07-17 12:56:20 +02:00
docs: mcp-ui support (#4049)
Co-authored-by: Angie Jones <jones.angie@gmail.com>
This commit is contained in:
@@ -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)
|
||||
@@ -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">
|
||||
|
||||
@@ -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.
Reference in New Issue
Block a user