Skip to main content
Glama
azharlabs
by azharlabs

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