feat: UI/UX redesign for MCP Apps - 3 new apps + enhanced existing

Add workflow-list, execution-history, and health-dashboard apps.
Redesign operation-result with operation-aware headers, detail panels,
and copy-to-clipboard. Fix React hooks violations in validation-summary
and execution-history (useMemo after early returns). Add local preview
harness for development. Update tests for 5-app config.

Conceived by Romuald Członkowski - www.aiadvisors.pl/en

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
czlonkowski
2026-02-09 10:18:36 +08:00
parent c601581714
commit cfb20a1cc6
25 changed files with 1614 additions and 122 deletions

View File

@@ -1,22 +1,25 @@
import { useState, useCallback } from 'react';
import { useApp } from '@modelcontextprotocol/ext-apps/react';
import { useApp, useHostStyles } from '@modelcontextprotocol/ext-apps/react';
import type { App } from '@modelcontextprotocol/ext-apps/react';
interface UseToolDataResult<T> {
data: T | null;
error: string | null;
isConnected: boolean;
app: App | null;
toolName: string | null;
}
export function useToolData<T>(): UseToolDataResult<T> {
const [data, setData] = useState<T | null>(null);
const onAppCreated = useCallback((app: any) => {
app.ontoolresult = (result: any) => {
const onAppCreated = useCallback((app: App) => {
app.ontoolresult = (result) => {
if (result?.content) {
const textItem = Array.isArray(result.content)
? result.content.find((c: any) => c.type === 'text')
? result.content.find((c) => c.type === 'text')
: null;
if (textItem?.text) {
if (textItem && 'text' in textItem) {
try {
setData(JSON.parse(textItem.text) as T);
} catch {
@@ -27,15 +30,21 @@ export function useToolData<T>(): UseToolDataResult<T> {
};
}, []);
const { isConnected, error } = useApp({
const { app, isConnected, error } = useApp({
appInfo: { name: 'n8n-mcp-ui', version: '1.0.0' },
capabilities: {},
onAppCreated,
});
useHostStyles(app, app?.getHostContext());
const toolName = app?.getHostContext()?.toolInfo?.tool.name ?? null;
return {
data,
error: error?.message ?? null,
isConnected,
app,
toolName,
};
}