-
-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Labels
component: frontendReact/TypeScript UIReact/TypeScript UIcomponent: mcpMCP server integrationMCP server integrationpriority: lowNice to haveNice to havesize: m4-8 hours (half to full day)4-8 hours (half to full day)type: featureNew functionality or enhancementNew functionality or enhancement
Description
Summary
Add renderer support for MCP tool results, using schema-based rendering when tool output schemas are available and generic structured rendering otherwise.
Context
MCP tools are dynamically registered from external servers. Unlike built-in tools, their output format is only known at runtime (if the MCP server declares an output schema) or not at all. This phase extends the rendering system to handle MCP tools gracefully.
Proposed Changes
1. Schema-based MCP result rendering
When an MCP tool declares an output JSON schema, auto-generate a renderer:
// src/services/tools/renderers/McpSchemaRenderer.tsx
function McpSchemaRenderer({ data, schema }: Props) {
// Use the JSON Schema to render a structured view:
// - Objects: key-value table
// - Arrays of objects: data table with sortable columns
// - Strings with format "uri": clickable links
// - Strings with format "date-time": formatted dates
// - Numbers: formatted with locale
return <SchemaBasedView data={data} schema={schema} />;
}2. Extend MCP registration to capture output schemas
// src/services/tools/mcpIntegration.ts
async function registerMcpTools(serverId: string, tools: McpToolDef[]) {
for (const tool of tools) {
registry.register({
name: `mcp_${serverId}_${tool.name}`,
// ... existing fields ...
renderer: tool.outputSchema
? createSchemaRenderer(tool.outputSchema)
: undefined,
outputSchema: tool.outputSchema, // preserve for later use
});
}
}3. Generic MCP fallback renderer
For MCP tools without output schemas, improve the generic renderer:
function McpGenericRenderer({ data, toolName }: Props) {
// Smart heuristics:
// - If data is a string that looks like markdown → render as markdown
// - If data is an array of objects with consistent keys → render as table
// - If data contains 'url' or 'href' keys → render as clickable links
// - Otherwise → pretty-printed JSON with syntax highlighting
return <SmartDataView data={data} />;
}4. MCP tool result caching for re-render
Since MCP tool calls can be expensive, cache the rendered result:
// Memoize rendered results by tool call ID
const renderedResults = useMemo(() => {
return new Map<string, React.ReactNode>();
}, []);Files to Create/Modify
| File | Change |
|---|---|
src/services/tools/renderers/McpSchemaRenderer.tsx |
New: schema-based renderer |
src/services/tools/renderers/McpGenericRenderer.tsx |
New: heuristic-based generic renderer |
src/services/tools/mcpIntegration.ts |
Capture output schemas, attach renderers |
src/services/tools/types.ts |
Add outputSchema to ToolRegistration |
src/services/tools/renderers/SchemaBasedView.tsx |
New: JSON Schema → React component |
Dependencies
- Phase 1 (sub(#250) Phase 1: ToolResultRenderer extension point and default renderers #273) and Phase 2 (sub(#250) Phase 2: Chat UI integration and collapsible tool result cards #274) must be completed first
Acceptance Criteria
- MCP tools with output schemas get auto-generated structured renderers
- Array-of-objects data renders as a sortable table
- URL fields render as clickable links
- MCP tools without schemas use smart heuristic rendering
- Markdown-like string content renders as markdown
- Rendered results are memoized to avoid re-computation
- Works with all existing MCP servers (no regressions)
- Schema renderer handles nested objects (at least 2 levels deep)
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
component: frontendReact/TypeScript UIReact/TypeScript UIcomponent: mcpMCP server integrationMCP server integrationpriority: lowNice to haveNice to havesize: m4-8 hours (half to full day)4-8 hours (half to full day)type: featureNew functionality or enhancementNew functionality or enhancement