Skip to content

Commit fe33d48

Browse files
committed
docs: add detailed execute_cell security paradigm to ARCHITECTURE.md
1 parent 2b61ae5 commit fe33d48

1 file changed

Lines changed: 139 additions & 0 deletions

File tree

notebook_mcp/ARCHITECTURE.md

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
# Notebook MCP Server - Architectural Design Rationale
2+
3+
This document outlines the design necessities, modes of operation, crucial architectural decisions, and limitations of the Notebook MCP server.
4+
5+
---
6+
7+
## Overview & Purpose
8+
9+
The Notebook MCP (Model Context Protocol) server acts as a bridge between Agentic AI capabilities and Jupyter Notebook operations (read, write, execute). Its primary goal is to allow AI agents to safely inspect, edit, and execute code within notebooks, whether running in a standalone local environment or deeply integrated with an active IDE session.
10+
11+
---
12+
13+
## Design Necessity: Zero-Config Static Distribution
14+
15+
One of the major necessities of this design is to ensure we can have a **simple, static `mcpserver` configuration** that we can ship directly with our Agent CLI plugins.
16+
17+
We plan to support plugins for various CLI agents, and in those plugins, the CLI agents only support static `mcpserver` configurations. Automating environment setups for end users requires that they do not need to clone repositories manually or configure absolute system paths. The desired configuration looks like this:
18+
19+
```json
20+
"notebook-tools": {
21+
"command": "npx",
22+
"args": [
23+
"-y",
24+
"github:gemini-cli-extensions/data-cloud-extension"
25+
]
26+
}
27+
```
28+
29+
### How Our Solution Solves This
30+
To support this static configuration running via `npx` (which downloads the code to a random sandbox cache directory), we:
31+
1. **Bundled the Proxy:** We placed the compiled `mcp_proxy_bundle.cjs` directly inside the repository (`notebook_mcp/bin/`).
32+
2. **Relative Path Resolution:** The server computes the path to the proxy dynamically using `import.meta.url` (ESM mode).
33+
This allows the server to find its own resources inside the random `npx` cache without any absolute path strings being passed from the host machine.
34+
35+
---
36+
37+
## Modes of Operation
38+
39+
The server supports two distinct modes depending on how the CLI agent is being executed:
40+
41+
### 1. CLI Agent running in a Standalone Terminal
42+
* **Context:** The user opens a normal terminal and runs the agent. No IDE extension is wrapping the execution.
43+
* **Tools Served:** The server serves **Standalone Tools**. These tools directly read and write `.ipynb` files on the disk using Node filesystem APIs.
44+
* **Scope:** Can only target saved files. Cannot see or manipulate unsaved memory buffers in an IDE tab.
45+
46+
### 2. CLI Agent running in an IDE's Terminal
47+
* **Context:** The user triggers the agent from within an extension tab or a terminal spawned by the IDE (like VS Code, Antigravity, or Jetski).
48+
* **Tools Served:** The server serves **Proxied Tools**. It acts as a client to a domain socket/named pipe opened by the IDE extension, forwarding all tool calls to the IDE.
49+
* **Scope:** Powerful. Can see unsaved changes in active tabs, trigger executions in the IDE kernel, and interact with visual elements.
50+
51+
---
52+
53+
## Key Features & Tools
54+
55+
The server exposes a rich set of tools for notebook manipulation:
56+
* **Cell CRUD Operations:** Add, update, delete, and list cells in a notebook.
57+
* **Content Inspection:** Retrieve the full content of specific cells or the entire notebook.
58+
* **Execution (IDE Mode only):** Trigger execution of cells and capture results via the IDE's active kernel.
59+
60+
---
61+
62+
## Resilience Standalone Fallback
63+
64+
To ensure the agent always has access to tools, the server implements a fallback mechanism:
65+
* When triggered in IDE mode, it attempts to connect to the IDE's domain socket.
66+
* It retries **5 times** with a **1-second delay**.
67+
* If the connection fails (e.g., extension not yet loaded or IDE not running), it **automatically falls back** to serving the Standalone Tools over stdio.
68+
* This guarantees a zero-freeze experience for the user.
69+
70+
---
71+
72+
## 🔒 Limitations of Standalone Mode
73+
74+
Users and developers must be aware of the strict boundaries of the Standalone Mode:
75+
* **No IDE API Access:** Standalone tools run purely at the filesystem child-process level. They have **no access to VS Code or IDE platform APIs**.
76+
* **Saved Files Only:** They cannot read or write to unsaved memory buffers in the user's editor. They only process the **last saved copy** found on disk. Unsaved edits in the IDE will be invisible to the standalone tools until the user saves them.
77+
78+
---
79+
80+
## Crucial Design Decisions
81+
82+
### Decision 1: Target Detection (Process Tree vs Env Vars)
83+
84+
To decide whether to connect to the socket (IDE mode) or fall back to standalone file manipulation.
85+
86+
* **Option A: Process Tree Inspection**
87+
* **Pros:** Theoretically zero-config; doesn't rely on terminal environment inheritance.
88+
* **Cons:** Fragile. Deeply complex to match random wrapper shell names. Fails if intermediate tools obscure the process ancestry.
89+
* **Option B: Environment Variables**
90+
* **Pros:** 100% accurate. Simple. Zero overhead.
91+
* **Cons:** Relies on the host IDE extension putting the environment variables (like `DATA_CLOUD_CURR_IDE_NAME`) into the spawned terminal session.
92+
* **Choice:** **Environment Variables**. Since our IDE extension natively spawns the agent terminals, it easily feeds the required indicator tag. We fell back to Standalone Mode if the variable was missing.
93+
94+
### Decision 2: Location of the Proxy Bundle
95+
96+
How should the server locate the `mcp_proxy_bundle` script needed to connect to the socket?
97+
98+
* **Option A: Read from the local machine path (passed by env var)**
99+
* **Pros:** Ensures the proxy matches exactly the version of the extension installed on the machine.
100+
* **Cons:** Breaks zero-config `npx` setups. Requires the extension to find its own installation path and pass it down.
101+
* **Option B: Bundle the Proxy in the Repository**
102+
* **Pros:** Completely self-contained. Works immediately with `npx` retrieval.
103+
* **Cons:** Requires engineering to maintain synchronization between the extension changes and repository commits.
104+
* **Choice:** **Bundle in the Repository**. The benefit of instant zero-configuration execution via `npx` outweighed the burden of occasional synchronization maintenance.
105+
106+
---
107+
108+
## Security Constraints
109+
110+
* **No Process Scanning:** The server does not scan the host machine's process tree for forensics, protecting system privacy and avoiding environment permission blocks.
111+
* **Isolated Env Tags:** It strictly obeys the isolated environment variables explicitly declared and passed to it by the IDE.
112+
113+
### Security of `execute_cell` Tool
114+
115+
The `execute_cell` tool involves running code on the user's compute resources, requiring a strict security paradigm:
116+
117+
* **IDE Exclusive:** The standalone MCP server does **not** offer this tool. It is exclusively provided by the MCP server running in the IDE through the Data Cloud extension.
118+
* **Server-Side Enforcement:** Operations obey all security checks put in place on the server side by the Data Cloud extension.
119+
* **Opt-In by Default:** The tool is **disabled by default** and not served by the MCP server to its clients until the user manually enables it in the extension setting panel.
120+
* **Runtime Verification:** The server checks for this enablement setting even when running the tool! If a tool is disabled after being enabled (and the user did not refresh the window for the tool to be formally removed from the served registry), the tool will actively refuse execution.
121+
* **Explicit Elicitation (User Consent):**
122+
* We support **elicitation** for the `execute_cell` tool on a best-effort basis (depending on MCP client compatibility).
123+
* **Client Compatibility:** If the third-party MCP client does not support prompt/consent elicitation bridges, the tool will **not work**.
124+
* **Forced Consent Prompts:** If the client supports elicitation, the system will ask for **explicit user consent** each time it is called by the agent (even if the agent is operating in autonomous "YOLO" mode).
125+
* **Override Toggle:** There is a secondary toggle setting in the extension that can be used to disable these forced execution elicitations. However, elicitations are strictly **on by default**.
126+
127+
---
128+
129+
## Development & Maintenance Guide
130+
131+
### Building the Bundle
132+
The project uses `esbuild` to compile `server.ts` into a single executable file at `dist/index.js`.
133+
```bash
134+
npm run bundle
135+
```
136+
137+
### ESM vs CommonJS
138+
* The server uses **ESM (ES Modules)** for cleaner modern execution chains and deterministic mapping via `import.meta.url`.
139+
* The bundled proxy (`mcp_proxy_bundle.cjs`) retains **CommonJS** mapping using Node's `.cjs` instruction override to prevent evaluation collisions in Node's module system.

0 commit comments

Comments
 (0)