integrate MCP UI (#2948)

Co-authored-by: Michael Neale <michael.neale@gmail.com>
This commit is contained in:
Andrew Harvard
2025-08-01 08:09:06 -04:00
committed by GitHub
parent b4ab774329
commit 900698777b
9 changed files with 256 additions and 62 deletions
@@ -6,8 +6,9 @@ import { Content, ToolRequestMessageContent, ToolResponseMessageContent } from '
import { cn, snakeToTitleCase } from '../utils';
import Dot, { LoadingStatus } from './ui/Dot';
import { NotificationEvent } from '../hooks/useMessageStream';
import { ChevronRight, LoaderCircle } from 'lucide-react';
import { ChevronRight, FlaskConical, LoaderCircle } from 'lucide-react';
import { TooltipWrapper } from './settings/providers/subcomponents/buttons/TooltipWrapper';
import MCPUIResourceRenderer from './MCPUIResourceRenderer';
interface ToolCallWithResponseProps {
isCancelledMessage: boolean;
@@ -30,15 +31,47 @@ export default function ToolCallWithResponse({
}
return (
<div
className={cn(
'w-full text-sm rounded-lg overflow-hidden border-borderSubtle border bg-background-muted'
)}
>
<ToolCallView
{...{ isCancelledMessage, toolCall, toolResponse, notifications, isStreamingMessage }}
/>
</div>
<>
<div
className={cn(
'w-full text-sm rounded-lg overflow-hidden border-borderSubtle border bg-background-muted'
)}
>
<ToolCallView
{...{
isCancelledMessage,
toolCall,
toolResponse,
notifications,
isStreamingMessage,
}}
/>
</div>
{/* MCP UI — Inline */}
{toolResponse?.toolResult?.value &&
toolResponse.toolResult.value.map((content, index, results) => {
if (content.type === 'resource' && content.resource.uri?.startsWith('ui://')) {
if (index === results.length - 1) {
return (
<>
<MCPUIResourceRenderer key={`${content.type}-${index}`} content={content} />
{/* Append a disclaimer if this is the last item in the array */}
<div className="mt-3 p-4 py-3 border border-borderSubtle rounded-lg bg-background-muted flex items-center">
<FlaskConical className="mr-2" size={20} />
<div className="text-sm font-medium mono">
MCP UI is experimental and may change at any time.
</div>
</div>
</>
);
} else {
return <MCPUIResourceRenderer key={`${content.type}-${index}`} content={content} />;
}
} else {
return null;
}
})}
</>
);
}
@@ -536,6 +569,7 @@ function ToolResultView({ result, isStartExpanded }: ToolResultViewProps) {
}}
/>
)}
{result.type === 'resource' && <pre>{JSON.stringify(result, null, 2)}</pre>}
</div>
</ToolCallExpandable>
);