@ggui-ai/mcp-server 0.1.0-rc.3 → 0.2.0-alpha.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.
- package/README.md +1 -1
- package/dist/build-mcp.d.ts +8 -8
- package/dist/build-mcp.d.ts.map +1 -1
- package/dist/build-mcp.js +53 -12
- package/dist/console-auth.d.ts +7 -7
- package/dist/console-auth.d.ts.map +1 -1
- package/dist/console-auth.js +4 -4
- package/dist/console-cache.d.ts +2 -2
- package/dist/console-cache.d.ts.map +1 -1
- package/dist/console-cache.js +10 -10
- package/dist/console-headers.d.ts +2 -2
- package/dist/console-headers.js +2 -2
- package/dist/console-payloads.d.ts +3 -3
- package/dist/console-payloads.d.ts.map +1 -1
- package/dist/console-payloads.js +10 -10
- package/dist/console-timeline.d.ts +12 -30
- package/dist/console-timeline.d.ts.map +1 -1
- package/dist/console-timeline.js +44 -45
- package/dist/index.d.ts +7 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -5
- package/dist/instructions-presets.d.ts +1 -1
- package/dist/instructions-presets.d.ts.map +1 -1
- package/dist/instructions-presets.js +40 -22
- package/dist/llm-backed-negotiator.d.ts +6 -6
- package/dist/llm-backed-negotiator.d.ts.map +1 -1
- package/dist/llm-backed-negotiator.js +92 -91
- package/dist/mcp-apps-inbound.d.ts +3 -3
- package/dist/mcp-apps-inbound.d.ts.map +1 -1
- package/dist/mcp-apps-inbound.js +28 -23
- package/dist/mcp-apps-outbound.d.ts +136 -121
- package/dist/mcp-apps-outbound.d.ts.map +1 -1
- package/dist/mcp-apps-outbound.js +384 -414
- package/dist/mcp-mounts.d.ts +21 -20
- package/dist/mcp-mounts.d.ts.map +1 -1
- package/dist/mcp-mounts.js +25 -29
- package/dist/{session-channel.d.ts → render-channel.d.ts} +145 -102
- package/dist/render-channel.d.ts.map +1 -0
- package/dist/{session-channel.js → render-channel.js} +481 -462
- package/dist/schema-compat.d.ts +11 -11
- package/dist/schema-compat.d.ts.map +1 -1
- package/dist/schema-compat.js +6 -6
- package/dist/server.d.ts +224 -219
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +1498 -1963
- package/dist/storage.d.ts +7 -7
- package/dist/storage.d.ts.map +1 -1
- package/dist/storage.js +12 -12
- package/package.json +12 -11
- package/dist/render-gate.d.ts +0 -87
- package/dist/render-gate.d.ts.map +0 -1
- package/dist/render-gate.js +0 -77
- package/dist/render-rate-limit.d.ts +0 -59
- package/dist/render-rate-limit.d.ts.map +0 -1
- package/dist/render-rate-limit.js +0 -73
- package/dist/render-signing.d.ts +0 -98
- package/dist/render-signing.d.ts.map +0 -1
- package/dist/render-signing.js +0 -113
- package/dist/session-channel.d.ts.map +0 -1
package/dist/server.d.ts
CHANGED
|
@@ -37,32 +37,32 @@
|
|
|
37
37
|
* handlers wired up. The `Logger.warn('dev_mode_auth_enabled')` fires
|
|
38
38
|
* once at boot so operators see the shape they're running.
|
|
39
39
|
*/
|
|
40
|
-
import {
|
|
41
|
-
import {
|
|
42
|
-
import type
|
|
43
|
-
import
|
|
44
|
-
import {
|
|
45
|
-
import type {
|
|
46
|
-
import type {
|
|
47
|
-
import type
|
|
48
|
-
import
|
|
49
|
-
import type
|
|
50
|
-
import { type
|
|
51
|
-
import { type AppsSource, type UserDefaultAppSource } from
|
|
52
|
-
import { type
|
|
53
|
-
import { type
|
|
54
|
-
import { type
|
|
55
|
-
import type
|
|
56
|
-
import
|
|
57
|
-
import { type ServerInfo } from
|
|
58
|
-
import { type
|
|
59
|
-
import { type
|
|
60
|
-
import { type
|
|
61
|
-
import { type
|
|
62
|
-
import { type
|
|
63
|
-
import { type
|
|
64
|
-
import { type
|
|
65
|
-
import { type
|
|
40
|
+
import type { AppMetadataStore, AuditSink, AuthAdapter, AuthResult, BlueprintProvider, BlueprintSearch, BlueprintSelector, BlueprintStore, CodeStore, ConnectorRegistry, EmbeddingProvider, GeneratorRegistry, KeyValueStore, PairingService, PendingEventConsumer, ProviderKeyStore, RateLimiter, RenderStore, SessionStreamBuffer, ShortCodeIndex, TelemetrySink, ThreadStore, VectorStore } from "@ggui-ai/mcp-server-core";
|
|
41
|
+
import type { SharedHandler } from "@ggui-ai/mcp-server-handlers";
|
|
42
|
+
import { type ThemeCatalogEntry } from "@ggui-ai/mcp-server-handlers/app-discovery";
|
|
43
|
+
import type { OperatorConfig } from "@ggui-ai/project-config";
|
|
44
|
+
import type { DiscoveredPrimitiveCatalog, LoadedTheme } from "@ggui-ai/project-config/node";
|
|
45
|
+
import type { Blueprint } from "@ggui-ai/protocol";
|
|
46
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
47
|
+
import { type Express, type Request } from "express";
|
|
48
|
+
import { Server as NodeHttpServer } from "node:http";
|
|
49
|
+
import { type ZodRawShape } from "zod";
|
|
50
|
+
import { type ThemeFileUploader, type ThemeWriter } from "./console-theme-routes.js";
|
|
51
|
+
import { type AppsSource, type UserDefaultAppSource } from "@ggui-ai/mcp-server-handlers/ops-apps";
|
|
52
|
+
import { type ConnectorKeysSource } from "@ggui-ai/mcp-server-handlers/ops-connector-keys";
|
|
53
|
+
import { type CouponRedeemSource } from "@ggui-ai/mcp-server-handlers/ops-coupon";
|
|
54
|
+
import { type OrgInvitesSource, type OrgsSource } from "@ggui-ai/mcp-server-handlers/ops-orgs";
|
|
55
|
+
import { type ChannelNotifier, type GenerationCredentials, type GenerationDeps, type HandshakeNegotiator, type PropsUpdateNotifier, type ProvisionalPreviewConfig, type ProvisionalPreviewDeps, type ProvisionalPreviewEmitter, type ProvisionalPreviewOutcome } from "@ggui-ai/mcp-server-handlers/renders";
|
|
56
|
+
import type { UiRegistry } from "@ggui-ai/ui-registry";
|
|
57
|
+
import { type ServerInfo } from "./build-mcp.js";
|
|
58
|
+
import { type EmailSender, type MagicLinkStore } from "./email-login.js";
|
|
59
|
+
import { type McpInstructionsValue } from "./instructions-presets.js";
|
|
60
|
+
import { type Logger } from "./logger.js";
|
|
61
|
+
import { type McpServerMount, type McpService } from "./mcp-mounts.js";
|
|
62
|
+
import { type OAuthConfig } from "./oauth.js";
|
|
63
|
+
import { type RenderChannelServer, type WiredActionRouter } from "./render-channel.js";
|
|
64
|
+
import { type SchemaCompatMode } from "./schema-compat.js";
|
|
65
|
+
import { type ThreadOwnerResolver } from "./thread-transport.js";
|
|
66
66
|
export declare function defaultHandlers(deps: {
|
|
67
67
|
readonly embedding: EmbeddingProvider;
|
|
68
68
|
readonly vectors: VectorStore;
|
|
@@ -93,24 +93,24 @@ export declare function defaultHandlers(deps: {
|
|
|
93
93
|
readonly uiRegistry?: UiRegistry;
|
|
94
94
|
/**
|
|
95
95
|
* Handshake-state KV store. When bound, `ggui_handshake` is
|
|
96
|
-
* registered and the paired `
|
|
96
|
+
* registered and the paired `ggui_render({handshakeId})` consume
|
|
97
97
|
* path is enabled. Both handlers share the same instance so the
|
|
98
98
|
* write + read sit on one source of truth.
|
|
99
99
|
*
|
|
100
100
|
* Absent = handshake handler is NOT registered AND
|
|
101
|
-
* `
|
|
101
|
+
* `ggui_render({handshakeId})` falls back to a rejection shape.
|
|
102
102
|
*/
|
|
103
103
|
readonly handshake?: {
|
|
104
104
|
readonly kvStore: KeyValueStore;
|
|
105
105
|
/**
|
|
106
|
-
* Optional
|
|
107
|
-
* the wire
|
|
106
|
+
* Optional render store. When bound, `ggui_handshake` validates
|
|
107
|
+
* the wire render id against this store (existence + tenant
|
|
108
108
|
* ownership) before negotiating. OSS sets this to the same store
|
|
109
|
-
*
|
|
110
|
-
* at the earliest boundary; cloud pods omit and
|
|
111
|
-
* time via their own DDB-backed path.
|
|
109
|
+
* the render-commit handler uses so the handshake catches unknown
|
|
110
|
+
* / cross-tenant ids at the earliest boundary; cloud pods omit and
|
|
111
|
+
* validate at render-commit time via their own DDB-backed path.
|
|
112
112
|
*/
|
|
113
|
-
readonly
|
|
113
|
+
readonly renderStore?: RenderStore;
|
|
114
114
|
/**
|
|
115
115
|
* Optional negotiator binding. Absent = `ggui_handshake` stamps
|
|
116
116
|
* `action: 'create'` + honest no-negotiator reason on the record
|
|
@@ -133,25 +133,18 @@ export declare function defaultHandlers(deps: {
|
|
|
133
133
|
* subscribe-for vs. must iframe-poll directly. Returning
|
|
134
134
|
* `undefined` omits the field (universal iframe-polling fallback).
|
|
135
135
|
*/
|
|
136
|
-
readonly serverCapabilities?: () => import(
|
|
136
|
+
readonly serverCapabilities?: () => import("@ggui-ai/protocol").ServerCapabilities | undefined;
|
|
137
137
|
};
|
|
138
138
|
readonly push?: {
|
|
139
|
-
readonly
|
|
140
|
-
readonly renderBaseUrl: string;
|
|
139
|
+
readonly renderStore: RenderStore;
|
|
141
140
|
/**
|
|
142
|
-
* Optional
|
|
143
|
-
*
|
|
144
|
-
*
|
|
145
|
-
*
|
|
141
|
+
* Optional bootstrap-credential minter. When present, `ggui_render`
|
|
142
|
+
* (the renamed render-commit tool) results carry the
|
|
143
|
+
* `ai.ggui/render` slice meta. When absent, they don't —
|
|
144
|
+
* non-MCP-Apps hosts read `{renderId}` off structuredContent and
|
|
145
|
+
* resolve the render-resource themselves.
|
|
146
146
|
*/
|
|
147
|
-
readonly
|
|
148
|
-
/**
|
|
149
|
-
* Optional bootstrap-credential minter. When present, `ggui_push`
|
|
150
|
-
* results carry `_meta.ggui.bootstrap`. When absent, they don't —
|
|
151
|
-
* non-MCP-Apps hosts still get `structuredContent.url` as the
|
|
152
|
-
* fallback link.
|
|
153
|
-
*/
|
|
154
|
-
readonly mintBootstrap?: (sessionId: string, appId: string) => {
|
|
147
|
+
readonly mintBootstrap?: (renderId: string, appId: string) => {
|
|
155
148
|
wsUrl: string;
|
|
156
149
|
token: string;
|
|
157
150
|
expiresAt: string;
|
|
@@ -159,7 +152,7 @@ export declare function defaultHandlers(deps: {
|
|
|
159
152
|
/**
|
|
160
153
|
* URL of the renderer bundle the thin-shell HTML should fetch
|
|
161
154
|
* (C8 — plan §C8). Padded onto
|
|
162
|
-
* {@link
|
|
155
|
+
* {@link McpAppAiGguiRenderMeta.runtimeUrl} at `resultMeta` time.
|
|
163
156
|
* Same-origin default is `/_ggui/iframe-runtime.js`; hosted cloud
|
|
164
157
|
* operators override to a CDN URL. Required when `mintBootstrap`
|
|
165
158
|
* is set (the thin shell depends on it); otherwise ignored.
|
|
@@ -174,13 +167,13 @@ export declare function defaultHandlers(deps: {
|
|
|
174
167
|
readonly runtimeUrl?: string | (() => string | undefined);
|
|
175
168
|
/**
|
|
176
169
|
* Theme preset id resolved from `ggui.json#theme`. Forwarded onto
|
|
177
|
-
* `
|
|
178
|
-
* MCP Apps hosts (claude.ai, Claude Desktop)
|
|
179
|
-
* operator's theme into the iframe.
|
|
170
|
+
* the `ai.ggui/render.themeId` slice field in the `ggui_render`
|
|
171
|
+
* resultMeta so MCP Apps hosts (claude.ai, Claude Desktop)
|
|
172
|
+
* propagate the operator's theme into the iframe.
|
|
180
173
|
*/
|
|
181
174
|
readonly themeId?: string;
|
|
182
175
|
/** Theme color mode resolved from `ggui.json#theme.mode`. */
|
|
183
|
-
readonly themeMode?:
|
|
176
|
+
readonly themeMode?: "light" | "dark";
|
|
184
177
|
/**
|
|
185
178
|
* Live theme getter — resolved per-push. When set, supersedes
|
|
186
179
|
* the static `themeId` / `themeMode` for every push's bootstrap.
|
|
@@ -192,7 +185,7 @@ export declare function defaultHandlers(deps: {
|
|
|
192
185
|
*/
|
|
193
186
|
readonly themeProvider?: () => {
|
|
194
187
|
readonly id?: string;
|
|
195
|
-
readonly mode?:
|
|
188
|
+
readonly mode?: "light" | "dark";
|
|
196
189
|
} | undefined;
|
|
197
190
|
/**
|
|
198
191
|
* Optional connector registry — required for accepting
|
|
@@ -201,16 +194,16 @@ export declare function defaultHandlers(deps: {
|
|
|
201
194
|
*/
|
|
202
195
|
readonly connectors?: ConnectorRegistry;
|
|
203
196
|
/**
|
|
204
|
-
* Optional admission-control limiter. When present, `
|
|
197
|
+
* Optional admission-control limiter. When present, `ggui_render`
|
|
205
198
|
* gates every call through `rateLimiter.check({key:
|
|
206
|
-
* '
|
|
199
|
+
* 'ggui_render:<appId>', cost:1})` before doing any work; denial
|
|
207
200
|
* surfaces as a `RateLimitedError`. Omitted = unlimited (the
|
|
208
201
|
* `NoopRateLimiter` server default).
|
|
209
202
|
*/
|
|
210
203
|
readonly rateLimiter?: RateLimiter;
|
|
211
204
|
/**
|
|
212
205
|
* Optional shortCode → session binding index. When present,
|
|
213
|
-
* `
|
|
206
|
+
* `ggui_render` records every minted `shortCode` so console's
|
|
214
207
|
* `/s/<shortCode>` viewer (via the session-cookie endpoint) can
|
|
215
208
|
* resolve it back to the right session. Absent = hosted cloud
|
|
216
209
|
* flow (DynamoDB side-table owns lookups), or console not
|
|
@@ -218,83 +211,83 @@ export declare function defaultHandlers(deps: {
|
|
|
218
211
|
*/
|
|
219
212
|
readonly shortCodeIndex?: ShortCodeIndex;
|
|
220
213
|
/**
|
|
221
|
-
* Optional provisional-preview wiring. When present, `
|
|
214
|
+
* Optional provisional-preview wiring. When present, `ggui_render`
|
|
222
215
|
* kicks off the configured emitter on every qualifying push (the
|
|
223
216
|
* `evaluateProvisionalPreviewGate` predicate filters MCP Apps
|
|
224
217
|
* pushes + storyless calls automatically). Absent = no preview
|
|
225
218
|
* channel traffic.
|
|
226
219
|
*
|
|
227
220
|
* Constructed by `createGguiServer` from `opts.provisionalPreview`
|
|
228
|
-
* plus the late-bound `
|
|
221
|
+
* plus the late-bound `RenderChannelServer.sendToSession`
|
|
229
222
|
* closure; callers threading their own handler set can build
|
|
230
223
|
* `ProvisionalPreviewDeps` directly.
|
|
231
224
|
*/
|
|
232
225
|
readonly provisionalPreview?: ProvisionalPreviewDeps;
|
|
233
226
|
/**
|
|
234
|
-
* Optional generation wiring. When present, `
|
|
227
|
+
* Optional generation wiring. When present, `ggui_render` invokes
|
|
235
228
|
* the supplied {@link UiGenerator} on every story-path call and
|
|
236
|
-
*
|
|
237
|
-
*
|
|
238
|
-
*
|
|
239
|
-
*
|
|
229
|
+
* commits the generated `Render` before returning `codeReady:
|
|
230
|
+
* true`. Absent = push stays in placeholder mode (render +
|
|
231
|
+
* shortCode + preview still work, but no componentCode is
|
|
232
|
+
* produced).
|
|
240
233
|
*
|
|
241
234
|
* Callers compose the `GenerationDeps` directly via the
|
|
242
235
|
* `@ggui-ai/mcp-server-handlers` export — `defaultHandlers`
|
|
243
|
-
* simply threads the bundle through to `
|
|
236
|
+
* simply threads the bundle through to `createGguiRenderHandler`.
|
|
244
237
|
*/
|
|
245
238
|
readonly generation?: GenerationDeps;
|
|
246
239
|
/**
|
|
247
|
-
* Optional live-subscriber
|
|
248
|
-
* When present, every successful `
|
|
249
|
-
* fan-outs a `{type:'
|
|
250
|
-
* every live subscriber on the affected
|
|
251
|
-
* to `
|
|
240
|
+
* Optional live-subscriber render-commit notifier.
|
|
241
|
+
* When present, every successful `renderStore.commit` inside `ggui_render`
|
|
242
|
+
* fan-outs a `{type:'render', payload:{render}}` live-channel frame to
|
|
243
|
+
* every live subscriber on the affected render. Forwarded as-is
|
|
244
|
+
* to `createGguiRenderHandler`.
|
|
252
245
|
*
|
|
253
|
-
* Hosts without a
|
|
246
|
+
* Hosts without a render channel (programmatic embedding, Lambda
|
|
254
247
|
* one-shot) leave this absent — there are no live subscribers to
|
|
255
|
-
* notify, and the
|
|
248
|
+
* notify, and the render handler's own no-op-on-absent posture
|
|
256
249
|
* keeps the path intact.
|
|
257
250
|
*/
|
|
258
251
|
readonly channelNotifier?: ChannelNotifier;
|
|
259
252
|
/**
|
|
260
253
|
* Optional F4 schema compat check hook. When present,
|
|
261
|
-
* `
|
|
262
|
-
* before every `
|
|
254
|
+
* `ggui_render` invokes it immediately
|
|
255
|
+
* before every `renderStore.commit` — if the pending Render's
|
|
263
256
|
* `actionSpec` / `streamSpec` references a tool whose schemas
|
|
264
257
|
* disagree, the hook throws `SchemaCompatError` and the handler
|
|
265
|
-
* converts the rejection into an error
|
|
266
|
-
* false`. Forwarded as-is to `
|
|
258
|
+
* converts the rejection into an error render + `codeReady:
|
|
259
|
+
* false`. Forwarded as-is to `createGguiRenderHandler`.
|
|
267
260
|
*
|
|
268
261
|
* `createGguiServer` binds this closure against the composed
|
|
269
262
|
* `handlers` list + `opts.schemaCompatCheck` (default `'reject'`)
|
|
270
263
|
* automatically; callers composing their own push handler via
|
|
271
264
|
* `defaultHandlers` wire the hook themselves.
|
|
272
265
|
*/
|
|
273
|
-
readonly
|
|
274
|
-
readonly actionSpec?: import(
|
|
275
|
-
readonly streamSpec?: import(
|
|
266
|
+
readonly checkRenderContracts?: (shape: {
|
|
267
|
+
readonly actionSpec?: import("@ggui-ai/protocol").ActionSpec;
|
|
268
|
+
readonly streamSpec?: import("@ggui-ai/protocol").StreamSpec;
|
|
276
269
|
}) => void;
|
|
277
270
|
/**
|
|
278
271
|
* Optional content-addressable code store. When present together
|
|
279
|
-
* with {@link codeBaseUrl}, `
|
|
272
|
+
* with {@link codeBaseUrl}, `ggui_render` writes generated
|
|
280
273
|
* componentCode to the store and surfaces `codeUrl` + `codeHash`
|
|
281
274
|
* on the response — the sole static-component delivery channel
|
|
282
275
|
* post-T3-1 (2026-05-13).
|
|
283
276
|
*
|
|
284
|
-
* Absent: `
|
|
277
|
+
* Absent: `ggui_render.resultMeta` omits `codeUrl`. The iframe boots
|
|
285
278
|
* via live-mode (wsUrl+token) and receives the stack item via the
|
|
286
|
-
* live-channel WS subscribe. `/r/<shortCode>`
|
|
279
|
+
* live-channel WS subscribe. `/r/<shortCode>` (HTML default; JSON branch on `Accept: application/json`)
|
|
287
280
|
* routes ALSO mint `codeUrl` when `codeStore` is set — they derive
|
|
288
281
|
* the base URL from `req.protocol + req.host` when `codeBaseUrl`
|
|
289
282
|
* isn't explicit (works for local dev + tunnel deployments).
|
|
290
|
-
* Forwarded as-is to `
|
|
283
|
+
* Forwarded as-is to `createGguiRenderHandler`.
|
|
291
284
|
*/
|
|
292
285
|
readonly codeStore?: CodeStore;
|
|
293
286
|
/**
|
|
294
287
|
* Base URL the code-blob route resolves to. Required when
|
|
295
288
|
* `codeStore` is present so the handler can compose
|
|
296
289
|
* `<base>/code/<hash>.js`. Forwarded as-is to
|
|
297
|
-
* `
|
|
290
|
+
* `createGguiRenderHandler`.
|
|
298
291
|
*/
|
|
299
292
|
readonly codeBaseUrl?: string;
|
|
300
293
|
/**
|
|
@@ -330,53 +323,55 @@ export declare function defaultHandlers(deps: {
|
|
|
330
323
|
* `channelBootstrap.refresh` so the OSS factory's behavior matches
|
|
331
324
|
* the cloud pod's tool-side composition.
|
|
332
325
|
*/
|
|
333
|
-
readonly bootstrapRefresh?: import(
|
|
326
|
+
readonly bootstrapRefresh?: import("@ggui-ai/mcp-server-handlers/renders").WsTokenRefreshSeam;
|
|
334
327
|
};
|
|
335
328
|
/**
|
|
336
329
|
* `ggui_update` wiring. When present, register the OSS update
|
|
337
|
-
* handler against the supplied
|
|
338
|
-
* props_update notifier. The handler reads
|
|
339
|
-
*
|
|
340
|
-
*
|
|
330
|
+
* handler against the supplied RenderStore + optional live-channel
|
|
331
|
+
* props_update notifier. The handler reads `renderId` from wire
|
|
332
|
+
* input today, but a future in-process dispatcher can populate it
|
|
333
|
+
* on the canonical context.
|
|
341
334
|
*
|
|
342
335
|
* Absent = `ggui_update` is NOT registered on this server. Hosts
|
|
343
336
|
* that don't expose props mutation keep the smaller surface (e.g.,
|
|
344
337
|
* static-blueprint demos, MCP-Apps-only deployments).
|
|
345
338
|
*/
|
|
346
339
|
readonly update?: {
|
|
347
|
-
readonly
|
|
340
|
+
readonly renderStore: RenderStore;
|
|
348
341
|
/**
|
|
349
342
|
* Optional live-subscriber `props_update` notifier — typically a
|
|
350
|
-
* thin closure over `
|
|
343
|
+
* thin closure over `RenderChannelServer.sendPropsUpdate`.
|
|
351
344
|
* Forwarded as-is to `createGguiUpdateHandler`. Hosts without a
|
|
352
|
-
*
|
|
353
|
-
* via `
|
|
345
|
+
* render channel leave this absent; the handler still persists
|
|
346
|
+
* via `renderStore.commit` on every successful patch.
|
|
354
347
|
*/
|
|
355
348
|
readonly propsUpdateNotifier?: PropsUpdateNotifier;
|
|
356
349
|
/**
|
|
357
350
|
* Bootstrap-credential minter (live trio). When wired, the
|
|
358
|
-
* `ggui_update` resultMeta emits `
|
|
359
|
-
* hosts that re-post
|
|
360
|
-
*
|
|
361
|
-
*
|
|
362
|
-
*
|
|
351
|
+
* `ggui_update` resultMeta emits the `ai.ggui/render` slice
|
|
352
|
+
* so MCP Apps hosts that re-post
|
|
353
|
+
* `ui/notifications/tool-result` via postMessage can re-apply
|
|
354
|
+
* patched props on the live mount without re-subscribing. Mirrors
|
|
355
|
+
* the same field on `render` deps; composing hosts wire both from
|
|
356
|
+
* the same minter.
|
|
363
357
|
*/
|
|
364
|
-
readonly mintBootstrap?: (
|
|
358
|
+
readonly mintBootstrap?: (renderId: string, appId: string) => {
|
|
365
359
|
wsUrl: string;
|
|
366
360
|
token: string;
|
|
367
361
|
expiresAt: string;
|
|
368
362
|
};
|
|
369
|
-
/** Iframe-runtime bundle URL forwarded onto
|
|
363
|
+
/** Iframe-runtime bundle URL forwarded onto the
|
|
364
|
+
* `ai.ggui/render.runtimeUrl` slice field.
|
|
370
365
|
* Function form mirrors push deps — see {@link BuildMcpDeps.push}. */
|
|
371
366
|
readonly runtimeUrl?: string | (() => string | undefined);
|
|
372
|
-
/** Theme preset id forwarded onto
|
|
367
|
+
/** Theme preset id forwarded onto the `ai.ggui/render.themeId` slice field. */
|
|
373
368
|
readonly themeId?: string;
|
|
374
|
-
/** Theme color mode forwarded onto
|
|
375
|
-
readonly themeMode?:
|
|
369
|
+
/** Theme color mode forwarded onto the `ai.ggui/render.themeMode` slice field. */
|
|
370
|
+
readonly themeMode?: "light" | "dark";
|
|
376
371
|
/** Live theme getter — overrides static themeId/themeMode per-update. */
|
|
377
372
|
readonly themeProvider?: () => {
|
|
378
373
|
readonly id?: string;
|
|
379
|
-
readonly mode?:
|
|
374
|
+
readonly mode?: "light" | "dark";
|
|
380
375
|
} | undefined;
|
|
381
376
|
/** Returns names of app-visible tools for bootstrap.appCallableTools. */
|
|
382
377
|
readonly appCallableTools?: () => readonly string[];
|
|
@@ -389,19 +384,19 @@ export declare function defaultHandlers(deps: {
|
|
|
389
384
|
* default; pass `consume.pendingEventConsumer` to override (e.g.,
|
|
390
385
|
* SQLite-backed for persistent dev or a Dynamo adapter on cloud).
|
|
391
386
|
*
|
|
392
|
-
* `
|
|
387
|
+
* `defaultRenderTtlSeconds` controls the activity-bump TTL the
|
|
393
388
|
* handler forwards to `consumeAndClear` on every read. Falls back
|
|
394
389
|
* to 1 day when omitted.
|
|
395
390
|
*/
|
|
396
391
|
readonly consume?: {
|
|
397
392
|
readonly pendingEventConsumer?: PendingEventConsumer;
|
|
398
|
-
readonly
|
|
393
|
+
readonly defaultRenderTtlSeconds?: number;
|
|
399
394
|
};
|
|
400
395
|
/**
|
|
401
396
|
* Stream channel wiring for `ggui_emit`. When `push` is bound, the
|
|
402
397
|
* handler registers automatically; its `sendEnvelope` closes over
|
|
403
398
|
* `stream.channelProvider`, a lazy getter that resolves the
|
|
404
|
-
* `
|
|
399
|
+
* `RenderChannelServer` at emit time (the channel is constructed
|
|
405
400
|
* AFTER `defaultHandlers` runs, so a static reference would always
|
|
406
401
|
* be null on the OSS in-process boot).
|
|
407
402
|
*
|
|
@@ -410,10 +405,10 @@ export declare function defaultHandlers(deps: {
|
|
|
410
405
|
* cloud's `ggui_emit_accepted_no_receiver` posture.
|
|
411
406
|
*
|
|
412
407
|
* The getter pattern lets the OSS server bind once at boot, then
|
|
413
|
-
* mutate the cell after `
|
|
408
|
+
* mutate the cell after `createRenderChannelServer` runs.
|
|
414
409
|
*/
|
|
415
410
|
readonly stream?: {
|
|
416
|
-
readonly channelProvider?: () =>
|
|
411
|
+
readonly channelProvider?: () => RenderChannelServer | null;
|
|
417
412
|
};
|
|
418
413
|
/**
|
|
419
414
|
* Structured-event logger threaded into handlers that emit
|
|
@@ -425,9 +420,10 @@ export declare function defaultHandlers(deps: {
|
|
|
425
420
|
readonly logger?: Logger;
|
|
426
421
|
/**
|
|
427
422
|
* Operational-signal sink. Threaded into handlers that emit named
|
|
428
|
-
* events (`
|
|
429
|
-
* `
|
|
430
|
-
* Lossy + non-throwing per the
|
|
423
|
+
* events (`ggui_render` emits `ui.created` / `ui.committed`;
|
|
424
|
+
* `ggui_handshake` emits `handshake.minted`). Absent =
|
|
425
|
+
* NoopTelemetrySink semantic. Lossy + non-throwing per the
|
|
426
|
+
* {@link TelemetrySink} contract.
|
|
431
427
|
*/
|
|
432
428
|
readonly telemetry?: TelemetrySink;
|
|
433
429
|
/**
|
|
@@ -445,7 +441,7 @@ export declare function defaultHandlers(deps: {
|
|
|
445
441
|
readonly appMetadataStore?: AppMetadataStore;
|
|
446
442
|
/**
|
|
447
443
|
* Global theme-catalog resolver consumed by `ggui_list_themes` AND by
|
|
448
|
-
* `
|
|
444
|
+
* `ggui_render`'s opt-in `requestThemeList` projection. Returns
|
|
449
445
|
* the full registry every call (kept as a function so additions to
|
|
450
446
|
* the catalog at runtime — e.g. operator-defined themes in a future
|
|
451
447
|
* slice — surface without a server restart). When BOTH this and
|
|
@@ -503,7 +499,7 @@ export declare function defaultHandlers(deps: {
|
|
|
503
499
|
* closure. When absent, the generate handler is NOT registered
|
|
504
500
|
* (list/update/delete still register).
|
|
505
501
|
*/
|
|
506
|
-
readonly resolveLlm?: (ctx: import(
|
|
502
|
+
readonly resolveLlm?: (ctx: import("@ggui-ai/mcp-server-handlers").HandlerContext) => Promise<GenerationCredentials | null> | GenerationCredentials | null;
|
|
507
503
|
/**
|
|
508
504
|
* BlueprintProvider passed to the generator (same instance
|
|
509
505
|
* `defaultHandlers`'s blueprint search reads). Required when
|
|
@@ -570,7 +566,7 @@ export interface CreateGguiServerOptions {
|
|
|
570
566
|
* dev, anything else including unset → prod). Pass an explicit
|
|
571
567
|
* value to override the env in test fixtures and embedders.
|
|
572
568
|
*/
|
|
573
|
-
readonly mode?:
|
|
569
|
+
readonly mode?: "dev" | "prod";
|
|
574
570
|
/**
|
|
575
571
|
* Shared handler set to expose. Defaults to the blueprint-read family
|
|
576
572
|
* (search + list_featured + render). Pass your own list to add / remove
|
|
@@ -596,7 +592,7 @@ export interface CreateGguiServerOptions {
|
|
|
596
592
|
* See `packages/mcp-server-handlers/src/types.ts`
|
|
597
593
|
* (`SharedHandler.allowedFor`).
|
|
598
594
|
*/
|
|
599
|
-
readonly allowedKinds?: ReadonlyArray<
|
|
595
|
+
readonly allowedKinds?: ReadonlyArray<"app" | "user" | "builder">;
|
|
600
596
|
/**
|
|
601
597
|
* Auth adapter. Defaults to `InMemoryAuthAdapter({devAllowAll: true})`
|
|
602
598
|
* — accepts any non-empty bearer token as the `builder` identity.
|
|
@@ -618,7 +614,7 @@ export interface CreateGguiServerOptions {
|
|
|
618
614
|
/**
|
|
619
615
|
* Per-app metadata source. When bound, threaded into
|
|
620
616
|
* `defaultHandlers` so `ggui_list_gadgets`,
|
|
621
|
-
* `ggui_list_themes`, `
|
|
617
|
+
* `ggui_list_themes`, `ggui_render({themeId?})`, and the
|
|
622
618
|
* handshake's `app.gadgets` lookup all read from the same
|
|
623
619
|
* store. The CLI binds an `InMemoryAppMetadataStore` seeded from
|
|
624
620
|
* `ggui.json#theme.preset` (so every appId picks up the operator's
|
|
@@ -633,7 +629,7 @@ export interface CreateGguiServerOptions {
|
|
|
633
629
|
/**
|
|
634
630
|
* Global theme-catalog resolver. When bound alongside
|
|
635
631
|
* `appMetadataStore`, registers `ggui_list_themes` and projects the
|
|
636
|
-
* same catalog into `
|
|
632
|
+
* same catalog into `ggui_render({requestThemeList: true})`
|
|
637
633
|
* outputs. Read each call so additions to the registry at runtime
|
|
638
634
|
* (operator-defined themes in a future slice) surface without a
|
|
639
635
|
* restart.
|
|
@@ -767,9 +763,9 @@ export interface CreateGguiServerOptions {
|
|
|
767
763
|
*/
|
|
768
764
|
readonly themeFileUploader?: ThemeFileUploader;
|
|
769
765
|
/**
|
|
770
|
-
* Live-theme getter. When set, the `
|
|
766
|
+
* Live-theme getter. When set, the `ggui_render` handler reads this
|
|
771
767
|
* on every result-meta computation and embeds the returned `id` /
|
|
772
|
-
* `mode` into `
|
|
768
|
+
* `mode` into the `ai.ggui/render` slice meta. Pair with
|
|
773
769
|
* {@link onThemeConfigChange} so a console save updates the
|
|
774
770
|
* shared state cell the closure reads from. The cell pattern
|
|
775
771
|
* closes the parallel-state-stores bug where the push handler
|
|
@@ -782,7 +778,7 @@ export interface CreateGguiServerOptions {
|
|
|
782
778
|
*/
|
|
783
779
|
readonly themeProvider?: () => {
|
|
784
780
|
readonly id?: string;
|
|
785
|
-
readonly mode?:
|
|
781
|
+
readonly mode?: "light" | "dark";
|
|
786
782
|
} | undefined;
|
|
787
783
|
/**
|
|
788
784
|
* Optional change notifier — fires when the operator's theme
|
|
@@ -800,11 +796,11 @@ export interface CreateGguiServerOptions {
|
|
|
800
796
|
*/
|
|
801
797
|
readonly onThemeConfigChange?: (next: string | {
|
|
802
798
|
preset: string;
|
|
803
|
-
mode?:
|
|
799
|
+
mode?: "light" | "dark";
|
|
804
800
|
overrides?: Record<string, string>;
|
|
805
801
|
} | {
|
|
806
802
|
file: string;
|
|
807
|
-
mode?:
|
|
803
|
+
mode?: "light" | "dark";
|
|
808
804
|
} | null) => void;
|
|
809
805
|
/**
|
|
810
806
|
* Map a resolved identity to the `appId` used by handlers for tenant
|
|
@@ -962,17 +958,17 @@ export interface CreateGguiServerOptions {
|
|
|
962
958
|
* `'auth-adapter'`, the admin token is irrelevant — the route is
|
|
963
959
|
* mounted whenever `providerKeys` is set.
|
|
964
960
|
*/
|
|
965
|
-
readonly providerKeysGate?:
|
|
961
|
+
readonly providerKeysGate?: "admin-token" | "auth-adapter";
|
|
966
962
|
/** Express body size limit. Defaults to `'4mb'`. */
|
|
967
963
|
readonly bodyLimit?: string;
|
|
968
964
|
/**
|
|
969
|
-
*
|
|
970
|
-
* (and
|
|
971
|
-
* `
|
|
965
|
+
* Render store — backing plane for the live-channel render endpoint
|
|
966
|
+
* (and OSS render-reading MCP tools). Defaults to
|
|
967
|
+
* `InMemoryRenderStore`, which is fine for OSS zero-config / dev.
|
|
972
968
|
* SQLite / Postgres / Redis adapters bind via the same interface
|
|
973
969
|
* when they land.
|
|
974
970
|
*/
|
|
975
|
-
readonly
|
|
971
|
+
readonly renderStore?: RenderStore;
|
|
976
972
|
/**
|
|
977
973
|
* Outbound stream replay buffer for the live-channel endpoint. Defaults
|
|
978
974
|
* to a fresh `InMemorySessionStreamBuffer` — fine for OSS zero-config
|
|
@@ -994,7 +990,7 @@ export interface CreateGguiServerOptions {
|
|
|
994
990
|
*
|
|
995
991
|
* The live channel is where the live-contract enforcement point
|
|
996
992
|
* lives. Enabling this makes the OSS server a second real consumer
|
|
997
|
-
* of the shared `@ggui-ai/mcp-server-handlers/
|
|
993
|
+
* of the shared `@ggui-ai/mcp-server-handlers/renders`
|
|
998
994
|
* helpers.
|
|
999
995
|
*/
|
|
1000
996
|
readonly sessionChannel?: boolean | {
|
|
@@ -1012,7 +1008,7 @@ export interface CreateGguiServerOptions {
|
|
|
1012
1008
|
*
|
|
1013
1009
|
* Absent = agent-mediated behavior (canonical for MCP Apps hosts and
|
|
1014
1010
|
* Claude Agent SDK consumers). Inbound actions land on the
|
|
1015
|
-
*
|
|
1011
|
+
* renderId-keyed pending-events pipe via `ggui_runtime_submit_action`
|
|
1016
1012
|
* and the agent's `ggui_consume` long-poll drains them. CLI
|
|
1017
1013
|
* composition in `ggui serve` wires a router by default over the
|
|
1018
1014
|
* same handler bundle `/mcp` uses, since that command runs WITHOUT
|
|
@@ -1025,7 +1021,7 @@ export interface CreateGguiServerOptions {
|
|
|
1025
1021
|
/**
|
|
1026
1022
|
* Per-call timeout for wired-tool invocations, in ms. Defaults to
|
|
1027
1023
|
* `DEFAULT_WIRED_TOOL_TIMEOUT_MS` (30 s) when omitted. Forwarded
|
|
1028
|
-
* verbatim to `
|
|
1024
|
+
* verbatim to `createRenderChannelServer`.
|
|
1029
1025
|
*/
|
|
1030
1026
|
readonly wiredActionTimeoutMs?: number;
|
|
1031
1027
|
/**
|
|
@@ -1043,20 +1039,39 @@ export interface CreateGguiServerOptions {
|
|
|
1043
1039
|
* agrees with the server on which channels use WS fan-out.
|
|
1044
1040
|
*
|
|
1045
1041
|
* Only consulted when `sessionChannel` is enabled. Forwarded
|
|
1046
|
-
* verbatim to `
|
|
1047
|
-
* `
|
|
1042
|
+
* verbatim to `createRenderChannelServer` (see
|
|
1043
|
+
* `RenderChannelOptions.streamWebSocketLocalTools`).
|
|
1044
|
+
*/
|
|
1045
|
+
readonly streamWebSocketLocalTools?: import("./render-channel.js").RenderChannelLocalToolsOptions;
|
|
1046
|
+
/**
|
|
1047
|
+
* Hook fired when the local subscriber count for `sessionId`
|
|
1048
|
+
* transitions 0 → 1 on the live channel. Forwarded verbatim to
|
|
1049
|
+
* `createRenderChannelServer`. Used by cloud adapters for per-session
|
|
1050
|
+
* cross-pod pubsub channel scoping; OSS callers leave this undefined.
|
|
1051
|
+
*
|
|
1052
|
+
* Only consulted when `sessionChannel` is enabled. See
|
|
1053
|
+
* `RenderChannelOptions.onFirstSubscriber` for the full contract.
|
|
1054
|
+
*/
|
|
1055
|
+
readonly onFirstSubscriber?: (sessionId: string) => void;
|
|
1056
|
+
/**
|
|
1057
|
+
* Hook fired when the local subscriber count for `sessionId`
|
|
1058
|
+
* transitions 1 → 0 on the live channel. Forwarded verbatim to
|
|
1059
|
+
* `createRenderChannelServer`.
|
|
1060
|
+
*
|
|
1061
|
+
* Only consulted when `sessionChannel` is enabled. See
|
|
1062
|
+
* `RenderChannelOptions.onLastSubscriberGone` for the full contract.
|
|
1048
1063
|
*/
|
|
1049
|
-
readonly
|
|
1064
|
+
readonly onLastSubscriberGone?: (sessionId: string) => void;
|
|
1050
1065
|
/**
|
|
1051
1066
|
* Override the sanitizer applied to the stringified original error
|
|
1052
1067
|
* written into `ContractErrorPayload.error.causedBy`. Defaults to
|
|
1053
1068
|
* `@ggui-ai/protocol::sanitizeCausedBy` when omitted — redacts
|
|
1054
1069
|
* Bearer tokens, query-param secrets, common env-var dumps, and
|
|
1055
1070
|
* truncates at 2 KB. Forwarded verbatim to
|
|
1056
|
-
* `
|
|
1071
|
+
* `createRenderChannelServer`. See `RenderChannelOptions
|
|
1057
1072
|
* .sanitizeCausedBy` for the contract.
|
|
1058
1073
|
*/
|
|
1059
|
-
readonly sanitizeCausedBy?: import(
|
|
1074
|
+
readonly sanitizeCausedBy?: import("@ggui-ai/protocol").SanitizeCausedBy;
|
|
1060
1075
|
/**
|
|
1061
1076
|
* Extra reserved-channel payload validators merged with the
|
|
1062
1077
|
* server's default A2UI preview validator before being passed to
|
|
@@ -1073,11 +1088,11 @@ export interface CreateGguiServerOptions {
|
|
|
1073
1088
|
* fall-through behavior on `_ggui:preview` without the adapter
|
|
1074
1089
|
* running.
|
|
1075
1090
|
*/
|
|
1076
|
-
readonly extraReservedValidators?: ReadonlyMap<string, import(
|
|
1091
|
+
readonly extraReservedValidators?: ReadonlyMap<string, import("@ggui-ai/protocol").ReservedChannelValidator>;
|
|
1077
1092
|
/**
|
|
1078
1093
|
* Protocol-version handshake policy for the session channel. Forwarded
|
|
1079
|
-
* verbatim to `
|
|
1080
|
-
* `
|
|
1094
|
+
* verbatim to `createRenderChannelServer` (see
|
|
1095
|
+
* `RenderChannelOptions.versionPolicy`). Defaults to `'reject'` —
|
|
1081
1096
|
* mismatched `SubscribePayload.supportedVersions` emits
|
|
1082
1097
|
* UPGRADE_REQUIRED and closes the connection. Legacy opt-out
|
|
1083
1098
|
* `'advisory'` keeps the connection open after the error frame for
|
|
@@ -1085,7 +1100,7 @@ export interface CreateGguiServerOptions {
|
|
|
1085
1100
|
*
|
|
1086
1101
|
* Only consulted when `sessionChannel` is enabled.
|
|
1087
1102
|
*/
|
|
1088
|
-
readonly versionPolicy?:
|
|
1103
|
+
readonly versionPolicy?: "advisory" | "reject";
|
|
1089
1104
|
/**
|
|
1090
1105
|
* Policy for the schema compat check. Checks that every
|
|
1091
1106
|
* `actionSpec[name]` tool ref points at a tool whose
|
|
@@ -1110,7 +1125,7 @@ export interface CreateGguiServerOptions {
|
|
|
1110
1125
|
* endpoint (blueprint registration — fires when a manifest
|
|
1111
1126
|
* blueprint's pre-declared `actionSpec` / `streamSpec`
|
|
1112
1127
|
* references a tool mounted on this server).
|
|
1113
|
-
* 2. The `
|
|
1128
|
+
* 2. The `ggui_render` generation path (render-time — defensive
|
|
1114
1129
|
* wiring for when the generator starts emitting
|
|
1115
1130
|
* actionSpec / streamSpec on its `UIGenerationResponse`;
|
|
1116
1131
|
* current generators emit only componentCode, but the
|
|
@@ -1158,32 +1173,29 @@ export interface CreateGguiServerOptions {
|
|
|
1158
1173
|
/**
|
|
1159
1174
|
* Enable the MCP Apps outbound delivery path on this server.
|
|
1160
1175
|
*
|
|
1161
|
-
* - `false` / omitted (default): `
|
|
1162
|
-
* `ui://ggui/
|
|
1176
|
+
* - `false` / omitted (default): `ggui_render` is NOT registered;
|
|
1177
|
+
* `ui://ggui/render` is NOT served; `io.modelcontextprotocol/ui`
|
|
1163
1178
|
* is NOT advertised. Server looks identical to the pre-MCP-Apps
|
|
1164
1179
|
* surface.
|
|
1165
1180
|
* - `true`: enable with sensible defaults. Requires
|
|
1166
1181
|
* `sessionChannel: true` so the iframe has a WebSocket to open;
|
|
1167
|
-
* throws at construction otherwise.
|
|
1168
|
-
*
|
|
1169
|
-
* override).
|
|
1170
|
-
* - `{ renderBaseUrl?, shellHtml?, wsUrl? }`: explicit config.
|
|
1182
|
+
* throws at construction otherwise.
|
|
1183
|
+
* - `{ shellHtml?, wsUrl? }`: explicit config.
|
|
1171
1184
|
*
|
|
1172
1185
|
* When enabled, FOUR things happen on every fresh per-request
|
|
1173
1186
|
* `McpServer`:
|
|
1174
|
-
* 1. `
|
|
1175
|
-
* "ui://ggui/
|
|
1187
|
+
* 1. `ggui_render` tool is registered, carrying `_meta.ui.resourceUri:
|
|
1188
|
+
* "ui://ggui/render"` and `_meta.ui.visibility: ["model"]` on
|
|
1176
1189
|
* its declaration.
|
|
1177
|
-
* 2. `ui://ggui/
|
|
1190
|
+
* 2. `ui://ggui/render` is served via `resources/read`.
|
|
1178
1191
|
* 3. `io.modelcontextprotocol/ui` is advertised in the server's
|
|
1179
1192
|
* `initialize` capabilities (under `experimental`).
|
|
1180
|
-
* 4. Each `
|
|
1181
|
-
* + short-TTL token + expiresAt
|
|
1182
|
-
* accepts that token on `subscribe` and issues a
|
|
1183
|
-
* `
|
|
1193
|
+
* 4. Each `ggui_render` result carries the `ai.ggui/render` slice
|
|
1194
|
+
* with wsUrl + short-TTL token + expiresAt. The session-channel
|
|
1195
|
+
* server accepts that token on `subscribe` and issues a
|
|
1196
|
+
* longer-TTL `renderToken` in the ack for iframe reconnects.
|
|
1184
1197
|
*/
|
|
1185
1198
|
readonly mcpApps?: boolean | {
|
|
1186
|
-
readonly renderBaseUrl?: string;
|
|
1187
1199
|
readonly shellHtml?: string;
|
|
1188
1200
|
/**
|
|
1189
1201
|
* External WebSocket URL the iframe should open, visible to
|
|
@@ -1196,11 +1208,11 @@ export interface CreateGguiServerOptions {
|
|
|
1196
1208
|
/**
|
|
1197
1209
|
* Iframe-runtime bundle mount (C8 — plan §C8).
|
|
1198
1210
|
*
|
|
1199
|
-
* The thin-shell HTML served from `ui://ggui/
|
|
1211
|
+
* The thin-shell HTML served from `ui://ggui/render` dynamic-
|
|
1200
1212
|
* script-loads the renderer bundle from this URL. The server needs
|
|
1201
1213
|
* to either (a) serve the bundle itself (default), or (b) publish
|
|
1202
|
-
* the operator-owned URL on `
|
|
1203
|
-
* so the shell knows where to look.
|
|
1214
|
+
* the operator-owned URL on the `ai.ggui/render.runtimeUrl` slice
|
|
1215
|
+
* field so the shell knows where to look.
|
|
1204
1216
|
*
|
|
1205
1217
|
* - `true` / omitted (default when `mcpApps` is on): serve the
|
|
1206
1218
|
* bundle via `express.static` at `/_ggui/iframe-runtime.js` from the
|
|
@@ -1242,7 +1254,7 @@ export interface CreateGguiServerOptions {
|
|
|
1242
1254
|
*
|
|
1243
1255
|
* Ignored entirely when MCP Apps is disabled.
|
|
1244
1256
|
*/
|
|
1245
|
-
readonly
|
|
1257
|
+
readonly wsTokenSecret?: string;
|
|
1246
1258
|
/**
|
|
1247
1259
|
* Enable the pairing transport. Adds `POST /pair` (public, completes a
|
|
1248
1260
|
* pairing handshake) and by default `POST /admin/pair/init` (builder-
|
|
@@ -1323,7 +1335,7 @@ export interface CreateGguiServerOptions {
|
|
|
1323
1335
|
* right durability claim; the server doesn't inspect the store
|
|
1324
1336
|
* instance to guess.
|
|
1325
1337
|
*/
|
|
1326
|
-
readonly durability?:
|
|
1338
|
+
readonly durability?: "durable" | "ephemeral";
|
|
1327
1339
|
};
|
|
1328
1340
|
readonly pairing?: boolean | {
|
|
1329
1341
|
/**
|
|
@@ -1399,7 +1411,7 @@ export interface CreateGguiServerOptions {
|
|
|
1399
1411
|
readonly audit?: AuditSink;
|
|
1400
1412
|
/**
|
|
1401
1413
|
* Admission-control limiter applied at the highest-cost handler
|
|
1402
|
-
* ingress — today just `
|
|
1414
|
+
* ingress — today just `ggui_render`. Defaults to
|
|
1403
1415
|
* {@link NoopRateLimiter} (always allows). Per-handler wiring maps
|
|
1404
1416
|
* denials from a `RateLimitedError` to HTTP 429 + `Retry-After` /
|
|
1405
1417
|
* `X-RateLimit-*` headers at the transport boundary.
|
|
@@ -1441,44 +1453,6 @@ export interface CreateGguiServerOptions {
|
|
|
1441
1453
|
* still mounts so operators can paste credentials in advance).
|
|
1442
1454
|
*/
|
|
1443
1455
|
readonly publicBaseUrl?: string;
|
|
1444
|
-
/**
|
|
1445
|
-
* Render-URL signing config — capability-URL hardening.
|
|
1446
|
-
*
|
|
1447
|
-
* When set (default), every minted `/r/<code>` URL carries
|
|
1448
|
-
* `?sig=<hmac>&exp=<unix>`. The gate on `/r/` + `/api/bootstrap/`
|
|
1449
|
-
* verifies the sig + freshness before lookup; tampered or expired
|
|
1450
|
-
* URLs return 410.
|
|
1451
|
-
*
|
|
1452
|
-
* - `secret`: 32-byte hex key. When omitted, a fresh random key
|
|
1453
|
-
* is minted at boot — restart = every outstanding URL dies
|
|
1454
|
-
* (good for incident response, bad if you don't want it).
|
|
1455
|
-
* Pin a stable secret to survive restarts.
|
|
1456
|
-
* - `ttlSeconds`: URL lifetime. Defaults to 24h (86400s).
|
|
1457
|
-
* - Set `renderSigning: false` to disable the layer entirely
|
|
1458
|
-
* (`--no-render-signing`). URLs revert to the plain unsigned
|
|
1459
|
-
* form. Use for legacy hosts that strip query strings or
|
|
1460
|
-
* tooling that pre-records URLs.
|
|
1461
|
-
*/
|
|
1462
|
-
readonly renderSigning?: false | {
|
|
1463
|
-
readonly secret?: string;
|
|
1464
|
-
readonly ttlSeconds?: number;
|
|
1465
|
-
};
|
|
1466
|
-
/**
|
|
1467
|
-
* Per-shortCode rate-limit config. Defends `/r/` and
|
|
1468
|
-
* `/api/bootstrap/` against brute-force scans.
|
|
1469
|
-
*
|
|
1470
|
-
* - `windowSeconds` + `limit`: bucket size. Default 60s / 30 hits.
|
|
1471
|
-
* - `false`: disable rate limiting entirely (CI/test convenience).
|
|
1472
|
-
*
|
|
1473
|
-
* Rate-limit decision is per-shortCode (not per-peer) — cross-origin
|
|
1474
|
-
* iframe hosts NAT every user through one proxy; per-peer limits
|
|
1475
|
-
* would either rate-limit the whole host or accept every peer.
|
|
1476
|
-
* See render-rate-limit.ts for the rationale.
|
|
1477
|
-
*/
|
|
1478
|
-
readonly renderRateLimit?: false | {
|
|
1479
|
-
readonly windowSeconds?: number;
|
|
1480
|
-
readonly limit?: number;
|
|
1481
|
-
};
|
|
1482
1456
|
/**
|
|
1483
1457
|
* Override path for `~/.ggui/oauth-providers.json`. Mainly for
|
|
1484
1458
|
* tests + per-deployment isolation. Defaults to the home-relative
|
|
@@ -1578,7 +1552,7 @@ export interface CreateGguiServerOptions {
|
|
|
1578
1552
|
readonly distDir?: string;
|
|
1579
1553
|
/**
|
|
1580
1554
|
* Enable the Slice-2 same-origin session-cookie flow
|
|
1581
|
-
* (`POST /ggui/console/
|
|
1555
|
+
* (`POST /ggui/console/render-cookie` + session-channel
|
|
1582
1556
|
* cookie-auth wiring). Defaults to OFF — the landing-page
|
|
1583
1557
|
* static surface is useful on its own (pair-code display,
|
|
1584
1558
|
* server identity); turning on the cookie flow is an
|
|
@@ -1593,7 +1567,7 @@ export interface CreateGguiServerOptions {
|
|
|
1593
1567
|
* cookie endpoint resolves shortCode → sessionId by reading
|
|
1594
1568
|
* it. Throws at construction if the index is absent.
|
|
1595
1569
|
*
|
|
1596
|
-
* The cookie signing secret is the same {@link
|
|
1570
|
+
* The cookie signing secret is the same {@link wsTokenSecret}
|
|
1597
1571
|
* used by the MCP Apps bootstrap/session tokens — different
|
|
1598
1572
|
* token `kind` claims make cross-kind confusion impossible
|
|
1599
1573
|
* (see `console-auth.ts` isolation comment).
|
|
@@ -1683,7 +1657,7 @@ export interface CreateGguiServerOptions {
|
|
|
1683
1657
|
* when `console.sessionCookie` is enabled (the cookie endpoint
|
|
1684
1658
|
* looks up the posted shortCode to find the session to bind).
|
|
1685
1659
|
*
|
|
1686
|
-
* Pair this with a `push` handler so the agent's `
|
|
1660
|
+
* Pair this with a `push` handler so the agent's `ggui_render` writes
|
|
1687
1661
|
* the shortCode into the same index that console later reads.
|
|
1688
1662
|
* See `defaultHandlers` for the wiring seam.
|
|
1689
1663
|
*/
|
|
@@ -1692,11 +1666,12 @@ export interface CreateGguiServerOptions {
|
|
|
1692
1666
|
* Content-addressable code blob storage. When wired, this server
|
|
1693
1667
|
* mounts `GET /code/<hash>.js` for the iframe runtime to fetch
|
|
1694
1668
|
* compiled componentCode by content hash. The push handler writes
|
|
1695
|
-
* to the store before emitting `
|
|
1669
|
+
* to the store before emitting `codeUrl` on the `ai.ggui/render`
|
|
1670
|
+
* slice.
|
|
1696
1671
|
*
|
|
1697
1672
|
* Defaults: when omitted the route is NOT mounted; the push
|
|
1698
|
-
* handler falls back to inline base64 `componentCode` on
|
|
1699
|
-
* `
|
|
1673
|
+
* handler falls back to inline base64 `componentCode` on the
|
|
1674
|
+
* `ai.ggui/render` slice (legacy delivery channel).
|
|
1700
1675
|
*
|
|
1701
1676
|
* OSS dev wires `FileSystemCodeStore` (rooted at `~/.ggui/code-cache/`)
|
|
1702
1677
|
* via `ggui-cli/buildMcpServerBackend`. Tests wire
|
|
@@ -1707,7 +1682,7 @@ export interface CreateGguiServerOptions {
|
|
|
1707
1682
|
*/
|
|
1708
1683
|
readonly codeStore?: CodeStore;
|
|
1709
1684
|
/**
|
|
1710
|
-
* Provisional A2UI preview wiring for `
|
|
1685
|
+
* Provisional A2UI preview wiring for `ggui_render`. When the config
|
|
1711
1686
|
* flag is on, every qualifying component push kicks off the
|
|
1712
1687
|
* supplied emitter; frames land on the reserved `_ggui:preview`
|
|
1713
1688
|
* channel of the push's session.
|
|
@@ -1735,7 +1710,7 @@ export interface CreateGguiServerOptions {
|
|
|
1735
1710
|
*/
|
|
1736
1711
|
readonly emitter: ProvisionalPreviewEmitter;
|
|
1737
1712
|
/** Per-push predicate. See {@link ProvisionalPreviewConfig}. */
|
|
1738
|
-
readonly isEnabledFor?: ProvisionalPreviewConfig[
|
|
1713
|
+
readonly isEnabledFor?: ProvisionalPreviewConfig["isEnabledFor"];
|
|
1739
1714
|
/** Lifecycle observer. Fires sync — must not throw. */
|
|
1740
1715
|
readonly onOutcome?: (outcome: ProvisionalPreviewOutcome) => void;
|
|
1741
1716
|
/** Clock override for tests. Defaults to `Date.now`. */
|
|
@@ -1744,7 +1719,7 @@ export interface CreateGguiServerOptions {
|
|
|
1744
1719
|
/**
|
|
1745
1720
|
* Handshake preflight wiring. When `mcpApps` is enabled, the
|
|
1746
1721
|
* server defaults to an `InMemoryKeyValueStore` + no negotiator:
|
|
1747
|
-
* `ggui_handshake` is registered, `
|
|
1722
|
+
* `ggui_handshake` is registered, `ggui_render({handshakeId})` is
|
|
1748
1723
|
* consumable, and handshake records persist for 10 minutes before
|
|
1749
1724
|
* single-use consumption.
|
|
1750
1725
|
*
|
|
@@ -1757,16 +1732,16 @@ export interface CreateGguiServerOptions {
|
|
|
1757
1732
|
* in a hosted closed runtime) so handshake records carry a
|
|
1758
1733
|
* decision the paired push echoes as `structuredContent.decision`.
|
|
1759
1734
|
* - `false` — explicitly disable: `ggui_handshake` is NOT
|
|
1760
|
-
* registered and `
|
|
1735
|
+
* registered and `ggui_render({handshakeId})` falls back to
|
|
1761
1736
|
* the rejection shape.
|
|
1762
1737
|
*
|
|
1763
1738
|
* Omitted entirely means "use the default in-memory store when
|
|
1764
|
-
* `mcpApps` is on". That matches how `
|
|
1739
|
+
* `mcpApps` is on". That matches how `renderStore` and
|
|
1765
1740
|
* `streamBuffer` default — no opt-in required for the OSS
|
|
1766
1741
|
* first-run path.
|
|
1767
1742
|
*
|
|
1768
1743
|
* Requires `mcpApps` to be enabled — handshake is paired with
|
|
1769
|
-
* `
|
|
1744
|
+
* `ggui_render`, which is only registered under MCP Apps. Throws
|
|
1770
1745
|
* at construction when handshake is explicitly enabled without
|
|
1771
1746
|
* MCP Apps.
|
|
1772
1747
|
*/
|
|
@@ -1783,14 +1758,14 @@ export interface CreateGguiServerOptions {
|
|
|
1783
1758
|
readonly negotiator?: HandshakeNegotiator;
|
|
1784
1759
|
};
|
|
1785
1760
|
/**
|
|
1786
|
-
* Generation wiring for the `
|
|
1787
|
-
* every component push invokes the bound `UiGenerator` and
|
|
1788
|
-
*
|
|
1789
|
-
*
|
|
1790
|
-
*
|
|
1761
|
+
* Generation wiring for the `ggui_render` story path. When present,
|
|
1762
|
+
* every component push invokes the bound `UiGenerator` and commits
|
|
1763
|
+
* the result as a real `Render`. Absent = placeholder mode:
|
|
1764
|
+
* `ggui_render` on the story path returns `codeReady: false`
|
|
1765
|
+
* without writing componentCode.
|
|
1791
1766
|
*
|
|
1792
1767
|
* Requires `mcpApps` to be enabled — generation attaches to
|
|
1793
|
-
* `
|
|
1768
|
+
* `ggui_render`, which is only registered when MCP Apps is on.
|
|
1794
1769
|
* Throws at construction otherwise so a misconfigured server
|
|
1795
1770
|
* doesn't silently drop the generator binding.
|
|
1796
1771
|
*
|
|
@@ -1937,6 +1912,36 @@ export interface CreateGguiServerOptions {
|
|
|
1937
1912
|
readonly opsCoupon?: {
|
|
1938
1913
|
readonly coupons: CouponRedeemSource;
|
|
1939
1914
|
};
|
|
1915
|
+
/**
|
|
1916
|
+
* Extra readiness checks merged into `GET /ggui/health`. Each check
|
|
1917
|
+
* is a `{name, check}` pair; `check()` returns a boolean (or a
|
|
1918
|
+
* Promise<boolean>) — `true` means "this dependency is ready".
|
|
1919
|
+
*
|
|
1920
|
+
* When ANY check returns `false` (or throws), `/ggui/health` answers
|
|
1921
|
+
* `503 Service Unavailable` with `status: 'degraded'` + a `checks`
|
|
1922
|
+
* map naming each failing dependency. The default `200 ok` shape is
|
|
1923
|
+
* preserved when every check passes (and when the option is unset).
|
|
1924
|
+
*
|
|
1925
|
+
* Use this when an embedder wires a stateful external dependency
|
|
1926
|
+
* (e.g. a pubsub subscriber connection, a vector-store reachability
|
|
1927
|
+
* probe, a worker-pool health view) and wants its K8s readinessProbe
|
|
1928
|
+
* to take the pod OUT OF SERVICE when that dependency fails. The
|
|
1929
|
+
* sibling `/ggui/live` endpoint is unaffected — that is the K8s
|
|
1930
|
+
* livenessProbe target and stays 200 regardless of readiness, so a
|
|
1931
|
+
* transient upstream blip removes the pod from rotation without
|
|
1932
|
+
* restarting the process. Wire the two probes separately:
|
|
1933
|
+
*
|
|
1934
|
+
* livenessProbe: { httpGet: { path: '/ggui/live', port } }
|
|
1935
|
+
* readinessProbe: { httpGet: { path: '/ggui/health', port } }
|
|
1936
|
+
*
|
|
1937
|
+
* Each check MUST complete within ~1s; the server enforces a 1s
|
|
1938
|
+
* per-check timeout so a hung dependency cannot block the probe.
|
|
1939
|
+
* A timeout is treated as a failed check.
|
|
1940
|
+
*/
|
|
1941
|
+
readonly readinessChecks?: ReadonlyArray<{
|
|
1942
|
+
readonly name: string;
|
|
1943
|
+
readonly check: () => boolean | Promise<boolean>;
|
|
1944
|
+
}>;
|
|
1940
1945
|
}
|
|
1941
1946
|
export interface GguiServer {
|
|
1942
1947
|
/**
|
|
@@ -1965,7 +1970,7 @@ export interface GguiServer {
|
|
|
1965
1970
|
* composition with future mutation handlers that want to fan out
|
|
1966
1971
|
* via `sessionChannel.sendToSession(sessionId, data)`.
|
|
1967
1972
|
*/
|
|
1968
|
-
readonly sessionChannel:
|
|
1973
|
+
readonly sessionChannel: RenderChannelServer | null;
|
|
1969
1974
|
/**
|
|
1970
1975
|
* The pairing service bound to this server, when the `pairing` option
|
|
1971
1976
|
* was enabled. `null` when pairing is disabled. In-process hosts
|