import { useEffect, useState } from 'react';
import { McpClientProvider, useMcpClient, useWebMCP } from '@mcp-b/react-webmcp';
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
import { TabClientTransport } from '@mcp-b/transports';
import { tool, useAssistantRuntime } from '@assistant-ui/react';
import { z } from 'zod';
// Create client and transport
const client = new Client({
name: 'MyAssistant',
version: '1.0.0'
});
const transport = new TabClientTransport('mcp', {
clientInstanceId: 'my-assistant'
});
// Main app with provider
export function App() {
return (
<McpClientProvider client={client} transport={transport}>
<MyAIAssistant />
</McpClientProvider>
);
}
// Tool provider component
function ToolProvider() {
const [counter, setCounter] = useState(0);
useWebMCP({
name: 'get_user_info',
description: 'Get current user information',
inputSchema: {},
handler: async () => {
const user = getCurrentUser();
return { user };
}
});
useWebMCP({
name: 'increment_counter',
description: 'Increment the counter',
inputSchema: {
amount: z.number().min(1).default(1)
},
handler: async (input) => {
setCounter(prev => prev + input.amount);
return { counter: counter + input.amount };
}
});
return null;
}
// AI Assistant component
function MyAIAssistant() {
const { client, tools, isConnected, isLoading } = useMcpClient();
const runtime = useAssistantRuntime();
// Register MCP tools with Assistant-UI runtime
useEffect(() => {
if (!isConnected || tools.length === 0) return;
const assistantTools = tools.map(mcpTool =>
tool({
type: 'frontend',
description: mcpTool.description,
parameters: mcpTool.inputSchema,
execute: async (args) => {
const result = await client.callTool({
name: mcpTool.name,
arguments: args
});
return result.content
.filter(c => c.type === 'text')
.map(c => c.text)
.join('\n');
}
})
);
const unregister = runtime.registerModelContextProvider({
getModelContext: () => ({
tools: Object.fromEntries(
tools.map((t, i) => [t.name, assistantTools[i]])
)
})
});
return () => unregister();
}, [client, tools, isConnected, runtime]);
if (isLoading) return <div>Connecting to WebMCP...</div>;
if (!isConnected) return <div>Not connected</div>;
return (
<div>
<ToolProvider />
<p>Available tools: {tools.length}</p>
{/* Your AI chat UI here */}
</div>
);
}