Documentation Index Fetch the complete documentation index at: https://docs.leanmcp.com/llms.txt
Use this file to discover all available pages before exploring further.
@leanmcp/ui
Build rich, interactive MCP Apps with React components designed for the Model Context Protocol. Features first-class tool integration, streaming support, and automatic host theming.
Features
MCP-Native Components ToolButton, ToolDataGrid, ToolForm - components that directly integrate with MCP tools
Dual Platform Support Works with ext-apps hosts (Claude Desktop) and ChatGPT GPT Actions
Host Theming Automatic theme sync with host application (light/dark mode)
Testing Utilities MockAppProvider for unit testing MCP App components
Installation
Import the styles in your app entry point:
import '@leanmcp/ui/styles.css' ;
Two App Paradigms
@leanmcp/ui supports two different host environments:
ext-apps (Claude Desktop, MCP Hosts)
Uses the @modelcontextprotocol/ext-apps protocol for iframe-based communication.
import { AppProvider , ToolButton } from '@leanmcp/ui' ;
import '@leanmcp/ui/styles.css' ;
function MyApp () {
return (
< AppProvider appInfo = { { name: 'MyApp' , version: '1.0.0' } } >
< ToolButton tool = "refresh-data" resultDisplay = "toast" >
Refresh Data
</ ToolButton >
</ AppProvider >
);
}
ChatGPT GPT Actions
Uses ChatGPT’s native window.openai SDK.
import { GPTAppProvider , useGptTool } from '@leanmcp/ui' ;
import '@leanmcp/ui/styles.css' ;
function MyGPTApp () {
return (
< GPTAppProvider appName = "MyApp" >
< DataDisplay />
</ GPTAppProvider >
);
}
function DataDisplay () {
const { call , result , loading } = useGptTool ( 'get-data' );
return (
< button onClick = { () => call () } disabled = { loading } >
{ loading ? 'Loading...' : 'Fetch Data' }
</ button >
);
}
Quick Start Example
Here’s a complete example showing a tool-linked UI component:
import { AppProvider , ToolDataGrid , RequireConnection } from '@leanmcp/ui' ;
import '@leanmcp/ui/styles.css' ;
function UsersApp () {
return (
< AppProvider appInfo = { { name: 'UsersApp' , version: '1.0.0' } } >
< RequireConnection >
< ToolDataGrid
dataTool = "list-users"
columns = { [
{ key: 'name' , header: 'Name' , sortable: true },
{ key: 'email' , header: 'Email' },
{ key: 'status' , header: 'Status' }
] }
transformData = { ( result ) => ({
rows: result . users ,
total: result . total
}) }
rowActions = { [
{ label: 'Edit' , tool: 'edit-user' },
{ label: 'Delete' , tool: 'delete-user' , variant: 'destructive' }
] }
pagination
/>
</ RequireConnection >
</ AppProvider >
);
}
Server-Side Integration
Link UI components to tools using the @UIApp decorator (for ext-apps) or @GPTApp decorator (for ChatGPT):
import { Tool } from '@leanmcp/core' ;
import { UIApp } from '@leanmcp/ui' ;
class WeatherService {
@ Tool ({ description: 'Get weather for a city' })
@ UIApp ({ component: './WeatherCard' })
async getWeather ( args : { city : string }) {
return { city: args . city , temperature: 22 , condition: 'Sunny' };
}
}
When the tool is called, the host will render the linked UI component with the tool result.
Testing
Use MockAppProvider for unit testing:
import { MockAppProvider } from '@leanmcp/ui/testing' ;
import { render , screen } from '@testing-library/react' ;
test ( 'WeatherCard displays temperature' , () => {
render (
< MockAppProvider
toolResult = { { city: 'London' , temperature: 20 } }
isConnected = { true }
>
< WeatherCard />
</ MockAppProvider >
);
expect ( screen . getByText ( '20°C' )). toBeInTheDocument ();
});
What’s Next
Components ToolButton, ToolDataGrid, ToolForm, and more
Hooks useTool, useResource, useMessage, useHostContext
GPT Apps & Decorators ChatGPT integration, @UIApp, @GPTApp decorators
Examples Complete working examples
Links