feat(basic-host): Add theme toggle and MCP style variables (#336)

* feat(basic-host): add theme toggle and MCP style variables

Add theme support to basic-host example:
- theme.ts: Global theme manager with light/dark toggle
- host-styles.ts: Full set of MCP CSS variables using light-dark()
- ThemeToggle component with sun/moon icons
- Theme-aware CSS using CSS custom properties
- Pass theme + styles to apps via hostContext
- Notify apps when theme changes via sendHostContextChange

Apps now receive:
- hostContext.theme: 'light' | 'dark'
- hostContext.styles.variables: All 60+ MCP CSS variables
- onhostcontextchanged notifications when theme changes

* test: update e2e goldens for theme changes
This commit is contained in:
Olivier Chafik 2026-01-23 20:41:26 +00:00 • committed by GitHub
commit 7bbf2bb250
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -3,6 +3,8 @@ import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
import type { CallToolResult, Tool } from "@modelcontextprotocol/sdk/types.js";
import { getTheme, onThemeChange } from "./theme";
import { HOST_STYLE_VARIABLES } from "./host-styles";
const SANDBOX_PROXY_BASE_URL = "http://localhost:8081/sandbox.html";
@ -270,13 +272,25 @@ export function newAppBridge(
// Declare support for model context updates
updateModelContext: { text: {} },
}, {
// Pass initial host context with theme, display mode, and style variables
hostContext: {
theme: getTheme(),
platform: "web",
styles: {
variables: HOST_STYLE_VARIABLES,
},
containerDimensions: options?.containerDimensions ?? { maxHeight: 6000 },
displayMode: options?.displayMode ?? "inline",
availableDisplayModes: ["inline", "fullscreen"],
},
});
// Listen for theme changes (from toggle or system) and notify the app
onThemeChange((newTheme) => {
log.info("Theme changed:", newTheme);
appBridge.sendHostContextChange({ theme: newTheme });
});
// Register all handlers before calling connect(). The view can start
// sending requests immediately after the initialization handshake, so any
// handlers registered after connect() might miss early requests.