Skip to main content
Glama
tofunori

Claude MCP Data Explorer

by tofunori

run-script

Execute JavaScript scripts to analyze and visualize data within Claude's Data Explorer for generating insights from loaded datasets.

Instructions

Execute a JavaScript script for data analysis and visualization

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
scriptYesJavaScript script to execute

Implementation Reference

  • Main handler function for the 'run-script' MCP tool in Python implementation. Dispatches to execute_script and handles errors.
    async def handle_run_script(arguments):
        """Handle the run-script tool"""
        script = arguments.get("script")
        
        if not script:
            return [TextContent(type="text", text="Error: script is required")]
        
        try:
            # Execute the script with access to loaded dataframes
            result = await execute_script(script)
            return [TextContent(type="text", text=result)]
        
        except Exception as e:
            error_message = f"Error executing script: {str(e)}\n{traceback.format_exc()}"
            logging.error(error_message)
            return [TextContent(
                type="text", 
                text=f"Error executing script: {str(e)}\n{traceback.format_exc()}"
            )]
  • Main handler function for the 'run-script' MCP tool in TypeScript implementation. Safely executes JavaScript code with access to loaded dataframes, capturing console output.
    export async function runScript(args: RunScriptArgs): Promise<{ type: string, text: string }[]> {
      const { script } = args;
      
      if (!script) {
        return [{ type: 'text', text: 'Error: script is required' }];
      }
      
      // Capture console output
      let consoleOutput: string[] = [];
      const originalConsoleLog = console.log;
      const originalConsoleError = console.error;
      const originalConsoleWarn = console.warn;
      
      console.log = (...args) => {
        consoleOutput.push(args.map(formatOutput).join(' '));
      };
      
      console.error = (...args) => {
        consoleOutput.push(`ERROR: ${args.map(formatOutput).join(' ')}`);
      };
      
      console.warn = (...args) => {
        consoleOutput.push(`WARNING: ${args.map(formatOutput).join(' ')}`);
      };
      
      try {
        // Create a context with available libraries and data
        const contextObject: Record<string, any> = {
          // Make loaded data frames available to the script
          ...getAllDataFrames(),
          // Add utilities
          require: (moduleName: string) => {
            try {
              // Only allow specific modules for security
              const allowedModules: { [key: string]: any } = {
                'simple-statistics': require('simple-statistics'),
                'papaparse': require('papaparse'),
              };
              
              if (moduleName in allowedModules) {
                return allowedModules[moduleName];
              } else {
                throw new Error(`Module not allowed: ${moduleName}`);
              }
            } catch (error) {
              throw new Error(`Error requiring module '${moduleName}': ${error}`);
            }
          },
          // Add global variables and functions
          console: {
            log: console.log,
            error: console.error,
            warn: console.warn
          },
          Math,
          Date,
          JSON,
          Object,
          Array,
          String,
          Number,
          Boolean,
          Map,
          Set,
          Promise,
          Error,
        };
        
        // Add Data Frame helper methods
        for (const [name, data] of Object.entries(getAllDataFrames())) {
          contextObject[name] = data;
          
          // Add common DataFrame operations
          if (Array.isArray(data) && data.length > 0) {
            // Use method binding to ensure 'this' is preserved
            contextObject[`${name}_describe`] = () => describeDataFrame(data);
            contextObject[`${name}_columns`] = () => Object.keys(data[0] || {});
            contextObject[`${name}_head`] = (n = 5) => data.slice(0, n);
            contextObject[`${name}_tail`] = (n = 5) => data.slice(-n);
            contextObject[`${name}_filter`] = (fn: (row: any) => boolean) => data.filter(fn);
            contextObject[`${name}_map`] = (fn: (row: any) => any) => data.map(fn);
            contextObject[`${name}_groupBy`] = (key: string) => {
              const groups: Record<string, any[]> = {};
              for (const row of data) {
                const groupKey = String(row[key]);
                if (!groups[groupKey]) {
                  groups[groupKey] = [];
                }
                groups[groupKey].push(row);
              }
              return groups;
            };
          }
        }
        
        // Create a secure function for execution
        const AsyncFunction = Object.getPrototypeOf(async function(){}).constructor;
        const secureFunction = new AsyncFunction(
          ...Object.keys(contextObject),
          `"use strict";
          try {
            return (async () => {
              ${script}
              return "Script executed successfully";
            })();
          } catch (error) {
            throw error;
          }`
        );
        
        // Execute the function with context
        const result = await secureFunction(...Object.values(contextObject));
        
        // Add result to console output if we got something back
        if (result !== "Script executed successfully") {
          consoleOutput.push(formatOutput(result));
        }
        
        // Clean up and return the result
        return [{ type: 'text', text: consoleOutput.join('\n') }];
      } catch (error: any) {
        return [{ type: 'text', text: `Error executing script: ${error.message}\n\nConsole output:\n${consoleOutput.join('\n')}` }];
      } finally {
        // Restore original console methods
        console.log = originalConsoleLog;
        console.error = originalConsoleError;
        console.warn = originalConsoleWarn;
      }
    }
  • Input schema definition for the 'run-script' tool in the Python server's list_tools implementation.
    types.Tool(
        name="run-script",
        description="Execute a Python script for data analysis and visualization",
        inputSchema={
            "type": "object",
            "properties": {
                "script": {
                    "type": "string",
                    "description": "Python script to execute"
                }
            },
            "required": ["script"]
        }
    )
  • Input schema definition for the 'run-script' tool in the TypeScript server's list tools handler.
      name: "run-script",
      description: "Execute a JavaScript script for data analysis and visualization",
      inputSchema: {
        type: "object",
        properties: {
          script: {
            type: "string",
            description: "JavaScript script to execute"
          }
        },
        required: ["script"]
      }
    }]
  • Registration dispatch in the call_tool handler for the 'run-script' tool in Python server.
    elif name == "run-script":
        return await handle_run_script(arguments)
Install Server

Other Tools

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/tofunori/claude-mcp-data-explorer'

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