sunpeak 0.17.7 → 0.18.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.
Files changed (90) hide show
  1. package/README.md +52 -44
  2. package/bin/commands/dev.mjs +5 -6
  3. package/bin/commands/inspect.mjs +17 -18
  4. package/bin/lib/inspect/inspect-config.d.mts +2 -2
  5. package/bin/lib/inspect/inspect-config.mjs +2 -2
  6. package/bin/lib/live/chatgpt-page.mjs +2 -2
  7. package/bin/lib/live/host-page.mjs +3 -8
  8. package/bin/lib/sandbox-server.mjs +11 -11
  9. package/bin/sunpeak.js +3 -3
  10. package/dist/chatgpt/chatgpt-conversation.d.ts +1 -1
  11. package/dist/chatgpt/index.cjs +20 -20
  12. package/dist/chatgpt/index.cjs.map +1 -1
  13. package/dist/chatgpt/index.d.ts +10 -10
  14. package/dist/chatgpt/index.js +5 -5
  15. package/dist/chatgpt/index.js.map +1 -1
  16. package/dist/claude/claude-conversation.d.ts +1 -1
  17. package/dist/claude/index.cjs +2 -2
  18. package/dist/claude/index.d.ts +1 -1
  19. package/dist/claude/index.js +2 -2
  20. package/dist/host/chatgpt/index.cjs +0 -40
  21. package/dist/host/chatgpt/index.cjs.map +1 -1
  22. package/dist/host/chatgpt/index.d.ts +0 -3
  23. package/dist/host/chatgpt/index.js +1 -40
  24. package/dist/host/chatgpt/index.js.map +1 -1
  25. package/dist/host/index.cjs +1 -4
  26. package/dist/host/index.cjs.map +1 -1
  27. package/dist/host/index.d.ts +1 -5
  28. package/dist/host/index.js +2 -4
  29. package/dist/host/index.js.map +1 -1
  30. package/dist/index.cjs +9 -10
  31. package/dist/index.cjs.map +1 -1
  32. package/dist/index.d.ts +1 -3
  33. package/dist/index.js +4 -4
  34. package/dist/index.js.map +1 -1
  35. package/dist/{simulator → inspector}/hosts.d.ts +3 -3
  36. package/dist/{simulator → inspector}/iframe-resource.d.ts +3 -3
  37. package/dist/inspector/index.cjs +74 -0
  38. package/dist/{simulator → inspector}/index.cjs.map +1 -1
  39. package/dist/{simulator → inspector}/index.d.ts +8 -8
  40. package/dist/{simulator → inspector}/index.js +8 -8
  41. package/dist/{simulator → inspector}/index.js.map +1 -1
  42. package/dist/{simulator/simulator-types.d.ts → inspector/inspector-types.d.ts} +1 -1
  43. package/dist/{simulator/simulator-url.d.ts → inspector/inspector-url.d.ts} +15 -15
  44. package/dist/{simulator/simulator.d.ts → inspector/inspector.d.ts} +3 -3
  45. package/dist/{simulator → inspector}/mcp-app-host.d.ts +5 -5
  46. package/dist/{simulator → inspector}/mock-openai-runtime.d.ts +2 -2
  47. package/dist/{simulator → inspector}/sandbox-proxy.d.ts +1 -1
  48. package/dist/{simulator/use-simulator-state.d.ts → inspector/use-inspector-state.d.ts} +4 -4
  49. package/dist/{simulator → inspector}/use-mcp-connection.d.ts +1 -1
  50. package/dist/{simulator-eU6sQTje.cjs → inspector-CByJjmPD.cjs} +51 -52
  51. package/dist/{simulator-eU6sQTje.cjs.map → inspector-CByJjmPD.cjs.map} +1 -1
  52. package/dist/{simulator-0dAb16Qt.js → inspector-ClhpqKLi.js} +42 -43
  53. package/dist/{simulator-0dAb16Qt.js.map → inspector-ClhpqKLi.js.map} +1 -1
  54. package/dist/{simulator-url-3ATCsPOT.cjs → inspector-url-7qhtJwY6.cjs} +10 -10
  55. package/dist/{simulator-url-3ATCsPOT.cjs.map → inspector-url-7qhtJwY6.cjs.map} +1 -1
  56. package/dist/{simulator-url-BbuuWa7S.js → inspector-url-DuEFmxLP.js} +9 -9
  57. package/dist/{simulator-url-BbuuWa7S.js.map → inspector-url-DuEFmxLP.js.map} +1 -1
  58. package/dist/mcp/index.cjs +146 -12
  59. package/dist/mcp/index.cjs.map +1 -1
  60. package/dist/mcp/index.d.ts +2 -0
  61. package/dist/mcp/index.js +143 -14
  62. package/dist/mcp/index.js.map +1 -1
  63. package/dist/mcp/production-server.d.ts +14 -0
  64. package/dist/mcp/resolve-domain.d.ts +55 -0
  65. package/dist/mcp/types.d.ts +1 -1
  66. package/dist/style.css +12 -12
  67. package/dist/types/resource-config.d.ts +20 -1
  68. package/dist/types/simulation.d.ts +1 -1
  69. package/package.json +7 -20
  70. package/template/dist/albums/albums.html +1 -1
  71. package/template/dist/albums/albums.json +1 -1
  72. package/template/dist/carousel/carousel.html +1 -1
  73. package/template/dist/carousel/carousel.json +1 -1
  74. package/template/dist/map/map.html +1 -1
  75. package/template/dist/map/map.json +1 -1
  76. package/template/dist/review/review.html +1 -1
  77. package/template/dist/review/review.json +1 -1
  78. package/template/playwright.config.ts +1 -1
  79. package/template/src/index-resource.tsx +1 -1
  80. package/template/src/styles/globals.css +2 -2
  81. package/template/tests/e2e/albums.spec.ts +13 -13
  82. package/template/tests/e2e/carousel.spec.ts +11 -11
  83. package/template/tests/e2e/map.spec.ts +16 -16
  84. package/template/tests/e2e/review.spec.ts +25 -25
  85. package/dist/chatgpt/globals.css +0 -2642
  86. package/dist/host/chatgpt/use-file-download.d.ts +0 -33
  87. package/dist/simulator/index.cjs +0 -74
  88. /package/dist/{simulator → inspector}/host-styles.d.ts +0 -0
  89. /package/dist/{simulator → inspector}/simple-sidebar.d.ts +0 -0
  90. /package/dist/{simulator → inspector}/theme-provider.d.ts +0 -0
@@ -70,6 +70,13 @@ export interface ProductionServerConfig {
70
70
  resources: ProductionResource[];
71
71
  /** Auth function from server entry (populates extra.authInfo via req.auth) */
72
72
  auth?: AuthFunction;
73
+ /**
74
+ * Public URL of the MCP server (e.g. `'https://example.com/mcp'`).
75
+ * Used to auto-compute a default `_meta.ui.domain` for resources that
76
+ * don't specify one. Without this, resources without an explicit domain
77
+ * may trigger host warnings (e.g. ChatGPT's "Widget domain is not set").
78
+ */
79
+ serverUrl?: string;
73
80
  }
74
81
  /**
75
82
  * Configuration for creating a Web Standard MCP handler (serverless/edge).
@@ -87,6 +94,13 @@ export interface WebHandlerConfig {
87
94
  resources: ProductionResource[];
88
95
  /** Auth function for Web Standard Request objects */
89
96
  auth?: WebAuthFunction;
97
+ /**
98
+ * Public URL of the MCP server (e.g. `'https://example.com/mcp'`).
99
+ * Used to auto-compute a default `_meta.ui.domain` for resources that
100
+ * don't specify one. Without this, resources without an explicit domain
101
+ * may trigger host warnings (e.g. ChatGPT's "Widget domain is not set").
102
+ */
103
+ serverUrl?: string;
90
104
  }
91
105
  /**
92
106
  * Create an MCP server with production tool handlers and pre-built resources.
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Domain config: a single string (used for all hosts) or a map of
3
+ * host `clientInfo.name` → domain string. Use `'default'` as a fallback
4
+ * key for unmatched hosts.
5
+ */
6
+ export type DomainConfig = string | Record<string, string>;
7
+ /**
8
+ * Resolve a domain config to a single string for the given host.
9
+ *
10
+ * Lookup order: `map[clientName]` → `map['default']` → `undefined`.
11
+ * If `domain` is a plain string, it's returned as-is regardless of host.
12
+ */
13
+ export declare function resolveDomain(domain: DomainConfig | undefined, clientName: string | undefined): string | undefined;
14
+ /**
15
+ * Compute the Claude sandbox domain for a given MCP server URL.
16
+ *
17
+ * Claude uses the first 32 hex characters of a SHA-256 hash of the server URL
18
+ * as a subdomain of `claudemcpcontent.com`.
19
+ *
20
+ * @example
21
+ * ```ts
22
+ * computeClaudeDomain('https://example.com/mcp')
23
+ * // → 'a904794854a047f6b936c2d62d57a3c0.claudemcpcontent.com'
24
+ * ```
25
+ */
26
+ export declare function computeClaudeDomain(serverUrl: string): string;
27
+ /**
28
+ * Compute the ChatGPT sandbox domain for a given MCP server URL.
29
+ *
30
+ * ChatGPT derives a subdomain from the server URL by replacing non-alphanumeric
31
+ * characters with hyphens and appending `.oaiusercontent.com`.
32
+ *
33
+ * @example
34
+ * ```ts
35
+ * computeChatGPTDomain('https://www.example.com/mcp')
36
+ * // → 'www-example-com.oaiusercontent.com'
37
+ * ```
38
+ */
39
+ export declare function computeChatGPTDomain(serverUrl: string): string;
40
+ /**
41
+ * Inject a resolved domain into resource metadata.
42
+ *
43
+ * If the `_meta.ui.domain` field is a map (Record), it's resolved to a single
44
+ * string using `clientName`. If it's already a string or absent, the metadata
45
+ * is returned unchanged.
46
+ */
47
+ export declare function injectResolvedDomain(meta: Record<string, unknown> | undefined, clientName: string | undefined): Record<string, unknown> | undefined;
48
+ /**
49
+ * Auto-compute a default domain for the connecting host when the resource
50
+ * metadata has no domain set.
51
+ *
52
+ * Returns the metadata unchanged if `_meta.ui.domain` is already present.
53
+ * Otherwise, computes a host-appropriate domain from the server URL.
54
+ */
55
+ export declare function injectDefaultDomain(meta: Record<string, unknown> | undefined, clientName: string | undefined, serverUrl: string): Record<string, unknown>;
@@ -83,7 +83,7 @@ export interface MCPServerHandle {
83
83
  /**
84
84
  * Notify non-local sessions that resources have changed.
85
85
  * Sends `notifications/resources/list_changed` so hosts re-fetch fresh content.
86
- * Local sessions (ChatGPT, simulator) are skipped since they use Vite HMR.
86
+ * Local sessions (ChatGPT, inspector) are skipped since they use Vite HMR.
87
87
  */
88
88
  invalidateResources(): void;
89
89
  }
package/dist/style.css CHANGED
@@ -2217,28 +2217,28 @@
2217
2217
  }
2218
2218
  }
2219
2219
 
2220
- .sunpeak-simulator-root select, .sunpeak-simulator-root input:not([type="checkbox"]), .sunpeak-simulator-root textarea {
2220
+ .sunpeak-inspector-root select, .sunpeak-inspector-root input:not([type="checkbox"]), .sunpeak-inspector-root textarea {
2221
2221
  box-shadow: inset 0 0 0 1px var(--color-border-primary);
2222
2222
  border: 0;
2223
2223
  transition: box-shadow .15s, color .15s, background-color .15s;
2224
2224
  }
2225
2225
 
2226
- .sunpeak-simulator-root select:hover, .sunpeak-simulator-root input:not([type="checkbox"]):hover, .sunpeak-simulator-root textarea:hover {
2226
+ .sunpeak-inspector-root select:hover, .sunpeak-inspector-root input:not([type="checkbox"]):hover, .sunpeak-inspector-root textarea:hover {
2227
2227
  box-shadow: inset 0 0 0 1px var(--color-border-secondary);
2228
2228
  }
2229
2229
 
2230
- .sunpeak-simulator-root select:focus-visible, .sunpeak-simulator-root input:not([type="checkbox"]):focus-visible, .sunpeak-simulator-root textarea:focus-visible {
2230
+ .sunpeak-inspector-root select:focus-visible, .sunpeak-inspector-root input:not([type="checkbox"]):focus-visible, .sunpeak-inspector-root textarea:focus-visible {
2231
2231
  box-shadow: inset 0 0 0 1px var(--color-border-secondary);
2232
2232
  outline: 2px solid var(--color-ring-primary);
2233
2233
  outline-offset: -1px;
2234
2234
  }
2235
2235
 
2236
- .sunpeak-simulator-root button:focus-visible {
2236
+ .sunpeak-inspector-root button:focus-visible {
2237
2237
  outline: 2px solid var(--color-ring-primary);
2238
2238
  outline-offset: -1px;
2239
2239
  }
2240
2240
 
2241
- .sunpeak-simulator-root input[type="checkbox"] {
2241
+ .sunpeak-inspector-root input[type="checkbox"] {
2242
2242
  appearance: none;
2243
2243
  border: 1px solid var(--color-border-secondary);
2244
2244
  cursor: pointer;
@@ -2253,36 +2253,36 @@
2253
2253
  transition: border-color .15s, background-color .15s;
2254
2254
  }
2255
2255
 
2256
- .sunpeak-simulator-root input[type="checkbox"]:hover {
2256
+ .sunpeak-inspector-root input[type="checkbox"]:hover {
2257
2257
  border-color: var(--color-text-tertiary);
2258
2258
  }
2259
2259
 
2260
- .sunpeak-simulator-root input[type="checkbox"]:checked {
2260
+ .sunpeak-inspector-root input[type="checkbox"]:checked {
2261
2261
  border-color: var(--color-background-inverse);
2262
2262
  background-color: var(--color-background-inverse);
2263
2263
  background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 10 10' fill='none' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M2 5L4.25 7L8 3' stroke='white' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3e%3c/svg%3e");
2264
2264
  }
2265
2265
 
2266
- [data-theme="dark"] .sunpeak-simulator-root input[type="checkbox"]:checked {
2266
+ [data-theme="dark"] .sunpeak-inspector-root input[type="checkbox"]:checked {
2267
2267
  background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 10 10' fill='none' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M2 5L4.25 7L8 3' stroke='%23111' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3e%3c/svg%3e");
2268
2268
  }
2269
2269
 
2270
- .sunpeak-simulator-root input[type="checkbox"]:focus-visible {
2270
+ .sunpeak-inspector-root input[type="checkbox"]:focus-visible {
2271
2271
  outline: 2px solid var(--color-ring-primary);
2272
2272
  outline-offset: 2px;
2273
2273
  }
2274
2274
 
2275
- .sunpeak-simulator-root input[type="number"]::-webkit-inner-spin-button {
2275
+ .sunpeak-inspector-root input[type="number"]::-webkit-inner-spin-button {
2276
2276
  -webkit-appearance: none;
2277
2277
  margin: 0;
2278
2278
  }
2279
2279
 
2280
- .sunpeak-simulator-root input[type="number"]::-webkit-outer-spin-button {
2280
+ .sunpeak-inspector-root input[type="number"]::-webkit-outer-spin-button {
2281
2281
  -webkit-appearance: none;
2282
2282
  margin: 0;
2283
2283
  }
2284
2284
 
2285
- .sunpeak-simulator-root input[type="number"] {
2285
+ .sunpeak-inspector-root input[type="number"] {
2286
2286
  -moz-appearance: textfield;
2287
2287
  }
2288
2288
 
@@ -1,5 +1,6 @@
1
1
  import { Resource } from '@modelcontextprotocol/sdk/types.js';
2
2
  import { McpUiResourceMeta } from '@modelcontextprotocol/ext-apps';
3
+ import { DomainConfig } from '../mcp/resolve-domain.js';
3
4
  /**
4
5
  * Configuration for an MCP App resource, exported from resource .tsx files.
5
6
  *
@@ -13,7 +14,25 @@ export type ResourceConfig = Omit<Resource, 'uri' | 'name'> & {
13
14
  name?: string;
14
15
  title?: string;
15
16
  _meta?: {
16
- ui?: McpUiResourceMeta;
17
+ ui?: Omit<McpUiResourceMeta, 'domain'> & {
18
+ /**
19
+ * Dedicated sandbox origin for this resource.
20
+ *
21
+ * Can be a single string (used for all hosts) or a map of
22
+ * `clientInfo.name` → domain string for host-specific values.
23
+ * Use `'default'` as a fallback key for unmatched hosts.
24
+ *
25
+ * @example
26
+ * ```ts
27
+ * domain: {
28
+ * claude: computeClaudeDomain('https://my-server.com/mcp'),
29
+ * 'openai-mcp': computeChatGPTDomain('https://my-server.com/mcp'),
30
+ * default: 'fallback.example.com',
31
+ * }
32
+ * ```
33
+ */
34
+ domain?: DomainConfig;
35
+ };
17
36
  [key: string]: unknown;
18
37
  };
19
38
  };
@@ -13,7 +13,7 @@ export type ServerToolMock = CallToolResult | Array<{
13
13
  }>;
14
14
  /**
15
15
  * A simulation packages a component with its example data and metadata.
16
- * Each simulation represents a complete tool experience in the simulator.
16
+ * Each simulation represents a complete tool experience in the inspector.
17
17
  *
18
18
  * Resource rendering options (mutually exclusive):
19
19
  * - `resourceUrl`: URL to an HTML page (dev mode with Vite HMR)
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "sunpeak",
3
- "version": "0.17.7",
4
- "description": "Local-first MCP Apps framework. Quickstart, build, test, and ship your Claude Connector or ChatGPT App!",
3
+ "version": "0.18.2",
4
+ "description": "Inspector, testing framework, and app framework for MCP Apps.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
7
7
  "module": "./dist/index.js",
@@ -17,10 +17,10 @@
17
17
  "default": "./dist/index.cjs"
18
18
  }
19
19
  },
20
- "./simulator": {
20
+ "./inspector": {
21
21
  "import": {
22
- "types": "./dist/simulator/index.d.ts",
23
- "default": "./dist/simulator/index.js"
22
+ "types": "./dist/inspector/index.d.ts",
23
+ "default": "./dist/inspector/index.js"
24
24
  }
25
25
  },
26
26
  "./chatgpt": {
@@ -36,7 +36,6 @@
36
36
  }
37
37
  },
38
38
  "./style.css": "./dist/style.css",
39
- "./chatgpt/globals.css": "./dist/chatgpt/globals.css",
40
39
  "./mcp": {
41
40
  "import": {
42
41
  "types": "./dist/mcp/index.d.ts",
@@ -55,18 +54,6 @@
55
54
  "default": "./dist/host/chatgpt/index.js"
56
55
  }
57
56
  },
58
- "./platform": {
59
- "import": {
60
- "types": "./dist/host/index.d.ts",
61
- "default": "./dist/host/index.js"
62
- }
63
- },
64
- "./platform/chatgpt": {
65
- "import": {
66
- "types": "./dist/host/chatgpt/index.d.ts",
67
- "default": "./dist/host/chatgpt/index.js"
68
- }
69
- },
70
57
  "./test": {
71
58
  "import": {
72
59
  "types": "./bin/lib/live/live-fixtures.d.mts",
@@ -119,9 +106,9 @@
119
106
  "chatgpt-app",
120
107
  "mcp-ui",
121
108
  "mcp",
122
- "chatgpt-simulator",
109
+ "chatgpt-inspector",
123
110
  "claude",
124
- "claude-simulator",
111
+ "claude-inspector",
125
112
  "testing",
126
113
  "multi-platform",
127
114
  "react",