From ae0ef563e9aa2f2cf39ebee4fd595e28e8d436f9 Mon Sep 17 00:00:00 2001 From: iamdoubz <> Date: Tue, 7 Jul 2026 00:32:22 -0500 Subject: [PATCH] feat(mcp): frontend AppSettings/McpStatus types for the new fields (T10.4) Adds mcp_transport/mcp_port/mcp_expose/mcp_expose_recordings to AppSettings and a typed McpStatus for mcp_status()'s response; types onMcpAccess's payload correctly (the live event is camelCase per docs/04-api-contracts.md, unlike the snake_case McpAccessEntry rows mcpAccessLog() returns). --- src/lib/api.ts | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/lib/api.ts b/src/lib/api.ts index bd734b6..428d998 100644 --- a/src/lib/api.ts +++ b/src/lib/api.ts @@ -289,6 +289,10 @@ export interface AppSettings { consent_acknowledged: boolean; sync_enabled: boolean; mcp_enabled: boolean; + mcp_transport: string; // http|stdio + mcp_port: number; + mcp_expose: string; // none|selected|all + mcp_expose_recordings: boolean; retention_max_age_days: number | null; retention_max_size_gb: number | null; pst_last_path: string | null; @@ -325,6 +329,15 @@ export interface McpAccessEntry { client: string | null; } +// mcp_status() response (FR-MCP-1/6). `endpoint` is empty while disabled. +export interface McpStatus { + enabled: boolean; + transport: "http" | "stdio"; + endpoint: string; + tokenSet: boolean; + exposeScope: "none" | "selected" | "all"; +} + // ---- Commands ---- export const api = { // `record` controls audio RETENTION (default false / off — ADR-0009). @@ -455,7 +468,7 @@ export const api = { getFeatureBrief: (id: string) => invoke("get_feature_brief", { id }), setBriefExposed: (id: string, exposed: boolean) => invoke("set_brief_exposed", { id, exposed }), - mcpStatus: () => invoke("mcp_status"), + mcpStatus: () => invoke("mcp_status"), setMcpEnabled: (enabled: boolean, transport?: "http" | "stdio", port?: number) => invoke<{ endpoint: string; token: string }>("set_mcp_enabled", { enabled, transport, port }), setMcpScope: (expose: "none" | "selected" | "all", exposeRecordings?: boolean) => @@ -538,8 +551,11 @@ export const events = { onSyncLinked: ( cb: (p: { ok: boolean; kind: string; error?: string }) => void, ): Promise => listen("sync://linked", (e) => cb(e.payload as never)), - onMcpAccess: (cb: (p: McpAccessEntry & { client?: string }) => void): Promise => - listen("mcp://access", (e) => cb(e.payload as never)), + // Live tail of the FR-MCP-5 audit log (camelCase on the wire, unlike the + // snake_case McpAccessEntry rows `mcpAccessLog()` returns). + onMcpAccess: ( + cb: (p: { at: number; tool: string; meetingId?: MeetingId; client?: string }) => void, + ): Promise => listen("mcp://access", (e) => cb(e.payload as never)), onAgentProgress: ( cb: (p: { briefId: string; tool: string; line: string }) => void, ): Promise => listen("agent://progress", (e) => cb(e.payload as never)),