@creature-ai/sdk 0.1.2 → 0.1.3

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.
@@ -1,7 +1,196 @@
1
- import { g as StateListener, f as HostClientEvents, e as HostClientState, H as HostClient, d as HostClientConfig, T as ToolResult, W as WidgetState, D as DisplayMode, L as LogLevel, E as Environment, a as AppSessionState, b as AppSessionListener } from '../types-JBEuUzEi.js';
2
- export { A as AppSessionOptions, c as HostContext, S as StructuredWidgetState } from '../types-JBEuUzEi.js';
3
1
  export { applyDocumentTheme, applyHostFonts, applyHostStyleVariables, getDocumentTheme } from '@modelcontextprotocol/ext-apps';
4
2
 
3
+ /**
4
+ * Core types for the MCP SDK.
5
+ * These are framework-agnostic and shared between vanilla JS and React.
6
+ */
7
+ /**
8
+ * Environment types for host detection.
9
+ */
10
+ type Environment = "chatgpt" | "mcp-apps" | "standalone";
11
+ /**
12
+ * Display modes for UI resources.
13
+ * - "inline": Embedded within the conversation flow
14
+ * - "pip": Picture-in-picture floating panel
15
+ * - "fullscreen": Full-screen overlay
16
+ */
17
+ type DisplayMode = "inline" | "pip" | "fullscreen";
18
+ /**
19
+ * Log severity levels matching MCP protocol LoggingLevel.
20
+ * These are displayed in the host's DevConsole with appropriate colors.
21
+ */
22
+ type LogLevel = "debug" | "info" | "notice" | "warning" | "error";
23
+ /**
24
+ * Structured widget state format (ChatGPT-compatible).
25
+ * Allows separating model-visible content from private UI state.
26
+ */
27
+ interface StructuredWidgetState {
28
+ /** Content visible to the AI model on follow-up turns */
29
+ modelContent?: string | Record<string, unknown> | null;
30
+ /** UI-only state, hidden from model */
31
+ privateContent?: Record<string, unknown> | null;
32
+ /** File IDs for images the model can see */
33
+ imageIds?: string[];
34
+ }
35
+ /**
36
+ * Widget state can be structured (with modelContent/privateContent)
37
+ * or a simple key-value object.
38
+ */
39
+ type WidgetState = StructuredWidgetState | Record<string, unknown>;
40
+ /**
41
+ * Tool call result structure.
42
+ */
43
+ interface ToolResult<T = Record<string, unknown>> {
44
+ content?: Array<{
45
+ type: string;
46
+ text: string;
47
+ }>;
48
+ structuredContent?: T;
49
+ isError?: boolean;
50
+ source?: "agent" | "ui";
51
+ }
52
+ /**
53
+ * Host context sent from MCP Apps host.
54
+ * Follows MCP Apps spec with Creature extensions via [key: string]: unknown.
55
+ */
56
+ interface HostContext {
57
+ theme?: "light" | "dark";
58
+ styles?: {
59
+ variables?: Record<string, string>;
60
+ };
61
+ displayMode?: DisplayMode;
62
+ availableDisplayModes?: DisplayMode[];
63
+ viewport?: {
64
+ width: number;
65
+ height: number;
66
+ };
67
+ platform?: string;
68
+ /**
69
+ * Widget state restored from previous widget instance.
70
+ * Creature extension - passed via hostContext on ui/initialize.
71
+ */
72
+ widgetState?: WidgetState;
73
+ }
74
+ /**
75
+ * Configuration for creating a host client.
76
+ */
77
+ interface HostClientConfig {
78
+ /** Name of the client (for protocol handshake) */
79
+ name: string;
80
+ /** Version of the client */
81
+ version: string;
82
+ }
83
+ /**
84
+ * State managed by the host client.
85
+ */
86
+ interface HostClientState {
87
+ /** Whether the host connection is ready */
88
+ isReady: boolean;
89
+ /** The detected environment */
90
+ environment: Environment;
91
+ /** Current widget state */
92
+ widgetState: WidgetState | null;
93
+ }
94
+ /**
95
+ * Event handlers that can be registered on the host client.
96
+ */
97
+ interface HostClientEvents {
98
+ /** Called when tool input is received (before execution) */
99
+ "tool-input": (args: Record<string, unknown>) => void;
100
+ /** Called when tool result is received */
101
+ "tool-result": (result: ToolResult) => void;
102
+ /** Called when theme changes (MCP Apps only) */
103
+ "theme-change": (theme: "light" | "dark") => void;
104
+ /** Called when host requests teardown (MCP Apps only) */
105
+ teardown: () => Promise<void> | void;
106
+ /** Called when widget state changes (restored or updated) */
107
+ "widget-state-change": (widgetState: WidgetState | null) => void;
108
+ }
109
+ /**
110
+ * Listener for state changes.
111
+ */
112
+ type StateListener = (state: HostClientState, prevState: HostClientState) => void;
113
+ /**
114
+ * Host client interface.
115
+ * Implemented by McpAppHostClient and ChatGptAppHostClient.
116
+ */
117
+ interface HostClient {
118
+ /** Get current state */
119
+ getState(): HostClientState;
120
+ /** Subscribe to state changes. Returns unsubscribe function. */
121
+ subscribe(listener: StateListener): () => void;
122
+ /** Call a tool on the MCP server */
123
+ callTool<T = Record<string, unknown>>(toolName: string, args: Record<string, unknown>): Promise<ToolResult<T>>;
124
+ /** Send a notification to the host (MCP Apps only, no-op on ChatGPT) */
125
+ sendNotification(method: string, params: unknown): void;
126
+ /** Set widget state */
127
+ setWidgetState(state: WidgetState | null): void;
128
+ /**
129
+ * Request a display mode change from the host.
130
+ *
131
+ * The host may refuse or coerce the request (e.g., "pip" → "fullscreen" on mobile).
132
+ * Always check `availableDisplayModes` in host context before calling, and handle
133
+ * the returned mode differing from the requested mode.
134
+ *
135
+ * @param params - Object containing the requested display mode
136
+ * @returns Promise resolving to the actual display mode granted by the host
137
+ */
138
+ requestDisplayMode(params: {
139
+ mode: DisplayMode;
140
+ }): Promise<{
141
+ mode: DisplayMode;
142
+ }>;
143
+ /**
144
+ * Send a log message to the host's DevConsole.
145
+ *
146
+ * Logs are sent via the MCP protocol's `notifications/message` notification
147
+ * and displayed in the host's unified log viewer alongside server logs.
148
+ *
149
+ * @param level - Log severity level
150
+ * @param message - Log message
151
+ * @param data - Optional structured data to include
152
+ */
153
+ log(level: LogLevel, message: string, data?: Record<string, unknown>): void;
154
+ /** Register an event handler. Returns unsubscribe function. */
155
+ on<K extends keyof HostClientEvents>(event: K, handler: HostClientEvents[K]): () => void;
156
+ /** Start listening for host messages */
157
+ connect(): void;
158
+ /** Stop listening for host messages */
159
+ disconnect(): void;
160
+ }
161
+ /**
162
+ * WebSocket connection status.
163
+ */
164
+ type WebSocketStatus = "disconnected" | "connecting" | "connected" | "error";
165
+ /**
166
+ * Configuration for creating a WebSocket client.
167
+ */
168
+ interface WebSocketClientConfig<TReceive = unknown> {
169
+ /** Called when a message is received */
170
+ onMessage?: (message: TReceive) => void;
171
+ /** Called when connection status changes */
172
+ onStatusChange?: (status: WebSocketStatus, error?: string) => void;
173
+ /** Whether to auto-reconnect on disconnect (default: true) */
174
+ reconnect?: boolean;
175
+ /** Base interval for reconnection attempts in ms (default: 1000) */
176
+ reconnectInterval?: number;
177
+ }
178
+ /**
179
+ * WebSocket client interface.
180
+ */
181
+ interface WebSocketClient<TSend = unknown, TReceive = unknown> {
182
+ /** Current connection status */
183
+ readonly status: WebSocketStatus;
184
+ /** Error message if status is "error" */
185
+ readonly error: string | undefined;
186
+ /** Connect to the WebSocket server */
187
+ connect(): void;
188
+ /** Disconnect from the WebSocket server */
189
+ disconnect(): void;
190
+ /** Send a message to the server */
191
+ send(message: TSend): void;
192
+ }
193
+
5
194
  declare abstract class Subscribable {
6
195
  private stateListeners;
7
196
  private eventHandlers;
@@ -20,14 +209,16 @@ declare abstract class Subscribable {
20
209
  * with the ChatGPT host client. Handles the protocol handshake, tool calls,
21
210
  * notifications, and automatic style/theme application.
22
211
  */
23
- declare class McpHostClient extends Subscribable implements HostClient {
212
+ declare class McpAppHostClient extends Subscribable implements HostClient {
24
213
  private state;
25
214
  private config;
26
215
  private app;
27
216
  private connected;
28
217
  constructor(config: HostClientConfig);
218
+ /**
219
+ * Get the current client state.
220
+ */
29
221
  getState(): HostClientState;
30
- private setState;
31
222
  /**
32
223
  * Connect to the MCP Apps host.
33
224
  *
@@ -36,20 +227,6 @@ declare class McpHostClient extends Subscribable implements HostClient {
36
227
  * with host context including theme, styles, and widgetState.
37
228
  */
38
229
  connect(): void;
39
- /**
40
- * Set up notification handlers on the App instance.
41
- *
42
- * Maps the official SDK's callback pattern to our event emitter pattern,
43
- * allowing consumers to use `.on("tool-result", ...)` etc.
44
- */
45
- private setupHandlers;
46
- /**
47
- * Initiate connection using PostMessageTransport.
48
- *
49
- * The SDK's App.connect() handles the protocol handshake correctly:
50
- * the guest (App) sends `ui/initialize` to the host.
51
- */
52
- private initiateConnection;
53
230
  /**
54
231
  * Disconnect from the host.
55
232
  *
@@ -101,15 +278,44 @@ declare class McpHostClient extends Subscribable implements HostClient {
101
278
  * to the host. Logs appear in the unified DevConsole alongside server logs,
102
279
  * with appropriate color coding based on level.
103
280
  *
104
- * The logger name is automatically set to the app name from config.
105
- *
106
281
  * @param level - Log severity level (debug, info, notice, warning, error)
107
282
  * @param message - Log message
108
283
  * @param data - Optional structured data to include with the log
109
284
  */
110
285
  log(level: LogLevel, message: string, data?: Record<string, unknown>): void;
286
+ /**
287
+ * Update internal state and notify listeners.
288
+ */
289
+ private setState;
290
+ /**
291
+ * Set up notification handlers on the App instance.
292
+ *
293
+ * Maps the official SDK's callback pattern to our event emitter pattern,
294
+ * allowing consumers to use `.on("tool-result", ...)` etc.
295
+ */
296
+ private setupHandlers;
297
+ /**
298
+ * Initiate connection using PostMessageTransport.
299
+ *
300
+ * The SDK's App.connect() handles the protocol handshake correctly:
301
+ * the guest (App) sends `ui/initialize` to the host.
302
+ */
303
+ private initiateConnection;
304
+ /**
305
+ * Apply theme, styles, and fonts from host context.
306
+ */
307
+ private applyHostContext;
308
+ /**
309
+ * Extract text content from SDK result content array.
310
+ * Filters to only include text items since our ToolResult type expects text.
311
+ */
312
+ private extractTextContent;
111
313
  }
112
314
 
315
+ /**
316
+ * OpenAI bridge interface exposed by ChatGPT Apps SDK.
317
+ * Available on `window.openai` when running inside ChatGPT.
318
+ */
113
319
  interface OpenAIBridge {
114
320
  toolOutput?: Record<string, unknown>;
115
321
  widgetState?: WidgetState;
@@ -132,33 +338,92 @@ declare global {
132
338
  openai?: OpenAIBridge;
133
339
  }
134
340
  }
135
- declare class ChatGPTHostClient extends Subscribable implements HostClient {
341
+ /**
342
+ * ChatGPT Apps host client implementation.
343
+ *
344
+ * Bridges the ChatGPT Apps SDK (`window.openai`) to provide a consistent
345
+ * interface with the MCP Apps host client. Handles initial data processing,
346
+ * globals updates, and widget state synchronization.
347
+ */
348
+ declare class ChatGptAppHostClient extends Subscribable implements HostClient {
136
349
  private state;
137
350
  private config;
138
351
  private connected;
139
352
  private hasProcessedInitialData;
140
353
  private globalsHandler;
141
354
  constructor(config: HostClientConfig);
355
+ /**
356
+ * Get the current client state.
357
+ */
142
358
  getState(): HostClientState;
143
- private setState;
359
+ /**
360
+ * Connect to the ChatGPT host.
361
+ *
362
+ * Processes initial data from `window.openai` and sets up a listener
363
+ * for subsequent `openai:set_globals` events.
364
+ */
144
365
  connect(): void;
366
+ /**
367
+ * Disconnect from the host.
368
+ *
369
+ * Removes the globals event listener.
370
+ */
145
371
  disconnect(): void;
146
- private processInitialData;
147
- private setupGlobalsListener;
372
+ /**
373
+ * Call a tool on the MCP server via the ChatGPT bridge.
374
+ *
375
+ * @param toolName - Name of the tool to call
376
+ * @param args - Arguments to pass to the tool
377
+ * @returns Tool result with content and structuredContent
378
+ */
148
379
  callTool<T = Record<string, unknown>>(toolName: string, args: Record<string, unknown>): Promise<ToolResult<T>>;
380
+ /**
381
+ * Send a notification to the host.
382
+ *
383
+ * No-op on ChatGPT — notifications are not supported.
384
+ */
149
385
  sendNotification(_method: string, _params: unknown): void;
386
+ /**
387
+ * Set widget state and sync with the ChatGPT host.
388
+ *
389
+ * @param state - New widget state (or null to clear)
390
+ */
150
391
  setWidgetState(state: WidgetState | null): void;
151
392
  /**
152
393
  * Log a message to the console.
153
394
  *
154
395
  * ChatGPT doesn't have a DevConsole, so logs go to browser console only.
155
- * This provides API parity with McpHostClient.
396
+ * This provides API parity with McpAppHostClient.
156
397
  *
157
398
  * @param level - Log severity level
158
399
  * @param message - Log message
159
400
  * @param data - Optional structured data
160
401
  */
161
402
  log(level: LogLevel, message: string, data?: Record<string, unknown>): void;
403
+ /**
404
+ * Update internal state and notify listeners.
405
+ */
406
+ private setState;
407
+ /**
408
+ * Process initial data from `window.openai`.
409
+ *
410
+ * Called once on connect to handle any tool output or widget state
411
+ * that was set before the client connected.
412
+ */
413
+ private processInitialData;
414
+ /**
415
+ * Set up listener for `openai:set_globals` events.
416
+ *
417
+ * ChatGPT dispatches this event when tool output or widget state
418
+ * changes after initial load.
419
+ */
420
+ private setupGlobalsListener;
421
+ /**
422
+ * Request a display mode change from the ChatGPT host.
423
+ *
424
+ * @param params - Display mode to request
425
+ * @returns The resulting display mode
426
+ */
162
427
  requestDisplayMode(params: {
163
428
  mode: DisplayMode;
164
429
  }): Promise<{
@@ -178,53 +443,15 @@ declare class ChatGPTHostClient extends Subscribable implements HostClient {
178
443
  */
179
444
  declare function detectEnvironment(): Environment;
180
445
 
181
- type PartialState<TState extends AppSessionState> = {
182
- [K in keyof TState]?: Partial<TState[K]> | TState[K];
183
- };
184
- declare class AppSession<TInternal extends Record<string, unknown> = Record<string, unknown>, TBackend extends Record<string, unknown> = Record<string, unknown>, TUi extends WidgetState | null = WidgetState | null> {
185
- readonly id: string;
186
- private _state;
187
- private listeners;
188
- private hostClient;
189
- private hostUnsubscribe;
190
- constructor(initialState?: Partial<AppSessionState<TInternal, TBackend, TUi>>, options?: {
191
- id?: string;
192
- });
193
- private generateId;
194
- get state(): AppSessionState<TInternal, TBackend, TUi>;
195
- get internal(): TInternal;
196
- get backend(): TBackend;
197
- get ui(): TUi;
198
- subscribe(listener: AppSessionListener<AppSessionState<TInternal, TBackend, TUi>>): () => void;
199
- private notify;
200
- setState(partial: PartialState<AppSessionState<TInternal, TBackend, TUi>>): void;
201
- setInternal(internal: TInternal | Partial<TInternal>): void;
202
- setBackend(backend: TBackend | Partial<TBackend>): void;
203
- setUi(ui: TUi): void;
204
- updateUi(partial: TUi extends null ? never : Partial<NonNullable<TUi>>): void;
205
- bindHost(host: HostClient): () => void;
206
- unbindHost(): void;
207
- injectAppSessionId<T extends Record<string, unknown>>(data: T): T & {
208
- appSessionId: string;
209
- };
210
- }
211
-
212
- type ChannelStatus = "disconnected" | "connecting" | "connected" | "error";
213
- interface ChannelClientConfig<TReceive = unknown> {
214
- onMessage?: (message: TReceive) => void;
215
- onStatusChange?: (status: ChannelStatus, error?: string) => void;
216
- reconnect?: boolean;
217
- reconnectInterval?: number;
218
- }
219
- interface ChannelClient<TSend = unknown, TReceive = unknown> {
220
- readonly status: ChannelStatus;
221
- readonly error: string | undefined;
222
- connect(): void;
223
- disconnect(): void;
224
- send(message: TSend): void;
225
- }
226
- declare function createChannel<TSend = unknown, TReceive = unknown>(url: string, config?: ChannelClientConfig<TReceive>): ChannelClient<TSend, TReceive>;
446
+ /**
447
+ * Create a WebSocket client with automatic reconnection.
448
+ *
449
+ * @param url - WebSocket server URL
450
+ * @param config - Client configuration
451
+ * @returns WebSocket client instance
452
+ */
453
+ declare function createWebSocket<TSend = unknown, TReceive = unknown>(url: string, config?: WebSocketClientConfig<TReceive>): WebSocketClient<TSend, TReceive>;
227
454
 
228
455
  declare function createHost(config: HostClientConfig): HostClient;
229
456
 
230
- export { AppSession, AppSessionListener, AppSessionState, type ChannelClient, type ChannelClientConfig, type ChannelStatus, ChatGPTHostClient, DisplayMode, Environment, HostClient, HostClientConfig, HostClientEvents, HostClientState, LogLevel, McpHostClient, StateListener, ToolResult, WidgetState, createChannel, createHost, detectEnvironment };
457
+ export { ChatGptAppHostClient, type DisplayMode, type Environment, type HostClient, type HostClientConfig, type HostClientEvents, type HostClientState, type HostContext, type LogLevel, McpAppHostClient, type StateListener, type StructuredWidgetState, type ToolResult, type WebSocketClient, type WebSocketClientConfig, type WebSocketStatus, type WidgetState, createHost, createWebSocket, detectEnvironment };