Background
PR #6 unified the SDK's host-context handling around a single currentHostContext: McpUiHostContext source of truth in createSynapse. New public API: synapse.getHostContext() / onHostContextChanged() and React useHostContext<T>(). getTheme / useTheme / onThemeChanged are typed selectors over it.
src/connect.ts (the lower-level connect() / App interface used via AppProvider + useApp for @reboot-dev-style consumers) was deliberately left out of that unification to keep PR #6 scoped. It's now a parallel universe:
- Its own
currentTheme: Theme (different shape — { mode, tokens }, no primaryColor).
toolInfo and containerDimensions extracted from hostContext and stashed as separate locals on the App (app.toolInfo, app.containerDimensions).
host-context-changed handler reconstructs theme from spec fields manually.
- No
app.hostContext getter, no host-context subscription.
- React side has
useConnectTheme but nothing for the broader context.
Open question (resolve first)
Is connect.ts still used by anyone? Internal NimbleBrain bundles use createSynapse, not connect(). The App / AppProvider / useApp surface was originally added for @reboot-dev-style remote MCP apps that wanted a thin imperative layer.
If no current consumer depends on it: delete it, drop the React adapters (AppProvider, useApp, useConnectTheme, useResize, useToolInput, useToolResult), and stop maintaining a parallel SDK surface. That's the highest-leverage answer.
Action: audit consumers (npm dependents + internal usage) before scoping the unification work below.
If we keep it: scope of unification
Share state shape, not implementation. Don't extract a common helper module — the two surfaces have different ergonomic shapes (typed getTheme/onThemeChanged callbacks vs. event-string app.on("theme-changed", ...)).
Estimated ~150 lines, ~5 files:
src/connect.ts — replace currentTheme / separate locals with currentHostContext: McpUiHostContext as single source of truth. app.theme, app.toolInfo, app.containerDimensions become getters that derive from it. host-context-changed handler replaces the whole bag (matches createSynapse semantics).
src/types.ts — add readonly hostContext: McpUiHostContext to the App interface. Existing fields stay (back-compat).
src/react/connect-hooks.ts — add useConnectHostContext<T>() mirroring useHostContext.
src/react/index.ts — export useConnectHostContext.
- Tests — extend
connect.test.ts for the new getter; add useConnectHostContext to __tests__/react/connect-hooks.test.tsx.
Out of scope
- Extracting a shared
host-context.ts module that both createSynapse and connect import from. Forces one ergonomic shape onto two consumers.
- Unifying React hook names (
useHostContext vs useConnectHostContext). The two SDK surfaces stay distinct by design.
Background
PR #6 unified the SDK's host-context handling around a single
currentHostContext: McpUiHostContextsource of truth increateSynapse. New public API:synapse.getHostContext()/onHostContextChanged()and ReactuseHostContext<T>().getTheme/useTheme/onThemeChangedare typed selectors over it.src/connect.ts(the lower-levelconnect()/Appinterface used viaAppProvider+useAppfor@reboot-dev-style consumers) was deliberately left out of that unification to keep PR #6 scoped. It's now a parallel universe:currentTheme: Theme(different shape —{ mode, tokens }, noprimaryColor).toolInfoandcontainerDimensionsextracted fromhostContextand stashed as separate locals on theApp(app.toolInfo,app.containerDimensions).host-context-changedhandler reconstructs theme from spec fields manually.app.hostContextgetter, no host-context subscription.useConnectThemebut nothing for the broader context.Open question (resolve first)
Is
connect.tsstill used by anyone? Internal NimbleBrain bundles usecreateSynapse, notconnect(). TheApp/AppProvider/useAppsurface was originally added for@reboot-dev-style remote MCP apps that wanted a thin imperative layer.If no current consumer depends on it: delete it, drop the React adapters (
AppProvider,useApp,useConnectTheme,useResize,useToolInput,useToolResult), and stop maintaining a parallel SDK surface. That's the highest-leverage answer.Action: audit consumers (npm dependents + internal usage) before scoping the unification work below.
If we keep it: scope of unification
Share state shape, not implementation. Don't extract a common helper module — the two surfaces have different ergonomic shapes (typed
getTheme/onThemeChangedcallbacks vs. event-stringapp.on("theme-changed", ...)).Estimated ~150 lines, ~5 files:
src/connect.ts— replacecurrentTheme/ separate locals withcurrentHostContext: McpUiHostContextas single source of truth.app.theme,app.toolInfo,app.containerDimensionsbecome getters that derive from it.host-context-changedhandler replaces the whole bag (matchescreateSynapsesemantics).src/types.ts— addreadonly hostContext: McpUiHostContextto theAppinterface. Existing fields stay (back-compat).src/react/connect-hooks.ts— adduseConnectHostContext<T>()mirroringuseHostContext.src/react/index.ts— exportuseConnectHostContext.connect.test.tsfor the new getter; adduseConnectHostContextto__tests__/react/connect-hooks.test.tsx.Out of scope
host-context.tsmodule that bothcreateSynapseandconnectimport from. Forces one ergonomic shape onto two consumers.useHostContextvsuseConnectHostContext). The two SDK surfaces stay distinct by design.