nebula-notebook-mcp 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/README.md +314 -0
  2. package/bin/nebula-mcp.js +10 -0
  3. package/dist/circuit-breaker.d.ts +157 -0
  4. package/dist/circuit-breaker.d.ts.map +1 -0
  5. package/dist/circuit-breaker.js +237 -0
  6. package/dist/circuit-breaker.js.map +1 -0
  7. package/dist/errors.d.ts +72 -0
  8. package/dist/errors.d.ts.map +1 -0
  9. package/dist/errors.js +314 -0
  10. package/dist/errors.js.map +1 -0
  11. package/dist/index.d.ts +13 -0
  12. package/dist/index.d.ts.map +1 -0
  13. package/dist/index.js +41 -0
  14. package/dist/index.js.map +1 -0
  15. package/dist/mcp/index.d.ts +8 -0
  16. package/dist/mcp/index.d.ts.map +1 -0
  17. package/dist/mcp/index.js +13 -0
  18. package/dist/mcp/index.js.map +1 -0
  19. package/dist/mcp/server.d.ts +31 -0
  20. package/dist/mcp/server.d.ts.map +1 -0
  21. package/dist/mcp/server.js +237 -0
  22. package/dist/mcp/server.js.map +1 -0
  23. package/dist/notebook/client.d.ts +643 -0
  24. package/dist/notebook/client.d.ts.map +1 -0
  25. package/dist/notebook/client.js +1720 -0
  26. package/dist/notebook/client.js.map +1 -0
  27. package/dist/notebook/index.d.ts +6 -0
  28. package/dist/notebook/index.d.ts.map +1 -0
  29. package/dist/notebook/index.js +6 -0
  30. package/dist/notebook/index.js.map +1 -0
  31. package/dist/notebook/tools.d.ts +244 -0
  32. package/dist/notebook/tools.d.ts.map +1 -0
  33. package/dist/notebook/tools.js +279 -0
  34. package/dist/notebook/tools.js.map +1 -0
  35. package/dist/tools/execution.d.ts +38 -0
  36. package/dist/tools/execution.d.ts.map +1 -0
  37. package/dist/tools/execution.js +116 -0
  38. package/dist/tools/execution.js.map +1 -0
  39. package/dist/tools/files.d.ts +70 -0
  40. package/dist/tools/files.d.ts.map +1 -0
  41. package/dist/tools/files.js +286 -0
  42. package/dist/tools/files.js.map +1 -0
  43. package/dist/tools/index.d.ts +74 -0
  44. package/dist/tools/index.d.ts.map +1 -0
  45. package/dist/tools/index.js +217 -0
  46. package/dist/tools/index.js.map +1 -0
  47. package/dist/tools/kernel.d.ts +36 -0
  48. package/dist/tools/kernel.d.ts.map +1 -0
  49. package/dist/tools/kernel.js +182 -0
  50. package/dist/tools/kernel.js.map +1 -0
  51. package/dist/tools/notebook.d.ts +252 -0
  52. package/dist/tools/notebook.d.ts.map +1 -0
  53. package/dist/tools/notebook.js +1089 -0
  54. package/dist/tools/notebook.js.map +1 -0
  55. package/dist/tools/types.d.ts +78 -0
  56. package/dist/tools/types.d.ts.map +1 -0
  57. package/dist/tools/types.js +8 -0
  58. package/dist/tools/types.js.map +1 -0
  59. package/dist/types.d.ts +473 -0
  60. package/dist/types.d.ts.map +1 -0
  61. package/dist/types.js +5 -0
  62. package/dist/types.js.map +1 -0
  63. package/dist/utils/imageResize.d.ts +24 -0
  64. package/dist/utils/imageResize.d.ts.map +1 -0
  65. package/dist/utils/imageResize.js +67 -0
  66. package/dist/utils/imageResize.js.map +1 -0
  67. package/dist/utils/polling.d.ts +40 -0
  68. package/dist/utils/polling.d.ts.map +1 -0
  69. package/dist/utils/polling.js +49 -0
  70. package/dist/utils/polling.js.map +1 -0
  71. package/package.json +61 -0
  72. package/setup-mcp.js +468 -0
package/README.md ADDED
@@ -0,0 +1,314 @@
1
+ # Nebula Notebook MCP Server
2
+
3
+ The Nebula MCP server allows Claude Code to interact with Jupyter-style notebooks programmatically through the Model Context Protocol.
4
+
5
+ ## Quick Start
6
+
7
+ ### 1. Make sure Nebula Notebook backend is running
8
+
9
+ ```bash
10
+ # Start the Nebula backend server (default: http://localhost:8000)
11
+ cd /path/to/nebula-notebook
12
+ npm run server
13
+ ```
14
+
15
+ ### 2. Automated setup (Recommended)
16
+
17
+ Run the interactive setup script to configure all detected clients:
18
+
19
+ ```bash
20
+ npm run setup-mcp
21
+ ```
22
+
23
+ **Supported tools** (auto-detected):
24
+ - Claude Code
25
+ - Claude Desktop
26
+ - Cursor IDE
27
+ - Gemini CLI
28
+ - Codex CLI
29
+ - VS Code / GitHub Copilot (workspace via `.vscode/mcp.json`)
30
+ - Antigravity (global config if present)
31
+
32
+ The setup script is idempotent and will skip configs that already contain the correct `nebula-notebook` entry.
33
+
34
+ ### 3. Manual setup (Claude Code example)
35
+
36
+ Add to your `~/.claude.json`:
37
+
38
+ ```json
39
+ {
40
+ "mcpServers": {
41
+ "nebula-notebook": {
42
+ "command": "node",
43
+ "args": ["/path/to/nebula-notebook/packages/mcp/bin/nebula-mcp.js"]
44
+ }
45
+ }
46
+ }
47
+ ```
48
+
49
+ **Important Configuration Notes:**
50
+ - ✅ This config only registers the MCP server binary
51
+ - ✅ The MCP server starts disconnected; you must call `connect_server(base_url=...)` in each MCP session
52
+
53
+ ### 4. Restart your AI client
54
+
55
+ After editing the config:
56
+ ```bash
57
+ # In Claude Code terminal
58
+ /exit
59
+ # Then restart your client
60
+ ```
61
+
62
+ ## Agent Workflow (IMPORTANT)
63
+
64
+ When working with Nebula notebooks, agents should follow this workflow pattern:
65
+
66
+ ### Session Setup (once per conversation)
67
+ ```
68
+ # Always call connect_server first.
69
+ connect_server(base_url="http://localhost:4000") // Example: Nebula UI at :4000
70
+ ```
71
+
72
+ ### Each Response Pattern
73
+ ```
74
+ start_agent_session(path="/path/to/notebook.ipynb")
75
+
76
+ [perform all notebook operations]
77
+ - read_notebook, read_cell, read_output
78
+ - insert_cell, update_cell, delete_cell
79
+ - execute_cell
80
+ - etc.
81
+
82
+ end_agent_session(path="/path/to/notebook.ipynb")
83
+ ```
84
+
85
+ ### Why This Pattern?
86
+ - **Locking**: `start_agent_session` locks the notebook, preventing user edits during agent work
87
+ - **UI Feedback**: Users see a badge showing which agent is working and what it's doing
88
+ - **Clean Handoff**: `end_agent_session` unlocks the notebook so users can edit again
89
+ - **Per-Response**: Start/end in EVERY response ensures the lock isn't held between turns
90
+ - **Path validation**: `start_agent_session` fails if the notebook path doesn't exist (typos are caught early)
91
+ - **Fallback**: If you skip `start_agent_session`, the MCP client will auto-start a session on the first write. You’ll see a warning in the tool response encouraging explicit start/end.
92
+
93
+ ### Example: Multi-step Analysis
94
+ ```
95
+ Response 1:
96
+ start_agent_session → insert_cell (imports) → execute_cell → end_agent_session
97
+
98
+ Response 2:
99
+ start_agent_session → insert_cell (analysis) → execute_cell → read_output → end_agent_session
100
+
101
+ Response 3:
102
+ start_agent_session → insert_cell (visualization) → execute_cell → end_agent_session
103
+ ```
104
+
105
+ ## Switching Between Nebula Instances
106
+
107
+ You can switch between different Nebula instances using the `connect_server` tool. This is useful for:
108
+ - Switching from local development to remote server (via SSH tunnel)
109
+ - Testing notebooks on different Nebula installations
110
+ - Moving between development and production environments
111
+
112
+ ### How it works
113
+
114
+ 1. **No default connection**: On startup, the MCP server is disconnected
115
+ 2. **Connect explicitly**: Use `connect_server(base_url=...)` to choose the server
116
+ 3. **All operations use current connection**: Every tool uses the currently connected server
117
+
118
+ ### Example: Switching between instances
119
+
120
+ ```typescript
121
+ // Connect to local server explicitly
122
+ connect_server(base_url="http://localhost:3000")
123
+ start_agent_session(path="/local/notebook.ipynb")
124
+ insert_cell(path="/local/notebook.ipynb", ...)
125
+
126
+ // Switch to remote server via SSH tunnel
127
+ connect_server(base_url="http://localhost:8001")
128
+
129
+ // Now all operations go to the new server
130
+ start_agent_session(path="/remote/notebook.ipynb")
131
+ insert_cell(path="/remote/notebook.ipynb", ...)
132
+ execute_cell(path="/remote/notebook.ipynb", ...)
133
+
134
+ // Switch back to local server
135
+ connect_server(base_url="http://localhost:3000")
136
+
137
+ // Back to local server
138
+ insert_cell(path="/local/notebook.ipynb", ...)
139
+ ```
140
+
141
+ ### Connection management
142
+
143
+ - One active connection at a time
144
+ - `connect_server` switches the current connection
145
+ - All tools automatically use the current connection
146
+ - Simple and predictable - no per-notebook URL tracking
147
+
148
+ ### Agent sessions and locking
149
+
150
+ Write operations require an agent session. The MCP server automatically creates a session (using a stable MCP-scoped ID) the first time it performs a write on a notebook, so you don't have to call it manually. You can still call `start_agent_session`/`end_agent_session` explicitly if you want tighter control over lock lifetimes.
151
+
152
+ ## Available MCP Tools
153
+
154
+ Once connected, Claude Code can use these tools:
155
+
156
+ ### Connection Management
157
+ - `connect_server` - Connect to a Nebula server (switches current connection)
158
+
159
+ ### Notebook Operations
160
+ - `read_notebook` - Read all cells from a notebook
161
+ - `read_cell` - Read a specific cell by index or ID
162
+ - `read_output` - Read cell execution outputs
163
+ - `insert_cell` - Insert a new cell
164
+ - `update_cell` - Update cell content or type
165
+ - `delete_cell` - Delete a cell
166
+ - `clear_notebook` - Clear all cells from a notebook
167
+ - `move_cell` - Move a cell to a different position
168
+ - `duplicate_cell` - Duplicate a cell
169
+ - `search_cells` - Search for cells by content
170
+ - `update_metadata` - Update cell metadata
171
+ - `start_agent_session` - Start an agent session (locks notebook)
172
+ - `end_agent_session` - End an agent session (unlocks notebook)
173
+
174
+ ### Kernel Operations
175
+ - `list_kernels` - List available kernel specs
176
+ - `kernel_start` - Start a new kernel session
177
+ - `kernel_stop` - Stop a kernel session
178
+ - `kernel_restart` - Restart a kernel
179
+ - `kernel_interrupt` - Interrupt a running kernel
180
+
181
+ ### Execution
182
+ - `execute_cell` - Execute a cell and get results
183
+
184
+ ## Usage Examples
185
+
186
+ ### Example 1: Create a notebook and run analysis
187
+
188
+ ```
189
+ User: "Create a notebook at /tmp/analysis.ipynb with a cell that imports pandas and numpy"
190
+
191
+ Claude uses:
192
+ 1. clear_notebook(path="/tmp/analysis.ipynb")
193
+ 2. insert_cell(path="/tmp/analysis.ipynb", content="import pandas as pd\nimport numpy as np", cell_type="code")
194
+ 3. execute_cell(path="/tmp/analysis.ipynb", cell_index=0)
195
+ 4. read_output(path="/tmp/analysis.ipynb", cell_index=0)
196
+ ```
197
+
198
+ ### Example 2: Read and analyze existing notebook
199
+
200
+ ```
201
+ User: "What's in my notebook at /tmp/data.ipynb?"
202
+
203
+ Claude uses:
204
+ 1. read_notebook(path="/tmp/data.ipynb", format="brief")
205
+ 2. read_cell(path="/tmp/data.ipynb", cell_index=0)
206
+ ```
207
+
208
+ ### Example 3: Interactive multi-step workflow
209
+
210
+ ```
211
+ User: "Analyze stock data for AAPL - fetch it, plot it, and calculate moving averages"
212
+
213
+ Claude uses:
214
+ 1. clear_notebook(path="/tmp/stock-analysis.ipynb")
215
+ 2. kernel_start(file_path="/tmp/stock-analysis.ipynb")
216
+ 3. insert_cell(...) - Add import cell
217
+ 4. execute_cell(...) - Run imports
218
+ 5. insert_cell(...) - Add data fetch cell
219
+ 6. execute_cell(...) - Fetch data
220
+ 7. read_output(...) - Check if data loaded
221
+ 8. insert_cell(...) - Add plotting cell
222
+ 9. execute_cell(...) - Generate plot
223
+ ... and so on
224
+ ```
225
+
226
+ ## Tool Usage in Claude Code
227
+
228
+ Claude Code will automatically use tools with the prefix:
229
+
230
+ ```
231
+ mcp__nebula-notebook__TOOL_NAME
232
+ ```
233
+
234
+ For example:
235
+ - `mcp__nebula-notebook__read_notebook`
236
+ - `mcp__nebula-notebook__execute_cell`
237
+ - `mcp__nebula-notebook__insert_cell`
238
+
239
+ ## Troubleshooting
240
+
241
+ ### MCP server not connecting
242
+
243
+ Check:
244
+ 1. Is Nebula running? Try `curl http://localhost:3000/api/health` (frontend dev proxy) or `curl http://localhost:8000/api/health` (backend)
245
+ 2. Did you call `connect_server(base_url=...)` before using other tools?
246
+ 3. Did you restart Claude Code after config changes?
247
+ 4. Check MCP server logs in Claude Code (usually visible in stderr)
248
+
249
+ ### "No such tool available" error
250
+
251
+ - The MCP server may not be configured or running
252
+ - Check that the server name matches: `nebula-notebook`
253
+ - Restart Claude Code after config changes
254
+
255
+ ### "Request failed: fetch failed" error
256
+
257
+ - The MCP server can't reach the Nebula backend
258
+ - Verify you're calling `connect_server(base_url=...)` with the correct server URL
259
+ - Check if the backend is actually running
260
+ - For SSH tunnels, ensure port forwarding is active
261
+
262
+ ### Tools work but responses are slow
263
+
264
+ - Increase timeout if using remote/forwarded connections
265
+ - Check network latency to the backend
266
+ - Consider running backend locally instead of over SSH
267
+
268
+ ## Publishing the MCP Server
269
+
270
+ See [MCP_DISTRIBUTION.md](./MCP_DISTRIBUTION.md) for instructions on publishing to npm and Smithery.
271
+
272
+ ## Development
273
+
274
+ ### Testing locally
275
+
276
+ ```bash
277
+ # Build the MCP server
278
+ npm run build
279
+
280
+ # Test manually via stdio
281
+ echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}' | node bin/nebula-mcp.js
282
+
283
+ # Test tool listing (specify custom URL if needed)
284
+ echo '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}' | node bin/nebula-mcp.js
285
+ ```
286
+
287
+ ### Adding new tools
288
+
289
+ 1. Add tool definition to `src/tools/notebook.ts`, `kernel.ts`, or `execution.ts`
290
+ 2. Export from the appropriate tools array
291
+ 3. Rebuild: `npm run build`
292
+ 4. Restart Claude Code to pick up new tools
293
+
294
+ ## Architecture
295
+
296
+ ```
297
+ Claude Code
298
+ ↓ (JSON-RPC over stdio)
299
+ nebula-mcp.js (MCP Server)
300
+ ↓ (HTTP/WebSocket)
301
+ Nebula Backend (FastAPI)
302
+
303
+ Jupyter Kernels
304
+ ```
305
+
306
+ The MCP server is a thin wrapper that:
307
+ 1. Implements Model Context Protocol (JSON-RPC 2.0 over stdio)
308
+ 2. Translates tool calls to Nebula API requests
309
+ 3. Formats responses for Claude Code display
310
+ 4. Handles WebSocket connections for streaming execution
311
+
312
+ ## License
313
+
314
+ MIT
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env node
2
+ // Single bin, two roles:
3
+ // `npx nebula-notebook-mcp` → start the MCP server (what agent configs run)
4
+ // `npx nebula-notebook-mcp setup-mcp` → register the MCP with installed agent CLIs
5
+ if (process.argv[2] === 'setup-mcp') {
6
+ process.argv.splice(2, 1); // drop the subcommand so setup sees its own flags
7
+ await import('../setup-mcp.js');
8
+ } else {
9
+ await import('../dist/mcp/index.js');
10
+ }
@@ -0,0 +1,157 @@
1
+ /**
2
+ * Circuit Breaker Pattern Implementation
3
+ *
4
+ * Prevents cascading failures by temporarily disabling requests to a failing service.
5
+ * When a service fails repeatedly, the circuit "opens" and subsequent requests
6
+ * fail immediately without attempting the operation, allowing the service time to recover.
7
+ *
8
+ * States:
9
+ * - CLOSED: Normal operation, requests pass through
10
+ * - OPEN: Service is failing, requests fail immediately
11
+ * - HALF_OPEN: Testing if service has recovered
12
+ */
13
+ import { ErrorCategory, type ClassifiedError } from './errors.js';
14
+ /**
15
+ * Circuit breaker states
16
+ */
17
+ export declare enum CircuitState {
18
+ /** Normal operation - requests pass through */
19
+ CLOSED = "CLOSED",
20
+ /** Service is failing - requests fail immediately */
21
+ OPEN = "OPEN",
22
+ /** Testing recovery - limited requests pass through */
23
+ HALF_OPEN = "HALF_OPEN"
24
+ }
25
+ /**
26
+ * Circuit breaker configuration options
27
+ */
28
+ export interface CircuitBreakerOptions {
29
+ /** Number of failures before opening the circuit (default: 5) */
30
+ failureThreshold?: number;
31
+ /** Time in ms to wait before trying again after opening (default: 30000) */
32
+ resetTimeout?: number;
33
+ /** Number of successful requests needed to close circuit from half-open (default: 2) */
34
+ successThreshold?: number;
35
+ /** Time window in ms for counting failures (default: 60000) */
36
+ failureWindow?: number;
37
+ /** Categories of errors that should trip the circuit (default: NETWORK, TIMEOUT, SERVER) */
38
+ tripOnCategories?: ErrorCategory[];
39
+ /** Optional name for this circuit breaker (for logging) */
40
+ name?: string;
41
+ }
42
+ /**
43
+ * Circuit breaker event types
44
+ */
45
+ export type CircuitBreakerEvent = {
46
+ type: 'state_change';
47
+ from: CircuitState;
48
+ to: CircuitState;
49
+ reason: string;
50
+ } | {
51
+ type: 'failure_recorded';
52
+ error: ClassifiedError;
53
+ failureCount: number;
54
+ } | {
55
+ type: 'success_recorded';
56
+ successCount: number;
57
+ } | {
58
+ type: 'request_rejected';
59
+ state: CircuitState;
60
+ };
61
+ /**
62
+ * Event listener type
63
+ */
64
+ export type CircuitBreakerListener = (event: CircuitBreakerEvent) => void;
65
+ /**
66
+ * Result of a circuit breaker execution
67
+ */
68
+ export type CircuitBreakerResult<T> = {
69
+ success: true;
70
+ data: T;
71
+ } | {
72
+ success: false;
73
+ error: string;
74
+ rejectedByCircuit: boolean;
75
+ classifiedError?: ClassifiedError;
76
+ };
77
+ /**
78
+ * Circuit Breaker implementation
79
+ */
80
+ export declare class CircuitBreaker {
81
+ private state;
82
+ private failures;
83
+ private successCount;
84
+ private lastFailureTime;
85
+ private openedAt;
86
+ private readonly failureThreshold;
87
+ private readonly resetTimeout;
88
+ private readonly successThreshold;
89
+ private readonly failureWindow;
90
+ private readonly tripOnCategories;
91
+ private readonly name;
92
+ private listeners;
93
+ constructor(options?: CircuitBreakerOptions);
94
+ /**
95
+ * Get current circuit state
96
+ */
97
+ getState(): CircuitState;
98
+ /**
99
+ * Get circuit breaker metrics
100
+ */
101
+ getMetrics(): {
102
+ state: CircuitState;
103
+ failureCount: number;
104
+ successCount: number;
105
+ lastFailureTime: number;
106
+ openedAt: number;
107
+ };
108
+ /**
109
+ * Check if the circuit allows requests
110
+ */
111
+ isAllowed(): boolean;
112
+ /**
113
+ * Execute an operation through the circuit breaker
114
+ */
115
+ execute<T>(operation: () => Promise<T>): Promise<CircuitBreakerResult<T>>;
116
+ /**
117
+ * Record a successful operation
118
+ */
119
+ recordSuccess(): void;
120
+ /**
121
+ * Record a failed operation
122
+ */
123
+ recordFailure(error: ClassifiedError): void;
124
+ /**
125
+ * Manually reset the circuit breaker to closed state
126
+ */
127
+ reset(): void;
128
+ /**
129
+ * Force the circuit open (for testing or emergency)
130
+ */
131
+ forceOpen(): void;
132
+ /**
133
+ * Add an event listener
134
+ */
135
+ onEvent(listener: CircuitBreakerListener): () => void;
136
+ /**
137
+ * Check if state should transition based on time
138
+ */
139
+ private checkStateTransition;
140
+ /**
141
+ * Transition to a new state
142
+ */
143
+ private transitionTo;
144
+ /**
145
+ * Get count of failures within the window
146
+ */
147
+ private getRecentFailureCount;
148
+ /**
149
+ * Emit an event to listeners
150
+ */
151
+ private emit;
152
+ }
153
+ /**
154
+ * Create a new circuit breaker instance
155
+ */
156
+ export declare function createCircuitBreaker(options?: CircuitBreakerOptions): CircuitBreaker;
157
+ //# sourceMappingURL=circuit-breaker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"circuit-breaker.d.ts","sourceRoot":"","sources":["../src/circuit-breaker.ts"],"names":[],"mappings":"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"}