Skip to main content
Glama

bulk_edit_cells

Edit, delete, or convert multiple cells in Jupyter notebooks simultaneously to manage content efficiently.

Instructions

Perform bulk operations on multiple cells

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
notebook_pathYesAbsolute path to the Jupyter notebook file
operationsYes

Implementation Reference

  • The main handler function that executes bulk cell operations (edit, delete, convert) on a Jupyter notebook. It reads the notebook, applies operations in sorted order to handle index shifts, writes back changes, and reports success/errors.
    async bulkEditCells(notebookPath, operations) { const notebook = await this.readNotebook(notebookPath); let successCount = 0; const errors = []; // Sort operations by index in descending order for deletions const sortedOps = operations.sort((a, b) => { if (a.type === 'delete' && b.type !== 'delete') return -1; if (a.type !== 'delete' && b.type === 'delete') return 1; return b.cell_index - a.cell_index; }); for (const op of sortedOps) { try { switch (op.type) { case 'edit': if (op.cell_index < 0 || op.cell_index >= notebook.cells.length) { throw new Error(`Invalid cell index ${op.cell_index}`); } // Convert string to array format - each line should end with \n except the last const lines = op.new_source.split('\n'); const sourceArray = lines.map((line, index) => { if (index === lines.length - 1) { return line === '' ? '' : line; } else { return line + '\n'; } }); // Remove empty last element if original ended with \n if (sourceArray.length > 1 && sourceArray[sourceArray.length - 1] === '') { sourceArray.pop(); } notebook.cells[op.cell_index].source = sourceArray; break; case 'delete': if (op.cell_index < 0 || op.cell_index >= notebook.cells.length) { throw new Error(`Invalid cell index ${op.cell_index}`); } notebook.cells.splice(op.cell_index, 1); break; case 'convert': if (op.cell_index < 0 || op.cell_index >= notebook.cells.length) { throw new Error(`Invalid cell index ${op.cell_index}`); } this.validateCellType(op.new_type); const cell = notebook.cells[op.cell_index]; cell.cell_type = op.new_type; if (op.new_type === 'code') { cell.execution_count = null; cell.outputs = []; } else { delete cell.execution_count; delete cell.outputs; } break; default: throw new Error(`Unknown operation type: ${op.type}`); } successCount++; } catch (error) { errors.push(`Operation ${op.type} on cell ${op.cell_index}: ${error.message}`); } } await this.writeNotebook(notebookPath, notebook); const resultText = [ `Bulk operation completed: ${successCount}/${operations.length} operations successful` ]; if (errors.length > 0) { resultText.push(`\nErrors:\n${errors.join('\n')}`); } return { content: [ { type: "text", text: resultText.join('\n') } ] }; }
  • Input schema for the bulk_edit_cells tool, defining parameters: notebook_path (string) and operations (array of objects with type 'edit'/'delete'/'convert', cell_index (required), optional new_source and new_type).
    name: "bulk_edit_cells", description: "Perform bulk operations on multiple cells", inputSchema: { type: "object", properties: { notebook_path: { type: "string", description: "Absolute path to the Jupyter notebook file" }, operations: { type: "array", items: { type: "object", properties: { type: { type: "string", enum: ["edit", "delete", "convert"] }, cell_index: { type: "integer" }, new_source: { type: "string" }, new_type: { type: "string", enum: ["code", "markdown", "raw"] } }, required: ["type", "cell_index"] } } }, required: ["notebook_path", "operations"] } },
  • src/index.js:369-373 (registration)
    Registration in the CallToolRequest handler switch statement, dispatching calls to bulk_edit_cells to the JupyterHandler.bulkEditCells method.
    case "bulk_edit_cells": return await this.jupyterHandler.bulkEditCells( args.notebook_path, args.operations );

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/azharlabs/mcp-jupyter-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server