mirror of
https://github.com/czlonkowski/n8n-mcp.git
synced 2026-02-09 23:03:12 +00:00
* feat: add MCP Apps with rich HTML UIs for tool results Add MCP Apps infrastructure that allows MCP hosts like Claude Desktop to render rich HTML UIs alongside tool results via `_meta.ui` and the MCP resources protocol. - Server-side UI module (src/mcp/ui/) with UIAppRegistry, tool-to-UI mapping, and _meta.ui injection into tool responses - React + Vite build pipeline (ui-apps/) producing self-contained HTML per app using vite-plugin-singlefile - Operation Result UI for workflow CRUD tools (create, update, delete, test, autofix, deploy) - Validation Summary UI for validation tools (validate_node, validate_workflow, n8n_validate_workflow) - Shared component library (Card, Badge, Expandable) with n8n dark theme - MCP resources protocol support (ListResources, ReadResource handlers) - Graceful degradation when ui-apps/dist/ is not built - 22 unit tests across 3 test files Conceived by Romuald Członkowski - https://www.aiadvisors.pl/en Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * test: improve MCP Apps test coverage and add security hardening - Expand test suite from 22 to 57 tests across 3 test files - Add UIAppRegistry.reset() for proper test isolation between tests - Replace some fs mocks with real temp directory tests in registry - Add edge case coverage: empty strings, pre-load state, double load, malformed URIs, duplicate tool patterns, empty HTML files - Add regression tests for specific tool-to-UI mappings - Add URI format consistency validation across all configs - Improve _meta.ui injection tests with structuredContent coexistence - Coverage: statements 79.4% -> 80%, lines 79.4% -> 80% Conceived by Romuald Członkowski - https://www.aiadvisors.pl/en Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
33 lines
901 B
TypeScript
33 lines
901 B
TypeScript
import React from 'react';
|
|
|
|
type BadgeVariant = 'success' | 'warning' | 'error' | 'info';
|
|
|
|
interface BadgeProps {
|
|
variant: BadgeVariant;
|
|
children: React.ReactNode;
|
|
}
|
|
|
|
const variantStyles: Record<BadgeVariant, { bg: string; color: string }> = {
|
|
success: { bg: 'var(--n8n-success-light)', color: 'var(--n8n-success)' },
|
|
warning: { bg: 'var(--n8n-warning-light)', color: 'var(--n8n-warning)' },
|
|
error: { bg: 'var(--n8n-error-light)', color: 'var(--n8n-error)' },
|
|
info: { bg: 'var(--n8n-info-light)', color: 'var(--n8n-info)' },
|
|
};
|
|
|
|
export function Badge({ variant, children }: BadgeProps) {
|
|
const style = variantStyles[variant];
|
|
return (
|
|
<span style={{
|
|
display: 'inline-block',
|
|
padding: '2px 10px',
|
|
borderRadius: '12px',
|
|
fontSize: '12px',
|
|
fontWeight: 600,
|
|
background: style.bg,
|
|
color: style.color,
|
|
}}>
|
|
{children}
|
|
</span>
|
|
);
|
|
}
|