From 77f09d322b84870904c02f76794a0b55b0840986 Mon Sep 17 00:00:00 2001 From: Felix Mumme Date: Fri, 10 Apr 2026 21:18:50 +0000 Subject: [PATCH] fix(ui): render MCP tool output in GenericTool fallback GenericTool now accepts and renders the output prop using the same Show/Markdown/data-scrollable pattern as built-in tools, making MCP tool results visible in the web/desktop UI. --- packages/ui/src/components/basic-tool.tsx | 42 +++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/packages/ui/src/components/basic-tool.tsx b/packages/ui/src/components/basic-tool.tsx index 7d18dfacd6f2..71cd06876117 100644 --- a/packages/ui/src/components/basic-tool.tsx +++ b/packages/ui/src/components/basic-tool.tsx @@ -1,10 +1,13 @@ -import { createEffect, For, Match, on, onCleanup, Show, Switch, type JSX } from "solid-js" +import { createEffect, createSignal, For, Match, on, onCleanup, Show, Switch, type JSX } from "solid-js" import { animate, type AnimationPlaybackControls } from "motion" import { useI18n } from "../context/i18n" import { createStore } from "solid-js/store" import { Collapsible } from "./collapsible" import type { IconProps } from "./icon" +import { IconButton } from "./icon-button" import { TextShimmer } from "./text-shimmer" +import { Tooltip } from "./tooltip" +import { Markdown } from "./markdown" export type TriggerTitle = { title: string @@ -265,8 +268,17 @@ export function GenericTool(props: { status?: string hideDetails?: boolean input?: Record + output?: string }) { const i18n = useI18n() + const [copied, setCopied] = createSignal(false) + + const handleCopy = async () => { + if (!props.output) return + await navigator.clipboard.writeText(props.output) + setCopied(true) + setTimeout(() => setCopied(false), 2000) + } return ( + > + +
+
+ + e.preventDefault()} + onClick={handleCopy} + aria-label={copied() ? i18n.t("ui.message.copied") : i18n.t("ui.message.copy")} + /> + +
+
+
+              {props.output}
+            
+
+
+
+
) }