mcp-app-studio 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,445 @@
1
+ /**
2
+ * Color theme of the host application.
3
+ * Use `useTheme()` hook to get the current theme and adapt your UI accordingly.
4
+ *
5
+ * @example
6
+ * ```tsx
7
+ * const theme = useTheme();
8
+ * return <div className={theme === 'dark' ? 'bg-gray-900' : 'bg-white'}>...</div>
9
+ * ```
10
+ */
11
+ type Theme = "light" | "dark";
12
+ /**
13
+ * Platform your app is running on.
14
+ * - `"chatgpt"` - Running inside ChatGPT (window.openai API available)
15
+ * - `"mcp"` - Running inside an MCP host like Claude Desktop
16
+ * - `"unknown"` - Platform not detected (development mode or unsupported host)
17
+ *
18
+ * Use `usePlatform()` hook or `detectPlatform()` to check at runtime.
19
+ *
20
+ * @example
21
+ * ```tsx
22
+ * const platform = usePlatform();
23
+ * if (platform === 'chatgpt') {
24
+ * // Use ChatGPT-specific features like widgetState
25
+ * }
26
+ * ```
27
+ */
28
+ type Platform = "chatgpt" | "mcp" | "unknown";
29
+ /**
30
+ * Display mode for the widget.
31
+ * - `"inline"` - Widget embedded in conversation flow (default)
32
+ * - `"fullscreen"` - Widget takes full screen
33
+ * - `"pip"` - Picture-in-picture floating window (ChatGPT only)
34
+ *
35
+ * Use `useDisplayMode()` to get current mode and request changes.
36
+ *
37
+ * @example
38
+ * ```tsx
39
+ * const [mode, setMode] = useDisplayMode();
40
+ * <button onClick={() => setMode('fullscreen')}>Expand</button>
41
+ * ```
42
+ */
43
+ type DisplayMode = "inline" | "fullscreen" | "pip";
44
+ /**
45
+ * Annotations for content blocks that provide hints to the host.
46
+ */
47
+ interface ContentBlockAnnotations {
48
+ /** Who should see this content: user, assistant, or both */
49
+ audience?: Array<"user" | "assistant">;
50
+ /** ISO timestamp of last modification */
51
+ lastModified?: string;
52
+ /** Priority hint for content ordering (higher = more important) */
53
+ priority?: number;
54
+ }
55
+ interface ContentBlockBase {
56
+ /** Arbitrary metadata passed through to the host */
57
+ _meta?: Record<string, unknown>;
58
+ /** Annotations providing hints about the content */
59
+ annotations?: ContentBlockAnnotations;
60
+ }
61
+ /**
62
+ * Icon definition for resource links.
63
+ */
64
+ interface ContentBlockIcon {
65
+ /** URL or data URI of the icon */
66
+ src: string;
67
+ /** MIME type of the icon (e.g., "image/png") */
68
+ mimeType?: string;
69
+ /** Available sizes (e.g., ["16x16", "32x32"]) */
70
+ sizes?: string[];
71
+ /** Which theme this icon is for */
72
+ theme?: "light" | "dark";
73
+ }
74
+ /**
75
+ * Text content block for plain text responses.
76
+ *
77
+ * @example
78
+ * ```ts
79
+ * const block: TextContentBlock = { type: "text", text: "Hello, world!" };
80
+ * // Or use the helper:
81
+ * const block = textBlock("Hello, world!");
82
+ * ```
83
+ */
84
+ interface TextContentBlock extends ContentBlockBase {
85
+ type: "text";
86
+ /** The text content */
87
+ text: string;
88
+ }
89
+ /**
90
+ * Image content block for inline images.
91
+ *
92
+ * @example
93
+ * ```ts
94
+ * const block = imageBlock(base64Data, "image/png");
95
+ * ```
96
+ */
97
+ interface ImageContentBlock extends ContentBlockBase {
98
+ type: "image";
99
+ /** Base64-encoded image data */
100
+ data: string;
101
+ /** MIME type (e.g., "image/png", "image/jpeg") */
102
+ mimeType: string;
103
+ }
104
+ /**
105
+ * Audio content block for inline audio.
106
+ */
107
+ interface AudioContentBlock extends ContentBlockBase {
108
+ type: "audio";
109
+ /** Base64-encoded audio data */
110
+ data: string;
111
+ /** MIME type (e.g., "audio/mp3", "audio/wav") */
112
+ mimeType: string;
113
+ }
114
+ /**
115
+ * Resource link content block for clickable links to external resources.
116
+ */
117
+ interface ResourceLinkContentBlock extends ContentBlockBase {
118
+ type: "resource_link";
119
+ /** URI of the resource */
120
+ uri: string;
121
+ /** Display name */
122
+ name: string;
123
+ /** Optional title for tooltip */
124
+ title?: string;
125
+ /** Optional description text */
126
+ description?: string;
127
+ /** MIME type of the linked resource */
128
+ mimeType?: string;
129
+ /** Icons to display with the link */
130
+ icons?: ContentBlockIcon[];
131
+ }
132
+ /**
133
+ * Embedded resource content block.
134
+ */
135
+ interface ResourceContentBlock extends ContentBlockBase {
136
+ type: "resource";
137
+ resource: {
138
+ /** URI identifying the resource */
139
+ uri: string;
140
+ /** MIME type of the resource */
141
+ mimeType?: string;
142
+ } & ({
143
+ text: string;
144
+ blob?: never;
145
+ } | {
146
+ blob: string;
147
+ text?: never;
148
+ });
149
+ }
150
+ /**
151
+ * Union type for all content block types.
152
+ * Used in tool results and chat messages.
153
+ */
154
+ type ContentBlock = TextContentBlock | ImageContentBlock | AudioContentBlock | ResourceLinkContentBlock | ResourceContentBlock;
155
+ /**
156
+ * Creates a text content block.
157
+ *
158
+ * @param text - The text content
159
+ * @param annotations - Optional annotations
160
+ * @returns A TextContentBlock object
161
+ *
162
+ * @example
163
+ * ```ts
164
+ * const result: ToolResult = {
165
+ * content: [textBlock("Operation completed successfully")]
166
+ * };
167
+ * ```
168
+ */
169
+ declare function textBlock(text: string, annotations?: ContentBlockAnnotations): TextContentBlock;
170
+ /**
171
+ * Creates an image content block.
172
+ *
173
+ * @param data - Base64-encoded image data
174
+ * @param mimeType - MIME type (e.g., "image/png")
175
+ * @param annotations - Optional annotations
176
+ * @returns An ImageContentBlock object
177
+ *
178
+ * @example
179
+ * ```ts
180
+ * const screenshot = await captureScreen();
181
+ * const result: ToolResult = {
182
+ * content: [imageBlock(screenshot, "image/png")]
183
+ * };
184
+ * ```
185
+ */
186
+ declare function imageBlock(data: string, mimeType: string, annotations?: ContentBlockAnnotations): ImageContentBlock;
187
+ /**
188
+ * Result returned from a tool call.
189
+ * Use with `useCallTool()` hook to call tools and handle responses.
190
+ *
191
+ * @example
192
+ * ```tsx
193
+ * const callTool = useCallTool();
194
+ * const result = await callTool('search', { query: 'restaurants' });
195
+ * if (result.isError) {
196
+ * console.error('Tool failed:', result.content);
197
+ * }
198
+ * ```
199
+ */
200
+ interface ToolResult {
201
+ /** Content blocks with the result (text, images, etc.) */
202
+ content?: ContentBlock[];
203
+ /** Structured JSON data for programmatic access */
204
+ structuredContent?: Record<string, unknown>;
205
+ /** Whether the tool call resulted in an error */
206
+ isError?: boolean;
207
+ /** Arbitrary metadata from the tool */
208
+ _meta?: Record<string, unknown>;
209
+ }
210
+ /**
211
+ * Container dimensions provided by the host.
212
+ */
213
+ interface ContainerDimensions {
214
+ /** Current height in pixels */
215
+ height?: number;
216
+ /** Maximum allowed height */
217
+ maxHeight?: number;
218
+ /** Current width in pixels */
219
+ width?: number;
220
+ /** Maximum allowed width */
221
+ maxWidth?: number;
222
+ }
223
+ /**
224
+ * CSS styling hints from the host.
225
+ */
226
+ interface HostStyles {
227
+ /** CSS custom properties (variables) from the host */
228
+ variables?: Record<string, string>;
229
+ css?: {
230
+ /** Font CSS to inject for consistent typography */
231
+ fonts?: string;
232
+ };
233
+ }
234
+ /**
235
+ * Context information about the host environment.
236
+ * Access via `useHostContext()` hook.
237
+ *
238
+ * @example
239
+ * ```tsx
240
+ * const context = useHostContext();
241
+ * console.log('Theme:', context?.theme);
242
+ * console.log('Locale:', context?.locale);
243
+ * console.log('Display mode:', context?.displayMode);
244
+ * ```
245
+ */
246
+ interface HostContext {
247
+ /** Current color theme ("light" or "dark") */
248
+ theme?: Theme;
249
+ /** User's locale (e.g., "en-US", "ja-JP") */
250
+ locale?: string;
251
+ /** User's timezone (e.g., "America/New_York") */
252
+ timeZone?: string;
253
+ /** Current display mode */
254
+ displayMode?: DisplayMode;
255
+ /** Display modes the host supports */
256
+ availableDisplayModes?: DisplayMode[];
257
+ /** Container size constraints */
258
+ containerDimensions?: ContainerDimensions;
259
+ /** Host-provided styling hints */
260
+ styles?: HostStyles;
261
+ /** Platform type (web, desktop, mobile) */
262
+ platform?: "web" | "desktop" | "mobile";
263
+ /** Device input capabilities */
264
+ deviceCapabilities?: {
265
+ /** Device has touch input */
266
+ touch?: boolean;
267
+ /** Device has hover capability (mouse) */
268
+ hover?: boolean;
269
+ };
270
+ /** Safe area insets for notched devices */
271
+ safeAreaInsets?: {
272
+ top: number;
273
+ right: number;
274
+ bottom: number;
275
+ left: number;
276
+ };
277
+ /** User agent string */
278
+ userAgent?: string;
279
+ /** Information about the tool that invoked this widget */
280
+ toolInfo?: {
281
+ /** Unique identifier for this tool call */
282
+ id?: string | number;
283
+ tool: {
284
+ /** Name of the tool */
285
+ name: string;
286
+ /** Tool description */
287
+ description?: string;
288
+ /** JSON Schema for tool input */
289
+ inputSchema?: Record<string, unknown>;
290
+ };
291
+ };
292
+ }
293
+ /**
294
+ * Chat message to send to the conversation.
295
+ * Used with `useSendMessage()` hook.
296
+ */
297
+ interface ChatMessage {
298
+ /** Message role (currently only "user" supported) */
299
+ role: "user";
300
+ /** Message content blocks */
301
+ content: ContentBlock[];
302
+ }
303
+
304
+ /**
305
+ * Feature keys that can be checked with `useFeature()` hook.
306
+ * These correspond to boolean capabilities in `HostCapabilities`.
307
+ */
308
+ type FeatureKey = "callTool" | "openLink" | "sizeReporting" | "closeWidget" | "sendMessage" | "modal" | "fileUpload" | "fileDownload" | "widgetState" | "modelContext" | "logging" | "partialToolInput" | "toolCancellation" | "teardown";
309
+ /**
310
+ * Capabilities supported by the host platform.
311
+ * Use `useCapabilities()` hook to access these at runtime.
312
+ *
313
+ * @example
314
+ * ```tsx
315
+ * const capabilities = useCapabilities();
316
+ * if (capabilities?.widgetState) {
317
+ * // ChatGPT-specific feature
318
+ * }
319
+ * ```
320
+ */
321
+ interface HostCapabilities {
322
+ /** The platform this capability set is for */
323
+ platform: Platform;
324
+ /** Can call tools registered with the host */
325
+ callTool: boolean;
326
+ /** Can open external links */
327
+ openLink: boolean;
328
+ /** Supported display modes */
329
+ displayModes: DisplayMode[];
330
+ /** Can report widget size to host */
331
+ sizeReporting: boolean;
332
+ /** Can request widget close */
333
+ closeWidget: boolean;
334
+ /** Can send messages to conversation */
335
+ sendMessage: boolean;
336
+ /** Can request modal dialogs */
337
+ modal: boolean;
338
+ /** Can upload files (ChatGPT only) */
339
+ fileUpload: boolean;
340
+ /** Can download files (ChatGPT only) */
341
+ fileDownload: boolean;
342
+ /** Can persist widget state (ChatGPT only) */
343
+ widgetState: boolean;
344
+ /** Can update model context (MCP only) */
345
+ modelContext: boolean;
346
+ /** Structured logging support (MCP only) */
347
+ logging: boolean;
348
+ /** Partial/streaming tool input (MCP only) */
349
+ partialToolInput: boolean;
350
+ /** Tool cancellation support (MCP only) */
351
+ toolCancellation: boolean;
352
+ /** Teardown notification support (MCP only) */
353
+ teardown: boolean;
354
+ }
355
+ /**
356
+ * Capabilities available on ChatGPT.
357
+ *
358
+ * Notable features:
359
+ * - `widgetState`: Persistent state across refreshes
360
+ * - `fileUpload`/`fileDownload`: File handling
361
+ * - `modal`: Modal dialog support
362
+ * - `pip`: Picture-in-picture display mode
363
+ */
364
+ declare const CHATGPT_CAPABILITIES: HostCapabilities;
365
+ /**
366
+ * Capabilities available on MCP hosts (e.g., Claude Desktop).
367
+ *
368
+ * Notable features:
369
+ * - `modelContext`: Update model context dynamically
370
+ * - `logging`: Structured logging to host
371
+ * - `partialToolInput`: Streaming input support
372
+ * - `toolCancellation`: Handle cancelled tool calls
373
+ * - `teardown`: Cleanup notification
374
+ */
375
+ declare const MCP_CAPABILITIES: HostCapabilities;
376
+ /**
377
+ * Check if a specific feature is available.
378
+ *
379
+ * @param capabilities - The host capabilities object
380
+ * @param feature - The feature key to check
381
+ * @returns Whether the feature is available
382
+ *
383
+ * @example
384
+ * ```ts
385
+ * if (hasFeature(capabilities, 'widgetState')) {
386
+ * // Safe to use widget state
387
+ * }
388
+ * ```
389
+ */
390
+ declare function hasFeature(capabilities: HostCapabilities | null, feature: FeatureKey): boolean;
391
+
392
+ type ToolInputCallback = (args: Record<string, unknown>) => void;
393
+ type ToolInputPartialCallback = (args: Record<string, unknown>) => void;
394
+ type ToolResultCallback = (result: ToolResult) => void;
395
+ type ToolCancelledCallback = (reason: string) => void;
396
+ type HostContextChangedCallback = (ctx: Partial<HostContext>) => void;
397
+ type TeardownCallback = () => Promise<void> | void;
398
+ interface HostBridge {
399
+ readonly platform: "chatgpt" | "mcp";
400
+ readonly capabilities: HostCapabilities;
401
+ connect(): Promise<void>;
402
+ getHostContext(): HostContext | null;
403
+ onToolInput(callback: ToolInputCallback): () => void;
404
+ onToolResult(callback: ToolResultCallback): () => void;
405
+ onHostContextChanged(callback: HostContextChangedCallback): () => void;
406
+ callTool(name: string, args: Record<string, unknown>): Promise<ToolResult>;
407
+ openLink(url: string): Promise<void>;
408
+ requestDisplayMode(mode: DisplayMode): Promise<DisplayMode>;
409
+ sendSizeChanged(size: {
410
+ width?: number;
411
+ height?: number;
412
+ }): void;
413
+ }
414
+ interface ExtendedBridge extends HostBridge {
415
+ onToolInputPartial?(callback: ToolInputPartialCallback): () => void;
416
+ onToolCancelled?(callback: ToolCancelledCallback): () => void;
417
+ onTeardown?(callback: TeardownCallback): () => void;
418
+ sendMessage?(message: ChatMessage): Promise<void>;
419
+ updateModelContext?(ctx: {
420
+ content?: ContentBlock[];
421
+ structuredContent?: Record<string, unknown>;
422
+ }): Promise<void>;
423
+ setWidgetState?(state: Record<string, unknown> | null): void;
424
+ getWidgetState?(): Record<string, unknown> | null;
425
+ uploadFile?(file: File): Promise<{
426
+ fileId: string;
427
+ }>;
428
+ getFileDownloadUrl?(fileId: string): Promise<{
429
+ downloadUrl: string;
430
+ }>;
431
+ requestClose?(): void;
432
+ requestModal?(options: {
433
+ title?: string;
434
+ params?: Record<string, unknown>;
435
+ anchor?: {
436
+ x: number;
437
+ y: number;
438
+ width: number;
439
+ height: number;
440
+ };
441
+ }): Promise<void>;
442
+ sendLog?(level: "debug" | "info" | "warning" | "error", data: string): void;
443
+ }
444
+
445
+ export { type AudioContentBlock, CHATGPT_CAPABILITIES, type ChatMessage, type ContainerDimensions, type ContentBlock, type ContentBlockAnnotations, type ContentBlockIcon, type DisplayMode, type ExtendedBridge, type FeatureKey, type HostBridge, type HostCapabilities, type HostContext, type HostContextChangedCallback, type HostStyles, type ImageContentBlock, MCP_CAPABILITIES, type Platform, type ResourceContentBlock, type ResourceLinkContentBlock, type TeardownCallback, type TextContentBlock, type Theme, type ToolCancelledCallback, type ToolInputCallback, type ToolInputPartialCallback, type ToolResult, type ToolResultCallback, hasFeature, imageBlock, textBlock };
@@ -0,0 +1,16 @@
1
+ import {
2
+ imageBlock,
3
+ textBlock
4
+ } from "../chunk-KRCGOYZ5.js";
5
+ import {
6
+ CHATGPT_CAPABILITIES,
7
+ MCP_CAPABILITIES,
8
+ hasFeature
9
+ } from "../chunk-4LAH4JH6.js";
10
+ export {
11
+ CHATGPT_CAPABILITIES,
12
+ MCP_CAPABILITIES,
13
+ hasFeature,
14
+ imageBlock,
15
+ textBlock
16
+ };