Open Science is an Electron desktop application built with React and TypeScript. Its internals are organized into four cooperating layers that carry a research task all the way from a researcher’s typed prompt to a durable, on-disk artifact: an interface layer that owns the browser window and renderer, an agent harness that manages the ACP protocol runtime, an execution and data plane that runs Python code and stores files, and a persistence layer that keeps project records and session state across app restarts.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/aipoch/open-science/llms.txt
Use this file to discover all available pages before exploring further.
The Four Architecture Layers
Interface Layer
Electron
BrowserWindow hosts the React renderer built from src/renderer/. The renderer owns every interactive surface — the home page, project and session sidebar, chat transcript, preview workbench, and permission dialogs. All renderer code runs in a sandboxed web context and communicates with the main process exclusively through the preload bridge.Agent Harness
src/main/acp/ contains the AcpRuntime class and the AcpPermissionBroker. The runtime owns the agent subprocess, speaks the Agent Client Protocol (ACP) over an ndJSON stream, and multiplexes one or more protocol sessions. The permission broker intercepts tool-call approval requests before they reach the agent and holds them until the researcher responds.Execution / Data Plane
src/main/notebook/ runs a persistent Python subprocess bridged over stdin/stdout. Each notebook session accumulates a durable run history. src/main/artifacts/ provides the ArtifactRepository that writes, validates, and moves agent-generated files through a pending → message lifecycle, together with the ArtifactRunRegistry that matches in-flight runs to renderer messages.Persistence
A Prisma/SQLite database (schema in
prisma/schema.prisma) stores Project and ProjectPreviewState records. All session data (messages, conversation history) lives on disk as JSON files under sessions/<projectId>/<sessionId>.json, managed by src/main/session-persistence/. Artifact files are stored as raw files on disk, not in SQLite.Preload Bridge
The renderer never imports Node.js or Electron APIs directly. Instead,src/preload/index.ts uses Electron’s contextBridge to expose a typed window.api object. Every renderer-initiated action — creating a session, sending a prompt, listing artifacts, approving a permission — is a call through window.api that crosses the process boundary as a named IPC channel.
On the main-process side, all IPC handlers are registered in a single call to registerIpcHandlers() from src/main/ipc.ts. That function wires together shared singletons — the ArtifactRepository, the ArtifactRunRegistry, the UploadRepository, and the notebook runtime service — so that the runtime and the renderer always reference the same in-memory state.
MCP Server Injection
Each ACP session receives two Model Context Protocol (MCP) servers injected at creation time so the agent can interact with the app’s managed storage and compute without being granted raw filesystem or process access.- Artifact MCP server (
open-science-artifacts) — exposes thewrite_artifact_filetool, which the agent calls to save any user-facing output file. The server validates filenames, resolves allowed import roots, and delegates writes to theArtifactRepository. It is launched by re-invoking the packaged main-entry bundle with a special--open-science-artifact-mcpflag. - Notebook MCP server — exposes code-execution tools the agent calls to run Python in the persistent kernel. It proxies requests to the app-owned notebook runtime service over a local RPC connection and is similarly launched from the same bundled entry point with
--open-science-notebook-mcp.
McpServer descriptors inside AcpRuntime.createMcpServers() and passed to connection.agent.buildSession() at session creation. The agent sees them as standard MCP capabilities and never needs to know they are actually child processes of the same Electron app.
Process Model
src/main/index.ts) detects at startup whether it has been invoked in MCP server mode (by checking process.argv for ARTIFACT_MCP_SERVER_ARG or NOTEBOOK_MCP_SERVER_ARG) and branches before any Electron import, keeping the MCP child processes lean and import-free.
Source Code Layout
| Directory | Role |
|---|---|
src/main/acp/ | ACP runtime, permission broker, agent process spawner, filesystem handlers |
src/main/artifacts/ | Artifact repository, run registry, MCP server, IPC handlers |
src/main/notebook/ | Notebook kernel, MCP server, local RPC server, IPC handlers |
src/main/projects/ | Project CRUD backed by Prisma/SQLite |
src/main/session-persistence/ | Per-project session JSON files, manifest, save queue |
src/main/uploads/ | Upload staging repository and IPC handlers |
src/main/storage-root.ts | Single dev/prod resolver for the app’s data root directory |
src/main/ipc.ts | Top-level IPC registration — wires all subsystems together |
src/main/index.ts | Entry point — routes between Electron app, artifact MCP, and notebook MCP modes |
src/renderer/ | React UI — home page, session workspace, preview workbench |
src/preload/ | contextBridge surface (window.api) |
src/shared/ | Type-only modules shared across the IPC boundary |
prisma/schema.prisma | SQLite schema for Project and ProjectPreviewState |