Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
32f6572
feat: Add auto-transport persistence transformation for Redis configu…
frontegg-david Dec 23, 2025
bc2f84a
feat: Add auto-transport persistence transformation for Redis configu…
frontegg-david Dec 23, 2025
6fdcb38
feat: Enhance multi-platform bundling with theme support and metadata…
frontegg-david Dec 23, 2025
92a4076
Merge branch 'main' into fix-minify-ui-builder
frontegg-david Dec 23, 2025
a4ee898
feat: Implement build modes for static, dynamic, and hybrid HTML gene…
frontegg-david Dec 23, 2025
4fdd092
feat: Enhance dynamic data injection with platform-aware handling for…
frontegg-david Dec 23, 2025
ab74e02
feat: Add documentation for build modes and data injection strategies
frontegg-david Dec 23, 2025
e6bd540
refactor: Simplify adapter access and improve error handling in vario…
frontegg-david Dec 23, 2025
37ac1ab
refactor: Remove unused imports and simplify variable declarations ac…
frontegg-david Dec 23, 2025
317f77e
refactor: Remove unused imports and simplify variable declarations ac…
frontegg-david Dec 23, 2025
eb9ea9b
refactor: Clean up unused capabilities and improve platform handling …
frontegg-david Dec 23, 2025
b19ec32
feat: Implement package allowlist functionality in TypeFetcher
frontegg-david Dec 23, 2025
14e6ca4
refactor: Remove ngrok platform references and update platform handling
frontegg-david Dec 23, 2025
a3311b4
feat: Add browser-compatible UI components with esbuild integration
frontegg-david Dec 23, 2025
a557042
feat: Enable widget support for Claude Artifacts platform
frontegg-david Dec 23, 2025
e3cd703
feat: Add CSS to Tailwind theme conversion utility and update button …
frontegg-david Dec 23, 2025
82a70d3
feat: Introduce new UI builder architecture with platform-specific pr…
frontegg-david Dec 23, 2025
f9c4a9f
feat: Update outline button variant styles for improved visibility an…
frontegg-david Dec 23, 2025
66db1e8
Merge branch 'main' into new-ui-builder
frontegg-david Dec 23, 2025
c019b9c
feat: Implement component name validation and sanitization to prevent…
frontegg-david Dec 24, 2025
45789f2
feat: Implement component name validation and sanitization to prevent…
frontegg-david Dec 24, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 77 additions & 40 deletions libs/ui/CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

`@frontmcp/ui` provides **React components, hooks, and rendering utilities** for building interactive MCP widgets.

This package requires React. For React-free utilities (bundling, build tools, HTML components, platform adapters), use `@frontmcp/uipack`.
This package requires React. For React-free utilities (bundling, build tools, platform adapters, theme), use `@frontmcp/uipack`.

**Key Principles:**

Expand All @@ -17,41 +17,55 @@ This package requires React. For React-free utilities (bundling, build tools, HT

```text
libs/ui/src/
├── bridge/ # MCP bridge runtime and adapters
├── bundler/ # SSR component bundling (re-exports from uipack)
├── components/ # HTML string components (button, card, etc.)
├── layouts/ # Page layout templates
├── react/ # React components and hooks
│ ├── components/ # Button, Card, Alert, Badge, etc.
│ ├── Card.tsx # Card component
│ ├── Button.tsx # Button component
│ ├── Alert.tsx # Alert component
│ ├── Badge.tsx # Badge component
│ └── hooks/ # useMcpBridge, useCallTool, useToolInput
├── render/ # React 19 static rendering utilities
├── renderers/ # React renderer for template processing
│ ├── react.renderer.ts # SSR renderer (react-dom/server)
── react.adapter.ts # Client-side hydration adapter
├── bundler/ # SSR component bundling
── react.adapter.ts # Client-side hydration adapter
│ └── mdx.renderer.ts # MDX server-side renderer
├── universal/ # Universal React app shell
├── web-components/ # Custom HTML elements
└── index.ts # Main barrel exports
```

## Package Split

| Package | Purpose | React Required |
| ------------------ | --------------------------------------------------------- | -------------- |
| `@frontmcp/ui` | React components, hooks, SSR | Yes |
| `@frontmcp/uipack` | Bundling, build tools, HTML components, platform adapters | No |
| Package | Purpose | React Required |
| ------------------ | ----------------------------------------------- | -------------- |
| `@frontmcp/ui` | React components, hooks, SSR, HTML components | Yes |
| `@frontmcp/uipack` | Bundling, build tools, platform adapters, theme | No |

### Import Patterns

```typescript
// React components and hooks (this package)
import { Button, Card, Alert } from '@frontmcp/ui/react';
import { useMcpBridge, useCallTool } from '@frontmcp/ui/react/hooks';
import { Button, Card, Alert, Badge } from '@frontmcp/ui/react';
import { useMcpBridge, useCallTool, useToolInput } from '@frontmcp/ui/react';

// SSR rendering
import { ReactRenderer, reactRenderer } from '@frontmcp/ui/renderers';
import { ReactRenderer, reactRenderer, MdxRenderer, mdxRenderer } from '@frontmcp/ui/renderers';

// Universal app shell
import { UniversalApp, FrontMCPProvider } from '@frontmcp/ui/universal';

// HTML string components
import { button, card, alert, badge } from '@frontmcp/ui/components';

// MCP bridge
import { FrontMcpBridge, createBridge } from '@frontmcp/ui/bridge';

// React-free utilities (from @frontmcp/uipack)
import { buildToolUI } from '@frontmcp/uipack/build';
import { button, card } from '@frontmcp/uipack/components';
import { DEFAULT_THEME } from '@frontmcp/uipack/theme';
import type { AIPlatformType } from '@frontmcp/uipack/adapters';
```

Expand All @@ -60,41 +74,50 @@ import type { AIPlatformType } from '@frontmcp/uipack/adapters';
### Available Components

```typescript
import {
Button,
Card,
Alert,
Badge,
// ... more components
} from '@frontmcp/ui/react';
import { Card, Badge, Button, Alert } from '@frontmcp/ui/react';

// Usage
<Button variant="primary" onClick={handleClick}>
Submit
</Button>

<Card title="Welcome">
<Card title="Welcome" variant="elevated">
<p>Card content</p>
</Card>

<Badge variant="success">Active</Badge>

<Alert variant="warning" title="Warning">
Please check your input
</Alert>
```

### MCP Bridge Hooks

```typescript
import { useMcpBridge, useCallTool, useToolInput, useToolOutput } from '@frontmcp/ui/react/hooks';
import {
McpBridgeProvider,
useMcpBridge,
useCallTool,
useToolInput,
useToolOutput,
useTheme,
} from '@frontmcp/ui/react';

function MyWidget() {
const bridge = useMcpBridge();
const { call, loading, error } = useCallTool();
const input = useToolInput();
const output = useToolOutput();
const input = useToolInput<{ location: string }>();
const theme = useTheme();
const [getWeather, { data, loading }] = useCallTool('get_weather');

return <Card title={`Weather for ${input?.location}`}>{loading ? 'Loading...' : data?.temperature}</Card>;
}

// Wrap your app with the provider
function App() {
return (
<div>
<p>Input: {JSON.stringify(input)}</p>
<p>Output: {JSON.stringify(output)}</p>
<button onClick={() => call('my-tool', { data: 'test' })}>Call Tool</button>
</div>
<McpBridgeProvider>
<MyWidget />
</McpBridgeProvider>
);
}
```
Expand All @@ -110,6 +133,15 @@ import { ReactRenderer, reactRenderer } from '@frontmcp/ui/renderers';
const html = await reactRenderer.render(MyComponent, context);
```

### MDX Server Rendering

```typescript
import { MdxRenderer, mdxRenderer } from '@frontmcp/ui/renderers';

// Render MDX to HTML with React components
const html = await mdxRenderer.render('# Hello {output.name}', context);
```

### Client-Side Hydration

```typescript
Expand Down Expand Up @@ -145,6 +177,8 @@ function App() {

## SSR Bundling

The bundler re-exports utilities from `@frontmcp/uipack/bundler`:

```typescript
import { InMemoryBundler, createBundler } from '@frontmcp/ui/bundler';

Expand Down Expand Up @@ -178,15 +212,18 @@ const result = await bundler.bundle(componentPath);

## Entry Points

| Path | Purpose |
| -------------------------- | ------------------------------------------ |
| `@frontmcp/ui` | Main exports (React components, renderers) |
| `@frontmcp/ui/react` | React components |
| `@frontmcp/ui/react/hooks` | MCP bridge hooks |
| `@frontmcp/ui/renderers` | ReactRenderer, ReactRendererAdapter |
| `@frontmcp/ui/render` | React 19 static rendering |
| `@frontmcp/ui/universal` | Universal app shell |
| `@frontmcp/ui/bundler` | SSR component bundler |
| Path | Purpose |
| ----------------------------- | ------------------------------------------ |
| `@frontmcp/ui` | Main exports (React components, renderers) |
| `@frontmcp/ui/react` | React components and hooks |
| `@frontmcp/ui/renderers` | ReactRenderer, MdxRenderer, adapters |
| `@frontmcp/ui/render` | React 19 static rendering |
| `@frontmcp/ui/universal` | Universal app shell |
| `@frontmcp/ui/bundler` | SSR component bundler |
| `@frontmcp/ui/bridge` | MCP bridge runtime |
| `@frontmcp/ui/components` | HTML string components |
| `@frontmcp/ui/layouts` | Page layout templates |
| `@frontmcp/ui/web-components` | Custom HTML elements |

## Anti-Patterns to Avoid

Expand All @@ -198,6 +235,6 @@ const result = await bundler.bundle(componentPath);

## Related Packages

- **@frontmcp/uipack** - React-free bundling, build tools, HTML components
- **@frontmcp/uipack** - React-free bundling, build tools, theme, platform adapters
- **@frontmcp/sdk** - Core FrontMCP SDK
- **@frontmcp/testing** - E2E testing utilities
1 change: 0 additions & 1 deletion libs/ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@
"dependencies": {
"@mdx-js/mdx": "^3.1.1",
"@swc/core": "^1.5.0",
"enclave-vm": "^1.0.3",
"esbuild": "^0.27.1",
"zod": "^4.0.0"
},
Expand Down
8 changes: 2 additions & 6 deletions libs/ui/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,11 @@
"libs/ui/src/bundler/index.ts",
"libs/ui/src/components/index.ts",
"libs/ui/src/layouts/index.ts",
"libs/ui/src/pages/index.ts",
"libs/ui/src/react/index.ts",
"libs/ui/src/render/index.ts",
"libs/ui/src/renderers/index.ts",
"libs/ui/src/universal/index.ts",
"libs/ui/src/web-components/index.ts",
"libs/ui/src/widgets/index.ts"
"libs/ui/src/web-components/index.ts"
],
"esbuildOptions": {
"outExtension": { ".js": ".js" },
Expand Down Expand Up @@ -63,13 +61,11 @@
"libs/ui/src/bundler/index.ts",
"libs/ui/src/components/index.ts",
"libs/ui/src/layouts/index.ts",
"libs/ui/src/pages/index.ts",
"libs/ui/src/react/index.ts",
"libs/ui/src/render/index.ts",
"libs/ui/src/renderers/index.ts",
"libs/ui/src/universal/index.ts",
"libs/ui/src/web-components/index.ts",
"libs/ui/src/widgets/index.ts"
"libs/ui/src/web-components/index.ts"
],
"esbuildOptions": {
"outExtension": { ".js": ".mjs" },
Expand Down
7 changes: 1 addition & 6 deletions libs/ui/src/bridge/__tests__/iife-generator.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,7 @@
* IIFE Generator Tests
*/

import {
generateBridgeIIFE,
generatePlatformBundle,
UNIVERSAL_BRIDGE_SCRIPT,
BRIDGE_SCRIPT_TAGS,
} from '../runtime/iife-generator';
import { generateBridgeIIFE, generatePlatformBundle, UNIVERSAL_BRIDGE_SCRIPT, BRIDGE_SCRIPT_TAGS } from '../runtime';

describe('IIFE Generator', () => {
describe('generateBridgeIIFE', () => {
Expand Down
4 changes: 2 additions & 2 deletions libs/ui/src/bridge/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,11 +102,11 @@ export { GenericAdapter, createGenericAdapter } from './adapters/generic.adapter

export { registerBuiltInAdapters } from './adapters';

// Runtime
// Runtime - Re-exported from @frontmcp/uipack (single source of truth)
export {
generateBridgeIIFE,
generatePlatformBundle,
UNIVERSAL_BRIDGE_SCRIPT,
BRIDGE_SCRIPT_TAGS,
type IIFEGeneratorOptions,
} from './runtime/iife-generator';
} from './runtime';
Loading
Loading