Skip to content
docs
GitHub

MCP architecture

The headless helper, authenticated broker, native adapters, UI bridge and built-in Chat integration.

Lomi separates MCP protocol handling, authorization and durable operations, and desktop resource execution. The same broker serves external clients and built-in Chat AI. Setup covers user-facing connection steps.

Component Responsibility Primary source
Application entry point Detect --mcp before GUI startup and run the headless server. src-tauri/src/main.rs
lomi-mcp rmcp stdio server, 74-tool catalog, schema parsing, MCP result/image encoding and native Chat bridge. src-tauri/crates/lomi-mcp/src/
lomi-control-protocol Closed request/result types, domain contracts, errors, Control API 1.0 and IPC version 1. src-tauri/crates/lomi-control-protocol/src/
lomi-control-core Signed discovery, authenticated client/broker, session grants, leases, receipts, cancellation and domain authorization. src-tauri/crates/lomi-control-core/src/
Native application adapter Host gate, startup preferences, broker lifetime, trusted approval commands and runtime dispatch callbacks. src-tauri/src/agent_control.rs
Workbench bridge Publish current domain identity, claim/acknowledge authorized UI operations, retain runtime/buffer state and apply existing guards. src/agent-control.ts, src/agent-*.ts
Settings UI Register clients, approve pairing/effects, inspect/revoke sessions, startup and YOLO preferences. src/AgentControlSettingsPage.tsx, src/AgentControlPairing.tsx, src/McpClientsSettings.tsx
Resource adapters Existing PTYs, browser child views, scoped files/editor/Git, managed Android and native Chat. src-tauri/src/{terminal,browser,files,android,chat}/, retained frontend runtimes

The helper owns no application terminal, browser or emulator. Catalog discovery does not grant resource access. Before pairing, status/diagnostics report connection state without disclosing workspace data.

The MCP host starts either the application with --mcp and signed-discovery arguments or the optional standalone lomi-mcp with direct instance arguments. Standard MCP messages use newline-delimited JSON-RPC over stdin/stdout. Diagnostics use stderr. The server advertises tools; it does not register a separate MCP resource/prompt catalog.

The broker runs inside the desktop application. On the qualified host, it binds a Unix-domain socket in a private temporary directory (0700), with socket mode 0600. It is not a public TCP/HTTP service. Application-owned discovery and durable state live beneath the app-data agent-control directory.

  1. Automatic registration pins the public half of a persistent Ed25519 registration key in the client’s command arguments.
  2. Lomi publishes discovery.json containing a signed endpoint payload: socket path, instance ID, broker certificate SHA-256 and IPC version.
  3. The helper checks the descriptor signature, ownership, permissions, file type and bounds before trusting the endpoint. The public pin alone does not authorize a client.
  4. Enrollment uses same-user peer checks and fresh session certificate identities. Settings exposes the pending request ID/certificate identity for explicit approval, or the saved YOLO policy approves it automatically.
  5. The approved connection exchanges framed requests over mutually authenticated TLS 1.3 on the local socket. Trust is pinned to the approved identities; early data and TLS session resumption are disabled.

Changing the endpoint does not require editing a valid signed registration. Changing the executable or registration identity does. A restart creates a new instance and invalidates connection authority; automatic discovery does not transparently resume a paired session.

The main workbench publishes a projection containing a UI epoch, domain revision and stable project/workspace/panel identities. It is an authorization input and routing view, not a second independently persisted layout.

The broker admits requests only for the connection’s current grant. It rechecks scopes, resource ownership, generation, revisions, limits and cancellation at relevant admission/dispatch/read boundaries. Native effect permits have expiry and revocation state. Approvals bind exact immutable plans and cannot be supplied by arbitrary MCP arguments.

Some work is purely native, such as bounded pinned file reads, storage reservations and device lifecycle. UI-dependent work uses a one-use claim/commit/acknowledgement bridge to the existing workbench. This preserves shared editor undo, running PTYs, browser/device generations and dirty-file close guards. Re-registering the workbench invalidates old authority rather than accepting stale renderer acknowledgements.

Only trusted application views may issue application commands. Browser child webviews report their own scoped events and cannot invoke the main/Settings privileged command set. Settings owns permission decisions; the workbench owns layout and live UI runtime coordination.

control.sqlite3 stores retry epochs, operation receipts/transitions and artifact reservations. An interprocess owner lock prevents competing owners of the same store. SQLite uses WAL with FULL synchronization and native full-fsync settings. Startup validates WAL integrity before opening; it preserves corrupt/unsupported storage rather than starting with an empty history.

Reservations precede effects. Duplicate identity plus an exact fingerprint returns the existing receipt; failed persistence prevents dispatch. After reopening, unfinished receipts become uncertain, not queued for replay. Persistence records what Lomi knows; it is not a transaction that can roll back external effects.

Leases, input sequence histories and native runtime ownership are session state. Artifacts retain immutable bytes plus original source classification; read/export rechecks that source. See operations for states, expiry and admission budgets.

The built-in Chat route uses the same native lomi-mcp catalog/parser/result encoder and authenticated Client, without spawning a separate stdio helper for each conversation.

  1. The native Chat backend retains a ChatSession for a conversation and broker endpoint. A reused, nonrevoked session can survive consecutive turns and view remounts.
  2. The backend supplies the catalog and origin guidance to the bundled AI runtime. Origin project/workspace IDs are guidance; they do not grant access.
  3. The AI runtime wraps schemas as AI SDK tools, forwards tool-call IDs/arguments through its native process protocol and converts text/structured/image results into provider model content.
  4. The native backend validates the call against the trusted catalog, bounds it and dispatches through the conversation’s retained authenticated MCP session.
  5. With YOLO off, Lomi Chat AI … appears as its own pairing request in Agent control. It requires the same workspace/scopes as an external client.

The AI process cannot execute shell commands directly and does not accept webview-supplied MCP catalogs, broker endpoints or credentials. Cancellation/revocation is handled natively. Request budgets include 128 tool calls, 64 KiB arguments, 8 MiB per result and 16 MiB total results; calls are tracked so duplicate IDs or concurrent invalid dispatch cannot create another effect.

This is distinct from the lomi_chat_* tools, which let an authorized agent manage explicitly shared Chat conversations. Chat as an MCP client does not automatically receive Chat-history read/send permissions. There is no general UI for attaching arbitrary external MCP servers to this built-in route.

Boundary Current bound/behavior
Control API / private IPC 1.0 / 1
Internal frame Up to 8 MiB; metadata and handshake up to 64 KiB.
Tool arguments Up to 64 KiB before typed parsing; unknown fields rejected.
Tool results Typed schemas; standard PNG content when applicable.
Text positions UTF-16 scalar boundaries; file/editor line-ending sources differ.
Project file access Descriptor-pinned roots, NOFOLLOW traversal, exclusions for known secrets/links/special files.
Runtime identities Explicit IDs/generations; temporary input leases and stale-reference rejection.
Observations Bounded pages/snapshots with omission/gap/expiry metadata; not complete atomic application snapshots.

The workflows explain domain limits. Tool annotations such as read-only/idempotent/destructive are client hints, not access grants or guarantees that an uncertain operation is safe to repeat.

Reviewed on 30 September 2026 against lomi-dev/lomi HEAD 93f47d818fe66ffada123cf49853e6bc00804433, application source version 0.5.0. The source snapshot records SHA-256 values for 183 contract, broker, native/UI adapter and related evidence files; tools.json records the actual catalog and schemas from the built helper.

The reviewed working tree also contained uncommitted changes to src-tauri/src/cli_integrations.rs, src-tauri/src/cli_launch.rs and src-tauri/src/cli_mcp.rs, including Antigravity blank-file/hybrid-entry handling and terminal-safe shell discovery. Pinned GitHub links identify the committed baseline; snapshot hashes identify the exact reviewed bytes. This audit does not assert publication of those changes.

For this documentation review, the standalone helper was built, the three MCP/control Cargo package suites passed, and an independent JSON-RPC helper test passed for MCP protocol versions 2025-11-25 and 2026-07-28. The tests checked catalog/schema behavior, result encoding, grants, authenticated transport, deduplication, revocation and related core behavior. Optional full-disk, long idle and GUI/model probes were not executed in this review; the embedded-executable discovery probe was not configured.

The application repository separately retains a native acceptance record and qualification report. Those historical records include a macOS ARM64 20-task model gate with 60 complete passes in 67 attempts; retained failures and host-specific limits remain part of the evidence. They are not new tests performed by this documentation task, cross-platform qualification or installer/release certification.

Source: authentication, workbench bridge, native Chat bridge, Chat backend, AI tool adapter.