Skip to content

Commit 4c9f151

Browse files
committed
Update MCP JupyterLab extension build and docs
Updated the MCP Active Cell Bridge JupyterLab extension build artifacts and package references after a rebuild. Added an 'instrmcp-setup' step to the development instructions in CLAUDE.md for improved extension linking.
1 parent e39f46f commit 4c9f151

File tree

10 files changed

+134
-22
lines changed

10 files changed

+134
-22
lines changed

CLAUDE.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ Located in `instrmcp/extensions/jupyterlab/`. After modifying TypeScript:
143143
```bash
144144
cd instrmcp/extensions/jupyterlab && jlpm run build
145145
pip install -e . --force-reinstall --no-deps
146+
instrmcp-setup # Link extension to Jupyter data directory
146147
# Restart JupyterLab completely
147148
```
148149

instrmcp/extensions/jupyterlab/mcp_active_cell_bridge/labextension/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@
6464
"extension": true,
6565
"webpackConfig": "./webpack.config.js",
6666
"_build": {
67-
"load": "static/remoteEntry.53d8c3e6039a645261fc.js",
67+
"load": "static/remoteEntry.aa0f00fdb8ca909a5e47.js",
6868
"extension": "./extension",
6969
"style": "./style"
7070
}

instrmcp/extensions/jupyterlab/mcp_active_cell_bridge/labextension/static/index.057bca2c715123d02dd6.js

Lines changed: 0 additions & 1 deletion
This file was deleted.

instrmcp/extensions/jupyterlab/mcp_active_cell_bridge/labextension/static/index.5d05d381876db71b1f9d.js

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

instrmcp/extensions/jupyterlab/mcp_active_cell_bridge/labextension/static/remoteEntry.53d8c3e6039a645261fc.js renamed to instrmcp/extensions/jupyterlab/mcp_active_cell_bridge/labextension/static/remoteEntry.aa0f00fdb8ca909a5e47.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

instrmcp/extensions/jupyterlab/src/index.ts

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1245,10 +1245,43 @@ const plugin: JupyterFrontEndPlugin<void> = {
12451245
return div.innerHTML;
12461246
};
12471247

1248-
// Pass through all output data including image base64.
1249-
// Image data is saved to temp files by the Python backend (image_utils.py).
1248+
// Maximum size for image data in bytes (10MB base64 ≈ 7.5MB raw image)
1249+
// Images larger than this will be replaced with a fallback message
1250+
const MAX_IMAGE_SIZE_BYTES = 10 * 1024 * 1024;
1251+
1252+
// Image MIME types to check for size limits
1253+
const IMAGE_MIME_TYPES = [
1254+
'image/png',
1255+
'image/jpeg',
1256+
'image/gif',
1257+
'image/svg+xml',
1258+
'image/webp',
1259+
'image/bmp',
1260+
'image/tiff'
1261+
];
1262+
1263+
// Pass through output data, but replace overly large images with fallback message.
1264+
// Normal-sized images are saved to temp files by the Python backend (image_utils.py).
12501265
const sanitizeOutputData = (data: Record<string, any>): Record<string, any> => {
1251-
return { ...data };
1266+
const result: Record<string, any> = {};
1267+
1268+
for (const [mimeType, content] of Object.entries(data)) {
1269+
if (IMAGE_MIME_TYPES.includes(mimeType) && typeof content === 'string') {
1270+
const sizeBytes = content.length;
1271+
if (sizeBytes > MAX_IMAGE_SIZE_BYTES) {
1272+
// Calculate approximate raw image size (base64 is ~1.33x raw size)
1273+
const rawSizeMB = (sizeBytes * 0.75) / (1024 * 1024);
1274+
result[mimeType] = `[IMAGE TOO LARGE: ~${rawSizeMB.toFixed(1)}MB - Use plt.savefig('/tmp/my_plot.png') to save large images to disk, then reference the file path]`;
1275+
console.log(`MCP Active Cell Bridge: Image too large (${rawSizeMB.toFixed(1)}MB), replaced with fallback message`);
1276+
} else {
1277+
result[mimeType] = content;
1278+
}
1279+
} else {
1280+
result[mimeType] = content;
1281+
}
1282+
}
1283+
1284+
return result;
12521285
};
12531286

12541287
// Handle patch consent request from kernel

instrmcp/extensions/jupyterlab/static/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@
6464
"extension": true,
6565
"webpackConfig": "./webpack.config.js",
6666
"_build": {
67-
"load": "static/remoteEntry.53d8c3e6039a645261fc.js",
67+
"load": "static/remoteEntry.aa0f00fdb8ca909a5e47.js",
6868
"extension": "./extension",
6969
"style": "./style"
7070
}

instrmcp/servers/jupyter_qcodes/active_cell_bridge.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -979,7 +979,7 @@ def move_cursor(target: str, timeout_s: float = 2.0) -> Dict[str, Any]:
979979
return result
980980

981981

982-
def get_active_cell_output(timeout_s: float = 2.0) -> Dict[str, Any]:
982+
def get_active_cell_output(timeout_s: float = 10.0) -> Dict[str, Any]:
983983
"""
984984
Get the output of the currently active cell directly from JupyterLab frontend.
985985
@@ -991,7 +991,7 @@ def get_active_cell_output(timeout_s: float = 2.0) -> Dict[str, Any]:
991991
frontend for the active cell's current outputs.
992992
993993
Args:
994-
timeout_s: How long to wait for response from frontend (default 2.0s)
994+
timeout_s: How long to wait for response from frontend (default 10.0s)
995995
996996
Returns:
997997
Dictionary with:

instrmcp/servers/jupyter_qcodes/backend/notebook_unsafe.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,7 @@ async def execute_editing_cell(self, timeout: float = 30.0) -> Dict[str, Any]:
346346

347347
# 6. Fetch output using shared logic from get_active_cell_output
348348
# This is the same path used by notebook_read_active_cell_output
349-
output_result = self.bridge.get_active_cell_output(timeout_s=2.0)
349+
output_result = self.bridge.get_active_cell_output(timeout_s=10.0)
350350

351351
# 7. Build combined result
352352
combined_result = {

0 commit comments

Comments
 (0)