Understanding the Gateway Runtime Architecture for the OpenWork Desktop Application
The OpenWork desktop application uses a three-layer gateway runtime architecture built on Electron that bridges the UI renderer process with cloud backends through a local HTTP server, enabling offline-capable, sandboxed operation.
The gateway runtime architecture serves as the central nervous system of the OpenWork desktop client (from the different-ai/openwork repository), acting as a local proxy between the Electron-based frontend and remote services including the OpenWork Den cloud, MCP tools, and local plugins. This design abstracts network complexity behind a stable, versioned API surface while maintaining the ability to run entirely offline.
Three-Layer Gateway Architecture
The gateway consists of three tightly coupled layers that handle everything from process lifecycle management to request routing and configuration merging.
1. Electron Main Process (Host Runtime)
The Electron main process acts as the host runtime that bootstraps the entire gateway stack. Located in dev/apps/server/src/server.ts, this layer initializes the local server and maintains a runtime-config store accessible to the UI renderer.
Key responsibilities include:
- Calling
createRuntimeServer()to initialize the runtime environment - Launching the gateway HTTP server via
startGateway()on a dynamically assigned local port - Watching file-system changes and forwarding IPC messages to the renderer
- Maintaining the runtime configuration state that persists across sessions
2. Gateway HTTP Server (API Surface)
The core networking layer is a lightweight Express/Koa-style HTTP server implemented in dev/ee/apps/den-gateway/src/app.ts. This local server exposes a minimal API surface that the desktop UI and MCP tools consume.
Critical endpoints include:
/api/runtime-config– Returns the current runtime configuration including active workspace, organization mode (single_orgvsmulti_org), and enabled providers/v1/cloud/gateway/resolve– Resolves requests to appropriate remote Den or MCP endpoints, validating theX-OpenWork-Gateway-Keyheader for authentication/__gw/healthand/__gw/ready– Health-check endpoints that enable the Electron process to detect crashes and trigger automatic restarts
3. Runtime Config & Provider Merge Layer
The configuration management layer merges local workspace state with cloud-side (Den) configuration to present a unified view to the UI. This implementation resides primarily in dev/apps/server/src/runtime-opencode-config-store.ts, with merge logic tested in dev/apps/server/src/runtime-config-global-providers.test.ts.
This layer ensures that MCP tool calls route through the gateway rather than hitting the network directly, allowing the desktop to function in-process or offline without modification to the calling code.
How the Gateway Runtime Processes Requests
The architecture follows a strict initialization and request flow:
-
Bootstrap Phase: When the desktop app launches, the Electron main process imports
server.tsand executescreateRuntimeServer(), followed bystartGateway({ port: 0, runtimeStore: server.store })to bind to a random local port. -
Configuration Discovery: The renderer process queries
http://localhost:PORT/api/runtime-configto retrieve the active workspace ID, organization mode, and provider list from the runtime-config store. -
Tool Invocation: When the UI or plugins need to execute MCP tools (such as LLM completions or cloud service calls), they POST to
/v1/cloud/gateway/resolvewith theX-OpenWork-Gateway-Keyheader. The gateway validates the header and forwards the request to the appropriate remote endpoint, injecting necessary authentication tokens. -
Health Monitoring: The Electron process polls
/__gw/healthand/__gw/readyto monitor gateway status. If the server becomes unresponsive, the main process terminates and restarts the gateway automatically.
Code Implementation Examples
Starting the gateway from the Electron main process:
// dev/apps/server/src/server.ts (excerpt)
import { createRuntimeServer } from "./runtime-opencode-config-store";
import { startGateway } from "./gateway";
// Electron main process calls:
const server = await createRuntimeServer({ /* options */ });
await startGateway({ port: 0, runtimeStore: server.store });
Fetching runtime configuration from the UI renderer:
// UI (renderer) – using fetch
const resp = await fetch("http://localhost:PORT/api/runtime-config");
const config = await resp.json(); // { workspaceId, orgMode, providers, ... }
Resolving an MCP tool call through the gateway:
// UI – making a tool call
await fetch("http://localhost:PORT/v1/cloud/gateway/resolve", {
method: "POST",
headers: { "X-OpenWork-Gateway-Key": "my-secret-key" },
body: JSON.stringify({ tool: "llm/completion", args: { model: "gpt-4" } })
});
Key Design Benefits
The gateway runtime architecture provides several architectural advantages:
- Offline Capability: Because the gateway runs locally, the desktop application can queue requests and execute MCP tools using local resources when network connectivity is unavailable.
- Sandboxed Execution: The local HTTP proxy isolates the renderer process from direct network access, enforcing security policies at the gateway layer before requests reach external services.
- Testing Support: The architecture supports mock server implementations (referenced as
enterprise-mcp-mock-serverin the codebase), enabling reliable CI/CD pipelines without cloud dependencies. - Version Stability: The UI communicates with a stable local API rather than directly coupling to cloud service contracts, allowing backend changes without desktop client updates.
Summary
- The Electron main process (
dev/apps/server/src/server.ts) bootstraps the gateway and manages the runtime-config store. - The gateway HTTP server (
dev/ee/apps/den-gateway/src/app.ts) exposes local endpoints for configuration retrieval, tool resolution, and health monitoring. - The provider merge layer (
dev/apps/server/src/runtime-opencode-config-store.ts) unifies local and cloud configuration while routing MCP calls through the gateway. - This architecture enables the OpenWork desktop application to operate as a local HTTP proxy, supporting offline modes, sandboxed execution, and reliable testing environments.
Frequently Asked Questions
What is the role of the Electron main process in the OpenWork gateway architecture?
The Electron main process serves as the host runtime that initializes the entire gateway stack. It calls createRuntimeServer() and startGateway() from dev/apps/server/src/server.ts to spawn the local HTTP server, manages the runtime-config store, watches for file-system changes, and handles automatic restarts if the gateway becomes unresponsive.
How does the gateway handle authentication for cloud requests?
Authentication is handled at the /v1/cloud/gateway/resolve endpoint in dev/ee/apps/den-gateway/src/app.ts. The gateway inspects the X-OpenWork-Gateway-Key header (defined in the source as gatewayKeyHeader) to validate incoming requests before forwarding them to remote Den or MCP endpoints, ensuring that only authenticated traffic reaches cloud services.
Can the OpenWork desktop application function without an internet connection?
Yes. Because the gateway runtime operates as a local HTTP proxy, it can route MCP tool calls to local implementations or queue requests for later synchronization. The architecture supports offline operation by merging local workspace state with cached cloud configuration, allowing users to continue working without direct network access.
Where is the gateway HTTP server implementation located in the codebase?
The concrete implementation of the gateway HTTP server resides in dev/ee/apps/den-gateway/src/app.ts. This file contains the Express/Koa-style server logic, endpoint definitions for /api/runtime-config and /v1/cloud/gateway/resolve, and the health-check handlers at /__gw/health and /__gw/ready.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →