Initial commit
This commit is contained in:
commit
92f42cf533
2 changed files with 2534 additions and 0 deletions
70
react/useApp.tsx
Normal file
70
react/useApp.tsx
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
import { useEffect, useState } from "react";
|
||||
import { Implementation } from "@modelcontextprotocol/sdk/types.js";
|
||||
import { Client } from "@modelcontextprotocol/sdk/client";
|
||||
import { App, McpUiAppCapabilities, PostMessageTransport } from "../app";
|
||||
export * from "../app";
|
||||
|
||||
export interface UseAppOptions {
|
||||
appInfo: Implementation;
|
||||
capabilities: McpUiAppCapabilities;
|
||||
/**
|
||||
* Called after client is created but before connection.
|
||||
* Use this to register request/notification handlers via
|
||||
* client.setRequestHandler() and client.setNotificationHandler().
|
||||
*/
|
||||
onAppCreated?: (app: App) => void;
|
||||
}
|
||||
|
||||
export interface AppState {
|
||||
app: App | null;
|
||||
isConnected: boolean;
|
||||
error: Error | null;
|
||||
}
|
||||
|
||||
export function useApp({
|
||||
appInfo,
|
||||
capabilities,
|
||||
onAppCreated,
|
||||
}: UseAppOptions): AppState {
|
||||
const [app, setApp] = useState<App | null>(null);
|
||||
const [isConnected, setIsConnected] = useState(false);
|
||||
const [error, setError] = useState<Error | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
let mounted = true;
|
||||
|
||||
async function connect() {
|
||||
try {
|
||||
const transport = new PostMessageTransport(window.parent);
|
||||
const app = new App(appInfo, capabilities);
|
||||
|
||||
// Register handlers BEFORE connecting
|
||||
onAppCreated?.(app);
|
||||
|
||||
await app.connect(transport);
|
||||
|
||||
if (mounted) {
|
||||
setApp(app);
|
||||
setIsConnected(true);
|
||||
setError(null);
|
||||
}
|
||||
} catch (error) {
|
||||
if (mounted) {
|
||||
setApp(null);
|
||||
setIsConnected(false);
|
||||
setError(
|
||||
error instanceof Error ? error : new Error("Failed to connect"),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
connect();
|
||||
|
||||
return () => {
|
||||
mounted = false;
|
||||
};
|
||||
}, []); // Intentionally not including options to avoid reconnection
|
||||
|
||||
return { app, isConnected, error };
|
||||
}
|
||||
20
react/useAutoResize.ts
Normal file
20
react/useAutoResize.ts
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
import { useEffect, RefObject } from "react";
|
||||
import { App } from "../app";
|
||||
|
||||
/**
|
||||
* Custom hook that automatically reports size changes to the parent window.
|
||||
*
|
||||
* @param client - MCP UI client for sending size notifications
|
||||
*/
|
||||
export function useAutoResize(
|
||||
app: App | null,
|
||||
elementRef?: RefObject<HTMLElement | null>,
|
||||
) {
|
||||
useEffect(() => {
|
||||
if (!app) {
|
||||
return;
|
||||
}
|
||||
|
||||
return app.setupSizeChangeNotifications();
|
||||
}, [app, elementRef]);
|
||||
}
|
||||
Loading…
Reference in a new issue