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
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Image Resize Utility
3
+ *
4
+ * Resizes base64 PNG images to fit within Claude API limits.
5
+ * Claude's multi-image requests require each image to be ≤2000 pixels in any dimension.
6
+ */
7
+ /**
8
+ * Resize a base64 PNG image if it exceeds the maximum dimension.
9
+ * Returns the original if already within limits or if resizing fails.
10
+ *
11
+ * @param base64Data - Base64 encoded PNG data (without data URL prefix)
12
+ * @param maxDimension - Maximum allowed dimension (default: 2000)
13
+ * @returns Resized base64 PNG data
14
+ */
15
+ export declare function resizeImageIfNeeded(base64Data: string, maxDimension?: number): Promise<string>;
16
+ /**
17
+ * Check image dimensions without resizing.
18
+ * Returns null if dimensions can't be determined.
19
+ */
20
+ export declare function getImageDimensions(base64Data: string): Promise<{
21
+ width: number;
22
+ height: number;
23
+ } | null>;
24
+ //# sourceMappingURL=imageResize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"imageResize.d.ts","sourceRoot":"","sources":["../../src/utils/imageResize.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH;;;;;;;GAOG;AACH,wBAAsB,mBAAmB,CACvC,UAAU,EAAE,MAAM,EAClB,YAAY,GAAE,MAA8B,GAC3C,OAAO,CAAC,MAAM,CAAC,CAoCjB;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CAWnD"}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Image Resize Utility
3
+ *
4
+ * Resizes base64 PNG images to fit within Claude API limits.
5
+ * Claude's multi-image requests require each image to be ≤2000 pixels in any dimension.
6
+ */
7
+ import sharp from 'sharp';
8
+ const DEFAULT_MAX_DIMENSION = 2000;
9
+ /**
10
+ * Resize a base64 PNG image if it exceeds the maximum dimension.
11
+ * Returns the original if already within limits or if resizing fails.
12
+ *
13
+ * @param base64Data - Base64 encoded PNG data (without data URL prefix)
14
+ * @param maxDimension - Maximum allowed dimension (default: 2000)
15
+ * @returns Resized base64 PNG data
16
+ */
17
+ export async function resizeImageIfNeeded(base64Data, maxDimension = DEFAULT_MAX_DIMENSION) {
18
+ try {
19
+ const buffer = Buffer.from(base64Data, 'base64');
20
+ const image = sharp(buffer);
21
+ const metadata = await image.metadata();
22
+ const { width, height } = metadata;
23
+ if (!width || !height) {
24
+ return base64Data; // Can't determine size, return original
25
+ }
26
+ // Check if resize is needed
27
+ if (width <= maxDimension && height <= maxDimension) {
28
+ return base64Data.trim(); // Already within limits, but trim any whitespace
29
+ }
30
+ // Calculate new dimensions maintaining aspect ratio
31
+ const scale = Math.min(maxDimension / width, maxDimension / height);
32
+ const newWidth = Math.round(width * scale);
33
+ const newHeight = Math.round(height * scale);
34
+ // Resize and convert back to base64
35
+ const resizedBuffer = await image
36
+ .resize(newWidth, newHeight, {
37
+ fit: 'inside',
38
+ withoutEnlargement: true,
39
+ })
40
+ .png()
41
+ .toBuffer();
42
+ return resizedBuffer.toString('base64').trim();
43
+ }
44
+ catch (error) {
45
+ // If resizing fails, return original (trimmed)
46
+ console.error('[ImageResize] Failed to resize image:', error);
47
+ return base64Data.trim();
48
+ }
49
+ }
50
+ /**
51
+ * Check image dimensions without resizing.
52
+ * Returns null if dimensions can't be determined.
53
+ */
54
+ export async function getImageDimensions(base64Data) {
55
+ try {
56
+ const buffer = Buffer.from(base64Data, 'base64');
57
+ const metadata = await sharp(buffer).metadata();
58
+ if (metadata.width && metadata.height) {
59
+ return { width: metadata.width, height: metadata.height };
60
+ }
61
+ return null;
62
+ }
63
+ catch {
64
+ return null;
65
+ }
66
+ }
67
+ //# sourceMappingURL=imageResize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"imageResize.js","sourceRoot":"","sources":["../../src/utils/imageResize.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,qBAAqB,GAAG,IAAI,CAAC;AAEnC;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,UAAkB,EAClB,eAAuB,qBAAqB;IAE5C,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QACjD,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;QAC5B,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,QAAQ,EAAE,CAAC;QAExC,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,QAAQ,CAAC;QACnC,IAAI,CAAC,KAAK,IAAI,CAAC,MAAM,EAAE,CAAC;YACtB,OAAO,UAAU,CAAC,CAAC,wCAAwC;QAC7D,CAAC;QAED,4BAA4B;QAC5B,IAAI,KAAK,IAAI,YAAY,IAAI,MAAM,IAAI,YAAY,EAAE,CAAC;YACpD,OAAO,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC,iDAAiD;QAC7E,CAAC;QAED,oDAAoD;QACpD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,YAAY,GAAG,KAAK,EAAE,YAAY,GAAG,MAAM,CAAC,CAAC;QACpE,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC;QAC3C,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,CAAC;QAE7C,oCAAoC;QACpC,MAAM,aAAa,GAAG,MAAM,KAAK;aAC9B,MAAM,CAAC,QAAQ,EAAE,SAAS,EAAE;YAC3B,GAAG,EAAE,QAAQ;YACb,kBAAkB,EAAE,IAAI;SACzB,CAAC;aACD,GAAG,EAAE;aACL,QAAQ,EAAE,CAAC;QAEd,OAAO,aAAa,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC;IACjD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,+CAA+C;QAC/C,OAAO,CAAC,KAAK,CAAC,uCAAuC,EAAE,KAAK,CAAC,CAAC;QAC9D,OAAO,UAAU,CAAC,IAAI,EAAE,CAAC;IAC3B,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,UAAkB;IAElB,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QACjD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,CAAC;QAChD,IAAI,QAAQ,CAAC,KAAK,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAC;YACtC,OAAO,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC;QAC5D,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Adaptive polling utility with exponential backoff
3
+ *
4
+ * Starts with fast intervals (50ms) and gradually increases to max (1000ms)
5
+ * to balance responsiveness for quick operations with efficiency for long waits.
6
+ */
7
+ export interface PollerConfig {
8
+ /** Initial polling interval in milliseconds (default: 50) */
9
+ initialInterval?: number;
10
+ /** Maximum polling interval in milliseconds (default: 1000) */
11
+ maxInterval?: number;
12
+ /** Backoff multiplier (default: 2 for exponential) */
13
+ backoffFactor?: number;
14
+ }
15
+ export declare class AdaptivePoller {
16
+ private currentInterval;
17
+ private config;
18
+ constructor(config?: PollerConfig);
19
+ /**
20
+ * Get current polling interval in milliseconds
21
+ */
22
+ getCurrentInterval(): number;
23
+ /**
24
+ * Increase polling interval using exponential backoff
25
+ */
26
+ incrementInterval(): void;
27
+ /**
28
+ * Reset polling interval to initial value
29
+ */
30
+ reset(): void;
31
+ /**
32
+ * Async sleep for current interval duration
33
+ */
34
+ wait(): Promise<void>;
35
+ }
36
+ /**
37
+ * Factory function for creating adaptive pollers
38
+ */
39
+ export declare function createAdaptivePoller(config?: PollerConfig): AdaptivePoller;
40
+ //# sourceMappingURL=polling.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"polling.d.ts","sourceRoot":"","sources":["../../src/utils/polling.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,YAAY;IAC3B,6DAA6D;IAC7D,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,+DAA+D;IAC/D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,sDAAsD;IACtD,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,MAAM,CAAyB;gBAE3B,MAAM,GAAE,YAAiB;IASrC;;OAEG;IACH,kBAAkB,IAAI,MAAM;IAI5B;;OAEG;IACH,iBAAiB,IAAI,IAAI;IAOzB;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAG5B;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,CAAC,EAAE,YAAY,GAAG,cAAc,CAE1E"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Adaptive polling utility with exponential backoff
3
+ *
4
+ * Starts with fast intervals (50ms) and gradually increases to max (1000ms)
5
+ * to balance responsiveness for quick operations with efficiency for long waits.
6
+ */
7
+ export class AdaptivePoller {
8
+ currentInterval;
9
+ config;
10
+ constructor(config = {}) {
11
+ this.config = {
12
+ initialInterval: config.initialInterval ?? 50,
13
+ maxInterval: config.maxInterval ?? 1000,
14
+ backoffFactor: config.backoffFactor ?? 2
15
+ };
16
+ this.currentInterval = this.config.initialInterval;
17
+ }
18
+ /**
19
+ * Get current polling interval in milliseconds
20
+ */
21
+ getCurrentInterval() {
22
+ return this.currentInterval;
23
+ }
24
+ /**
25
+ * Increase polling interval using exponential backoff
26
+ */
27
+ incrementInterval() {
28
+ this.currentInterval = Math.min(this.currentInterval * this.config.backoffFactor, this.config.maxInterval);
29
+ }
30
+ /**
31
+ * Reset polling interval to initial value
32
+ */
33
+ reset() {
34
+ this.currentInterval = this.config.initialInterval;
35
+ }
36
+ /**
37
+ * Async sleep for current interval duration
38
+ */
39
+ async wait() {
40
+ await new Promise(resolve => setTimeout(resolve, this.currentInterval));
41
+ }
42
+ }
43
+ /**
44
+ * Factory function for creating adaptive pollers
45
+ */
46
+ export function createAdaptivePoller(config) {
47
+ return new AdaptivePoller(config);
48
+ }
49
+ //# sourceMappingURL=polling.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"polling.js","sourceRoot":"","sources":["../../src/utils/polling.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAWH,MAAM,OAAO,cAAc;IACjB,eAAe,CAAS;IACxB,MAAM,CAAyB;IAEvC,YAAY,SAAuB,EAAE;QACnC,IAAI,CAAC,MAAM,GAAG;YACZ,eAAe,EAAE,MAAM,CAAC,eAAe,IAAI,EAAE;YAC7C,WAAW,EAAE,MAAM,CAAC,WAAW,IAAI,IAAI;YACvC,aAAa,EAAE,MAAM,CAAC,aAAa,IAAI,CAAC;SACzC,CAAC;QACF,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC;IACrD,CAAC;IAED;;OAEG;IACH,kBAAkB;QAChB,OAAO,IAAI,CAAC,eAAe,CAAC;IAC9B,CAAC;IAED;;OAEG;IACH,iBAAiB;QACf,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,GAAG,CAC7B,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,MAAM,CAAC,aAAa,EAChD,IAAI,CAAC,MAAM,CAAC,WAAW,CACxB,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,KAAK;QACH,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC;IACrD,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,IAAI;QACR,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC;IAC1E,CAAC;CACF;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAAC,MAAqB;IACxD,OAAO,IAAI,cAAc,CAAC,MAAM,CAAC,CAAC;AACpC,CAAC"}
package/package.json ADDED
@@ -0,0 +1,61 @@
1
+ {
2
+ "name": "nebula-notebook-mcp",
3
+ "version": "0.1.0",
4
+ "description": "MCP server for Nebula Notebook \u2014 lets agents (Claude Code, Codex, etc.) read, edit, and execute notebooks on a running Nebula server",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "bin": {
9
+ "nebula-notebook-mcp": "./bin/nebula-mcp.js"
10
+ },
11
+ "files": [
12
+ "dist",
13
+ "bin",
14
+ "setup-mcp.js"
15
+ ],
16
+ "keywords": [
17
+ "mcp",
18
+ "model-context-protocol",
19
+ "jupyter",
20
+ "notebook",
21
+ "ai",
22
+ "claude"
23
+ ],
24
+ "repository": {
25
+ "type": "git",
26
+ "url": "https://github.com/jzthree/nebula-notebook.git",
27
+ "directory": "packages/mcp"
28
+ },
29
+ "exports": {
30
+ ".": "./dist/index.js",
31
+ "./notebook": "./dist/notebook/index.js",
32
+ "./mcp": "./dist/mcp/index.js"
33
+ },
34
+ "scripts": {
35
+ "build": "tsc",
36
+ "dev": "tsc --watch",
37
+ "test": "vitest",
38
+ "clean": "rm -rf dist",
39
+ "mcp": "node dist/mcp/index.js",
40
+ "setup-mcp": "node setup-mcp.js",
41
+ "prepublishOnly": "npm run build"
42
+ },
43
+ "dependencies": {
44
+ "@modelcontextprotocol/sdk": "^1.0.0",
45
+ "glob": "^11.0.0",
46
+ "sharp": "^0.34.5",
47
+ "strip-ansi": "^7.1.0",
48
+ "ws": "^8.18.0"
49
+ },
50
+ "devDependencies": {
51
+ "@types/node": "^22.0.0",
52
+ "@types/sharp": "^0.31.1",
53
+ "@types/ws": "^8.5.0",
54
+ "typescript": "^5.7.0",
55
+ "vitest": "^3.0.0"
56
+ },
57
+ "engines": {
58
+ "node": ">=20"
59
+ },
60
+ "license": "MIT"
61
+ }