@ggui-ai/mcp-server 0.1.0-rc.1

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 (141) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +48 -0
  3. package/dist/admin-blueprints-transport.d.ts +114 -0
  4. package/dist/admin-blueprints-transport.d.ts.map +1 -0
  5. package/dist/admin-blueprints-transport.js +118 -0
  6. package/dist/admin-oauth-providers-transport.d.ts +40 -0
  7. package/dist/admin-oauth-providers-transport.d.ts.map +1 -0
  8. package/dist/admin-oauth-providers-transport.js +263 -0
  9. package/dist/auth.d.ts +39 -0
  10. package/dist/auth.d.ts.map +1 -0
  11. package/dist/auth.js +75 -0
  12. package/dist/build-mcp.d.ts +128 -0
  13. package/dist/build-mcp.d.ts.map +1 -0
  14. package/dist/build-mcp.js +113 -0
  15. package/dist/code-store-fs.d.ts +19 -0
  16. package/dist/code-store-fs.d.ts.map +1 -0
  17. package/dist/code-store-fs.js +98 -0
  18. package/dist/console-auth.d.ts +139 -0
  19. package/dist/console-auth.d.ts.map +1 -0
  20. package/dist/console-auth.js +102 -0
  21. package/dist/console-cache.d.ts +78 -0
  22. package/dist/console-cache.d.ts.map +1 -0
  23. package/dist/console-cache.js +105 -0
  24. package/dist/console-headers.d.ts +124 -0
  25. package/dist/console-headers.d.ts.map +1 -0
  26. package/dist/console-headers.js +49 -0
  27. package/dist/console-llm-trace.d.ts +66 -0
  28. package/dist/console-llm-trace.d.ts.map +1 -0
  29. package/dist/console-llm-trace.js +105 -0
  30. package/dist/console-payloads.d.ts +67 -0
  31. package/dist/console-payloads.d.ts.map +1 -0
  32. package/dist/console-payloads.js +105 -0
  33. package/dist/console-theme-routes.d.ts +111 -0
  34. package/dist/console-theme-routes.d.ts.map +1 -0
  35. package/dist/console-theme-routes.js +202 -0
  36. package/dist/console-timeline.d.ts +45 -0
  37. package/dist/console-timeline.d.ts.map +1 -0
  38. package/dist/console-timeline.js +169 -0
  39. package/dist/console-validator.d.ts +67 -0
  40. package/dist/console-validator.d.ts.map +1 -0
  41. package/dist/console-validator.js +105 -0
  42. package/dist/console-welcome.d.ts +7 -0
  43. package/dist/console-welcome.d.ts.map +1 -0
  44. package/dist/console-welcome.js +221 -0
  45. package/dist/csrf-middleware.d.ts +55 -0
  46. package/dist/csrf-middleware.d.ts.map +1 -0
  47. package/dist/csrf-middleware.js +138 -0
  48. package/dist/email-login.d.ts +174 -0
  49. package/dist/email-login.d.ts.map +1 -0
  50. package/dist/email-login.js +254 -0
  51. package/dist/email-resend.d.ts +29 -0
  52. package/dist/email-resend.d.ts.map +1 -0
  53. package/dist/email-resend.js +71 -0
  54. package/dist/email-sender-from-env.d.ts +34 -0
  55. package/dist/email-sender-from-env.d.ts.map +1 -0
  56. package/dist/email-sender-from-env.js +112 -0
  57. package/dist/email-smtp.d.ts +42 -0
  58. package/dist/email-smtp.d.ts.map +1 -0
  59. package/dist/email-smtp.js +81 -0
  60. package/dist/index.d.ts +102 -0
  61. package/dist/index.d.ts.map +1 -0
  62. package/dist/index.js +122 -0
  63. package/dist/instructions-presets.d.ts +112 -0
  64. package/dist/instructions-presets.d.ts.map +1 -0
  65. package/dist/instructions-presets.js +195 -0
  66. package/dist/llm-backed-negotiator.d.ts +178 -0
  67. package/dist/llm-backed-negotiator.d.ts.map +1 -0
  68. package/dist/llm-backed-negotiator.js +579 -0
  69. package/dist/logger.d.ts +23 -0
  70. package/dist/logger.d.ts.map +1 -0
  71. package/dist/logger.js +41 -0
  72. package/dist/mcp-apps-inbound.d.ts +86 -0
  73. package/dist/mcp-apps-inbound.d.ts.map +1 -0
  74. package/dist/mcp-apps-inbound.js +278 -0
  75. package/dist/mcp-apps-outbound.d.ts +448 -0
  76. package/dist/mcp-apps-outbound.d.ts.map +1 -0
  77. package/dist/mcp-apps-outbound.js +1163 -0
  78. package/dist/mcp-mounts.d.ts +239 -0
  79. package/dist/mcp-mounts.d.ts.map +1 -0
  80. package/dist/mcp-mounts.js +222 -0
  81. package/dist/oauth-login-types.d.ts +160 -0
  82. package/dist/oauth-login-types.d.ts.map +1 -0
  83. package/dist/oauth-login-types.js +9 -0
  84. package/dist/oauth-login.d.ts +77 -0
  85. package/dist/oauth-login.d.ts.map +1 -0
  86. package/dist/oauth-login.js +455 -0
  87. package/dist/oauth-providers/github.d.ts +17 -0
  88. package/dist/oauth-providers/github.d.ts.map +1 -0
  89. package/dist/oauth-providers/github.js +89 -0
  90. package/dist/oauth-providers/google.d.ts +18 -0
  91. package/dist/oauth-providers/google.d.ts.map +1 -0
  92. package/dist/oauth-providers/google.js +59 -0
  93. package/dist/oauth-providers-store.d.ts +32 -0
  94. package/dist/oauth-providers-store.d.ts.map +1 -0
  95. package/dist/oauth-providers-store.js +291 -0
  96. package/dist/oauth.d.ts +347 -0
  97. package/dist/oauth.d.ts.map +1 -0
  98. package/dist/oauth.js +686 -0
  99. package/dist/pairing-transport.d.ts +99 -0
  100. package/dist/pairing-transport.d.ts.map +1 -0
  101. package/dist/pairing-transport.js +223 -0
  102. package/dist/rate-limit-middleware.d.ts +36 -0
  103. package/dist/rate-limit-middleware.d.ts.map +1 -0
  104. package/dist/rate-limit-middleware.js +57 -0
  105. package/dist/render-gate.d.ts +87 -0
  106. package/dist/render-gate.d.ts.map +1 -0
  107. package/dist/render-gate.js +77 -0
  108. package/dist/render-rate-limit.d.ts +59 -0
  109. package/dist/render-rate-limit.d.ts.map +1 -0
  110. package/dist/render-rate-limit.js +73 -0
  111. package/dist/render-signing.d.ts +98 -0
  112. package/dist/render-signing.d.ts.map +1 -0
  113. package/dist/render-signing.js +113 -0
  114. package/dist/request-context.d.ts +113 -0
  115. package/dist/request-context.d.ts.map +1 -0
  116. package/dist/request-context.js +154 -0
  117. package/dist/reserved-validators.d.ts +22 -0
  118. package/dist/reserved-validators.d.ts.map +1 -0
  119. package/dist/reserved-validators.js +101 -0
  120. package/dist/schema-compat.d.ts +167 -0
  121. package/dist/schema-compat.d.ts.map +1 -0
  122. package/dist/schema-compat.js +187 -0
  123. package/dist/security-headers-middleware.d.ts +38 -0
  124. package/dist/security-headers-middleware.d.ts.map +1 -0
  125. package/dist/security-headers-middleware.js +30 -0
  126. package/dist/server.d.ts +2060 -0
  127. package/dist/server.d.ts.map +1 -0
  128. package/dist/server.js +6338 -0
  129. package/dist/session-channel.d.ts +651 -0
  130. package/dist/session-channel.d.ts.map +1 -0
  131. package/dist/session-channel.js +1756 -0
  132. package/dist/storage.d.ts +89 -0
  133. package/dist/storage.d.ts.map +1 -0
  134. package/dist/storage.js +171 -0
  135. package/dist/thread-transport.d.ts +118 -0
  136. package/dist/thread-transport.d.ts.map +1 -0
  137. package/dist/thread-transport.js +478 -0
  138. package/dist/user-session-auth.d.ts +167 -0
  139. package/dist/user-session-auth.d.ts.map +1 -0
  140. package/dist/user-session-auth.js +148 -0
  141. package/package.json +76 -0
@@ -0,0 +1,102 @@
1
+ /**
2
+ * @ggui-ai/mcp-server — open self-hosted MCP server for the ggui protocol.
3
+ *
4
+ * **Role**: thin HTTP/MCP binding layer.
5
+ * Composes `@ggui-ai/mcp-server-handlers` (real handler logic) with
6
+ * `@ggui-ai/mcp-server-core` in-memory reference adapters to produce a
7
+ * runnable open server. No business logic lives here — if you need to
8
+ * change tool behavior, edit the shared handler package.
9
+ *
10
+ * Zero-config boot:
11
+ *
12
+ * ```ts
13
+ * import { createGguiServer } from '@ggui-ai/mcp-server';
14
+ * const server = createGguiServer();
15
+ * await server.listen(4567);
16
+ * ```
17
+ *
18
+ * This package deliberately does NOT:
19
+ *
20
+ * - embed AWS / DDB / Redis / cloud-specific wiring (those bind to
21
+ * `@ggui-ai/mcp-server-core` interfaces in separate adapter
22
+ * packages),
23
+ * - implement authoring / pairing / UI generation (those are separate
24
+ * packages + protocol flows).
25
+ *
26
+ * The `ggui serve` CLI command boots this server with the OSS defaults.
27
+ */
28
+ export type { HandlerContext, SharedHandler } from '@ggui-ai/mcp-server-handlers';
29
+ export type { GadgetDescriptor, McpAppsMode, SessionStackEntry, StackItem, SystemStackItem, } from '@ggui-ai/protocol';
30
+ export type { GenerationCredentials, GenerationDeps, } from '@ggui-ai/mcp-server-handlers';
31
+ export { NO_CREDENTIALS_SYSTEM_CARD_KIND, buildNoCredentialsStackItem, } from '@ggui-ai/mcp-server-handlers';
32
+ export { createGguiServer, defaultHandlers } from './server.js';
33
+ export type { CreateGguiServerOptions, GguiServer, } from './server.js';
34
+ export { FileSystemCodeStore } from './code-store-fs.js';
35
+ export type { FileSystemCodeStoreOptions } from './code-store-fs.js';
36
+ export type { McpServerMount } from './mcp-mounts.js';
37
+ export { composeWiredActionRouterFromMounts } from './mcp-mounts.js';
38
+ export type { McpService, ServicePath } from './mcp-mounts.js';
39
+ export { validateMcpServices, validateServicePath } from './mcp-mounts.js';
40
+ export { composePreviewReservedValidator, mergeReservedValidators, } from './reserved-validators.js';
41
+ export { checkStackItemSchemaCompat, DEFAULT_SCHEMA_COMPAT_MODE, SchemaCompatError, } from './schema-compat.js';
42
+ export type { SchemaCompatFinding, SchemaCompatMode, SchemaCompatReport, StackItemContractShape, ToolSchemaRef, } from './schema-compat.js';
43
+ export type { ServerInfo } from './build-mcp.js';
44
+ export { UnauthenticatedError, DEFAULT_BUILDER_APP_ID, defaultAppIdFromIdentity, } from './auth.js';
45
+ export { createConsoleLogger } from './logger.js';
46
+ export type { Logger } from './logger.js';
47
+ export { createSessionChannelServer, DEFAULT_SESSION_CHANNEL_PATH, DEFAULT_WIRED_TOOL_TIMEOUT_MS, } from './session-channel.js';
48
+ export type { SessionChannelOptions, SessionChannelServer, WiredActionContext, WiredActionRouter, } from './session-channel.js';
49
+ export { resolveStorageFromConfig } from './storage.js';
50
+ export type { ResolveStorageFromConfigOptions, ResolvedStorageStores, } from './storage.js';
51
+ export { DEFAULT_PAIRING_ADMIN_INIT_PATH, DEFAULT_PAIRING_PATH, mountPairingTransport, } from './pairing-transport.js';
52
+ export type { PairingTransportOptions } from './pairing-transport.js';
53
+ export { USER_SESSION_COOKIE_NAME, DEFAULT_USER_SESSION_TTL_SEC, cookieAuthMiddleware, extractUserSessionCookie, formatUserSessionCookieHeader, formatClearUserSessionCookieHeader, readUserSessionCookie, readUserSessionCookieFromHeaders, } from './user-session-auth.js';
54
+ export type { FormatUserSessionCookieInput } from './user-session-auth.js';
55
+ export { createPairLoginRateLimitMiddleware, resolveClientIp, } from './rate-limit-middleware.js';
56
+ export type { PairLoginRateLimitOptions } from './rate-limit-middleware.js';
57
+ export { CSRF_HEADER_NAME, CSRF_RESPONSE_HEADER_NAME, DEFAULT_CSRF_TOKEN_PATH, createCsrfMiddleware, mintCsrfToken, mountCsrfTokenRoute, } from './csrf-middleware.js';
58
+ export type { CsrfMiddlewareOptions, MintCsrfTokenInput, MountCsrfTokenRouteOptions, } from './csrf-middleware.js';
59
+ export { createSecurityHeadersMiddleware } from './security-headers-middleware.js';
60
+ export type { SecurityHeadersMiddlewareOptions } from './security-headers-middleware.js';
61
+ export { composeOAuthUserId, } from './oauth-login-types.js';
62
+ export type { OAuthLoginProvider, AuthorizeUrlInput, ExchangeCodeInput, OAuthExchangeResult, OAuthProviderConfigRecord, OAuthAuthResult, } from './oauth-login-types.js';
63
+ export { DEFAULT_OAUTH_START_PATH, DEFAULT_OAUTH_CALLBACK_PATH, DEFAULT_OAUTH_PROVIDERS_LIST_PATH, OAUTH_PKCE_COOKIE_NAME, mountOAuthLoginRoutes, } from './oauth-login.js';
64
+ export { DEFAULT_EMAIL_LOGIN_START_PATH, DEFAULT_EMAIL_LOGIN_VERIFY_PATH, DEFAULT_EMAIL_LOGIN_CONFIG_PATH, ConsoleEmailSender, InMemoryMagicLinkStore, mountEmailLoginRoutes, } from './email-login.js';
65
+ export type { EmailSender, EmailMessage, MagicLinkStore, MagicLinkRecord, MintTokenInput, EmailLoginRoutesOptions, } from './email-login.js';
66
+ export { ResendEmailSender } from './email-resend.js';
67
+ export type { ResendEmailSenderOptions } from './email-resend.js';
68
+ export { SmtpEmailSender } from './email-smtp.js';
69
+ export type { SmtpEmailSenderOptions } from './email-smtp.js';
70
+ export { selectEmailSenderFromEnv } from './email-sender-from-env.js';
71
+ export type { EmailSenderKind, EmailSenderSelection, SelectEmailSenderOptions, } from './email-sender-from-env.js';
72
+ export { MCP_INSTRUCTIONS_PRESETS, resolveMcpInstructions, } from './instructions-presets.js';
73
+ export type { McpInstructionsPreset, McpInstructionsValue, } from './instructions-presets.js';
74
+ export type { OAuthLoginRoutesOptions } from './oauth-login.js';
75
+ export { googleLoginProvider } from './oauth-providers/google.js';
76
+ export type { GoogleLoginProviderOptions } from './oauth-providers/google.js';
77
+ export { githubLoginProvider } from './oauth-providers/github.js';
78
+ export type { GithubLoginProviderOptions } from './oauth-providers/github.js';
79
+ export { createOAuthProvidersStore } from './oauth-providers-store.js';
80
+ export type { OAuthProvidersStore, OAuthProvidersStoreOptions, PutInput as OAuthProvidersStorePutInput, } from './oauth-providers-store.js';
81
+ export { DEFAULT_ADMIN_OAUTH_PROVIDERS_PATH, mountAdminOAuthProvidersTransport, } from './admin-oauth-providers-transport.js';
82
+ export type { AdminOAuthProvidersTransportOptions } from './admin-oauth-providers-transport.js';
83
+ export type { CompletePairingInput, Pairing, PairingCompletion, PairingInit, PairingService, PairingWithToken, } from '@ggui-ai/mcp-server-core';
84
+ export { DEFAULT_BUILDER_OWNER_ID, DEFAULT_THREADS_PATH, defaultThreadOwnerFromIdentity, mountThreadTransport, } from './thread-transport.js';
85
+ export type { ThreadOwnerResolver, ThreadTransportOptions, } from './thread-transport.js';
86
+ export { InMemoryShortCodeIndex } from '@ggui-ai/mcp-server-core/in-memory';
87
+ export type { ShortCodeIndex } from '@ggui-ai/mcp-server-core';
88
+ export { InMemoryAuthAdapter } from '@ggui-ai/mcp-server-core/in-memory';
89
+ export type { InMemoryAuthAdapterOptions } from '@ggui-ai/mcp-server-core/in-memory';
90
+ export { FixedWindowRateLimiter, InMemoryQuotaStore, } from '@ggui-ai/mcp-server-core/in-memory';
91
+ export type { FixedWindowRateLimiterOptions, InMemoryQuotaStoreOptions, } from '@ggui-ai/mcp-server-core/in-memory';
92
+ export type { RateLimiter, QuotaStore } from '@ggui-ai/mcp-server-core';
93
+ export { ManifestBlueprintProvider } from '@ggui-ai/mcp-server-core/in-memory';
94
+ export type { ManifestBlueprintSeed, ManifestBlueprintProviderOptions, } from '@ggui-ai/mcp-server-core/in-memory';
95
+ export type { BlueprintProvider } from '@ggui-ai/mcp-server-core';
96
+ export type { DiscoveredPrimitiveCatalog } from '@ggui-ai/project-config/node';
97
+ export type { LoadedTheme } from '@ggui-ai/project-config/node';
98
+ export type { OperatorConfig } from '@ggui-ai/project-config';
99
+ export type { ThemeWriter, ThemeFileUploader, } from './console-theme-routes.js';
100
+ export type { LlmProvider, LlmSelection, ProviderKeyRef, UiGenerateEvent, UiGenerateInput, UiGenerateResult, UiGenerator, GeneratorTier, GeneratorRegistry, GeneratorSlugParts, } from '@ggui-ai/mcp-server-core';
101
+ export { formatGeneratorSlug, isValidGeneratorSlug, parseGeneratorSlug, } from '@ggui-ai/mcp-server-core';
102
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js ADDED
@@ -0,0 +1,122 @@
1
+ /**
2
+ * @ggui-ai/mcp-server — open self-hosted MCP server for the ggui protocol.
3
+ *
4
+ * **Role**: thin HTTP/MCP binding layer.
5
+ * Composes `@ggui-ai/mcp-server-handlers` (real handler logic) with
6
+ * `@ggui-ai/mcp-server-core` in-memory reference adapters to produce a
7
+ * runnable open server. No business logic lives here — if you need to
8
+ * change tool behavior, edit the shared handler package.
9
+ *
10
+ * Zero-config boot:
11
+ *
12
+ * ```ts
13
+ * import { createGguiServer } from '@ggui-ai/mcp-server';
14
+ * const server = createGguiServer();
15
+ * await server.listen(4567);
16
+ * ```
17
+ *
18
+ * This package deliberately does NOT:
19
+ *
20
+ * - embed AWS / DDB / Redis / cloud-specific wiring (those bind to
21
+ * `@ggui-ai/mcp-server-core` interfaces in separate adapter
22
+ * packages),
23
+ * - implement authoring / pairing / UI generation (those are separate
24
+ * packages + protocol flows).
25
+ *
26
+ * The `ggui serve` CLI command boots this server with the OSS defaults.
27
+ */
28
+ // No-credentials fallback helpers — re-exported so the OSS CLI can
29
+ // build the no-credentials card stack item (pointing at the resolved
30
+ // `/settings` URL) without taking a direct `@ggui-ai/mcp-server-handlers`
31
+ // dependency.
32
+ export { NO_CREDENTIALS_SYSTEM_CARD_KIND, buildNoCredentialsStackItem, } from '@ggui-ai/mcp-server-handlers';
33
+ export { createGguiServer, defaultHandlers } from './server.js';
34
+ // Content-addressable code delivery (2026-05-03). FileSystemCodeStore
35
+ // is the OSS dev default; in-memory variant ships in
36
+ // `@ggui-ai/mcp-server-core/in-memory` for tests + ephemeral runs.
37
+ export { FileSystemCodeStore } from './code-store-fs.js';
38
+ export { composeWiredActionRouterFromMounts } from './mcp-mounts.js';
39
+ export { validateMcpServices, validateServicePath } from './mcp-mounts.js';
40
+ // Reserved-channel payload validator composition.
41
+ // `composePreviewReservedValidator` binds the A2UI adapter
42
+ // for `_ggui:preview`; `mergeReservedValidators` layers caller-provided
43
+ // extras on top. `createGguiServer` composes these automatically —
44
+ // consumers that embed the session-channel server directly (via
45
+ // `createSessionChannelServer`) wire them up manually.
46
+ export { composePreviewReservedValidator, mergeReservedValidators, } from './reserved-validators.js';
47
+ // Schema compatibility checker. Exposes the helper, the policy-mode
48
+ // type, the canonical error, and the default mode constant. Consumers
49
+ // embedding their own endpoint paths (custom hosted wrappers) can
50
+ // reuse the helper directly.
51
+ export { checkStackItemSchemaCompat, DEFAULT_SCHEMA_COMPAT_MODE, SchemaCompatError, } from './schema-compat.js';
52
+ export { UnauthenticatedError, DEFAULT_BUILDER_APP_ID, defaultAppIdFromIdentity, } from './auth.js';
53
+ export { createConsoleLogger } from './logger.js';
54
+ export { createSessionChannelServer, DEFAULT_SESSION_CHANNEL_PATH, DEFAULT_WIRED_TOOL_TIMEOUT_MS, } from './session-channel.js';
55
+ export { resolveStorageFromConfig } from './storage.js';
56
+ export { DEFAULT_PAIRING_ADMIN_INIT_PATH, DEFAULT_PAIRING_PATH, mountPairingTransport, } from './pairing-transport.js';
57
+ // End-user browser-session cookie + login routes. Cookie + endpoints
58
+ // are mounted automatically by `createGguiServer` when pairing is
59
+ // enabled; re-exported here so embedders composing custom transports
60
+ // can reuse the cookie shape directly.
61
+ export { USER_SESSION_COOKIE_NAME, DEFAULT_USER_SESSION_TTL_SEC, cookieAuthMiddleware, extractUserSessionCookie, formatUserSessionCookieHeader, formatClearUserSessionCookieHeader, readUserSessionCookie, readUserSessionCookieFromHeaders, } from './user-session-auth.js';
62
+ // Per-IP rate limit on `/pair`. Mounted automatically by
63
+ // `createGguiServer` when pairing is enabled. Re-exported so hosted
64
+ // bindings can swap in their own RateLimiter (Redis-backed,
65
+ // sliding-window, etc.) and reuse the middleware.
66
+ export { createPairLoginRateLimitMiddleware, resolveClientIp, } from './rate-limit-middleware.js';
67
+ // Browser-session hardening: CSRF (double-submit, HMAC-bound to the
68
+ // session cookie), audit hooks (wired through
69
+ // `LoginRoutesOptions.auditSink`), and security headers
70
+ // (X-Frame-Options DENY, Referrer-Policy, X-Content-Type-Options).
71
+ // All three mount automatically.
72
+ export { CSRF_HEADER_NAME, CSRF_RESPONSE_HEADER_NAME, DEFAULT_CSRF_TOKEN_PATH, createCsrfMiddleware, mintCsrfToken, mountCsrfTokenRoute, } from './csrf-middleware.js';
73
+ export { createSecurityHeadersMiddleware } from './security-headers-middleware.js';
74
+ // OAuth login providers. Server mounts admin transport always +
75
+ // login routes when publicBaseUrl is set; operators paste
76
+ // credentials at /admin/oauth-providers and end-users sign in at
77
+ // /login via provider buttons.
78
+ export { composeOAuthUserId, } from './oauth-login-types.js';
79
+ export { DEFAULT_OAUTH_START_PATH, DEFAULT_OAUTH_CALLBACK_PATH, DEFAULT_OAUTH_PROVIDERS_LIST_PATH, OAUTH_PKCE_COOKIE_NAME, mountOAuthLoginRoutes, } from './oauth-login.js';
80
+ export { DEFAULT_EMAIL_LOGIN_START_PATH, DEFAULT_EMAIL_LOGIN_VERIFY_PATH, DEFAULT_EMAIL_LOGIN_CONFIG_PATH, ConsoleEmailSender, InMemoryMagicLinkStore, mountEmailLoginRoutes, } from './email-login.js';
81
+ export { ResendEmailSender } from './email-resend.js';
82
+ export { SmtpEmailSender } from './email-smtp.js';
83
+ export { selectEmailSenderFromEnv } from './email-sender-from-env.js';
84
+ export { MCP_INSTRUCTIONS_PRESETS, resolveMcpInstructions, } from './instructions-presets.js';
85
+ export { googleLoginProvider } from './oauth-providers/google.js';
86
+ export { githubLoginProvider } from './oauth-providers/github.js';
87
+ export { createOAuthProvidersStore } from './oauth-providers-store.js';
88
+ export { DEFAULT_ADMIN_OAUTH_PROVIDERS_PATH, mountAdminOAuthProvidersTransport, } from './admin-oauth-providers-transport.js';
89
+ export { DEFAULT_BUILDER_OWNER_ID, DEFAULT_THREADS_PATH, defaultThreadOwnerFromIdentity, mountThreadTransport, } from './thread-transport.js';
90
+ // Zero-config in-memory reference for the console shortCode → session
91
+ // lookup. Re-exported here (alongside `createGguiServer`) so CLI hosts
92
+ // composing the OSS first-run path can pass one without taking a direct
93
+ // dep on `@ggui-ai/mcp-server-core`. For durable deployments the
94
+ // operator swaps in their own `ShortCodeIndex` implementation.
95
+ export { InMemoryShortCodeIndex } from '@ggui-ai/mcp-server-core/in-memory';
96
+ // In-memory reference AuthAdapter. Re-exported for the same reason as
97
+ // `InMemoryShortCodeIndex` — CLI hosts that want strict auth (no
98
+ // implicit `devAllowAll`) construct one with `devAllowAll: false` and
99
+ // pass it to `createGguiServer({ auth: ... })` without taking a direct
100
+ // `@ggui-ai/mcp-server-core` dep. `ggui serve` does this by default to
101
+ // keep its `/mcp` ingress honest; pair-minted tokens register through
102
+ // `onTokenIssued`.
103
+ export { InMemoryAuthAdapter } from '@ggui-ai/mcp-server-core/in-memory';
104
+ // In-memory rate-limiter + quota-store reference adapters. Re-exported
105
+ // for the same reason as `InMemoryAuthAdapter` — CLI hosts can compose
106
+ // `--public-demo` posture (per-IP rate limit on ggui_push) without
107
+ // taking a direct `@ggui-ai/mcp-server-core` dep. The default fallback
108
+ // inside `createGguiServer` is `NoopRateLimiter`; this is the smallest
109
+ // non-trivial alternative.
110
+ export { FixedWindowRateLimiter, InMemoryQuotaStore, } from '@ggui-ai/mcp-server-core/in-memory';
111
+ // Manifest-backed blueprint provider.
112
+ // CLI hosts construct one from `discoverLocalUis()` results and pass it
113
+ // as `createGguiServer({ blueprintProvider: ... })` so every UI declared
114
+ // in `ggui.json#blueprints.include` surfaces through
115
+ // `ggui_list_featured_blueprints`. Re-exported here for the same reason
116
+ // as `InMemoryShortCodeIndex` — CLI hosts shouldn't need a direct
117
+ // `@ggui-ai/mcp-server-core` dep to compose the first-run server.
118
+ export { ManifestBlueprintProvider } from '@ggui-ai/mcp-server-core/in-memory';
119
+ // Generator-registry helpers re-exported so callers composing a
120
+ // custom registry don't need a direct `@ggui-ai/mcp-server-core`
121
+ // import just for slug parsing.
122
+ export { formatGeneratorSlug, isValidGeneratorSlug, parseGeneratorSlug, } from '@ggui-ai/mcp-server-core';
@@ -0,0 +1,112 @@
1
+ /**
2
+ * Server-level instructions presets for the MCP `InitializeResult.
3
+ * instructions` field.
4
+ *
5
+ * **What this string does**: per the MCP spec
6
+ * (`@modelcontextprotocol/sdk/types.js`), `instructions` is "a hint to
7
+ * the model" that hosts MAY add to the system prompt. Its job is to
8
+ * help the LLM **understand the server's tools and protocol**. It is
9
+ * NOT an enforcement mechanism — the LLM weighs it against the host's
10
+ * own system prompt, the user's chat-level instructions, and built-in
11
+ * tool-selection priors.
12
+ *
13
+ * **Difference from per-tool description**: per-tool descriptions
14
+ * answer "what does THIS tool do?" Server instructions answer "what is
15
+ * this server, and how do its tools fit together?" Both are spec-
16
+ * defined hints, both compose into the same system prompt.
17
+ *
18
+ * **Why presets explain protocol, not behavior**: previous iterations
19
+ * tried to nudge the LLM to "render every response" via imperative
20
+ * language. In observed practice this is worth less than a single
21
+ * line of user-side custom instruction, AND the spec doesn't promise
22
+ * the field has that pull. Honest framing: the presets explain what
23
+ * ggui is, how the three lifecycle tools relate, and how rendered UIs
24
+ * route actions/streams back. The LLM picks tools when its judgment
25
+ * matches; for stronger pull, ship a recommended user-instruction
26
+ * snippet (see the console `/settings` onboarding card).
27
+ *
28
+ * **Preset depth**:
29
+ *
30
+ * - `'default'` — concise protocol explainer (server identity +
31
+ * live-UI mechanism + lifecycle bullets).
32
+ * - `'aggressive'` — adds the action-routing detail.
33
+ * - `'always'` — adds a worked invocation example.
34
+ * - `'minimal'` — server identity only.
35
+ * - `'off'` — omit the field entirely.
36
+ *
37
+ * Names are kept (vs renaming to `verbose` etc.) for compat with the
38
+ * already-shipped `--mcp-instructions` CLI flag and operator configs.
39
+ */
40
+ /**
41
+ * Preset name → instruction-string map. Operators select a preset by
42
+ * passing `mcpInstructions: 'default'` (etc.) to `createGguiServer`.
43
+ * Pass an arbitrary string to substitute custom copy. Pass `'off'` or
44
+ * the empty string to omit the field entirely.
45
+ *
46
+ * @public
47
+ */
48
+ export declare const MCP_INSTRUCTIONS_PRESETS: {
49
+ /**
50
+ * Concise protocol explainer — what ggui is, four-spec mental
51
+ * model, lifecycle with nextStep-driven routing, complementary
52
+ * tools. No-preset default.
53
+ */
54
+ readonly default: string;
55
+ /**
56
+ * Default protocol primer + the host-side action-routing detail
57
+ * (Pattern α direct dispatch vs Pattern β cross-server consent
58
+ * bridge). Pick when the operator wants the LLM to also reason
59
+ * about how the underlying tools/call envelopes flow.
60
+ */
61
+ readonly aggressive: string;
62
+ /**
63
+ * `aggressive` + a worked invocation example. Useful when the
64
+ * operator wants the LLM to see a complete handshake → push
65
+ * pattern at boot.
66
+ */
67
+ readonly always: string;
68
+ /**
69
+ * Server identity only — no protocol detail. Pick when the
70
+ * operator wants per-tool descriptions to be the sole signal.
71
+ */
72
+ readonly minimal: "This server speaks the ggui protocol — an open standard for delivering interactive UIs to end-users (https://github.com/ggui-ai/ggui).";
73
+ /**
74
+ * Sentinel value. The wiring layer sees `'off'` and passes
75
+ * `instructions: undefined` to the McpServer constructor — the
76
+ * server omits the field on InitializeResult entirely.
77
+ */
78
+ readonly off: "";
79
+ };
80
+ /**
81
+ * The preset enum's string keys, exported as a type for caller
82
+ * autocomplete.
83
+ *
84
+ * @public
85
+ */
86
+ export type McpInstructionsPreset = keyof typeof MCP_INSTRUCTIONS_PRESETS;
87
+ /**
88
+ * The values `createGguiServer.mcpInstructions` accepts:
89
+ *
90
+ * - One of the preset names: `'default' | 'aggressive' | 'always' | 'minimal' | 'off'`.
91
+ * - An arbitrary string — used verbatim as the `instructions` field.
92
+ * - `undefined` — falls through to the no-preset default (`'default'`).
93
+ *
94
+ * @public
95
+ */
96
+ export type McpInstructionsValue = McpInstructionsPreset | string;
97
+ /**
98
+ * Resolve the operator-provided value into the actual string the MCP
99
+ * server should send. Returns `undefined` when the result is empty
100
+ * (the constructor should omit the field).
101
+ *
102
+ * **No-preset default = `'default'`.** All behavior-text presets
103
+ * explain the protocol now (vs nudging tool-use), so the previous
104
+ * "aggressive as no-preset default" rationale no longer applies —
105
+ * `'default'` is the appropriate baseline. Operators who want fuller
106
+ * protocol detail opt into `'aggressive'` or `'always'`. To turn
107
+ * instructions off entirely, pass `'off'`.
108
+ *
109
+ * @public
110
+ */
111
+ export declare function resolveMcpInstructions(value: McpInstructionsValue | undefined): string | undefined;
112
+ //# sourceMappingURL=instructions-presets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"instructions-presets.d.ts","sourceRoot":"","sources":["../src/instructions-presets.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AA4FH;;;;;;;GAOG;AACH,eAAO,MAAM,wBAAwB;IACnC;;;;OAIG;;IAGH;;;;;OAKG;;IAGH;;;;OAIG;;IASH;;;OAGG;;IAIH;;;;OAIG;;CAEK,CAAC;AAEX;;;;;GAKG;AACH,MAAM,MAAM,qBAAqB,GAAG,MAAM,OAAO,wBAAwB,CAAC;AAE1E;;;;;;;;GAQG;AACH,MAAM,MAAM,oBAAoB,GAAG,qBAAqB,GAAG,MAAM,CAAC;AAElE;;;;;;;;;;;;;GAaG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,oBAAoB,GAAG,SAAS,GACtC,MAAM,GAAG,SAAS,CAWpB"}
@@ -0,0 +1,195 @@
1
+ /**
2
+ * Server-level instructions presets for the MCP `InitializeResult.
3
+ * instructions` field.
4
+ *
5
+ * **What this string does**: per the MCP spec
6
+ * (`@modelcontextprotocol/sdk/types.js`), `instructions` is "a hint to
7
+ * the model" that hosts MAY add to the system prompt. Its job is to
8
+ * help the LLM **understand the server's tools and protocol**. It is
9
+ * NOT an enforcement mechanism — the LLM weighs it against the host's
10
+ * own system prompt, the user's chat-level instructions, and built-in
11
+ * tool-selection priors.
12
+ *
13
+ * **Difference from per-tool description**: per-tool descriptions
14
+ * answer "what does THIS tool do?" Server instructions answer "what is
15
+ * this server, and how do its tools fit together?" Both are spec-
16
+ * defined hints, both compose into the same system prompt.
17
+ *
18
+ * **Why presets explain protocol, not behavior**: previous iterations
19
+ * tried to nudge the LLM to "render every response" via imperative
20
+ * language. In observed practice this is worth less than a single
21
+ * line of user-side custom instruction, AND the spec doesn't promise
22
+ * the field has that pull. Honest framing: the presets explain what
23
+ * ggui is, how the three lifecycle tools relate, and how rendered UIs
24
+ * route actions/streams back. The LLM picks tools when its judgment
25
+ * matches; for stronger pull, ship a recommended user-instruction
26
+ * snippet (see the console `/settings` onboarding card).
27
+ *
28
+ * **Preset depth**:
29
+ *
30
+ * - `'default'` — concise protocol explainer (server identity +
31
+ * live-UI mechanism + lifecycle bullets).
32
+ * - `'aggressive'` — adds the action-routing detail.
33
+ * - `'always'` — adds a worked invocation example.
34
+ * - `'minimal'` — server identity only.
35
+ * - `'off'` — omit the field entirely.
36
+ *
37
+ * Names are kept (vs renaming to `verbose` etc.) for compat with the
38
+ * already-shipped `--mcp-instructions` CLI flag and operator configs.
39
+ */
40
+ /**
41
+ * Action-routing pattern detail (Pattern α / Pattern β). Layered atop
42
+ * `default` by the `aggressive` and `always` presets — `default`
43
+ * already covers the actionSpec wire shape via the MENTAL MODEL
44
+ * block; this paragraph adds the host-side dispatch semantics that
45
+ * matter when an operator wants the LLM to also reason about how the
46
+ * underlying tools/call envelopes flow.
47
+ */
48
+ const ACTION_ROUTING_PARAGRAPH = "Action routing: every actionSpec entry is a GESTURE — a discrete event the agent reacts to on its next turn. When the user interacts, the iframe relays the action through `ggui_runtime_submit_action` to the server, which appends the event onto a per-stack-item pipe. Your `ggui_consume` long-poll unblocks mid-turn with the event payload plus a uiContext snapshot of every declared contextSpec slot. There is no synchronous server-side tool-fire — `actions drive turns` is a structural invariant (docs/principles/actions-vs-context.md): an action always waits for the agent. Cross-MCP `nextStep` hints work the same way: the agent reads the event's `actionData.nextStep`, decides whether to honor it, and calls the named tool on the next turn (the tool MAY live on a different MCP server — declare it in `agentCapabilities.tools` so the cross-ref invariant passes).";
49
+ /**
50
+ * Worked invocation example. Layered atop the `aggressive` content by
51
+ * `always` only — shows the literal handshake → push pattern an
52
+ * operator can copy.
53
+ */
54
+ const WORKED_EXAMPLE_PARAGRAPH = "Example: ggui_handshake({ sessionId: 's_…', intent: 'a settings panel for notification preferences', blueprintDraft: { contract: {...}, variance: { persona: 'minimalist' } } }) returns { handshakeId: 'h_…', suggestion: { origin: 'cache' | 'agent' | 'synth', blueprintMeta: { blueprintId, contractHash, codeHash?, generator, variance }, amendments?, validationFindings? }, contractHash: '<hex>' }. ACCEPT PATH: ggui_push({ handshakeId: 'h_…', decision: { kind: 'accept' } }) — reuses the provisional blueprintId. OVERRIDE PATH: ggui_push({ handshakeId: 'h_…', decision: { kind: 'override', blueprintDraft: { contract: { ...refined } } } }) — mints a fresh blueprintId against your new draft.";
55
+ /**
56
+ * The default-preset body, captured as a const so `aggressive` and
57
+ * `always` can layer additional paragraphs on top without diverging
58
+ * from the protocol-primer baseline.
59
+ */
60
+ const DEFAULT_PRESET_BODY = [
61
+ 'GGUI PROTOCOL — open standard for agents to deliver real interactive UIs to end-users (https://github.com/ggui-ai/ggui). You are the agent; the user is on the other side of a rendered UI, NOT a text terminal. Every user message — whether an obvious UI request (a card, a form, a list, a chart, a settings panel) OR conversational chat (a greeting, a question, a follow-up, even "hey") — must be rendered via the ggui_* tools rather than replied to in plain text. There is no plain-text reply path. For greetings, render a greeting/chat UI. For questions, render an answer card. For "hey", render a hello-bubble or a quick-reply chooser. The renderer can paint any HTML/CSS/JS your contract describes — including simple text bubbles — so "should I use ggui?" reduces to "always".',
62
+ '',
63
+ '═══ MENTAL MODEL ═══',
64
+ '',
65
+ 'Every UI you render is described by a DataContract — a typed declaration of four data surfaces. You author the contract at handshake time; the contract is what the renderer compiles + the agent later interacts with. Four specs, each with one job:',
66
+ '',
67
+ ' • propsSpec — agent → client (one-shot data). The initial values the rendered UI displays. Push sends these as `props`; ggui_update mutates them after delivery. e.g. a weather card has {temperature, condition, city} on propsSpec.',
68
+ '',
69
+ ' • actionSpec — client → agent (discrete events). User gestures (clicks, submits) that drive the agent\'s NEXT TURN. Each entry has a `label`, optional `schema` for the payload, and optional `nextStep: "<toolName>"`. When `nextStep` is present, it names the tool the agent SHOULD call next AND the same name MUST also appear in `agentCapabilities.tools` (cross-ref invariant; rejection code `cross_reference_unresolved`). Omit `nextStep` entirely when the agent should decide freely from broader context (open-ended form submits). e.g. a feedback form has `submit` on actionSpec with `nextStep:"record_feedback"` (and `record_feedback` listed under `agentCapabilities.tools`).',
70
+ '',
71
+ ' • contextSpec — client → agent (observed state, not events). Continuous client state the agent observes — slider position, draft text, current selection. Use contextSpec when you need to KNOW the state but don\'t need to ACT on every change. On MCP Apps hosts the runtime auto-mirrors the snapshot into the host\'s widget-context surface (the agent sees it on the next turn without polling). On raw MCP clients there is no auto-mirror — call ggui_get_stack to read `contextSnapshot` when you need the latest values. e.g. a calendar has `selectedDate` on contextSpec.',
72
+ '',
73
+ ' • streamSpec — agent → client (live updates). Live outbound channels for streaming data to the UI mid-render — chat tokens, progress events, log lines, time-series data. Each entry has a `schema` for the frame shape; you push frames via ggui_emit. e.g. a chat surface has `assistantMessage` on streamSpec for token-by-token output.',
74
+ '',
75
+ 'PLACEMENT RULE for actionSpec vs contextSpec: "does this thing need the agent\'s next-turn reasoning?" Yes → actionSpec. No → contextSpec. There is no third category (full rule: docs/principles/actions-vs-context.md).',
76
+ '',
77
+ '═══ LIFECYCLE ═══',
78
+ '',
79
+ 'Every chat that touches ggui follows this loop:',
80
+ '',
81
+ ' 1. ggui_new_session — FIRST CALL of any chat. Mints a sessionId. Call once per conversation; thread the result through every subsequent handshake.',
82
+ '',
83
+ ' 2. ggui_handshake — negotiate a contract for the next UI. Post {sessionId, intent, blueprintDraft: {contract, variance?, generator?}}. `variance` is optional and lets you steer cache lookup + gen by axis: `persona` ("minimalist", "playful"), `aesthetic` ("dense", "spacious"), `intentContext` (free-form usage notes), `seedPrompt` (deterministic seed). Server runs BlueprintSearch + contract-validation in parallel and returns a handshakeId + suggestion (origin: cache | agent | synth). cache → blueprint already exists, push delivers it instantly. agent → novel-but-clean draft, gen runs on push. synth → your draft failed validation, server amended it; diff is on suggestion.amendments.',
84
+ '',
85
+ ' 3. ggui_push — deliver the UI. handshakeId is REQUIRED (from step 2); calling push without it fails with `handshake_not_found`. Send {handshakeId, decision: {kind:"accept"}} to use the suggestion verbatim, OR {handshakeId, decision: {kind:"override", blueprintDraft:{...}}} to mint fresh against a new draft. If the contract declares propsSpec, props is REQUIRED. Handshake records are SINGLE-USE and expire after 10 minutes. On error: `handshake_not_found` → call ggui_handshake again. `contract_violation` (props don\'t match propsSpec) / `contract_schema_invalid` (an inner JSON Schema is malformed) / `cross_reference_unresolved` (`actionSpec[*].nextStep` or `streamSpec[*].source.tool` names a tool not in `agentCapabilities.tools`) / `schema_mismatch_error` (action schema not a subset of the named tool\'s inputSchema) / `missing_props` → fix the input and retry with the SAME handshakeId (still valid until consumed).',
86
+ '',
87
+ ' 4. NEXT STEP — read the push response. If it carries a `nextStep` field, call that tool with the given args. Push only emits `nextStep` when the contract declared a non-empty actionSpec (i.e., the UI has interactive buttons/forms); in that case nextStep names ggui_consume and your job is to long-poll for the user\'s gesture. If the push response has NO nextStep, the UI is pure-display (props only, no actionSpec) — you can end your turn; the user reads the UI and types their next prompt when they\'re ready.',
88
+ '',
89
+ ' 5. ggui_consume (when push said to) — long-poll for user interaction. Keyed by stackItemId. Blocks up to ~15 min (deployment-configurable); returns when an actionSpec event arrives or the session closes. Each return carries `{events, status}`: `events[]` is the discrete action(s) the user just took. Each event is an envelope `{intent, actionData, uiContext, actionId, firedAt}` — `actionData` is WHAT the user did (action name + validated payload, plus `nextStep` hint if the author declared one); `uiContext` is the iframe-local snapshot of every declared contextSpec slot AT THE MOMENT the action fired (form fields, selected tab, slider value, scroll position — whatever the contract declared). Both inform your reaction without a second round trip. Honor each event\'s `actionData.nextStep` hint if the tool is available, then loop back to step 2 to render the response. Continue until consume returns status:"completed" or no further follow-up is needed.',
90
+ '',
91
+ ' 6. ggui_update — reflect the new state in the UI. After ANY domain-tool call whose result changed data the rendered UI displays (e.g. `todo_toggle` flips a todo\'s `done`, `cart_add_item` extends a cart, `note_save` persists text), you MUST immediately call `ggui_update` with the refreshed props so the user sees what just happened. The rendered UI does NOT auto-refresh — it only shows the props it was last given. Skipping `ggui_update` after a state-mutating tool call leaves the user staring at stale state and is the #1 wire bug. Pattern: `consume → domain-tool → ggui_update → loop to consume`. Two modes: `{stackItemId, kind:"replace", props}` sends the FULL new props map (use when most fields changed or you want deterministic restoration); `{stackItemId, kind:"merge", patch}` sends ONLY the delta as RFC 7396 JSON Merge Patch (shallow merge, recurse on nested objects, `null` deletes a key, arrays fully replace — use when most props stay the same and only one or two fields changed). Prefer `merge` after a single domain-tool mutation; prefer `replace` when restoring state or when most fields changed. The only times you skip `ggui_update` are: (a) the domain tool was pure-read (todo_list, search, etc.) AND its result wasn\'t for the UI, or (b) the contract has no propsSpec (pure-display with no mutable state).',
92
+ '',
93
+ 'In short: let the protocol\'s `nextStep` fields drive routing. Every ggui_* tool whose response logically chains forwards (new_session → handshake → push → consume) emits a nextStep when there IS a next step; the absence of nextStep means "you\'re done with this thread for now."',
94
+ '',
95
+ '═══ COMPLEMENTARY TOOLS ═══',
96
+ '',
97
+ ' • ggui_update — refresh a delivered UI with new props WITHOUT destroying it. Two modes: `kind:"replace"` (full props) or `kind:"merge"` (RFC 7396 delta — see step 6). ALWAYS call this after any state-mutating tool call; re-pushing would lose scroll position, focus, and uncommitted input. Forgetting `ggui_update` after a mutation is the most common protocol bug.',
98
+ '',
99
+ ' • ggui_emit — push frames to a streamSpec channel on a delivered UI. Use when the contract declared streamSpec (chat tokens, progress bars, live data). Frames must match the channel\'s declared `schema`. The live channel of the wire carries these.',
100
+ '',
101
+ ' • ggui_pop — pop the top stack item (e.g., close a modal you pushed). Idempotent — popping an empty stack returns null without error.',
102
+ '',
103
+ ' • ggui_close — explicitly end a session. Optional; sessions GC on their own. Use when the user has clearly finished and you want to free resources.',
104
+ '',
105
+ ' • ggui_get_session / ggui_get_stack — inspect current session state if you\'ve lost track of what\'s rendered. ggui_get_stack also returns each item\'s `contextSnapshot` — the canonical way to read contextSpec values from a raw MCP client.',
106
+ '',
107
+ '═══ HOST RENDERING ═══',
108
+ '',
109
+ 'Two host shapes consume push output identically — your job is the same:',
110
+ '',
111
+ ' • MCP Apps hosts (claude.ai, MCP-Apps-aware desktop clients) — push responses carry the rendered UI inline via `_meta.ggui.bootstrap`; the host displays it automatically. The user interacts with the UI directly, and contextSpec snapshots flow back into your widget-context surface without any agent action.',
112
+ '',
113
+ ' • Plain MCP clients (Claude Agent SDK without MCP Apps host adapter, raw CLI clients) — push responses carry a renderer URL in the structured content; the host either embeds it as an iframe or displays it as a link. Wire flow is identical (handshake → push → consume); only the rendering surface differs.',
114
+ '',
115
+ 'Rendered UIs are LIVE — actionSpec entries route back to you as events you receive via consume (each gesture\'s payload validated against the entry\'s declared schema). You don\'t write glue code for any of this; declaring the spec at handshake time is enough.',
116
+ '',
117
+ '═══ TOOL DISCOVERY (lazy-loading hosts) ═══',
118
+ '',
119
+ 'Some MCP hosts (notably claude.ai\'s connector model) use PROGRESSIVE tool discovery — only a small priority subset of tools is warmed at conversation start; the rest must be explicitly discovered via `tool_search` before they\'re callable. The ggui_* loop crosses this boundary on every push: handshake/push warm easily because you call them early, but `ggui_consume` and `ggui_update` are needed AFTER push and the host may not have loaded them yet.',
120
+ '',
121
+ 'SYMPTOM: a tool call fails with a message like "tool has not been loaded yet — call tool_search first" or "you do not have the correct parameter names." RECOVERY: call `tool_search` with the tool name as a query (e.g. `tool_search({ query: "ggui_consume" })`), wait for the load to complete, then retry the original call with the same args. Same pattern for `ggui_update`. After one successful `tool_search` per tool per conversation, subsequent calls work directly.',
122
+ '',
123
+ 'WHEN IN DOUBT: if the push response carries `nextStep`, the host has effectively asked you to call that tool. Don\'t skip ggui_consume because the host whined about it being unloaded — `tool_search` first, then call. Skipping it leaves the user staring at a UI whose actions silently never reach the agent — the worst protocol failure mode.',
124
+ ];
125
+ /**
126
+ * Preset name → instruction-string map. Operators select a preset by
127
+ * passing `mcpInstructions: 'default'` (etc.) to `createGguiServer`.
128
+ * Pass an arbitrary string to substitute custom copy. Pass `'off'` or
129
+ * the empty string to omit the field entirely.
130
+ *
131
+ * @public
132
+ */
133
+ export const MCP_INSTRUCTIONS_PRESETS = {
134
+ /**
135
+ * Concise protocol explainer — what ggui is, four-spec mental
136
+ * model, lifecycle with nextStep-driven routing, complementary
137
+ * tools. No-preset default.
138
+ */
139
+ default: DEFAULT_PRESET_BODY.join('\n'),
140
+ /**
141
+ * Default protocol primer + the host-side action-routing detail
142
+ * (Pattern α direct dispatch vs Pattern β cross-server consent
143
+ * bridge). Pick when the operator wants the LLM to also reason
144
+ * about how the underlying tools/call envelopes flow.
145
+ */
146
+ aggressive: [...DEFAULT_PRESET_BODY, '', ACTION_ROUTING_PARAGRAPH].join('\n'),
147
+ /**
148
+ * `aggressive` + a worked invocation example. Useful when the
149
+ * operator wants the LLM to see a complete handshake → push
150
+ * pattern at boot.
151
+ */
152
+ always: [
153
+ ...DEFAULT_PRESET_BODY,
154
+ '',
155
+ ACTION_ROUTING_PARAGRAPH,
156
+ '',
157
+ WORKED_EXAMPLE_PARAGRAPH,
158
+ ].join('\n'),
159
+ /**
160
+ * Server identity only — no protocol detail. Pick when the
161
+ * operator wants per-tool descriptions to be the sole signal.
162
+ */
163
+ minimal: 'This server speaks the ggui protocol — an open standard for delivering interactive UIs to end-users (https://github.com/ggui-ai/ggui).',
164
+ /**
165
+ * Sentinel value. The wiring layer sees `'off'` and passes
166
+ * `instructions: undefined` to the McpServer constructor — the
167
+ * server omits the field on InitializeResult entirely.
168
+ */
169
+ off: '',
170
+ };
171
+ /**
172
+ * Resolve the operator-provided value into the actual string the MCP
173
+ * server should send. Returns `undefined` when the result is empty
174
+ * (the constructor should omit the field).
175
+ *
176
+ * **No-preset default = `'default'`.** All behavior-text presets
177
+ * explain the protocol now (vs nudging tool-use), so the previous
178
+ * "aggressive as no-preset default" rationale no longer applies —
179
+ * `'default'` is the appropriate baseline. Operators who want fuller
180
+ * protocol detail opt into `'aggressive'` or `'always'`. To turn
181
+ * instructions off entirely, pass `'off'`.
182
+ *
183
+ * @public
184
+ */
185
+ export function resolveMcpInstructions(value) {
186
+ if (value === undefined) {
187
+ return MCP_INSTRUCTIONS_PRESETS.default;
188
+ }
189
+ if (value in MCP_INSTRUCTIONS_PRESETS) {
190
+ const resolved = MCP_INSTRUCTIONS_PRESETS[value];
191
+ return resolved.length > 0 ? resolved : undefined;
192
+ }
193
+ // Caller passed a custom string. Empty string → omit.
194
+ return value.length > 0 ? value : undefined;
195
+ }