[MCP-UI] Proxy and Better Message Handling (#5487)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Alex Hancock <alexhancock@block.xyz> Co-authored-by: Zane <75694352+zanesq@users.noreply.github.com>
This commit is contained in:
@@ -1042,6 +1042,33 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/mcp-ui-proxy": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"super::routes::mcp_ui_proxy"
|
||||
],
|
||||
"operationId": "mcp_ui_proxy",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "secret",
|
||||
"in": "query",
|
||||
"description": "Secret key for authentication",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "MCP UI proxy HTML page"
|
||||
},
|
||||
"401": {
|
||||
"description": "Unauthorized - invalid or missing secret"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/recipes/create": {
|
||||
"post": {
|
||||
"tags": [
|
||||
|
||||
Generated
+4
-4
@@ -11,7 +11,7 @@
|
||||
"dependencies": {
|
||||
"@ai-sdk/openai": "^2.0.52",
|
||||
"@ai-sdk/ui-utils": "^1.2.11",
|
||||
"@mcp-ui/client": "^5.13.0",
|
||||
"@mcp-ui/client": "^5.14.1",
|
||||
"@radix-ui/react-accordion": "^1.2.12",
|
||||
"@radix-ui/react-avatar": "^1.1.10",
|
||||
"@radix-ui/react-dialog": "^1.1.15",
|
||||
@@ -3018,9 +3018,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@mcp-ui/client": {
|
||||
"version": "5.13.1",
|
||||
"resolved": "https://registry.npmjs.org/@mcp-ui/client/-/client-5.13.1.tgz",
|
||||
"integrity": "sha512-U0+kgdgmBRfqVM1MbqDZnaxBWboyDWQNmYrS72loL+XL9ZMtej5B7EThrPsE3wtwJftLURVagYqgDAnfSgKhXw==",
|
||||
"version": "5.14.1",
|
||||
"resolved": "https://registry.npmjs.org/@mcp-ui/client/-/client-5.14.1.tgz",
|
||||
"integrity": "sha512-DHJ4H01L2oIiMdDzUrBErxYoli9Q3cQq5sXk3hhBQNqASbc55PtEhz6k0pOp7ykkj63MfxDKDmYXLw5jseY7/g==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@modelcontextprotocol/sdk": "*",
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
"dependencies": {
|
||||
"@ai-sdk/openai": "^2.0.52",
|
||||
"@ai-sdk/ui-utils": "^1.2.11",
|
||||
"@mcp-ui/client": "^5.13.0",
|
||||
"@mcp-ui/client": "^5.14.1",
|
||||
"@radix-ui/react-accordion": "^1.2.12",
|
||||
"@radix-ui/react-avatar": "^1.1.10",
|
||||
"@radix-ui/react-dialog": "^1.1.15",
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import type { Client, Options as Options2, TDataShape } from './client';
|
||||
import { client } from './client.gen';
|
||||
import type { AddExtensionData, AddExtensionErrors, AddExtensionResponses, AgentAddExtensionData, AgentAddExtensionErrors, AgentAddExtensionResponses, AgentRemoveExtensionData, AgentRemoveExtensionErrors, AgentRemoveExtensionResponses, BackupConfigData, BackupConfigErrors, BackupConfigResponses, CheckProviderData, ConfirmPermissionData, ConfirmPermissionErrors, ConfirmPermissionResponses, CreateCustomProviderData, CreateCustomProviderErrors, CreateCustomProviderResponses, CreateRecipeData, CreateRecipeErrors, CreateRecipeResponses, CreateScheduleData, CreateScheduleErrors, CreateScheduleResponses, DecodeRecipeData, DecodeRecipeErrors, DecodeRecipeResponses, DeleteRecipeData, DeleteRecipeErrors, DeleteRecipeResponses, DeleteScheduleData, DeleteScheduleErrors, DeleteScheduleResponses, DeleteSessionData, DeleteSessionErrors, DeleteSessionResponses, DiagnosticsData, DiagnosticsErrors, DiagnosticsResponses, EncodeRecipeData, EncodeRecipeErrors, EncodeRecipeResponses, ExportSessionData, ExportSessionErrors, ExportSessionResponses, GetCustomProviderData, GetCustomProviderErrors, GetCustomProviderResponses, GetExtensionsData, GetExtensionsErrors, GetExtensionsResponses, GetProviderModelsData, GetProviderModelsErrors, GetProviderModelsResponses, GetSessionData, GetSessionErrors, GetSessionInsightsData, GetSessionInsightsErrors, GetSessionInsightsResponses, GetSessionResponses, GetToolsData, GetToolsErrors, GetToolsResponses, ImportSessionData, ImportSessionErrors, ImportSessionResponses, InitConfigData, InitConfigErrors, InitConfigResponses, InspectRunningJobData, InspectRunningJobErrors, InspectRunningJobResponses, KillRunningJobData, KillRunningJobResponses, ListRecipesData, ListRecipesErrors, ListRecipesResponses, ListSchedulesData, ListSchedulesErrors, ListSchedulesResponses, ListSessionsData, ListSessionsErrors, ListSessionsResponses, ParseRecipeData, ParseRecipeErrors, ParseRecipeResponses, PauseScheduleData, PauseScheduleErrors, PauseScheduleResponses, ProvidersData, ProvidersResponses, ReadAllConfigData, ReadAllConfigResponses, ReadConfigData, ReadConfigErrors, ReadConfigResponses, RecoverConfigData, RecoverConfigErrors, RecoverConfigResponses, RemoveConfigData, RemoveConfigErrors, RemoveConfigResponses, RemoveCustomProviderData, RemoveCustomProviderErrors, RemoveCustomProviderResponses, RemoveExtensionData, RemoveExtensionErrors, RemoveExtensionResponses, ReplyData, ReplyErrors, ReplyResponses, ResumeAgentData, ResumeAgentErrors, ResumeAgentResponses, RunNowHandlerData, RunNowHandlerErrors, RunNowHandlerResponses, SaveRecipeData, SaveRecipeErrors, SaveRecipeResponses, ScanRecipeData, ScanRecipeResponses, SessionsHandlerData, SessionsHandlerErrors, SessionsHandlerResponses, SetConfigProviderData, StartAgentData, StartAgentErrors, StartAgentResponses, StartOpenrouterSetupData, StartOpenrouterSetupResponses, StartTetrateSetupData, StartTetrateSetupResponses, StatusData, StatusResponses, UnpauseScheduleData, UnpauseScheduleErrors, UnpauseScheduleResponses, UpdateAgentProviderData, UpdateAgentProviderErrors, UpdateAgentProviderResponses, UpdateCustomProviderData, UpdateCustomProviderErrors, UpdateCustomProviderResponses, UpdateFromSessionData, UpdateFromSessionErrors, UpdateFromSessionResponses, UpdateRouterToolSelectorData, UpdateRouterToolSelectorErrors, UpdateRouterToolSelectorResponses, UpdateScheduleData, UpdateScheduleErrors, UpdateScheduleResponses, UpdateSessionNameData, UpdateSessionNameErrors, UpdateSessionNameResponses, UpdateSessionUserRecipeValuesData, UpdateSessionUserRecipeValuesErrors, UpdateSessionUserRecipeValuesResponses, UpsertConfigData, UpsertConfigErrors, UpsertConfigResponses, UpsertPermissionsData, UpsertPermissionsErrors, UpsertPermissionsResponses, ValidateConfigData, ValidateConfigErrors, ValidateConfigResponses } from './types.gen';
|
||||
import type { AddExtensionData, AddExtensionErrors, AddExtensionResponses, AgentAddExtensionData, AgentAddExtensionErrors, AgentAddExtensionResponses, AgentRemoveExtensionData, AgentRemoveExtensionErrors, AgentRemoveExtensionResponses, BackupConfigData, BackupConfigErrors, BackupConfigResponses, CheckProviderData, ConfirmPermissionData, ConfirmPermissionErrors, ConfirmPermissionResponses, CreateCustomProviderData, CreateCustomProviderErrors, CreateCustomProviderResponses, CreateRecipeData, CreateRecipeErrors, CreateRecipeResponses, CreateScheduleData, CreateScheduleErrors, CreateScheduleResponses, DecodeRecipeData, DecodeRecipeErrors, DecodeRecipeResponses, DeleteRecipeData, DeleteRecipeErrors, DeleteRecipeResponses, DeleteScheduleData, DeleteScheduleErrors, DeleteScheduleResponses, DeleteSessionData, DeleteSessionErrors, DeleteSessionResponses, DiagnosticsData, DiagnosticsErrors, DiagnosticsResponses, EncodeRecipeData, EncodeRecipeErrors, EncodeRecipeResponses, ExportSessionData, ExportSessionErrors, ExportSessionResponses, GetCustomProviderData, GetCustomProviderErrors, GetCustomProviderResponses, GetExtensionsData, GetExtensionsErrors, GetExtensionsResponses, GetProviderModelsData, GetProviderModelsErrors, GetProviderModelsResponses, GetSessionData, GetSessionErrors, GetSessionInsightsData, GetSessionInsightsErrors, GetSessionInsightsResponses, GetSessionResponses, GetToolsData, GetToolsErrors, GetToolsResponses, ImportSessionData, ImportSessionErrors, ImportSessionResponses, InitConfigData, InitConfigErrors, InitConfigResponses, InspectRunningJobData, InspectRunningJobErrors, InspectRunningJobResponses, KillRunningJobData, KillRunningJobResponses, ListRecipesData, ListRecipesErrors, ListRecipesResponses, ListSchedulesData, ListSchedulesErrors, ListSchedulesResponses, ListSessionsData, ListSessionsErrors, ListSessionsResponses, McpUiProxyData, McpUiProxyErrors, McpUiProxyResponses, ParseRecipeData, ParseRecipeErrors, ParseRecipeResponses, PauseScheduleData, PauseScheduleErrors, PauseScheduleResponses, ProvidersData, ProvidersResponses, ReadAllConfigData, ReadAllConfigResponses, ReadConfigData, ReadConfigErrors, ReadConfigResponses, RecoverConfigData, RecoverConfigErrors, RecoverConfigResponses, RemoveConfigData, RemoveConfigErrors, RemoveConfigResponses, RemoveCustomProviderData, RemoveCustomProviderErrors, RemoveCustomProviderResponses, RemoveExtensionData, RemoveExtensionErrors, RemoveExtensionResponses, ReplyData, ReplyErrors, ReplyResponses, ResumeAgentData, ResumeAgentErrors, ResumeAgentResponses, RunNowHandlerData, RunNowHandlerErrors, RunNowHandlerResponses, SaveRecipeData, SaveRecipeErrors, SaveRecipeResponses, ScanRecipeData, ScanRecipeResponses, SessionsHandlerData, SessionsHandlerErrors, SessionsHandlerResponses, SetConfigProviderData, StartAgentData, StartAgentErrors, StartAgentResponses, StartOpenrouterSetupData, StartOpenrouterSetupResponses, StartTetrateSetupData, StartTetrateSetupResponses, StatusData, StatusResponses, UnpauseScheduleData, UnpauseScheduleErrors, UnpauseScheduleResponses, UpdateAgentProviderData, UpdateAgentProviderErrors, UpdateAgentProviderResponses, UpdateCustomProviderData, UpdateCustomProviderErrors, UpdateCustomProviderResponses, UpdateFromSessionData, UpdateFromSessionErrors, UpdateFromSessionResponses, UpdateRouterToolSelectorData, UpdateRouterToolSelectorErrors, UpdateRouterToolSelectorResponses, UpdateScheduleData, UpdateScheduleErrors, UpdateScheduleResponses, UpdateSessionNameData, UpdateSessionNameErrors, UpdateSessionNameResponses, UpdateSessionUserRecipeValuesData, UpdateSessionUserRecipeValuesErrors, UpdateSessionUserRecipeValuesResponses, UpsertConfigData, UpsertConfigErrors, UpsertConfigResponses, UpsertPermissionsData, UpsertPermissionsErrors, UpsertPermissionsResponses, ValidateConfigData, ValidateConfigErrors, ValidateConfigResponses } from './types.gen';
|
||||
|
||||
export type Options<TData extends TDataShape = TDataShape, ThrowOnError extends boolean = boolean> = Options2<TData, ThrowOnError> & {
|
||||
/**
|
||||
@@ -310,6 +310,13 @@ export const startTetrateSetup = <ThrowOnError extends boolean = false>(options?
|
||||
});
|
||||
};
|
||||
|
||||
export const mcpUiProxy = <ThrowOnError extends boolean = false>(options: Options<McpUiProxyData, ThrowOnError>) => {
|
||||
return (options.client ?? client).get<McpUiProxyResponses, McpUiProxyErrors, ThrowOnError>({
|
||||
url: '/mcp-ui-proxy',
|
||||
...options
|
||||
});
|
||||
};
|
||||
|
||||
export const createRecipe = <ThrowOnError extends boolean = false>(options: Options<CreateRecipeData, ThrowOnError>) => {
|
||||
return (options.client ?? client).post<CreateRecipeResponses, CreateRecipeErrors, ThrowOnError>({
|
||||
url: '/recipes/create',
|
||||
|
||||
@@ -1725,6 +1725,32 @@ export type StartTetrateSetupResponses = {
|
||||
|
||||
export type StartTetrateSetupResponse = StartTetrateSetupResponses[keyof StartTetrateSetupResponses];
|
||||
|
||||
export type McpUiProxyData = {
|
||||
body?: never;
|
||||
path?: never;
|
||||
query: {
|
||||
/**
|
||||
* Secret key for authentication
|
||||
*/
|
||||
secret: string;
|
||||
};
|
||||
url: '/mcp-ui-proxy';
|
||||
};
|
||||
|
||||
export type McpUiProxyErrors = {
|
||||
/**
|
||||
* Unauthorized - invalid or missing secret
|
||||
*/
|
||||
401: unknown;
|
||||
};
|
||||
|
||||
export type McpUiProxyResponses = {
|
||||
/**
|
||||
* MCP UI proxy HTML page
|
||||
*/
|
||||
200: unknown;
|
||||
};
|
||||
|
||||
export type CreateRecipeData = {
|
||||
body: CreateRecipeRequest;
|
||||
path?: never;
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
UIActionResultNotification,
|
||||
UIActionResultPrompt,
|
||||
UIActionResultToolCall,
|
||||
UIActionResult,
|
||||
} from '@mcp-ui/client';
|
||||
import { useState, useEffect } from 'react';
|
||||
import { toast } from 'react-toastify';
|
||||
@@ -15,41 +16,6 @@ interface MCPUIResourceRendererProps {
|
||||
appendPromptToChat?: (value: string) => void;
|
||||
}
|
||||
|
||||
type UISizeChange = {
|
||||
type: 'ui-size-change';
|
||||
payload: {
|
||||
height: number;
|
||||
width: number;
|
||||
};
|
||||
};
|
||||
|
||||
// Reserved message types from iframe to host
|
||||
type UILifecycleIframeReady = {
|
||||
type: 'ui-lifecycle-iframe-ready';
|
||||
payload?: Record<string, unknown>;
|
||||
};
|
||||
|
||||
type UIRequestData = {
|
||||
type: 'ui-request-data';
|
||||
messageId: string;
|
||||
payload: {
|
||||
requestType: string;
|
||||
params: Record<string, unknown>;
|
||||
};
|
||||
};
|
||||
|
||||
// We are creating a new type to support all reserved message types that may come from the iframe
|
||||
// Not all reserved message types are currently exported by @mcp-ui/client
|
||||
type ActionEventsFromIframe =
|
||||
| UIActionResultIntent
|
||||
| UIActionResultLink
|
||||
| UIActionResultNotification
|
||||
| UIActionResultPrompt
|
||||
| UIActionResultToolCall
|
||||
| UISizeChange
|
||||
| UILifecycleIframeReady
|
||||
| UIRequestData;
|
||||
|
||||
// More specific result types using discriminated unions
|
||||
type UIActionHandlerSuccess<T = unknown> = {
|
||||
status: 'success';
|
||||
@@ -126,20 +92,34 @@ export default function MCPUIResourceRenderer({
|
||||
appendPromptToChat,
|
||||
}: MCPUIResourceRendererProps) {
|
||||
const [currentThemeValue, setCurrentThemeValue] = useState<string>('light');
|
||||
const [proxyUrl, setProxyUrl] = useState<string | undefined>(undefined);
|
||||
|
||||
useEffect(() => {
|
||||
const theme = localStorage.getItem('theme') || 'light';
|
||||
setCurrentThemeValue(theme);
|
||||
console.log('[MCP-UI] Current theme value:', theme);
|
||||
|
||||
const fetchProxyUrl = async () => {
|
||||
try {
|
||||
const baseUrl = await window.electron.getGoosedHostPort();
|
||||
const secretKey = await window.electron.getSecretKey();
|
||||
if (baseUrl && secretKey) {
|
||||
setProxyUrl(`${baseUrl}/mcp-ui-proxy?secret=${encodeURIComponent(secretKey)}`);
|
||||
} else {
|
||||
console.error('Failed to get goosed host/port or secret key');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error fetching MCP-UI Proxy URL:', error);
|
||||
}
|
||||
};
|
||||
|
||||
fetchProxyUrl().catch(console.error);
|
||||
}, []);
|
||||
|
||||
const handleUIAction = async (
|
||||
actionEvent: ActionEventsFromIframe
|
||||
): Promise<UIActionHandlerResult> => {
|
||||
const handleUIAction = async (actionEvent: UIActionResult): Promise<UIActionHandlerResult> => {
|
||||
// result to pass back to the MCP-UI
|
||||
let result: UIActionHandlerResult;
|
||||
|
||||
const handleToolCase = async (
|
||||
const handleToolAction = async (
|
||||
actionEvent: UIActionResultToolCall
|
||||
): Promise<UIActionHandlerResult> => {
|
||||
const { toolName, params } = actionEvent.payload;
|
||||
@@ -156,7 +136,7 @@ export default function MCPUIResourceRenderer({
|
||||
};
|
||||
};
|
||||
|
||||
const handlePromptCase = async (
|
||||
const handlePromptAction = async (
|
||||
actionEvent: UIActionResultPrompt
|
||||
): Promise<UIActionHandlerResult> => {
|
||||
const { prompt } = actionEvent.payload;
|
||||
@@ -191,7 +171,9 @@ export default function MCPUIResourceRenderer({
|
||||
};
|
||||
};
|
||||
|
||||
const handleLinkCase = async (actionEvent: UIActionResultLink) => {
|
||||
const handleLinkAction = async (
|
||||
actionEvent: UIActionResultLink
|
||||
): Promise<UIActionHandlerResult> => {
|
||||
const { url } = actionEvent.payload;
|
||||
|
||||
try {
|
||||
@@ -244,7 +226,7 @@ export default function MCPUIResourceRenderer({
|
||||
}
|
||||
};
|
||||
|
||||
const handleNotifyCase = async (
|
||||
const handleNotifyAction = async (
|
||||
actionEvent: UIActionResultNotification
|
||||
): Promise<UIActionHandlerResult> => {
|
||||
const { message } = actionEvent.payload;
|
||||
@@ -262,7 +244,7 @@ export default function MCPUIResourceRenderer({
|
||||
};
|
||||
};
|
||||
|
||||
const handleIntentCase = async (
|
||||
const handleIntentAction = async (
|
||||
actionEvent: UIActionResultIntent
|
||||
): Promise<UIActionHandlerResult> => {
|
||||
toast.info(
|
||||
@@ -285,82 +267,31 @@ export default function MCPUIResourceRenderer({
|
||||
};
|
||||
};
|
||||
|
||||
const handleSizeChangeCase = async (
|
||||
actionEvent: UISizeChange
|
||||
): Promise<UIActionHandlerResult> => {
|
||||
return {
|
||||
status: 'success' as const,
|
||||
message: 'Size change handled',
|
||||
data: actionEvent.payload,
|
||||
};
|
||||
};
|
||||
|
||||
const handleIframeReadyCase = async (
|
||||
actionEvent: UILifecycleIframeReady
|
||||
): Promise<UIActionHandlerResult> => {
|
||||
console.log('[MCP-UI] Iframe ready to receive messages');
|
||||
return {
|
||||
status: 'success' as const,
|
||||
message: 'Iframe is ready to receive messages',
|
||||
data: actionEvent.payload,
|
||||
};
|
||||
};
|
||||
|
||||
const handleRequestDataCase = async (
|
||||
actionEvent: UIRequestData
|
||||
): Promise<UIActionHandlerResult> => {
|
||||
const { messageId, payload } = actionEvent;
|
||||
const { requestType, params } = payload;
|
||||
console.log('[MCP-UI] Data request received:', { messageId, requestType, params });
|
||||
return {
|
||||
status: 'success' as const,
|
||||
message: `Data request received: ${requestType}`,
|
||||
data: {
|
||||
messageId,
|
||||
requestType,
|
||||
params,
|
||||
response: { status: 'acknowledged' },
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
try {
|
||||
switch (actionEvent.type) {
|
||||
case 'tool':
|
||||
result = await handleToolCase(actionEvent);
|
||||
result = await handleToolAction(actionEvent);
|
||||
break;
|
||||
|
||||
case 'prompt':
|
||||
result = await handlePromptCase(actionEvent);
|
||||
result = await handlePromptAction(actionEvent);
|
||||
break;
|
||||
|
||||
case 'link':
|
||||
result = await handleLinkCase(actionEvent);
|
||||
result = await handleLinkAction(actionEvent);
|
||||
break;
|
||||
|
||||
case 'notify':
|
||||
result = await handleNotifyCase(actionEvent);
|
||||
result = await handleNotifyAction(actionEvent);
|
||||
break;
|
||||
|
||||
case 'intent':
|
||||
result = await handleIntentCase(actionEvent);
|
||||
break;
|
||||
|
||||
case 'ui-size-change':
|
||||
result = await handleSizeChangeCase(actionEvent);
|
||||
break;
|
||||
|
||||
case 'ui-lifecycle-iframe-ready':
|
||||
result = await handleIframeReadyCase(actionEvent);
|
||||
break;
|
||||
|
||||
case 'ui-request-data':
|
||||
result = await handleRequestDataCase(actionEvent);
|
||||
result = await handleIntentAction(actionEvent);
|
||||
break;
|
||||
|
||||
default: {
|
||||
const _exhaustiveCheck: never = actionEvent;
|
||||
console.error('Unhandled action type:', _exhaustiveCheck);
|
||||
console.error('Unhandled MCP-UI action type:', _exhaustiveCheck);
|
||||
result = {
|
||||
status: 'error',
|
||||
error: {
|
||||
@@ -372,7 +303,7 @@ export default function MCPUIResourceRenderer({
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('[MCP-UI] Unexpected error:', error);
|
||||
console.error('Unexpected error handling MCP-UI action:', error);
|
||||
result = {
|
||||
status: 'error',
|
||||
error: {
|
||||
@@ -383,12 +314,6 @@ export default function MCPUIResourceRenderer({
|
||||
};
|
||||
}
|
||||
|
||||
if (result.status === 'error') {
|
||||
console.error('[MCP-UI] Action failed:', result);
|
||||
} else {
|
||||
console.log('[MCP-UI] Action succeeded:', result);
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
@@ -398,19 +323,20 @@ export default function MCPUIResourceRenderer({
|
||||
<UIResourceRenderer
|
||||
resource={content.resource}
|
||||
onUIAction={handleUIAction}
|
||||
supportedContentTypes={['rawHtml', 'externalUrl']} // Goose does not support remoteDom content
|
||||
htmlProps={{
|
||||
autoResizeIframe: {
|
||||
height: true,
|
||||
width: false, // set to false to allow for responsive design
|
||||
},
|
||||
sandboxPermissions: 'allow-forms', // enabled for experimentation, is spread into underlying iframe defaults
|
||||
iframeRenderData: {
|
||||
// iframeRenderData allows us to pass data down to MCP-UIs
|
||||
// MPC-UIs might find stuff like host and theme for conditional rendering
|
||||
// MCP-UIs might find stuff like host and theme for conditional rendering
|
||||
// usage of this is experimental, leaving in place for demos
|
||||
host: 'goose',
|
||||
theme: currentThemeValue,
|
||||
},
|
||||
proxy: proxyUrl, // refer to https://mcpui.dev/guide/client/using-a-proxy
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user