import React, { useMemo, useState } from 'react'; import { Text, View } from 'react-native'; import { Plug } from 'lucide-react-native'; import type { SuperagentToolRendererProps } from '../../types'; import { CodeBlock } from '../primitives/CodeBlock'; import { ToolWidgetRow } from '../primitives/ToolWidgetRow'; import { toolWidgetStyles } from '../primitives/toolWidgetStyles'; import { getFailureReason } from '../skillsAndConnectionsUtils'; import { formatMcpDisplayName, formatUnknownValue, getMcpToolRowTitle, getSettledWidgetStatus, parseMcpToolName, parseToolArgs, } from '../toolWidgetUtils'; /** * mcp_* — native port of the web MCPToolUI row ("Run · Server: Tool" chip). * Everyone sees the safe summary (server + tool name); the raw arguments / * result payloads are external-server data the web only exposes through the * platform-admin debug modal (ToolUIBase debugInfo), so like * get_backend_function_logs they render only when the host opts in via * `showDebugPayloads`. */ export function McpToolWidget({ isLastAssistantMessage, showDebugPayloads, toolCall }: SuperagentToolRendererProps) { const args = useMemo(() => parseToolArgs(toolCall), [toolCall]); // Settled status keeps stale rows on old turns from spinning forever. const status = getSettledWidgetStatus(toolCall, isLastAssistantMessage); const { serverName, toolName } = parseMcpToolName(toolCall.name); const displayServer = formatMcpDisplayName(serverName); const displayTool = formatMcpDisplayName(toolName); const chip = displayServer ? `${displayServer}: ${displayTool}` : displayTool; // Arbitrary MCP payloads can be large — don't stringify unless shown. const showPayloads = Boolean(showDebugPayloads); const argsText = useMemo( () => (showPayloads && args && Object.keys(args).length > 0 ? formatUnknownValue(args) : ''), [args, showPayloads], ); const resultText = useMemo( () => (showPayloads && toolCall.results != null && toolCall.results !== '' ? formatUnknownValue(toolCall.results) : ''), [showPayloads, toolCall.results], ); const [expanded, setExpanded] = useState(false); const canExpand = status !== 'running' && Boolean(argsText || resultText); return ( setExpanded((current) => !current) : undefined} status={status === 'stopped' ? 'error' : status} title={getMcpToolRowTitle(status)} > {argsText ? ( <> Arguments ) : null} {resultText ? ( <> Result ) : null} ); }