Skip to content

AI Bridge Control

MasterSelects exposes its live in-app AI tool surface to local external agents through an authenticated development bridge. The bridge is intended for debugging, parity checks, and controlled automation: an external client can inspect the same tool schemas offered to FlashBoard Chat, execute tools through the browser, and inspect resulting history.

Codex or another MCP client
|
| stdio MCP
v
scripts/masterselects-mcp.mjs
|
| authenticated HTTP
v
Vite /api/agent-control
|
| targeted Vite HMR request
v
Selected MasterSelects browser tab
|
+-- FlashBoard Chat tool executor
+-- AI tool dispatcher and policy registry
+-- browser AI-tool audit and project chat history

The browser is the execution authority. The HTTP server does not reproduce editor state or tool behavior, so bridge calls observe the same currently loaded project and state as the selected browser tab.

  • Run the MasterSelects Vite development server at http://localhost:5173.
  • Keep at least one editor tab open. The browser client announces bridge presence at registration and then every three seconds.
  • Keep .ai-bridge-token private. The MCP adapter reads it directly and does not expose it as a tool result.
  • Restart Codex after adding or changing the MCP registration so it reloads the server configuration.

The checked-in .mcp.json registers the adapter for clients that support project-local MCP configuration. A matching personal Codex registration can run:

node scripts/masterselects-mcp.mjs

Environment variables:

VariableDefaultPurpose
MASTERSELECTS_BRIDGE_URLhttp://localhost:5173Vite bridge base URL
MASTERSELECTS_BRIDGE_SURFACEchatDefault execution surface: chat or devBridge
MASTERSELECTS_BRIDGE_SESSION_IDnoneInitial target session
MASTERSELECTS_BRIDGE_TOKEN_FILEproject .ai-bridge-tokenAlternate token file
MASTERSELECTS_BRIDGE_TIMEOUT_MS60000Default request timeout

The MCP server publishes the current FlashBoard Chat tools with their exact live JSON schemas. It also provides these control tools:

ToolPurpose
bridge_list_sessionsList connected browser tabs and their project/chat metadata
bridge_select_sessionSelect the tab used by subsequent direct calls
bridge_list_toolsRead the live tool registry for either surface
bridge_get_tool_schemaInspect one live schema and policy
bridge_call_toolExecute a named tool, optionally as a dry run
bridge_send_chat_messageSubmit a prompt through the real visible FlashBoard chat and wait for its terminal result
bridge_set_chat_model_classSwitch the visible chat speed selector between Very Fast, Fast, and Slow without sending a prompt
bridge_get_historyMerge current project chat calls, browser audit calls, and bridge traces
bridge_get_tool_resultRead the stored details of one call
bridge_replay_tool_callReplay a stored call with optional replacement arguments

Direct MCP calls to a published editor tool use the chat surface by default. That route invokes the FlashBoard Chat tool executor. The devBridge surface instead invokes the policy-filtered AI tool dispatcher.

dryRun: true resolves the target session, reads the selected tool schema and policy, and does not execute the tool. It does not invoke a model or validate the tool arguments. Direct devBridge calls require confirm: true when policy marks the tool as mutating, sensitive, or local-file access.

The development surface includes three UI/API inspection helpers:

ToolPurpose
captureAppScreenshotCapture the connected app viewport or full scrolling document as a bounded PNG; browser chrome and operating-system UI are excluded
clickAppControlClick one visible control by accessible text or a specific CSS selector, then wait for UI work to settle
probeSameOriginRequestMake a credentialed same-origin /api/ request in the selected tab and return bounded, redacted status/error data

Always select and pass an explicit sessionId when several tabs are connected. These helpers are restricted to devBridge, console, and internal callers. Screenshot and same-origin data are treated as sensitive bridge access, so direct calls must include the confirmation required by the resolved policy. Durable traces omit embedded image data and redact secret-like response fields.

All routes are under /api/agent-control and require the same bridge token accepted by /api/ai-tools.

MethodRoutePurpose
GET/sessionsConnected browser sessions
GET/tools?surface=chatLive tool list
GET/tools/:name?surface=chatOne tool schema
GET/history?sessionId=...&limit=500Merged history
GET/calls/:callId?sessionId=...One stored result
POST/callExecute or dry-run a tool
POST/chatSubmit a prompt through the visible chat controller
POST/chat/model-classSwitch the visible chat speed selector
POST/replayReplay a stored call

Example request body:

{
"sessionId": "opaque-tab-id",
"surface": "chat",
"tool": "getTimelineState",
"args": {},
"dryRun": false,
"idempotencyKey": "debug-read-001"
}

Explicit unknown or stale session IDs fail instead of silently targeting another tab.

POST /chat and bridge_send_chat_message use the selected tab’s current model class and Auto/Co-direct setting. Tests may provide requestedModelClass (very-fast, fast, or slow) explicitly; that also updates the visible selector before the prompt runs. POST /chat/model-class and bridge_set_chat_model_class switch the same UI selector without sending a prompt. The prompt is inserted into the normal visible chat history and follows the same hosted-agent, cancellation, and timeline-edit path as clicking the Chat button.

The in-app FlashBoard chat uses prompt version v2 and records its own runs in browser IndexedDB. Bridge history exposes current FlashBoard chat messages and executed tool calls, browser AI-tool audit records, and bridge traces.

Long inspection tool responses are bounded by their tool implementations:

  • getClipAnalysis returns a summary by default; use includeFrames, a source-time range, offset, and limit for details.
  • getClipTranscript returns a bounded word page with hasMore and nextOffset continuation metadata.

The history response keeps three sources distinct:

  • project: tool calls stored in the current FlashBoard chat messages;
  • audit: central browser-side records for in-app and bridge-triggered AI tool execution;
  • bridgeCalls: durable JSONL traces created by HTTP/MCP bridge requests.

FlashBoard chat runs are stored separately in browser IndexedDB (masterselects-ai-chat-runs). They contain source, session/project, provider/model, prompt version, system prompt, request prompt, response, tool calls/results, execution mode, status, and timing.

Audit and bridge records include source, caller context, session, timing, policy snapshot, arguments, status, result, replay origin, and idempotency key where applicable. Secret-like fields are redacted, and embedded base64 images are omitted from durable traces. MCP returns a discovered image as image content instead of duplicating its data in structured output.

An idempotencyKey is scoped to the resolved browser session and returns an existing trace for retries. Replays keep a link to the original call. On the devBridge surface, mutating or sensitive calls require explicit confirm: true as determined by tool policy.

  • This control plane is attached to the local Vite development bridge; it is not a hosted production API.
  • A browser tab must remain connected because the real editor state and dispatcher live in the browser.
  • Hosted Cloudflare/D1 chat logs are a separate data source and are not silently merged into local project history.
  • A timeout stops waiting on the HTTP side but cannot forcibly cancel browser work that has already started. Use idempotency keys for safe retries.
  • The Vite bridge supports multiple connected browser sessions: it prefers a focused visible tab when no session is requested, and direct callers can select an explicit session. Native Helper exposes a separate local bridge and is not routed through these endpoints.