An MCP call can return a bounded observation immediately or accept an operation that continues in Lomi. An operationId is acknowledgement of admission, not proof that a command, write, upload or installation finished.
Result envelope
Section titled “Result envelope”The server returns standard MCP content, structuredContent and isError. Structured Lomi replies use controlApiVersion: "1.0", status: "ok" with typed data, or status: "error" with an error code and message. PNG captures also include a standard MCP image block with MIME type image/png.
Illustrative error response inside structuredContent:
{ "controlApiVersion": "1.0", "status": "error", "code": "PAIRING_REQUIRED", "message": "Approve the pending session in Lomi Settings."}An operation can settle as failed or outcome_unknown in a successful read of its receipt. Inspect the receipt’s state, effectState and typed result; isError: false alone does not prove the effect succeeded. The catalog JSON includes each tool’s complete output schema.
Identity and revision fields
Section titled “Identity and revision fields”| Field | Meaning |
|---|---|
workspaceId, projectId, panelId |
Explicit authorized targets; never infer access from focus or a display name. |
terminalSessionId, browserGeneration, generation |
The exact current terminal/browser/Android runtime. A retained panel can outlive one runtime. |
leaseId |
Temporary input authority for the owned runtime. It expires on relevant takeover/revoke. |
expectedRevision |
Usually the decimal domainRevision from a fresh workspace/panel list for layout mutations. Some read/export APIs use this name for their own snapshot; follow that tool’s schema. |
expectedBufferRevision, documentId |
The exact shared editor document and text revision. |
expectedDiskRevision |
SHA-256 of exact file bytes, including original encoding/line endings. |
expectedParentRevision, expectedDirectoryRevision, expectedEntryRevision |
The relevant observed directory or entry, not the layout counter. |
expectedSettingsRevision, expectedConversationRevision, expectedDraftRevision |
Compare-and-set tokens for the matching settings section or saved Chat state. |
navigationId, snapshotId, elementRef, frameId |
Browser document and snapshot-scoped target identity; references are not selectors reusable forever. |
retryEpoch, requestKey |
Durable request identity, where required by the tool. |
inputSequence |
Decimal ordered input counter. Same sequence and exact payload acknowledge the prior dispatch rather than sending again. |
Schema input names use camelCase. Unknown fields are rejected. Union inputs require one supported variant; a field’s optionality does not remove conditional runtime requirements. Schemas describe shape, while native validators also enforce narrower ranges, permissions and resource state. Do not add common fields to tools that do not accept them.
Make and monitor a mutation
Section titled “Make and monitor a mutation”For example, creating a terminal:
- Call
lomi_workspace_list, thenlomi_connectfor the approved workspace. Obtain a currentdomainRevisionfrom the workspace/panel listing. - Call
lomi_terminal_createusing real values in place of the placeholders below. - Call
lomi_operation_getwith itsoperationIduntil it settles. Keep the terminal session and lease from the confirmed result. - Refresh layout observations before a later operation that requires the current domain revision.
Arguments for lomi_terminal_create:
{ "workspaceId": "WORKSPACE_ID", "cwdRelative": "", "title": "Tests", "expectedRevision": "CURRENT_DOMAIN_REVISION", "retryEpoch": "RETRY_EPOCH_FROM_CONNECT", "requestKey": "create-test-terminal-1"}Arguments for lomi_operation_get:
{ "operationId": "OPERATION_ID_FROM_CREATE"}lomi_events_read offers a bounded feed of operation-state metadata in an approved workspace. Continue with its cursor even if a page is empty. It is not a terminal-output stream, a general UI event subscription or proof of effect by itself.
Operation states
Section titled “Operation states”state |
Interpretation |
|---|---|
queued |
Accepted and durably recorded; waiting for dispatch. |
awaiting_user |
Needs the native decision shown in Lomi. |
running |
Work dispatched; inspect progress/result when available. |
cancelling |
Cancellation requested; effects may already exist. |
succeeded |
The tool’s specified postcondition was confirmed. |
failed |
Failed; inspect partial effects and the concrete failure. |
cancelled |
Settled after cancellation; this does not mean rollback. |
outcome_unknown |
Lomi cannot establish the final effect. Inspect the actual resource. |
effectState is separately none, partial, complete or unknown. For example, saving dirty files during a workspace-close guard can leave the workspace open with partial effects. A browser upload can succeed at attachment/event dispatch without proving a server accepted the file. Android launch can confirm intent delivery without proving the screen you expected appeared.
Retry identity
Section titled “Retry identity”The native receipt key binds the pairing, retry epoch, project, tool and request key. The fingerprint also binds the exact payload, target generation and relevant revision. A duplicate with the same identity and arguments returns the prior operation. Changed arguments under that identity return IDEMPOTENCY_CONFLICT.
If a reply is lost, preserve the entire original request, including its revision. Retrieve it by operationId or by its key:
{ "retryEpoch": "ORIGINAL_RETRY_EPOCH", "requestKey": "create-test-terminal-1", "tool": "lomi_terminal_create"}Include the original anchor projectId in key lookup when the connection has more than one approved project. Once the original effect is understood, an intentionally different operation uses a fresh key and fresh observations. Never generate a new key merely to bypass uncertainty or a denial.
Retry epochs have a 24-hour validity window and are also tied to the running broker instance and connection. Restarting does not resume old authority. Receipts are retained locally but do not authorize replay or disclose another connection’s results.
Terminal input deduplication uses the lease and inputSequence rather than the durable request-key pattern. Android input likewise uses an ordered sequence and its specified retry fields. Check each schema; these session-only input histories are not restart recovery.
Cancellation and restart
Section titled “Cancellation and restart”lomi_operation_cancel cancels queued work or requests cancellation of running work. It cannot undo a completed save, Git change, upload, process start or provider send. Sending Ctrl+C through lomi_terminal_interrupt confirms dispatch of the interrupt, not shell/process exit; monitor the original command.
Before dispatch, Lomi reserves a receipt in its private SQLite store. Failure to persist the reservation blocks the effect. WAL/FULL synchronization and guarded transitions preserve uncertainty across failures. On store reopening, unfinished operations become outcome_unknown; they are never replayed automatically.
The store admits at most 4,096 receipts and 4,096 retry epochs. Expired records are not automatically removed. RESOURCE_EXHAUSTED requires deliberate reconciliation/maintenance; reconnecting does not clear history. Preserve storage and inspect real resources using the recovery guide.
Source: protocol inputs and typed results, durable receipts, native dispatch permits.