run_skill_script
Execute scripts within skill directories with automatic dependency installation, environment variable loading, and argument passing for Python, Bash, and other executable files.
Instructions
Execute a script or executable program within a skill directory with optional arguments and automatic dependency management.
This tool runs scripts in multiple languages and automatically manages dependencies:
SUPPORTED LANGUAGES:
Python: Automatically installs PEP 723 inline dependencies via 'uv run' if declared in the script
Bash: Executes shell scripts (.sh files)
Other: Any executable file with proper shebang line
FEATURES:
Automatic dependency installation: Python scripts with PEP 723 metadata (/* script */ dependencies) are run with 'uv run' automatically
Environment variables: Loads skill-specific .env file and injects variables into script environment
Working directory: Can specify a subdirectory to run the script from
Arguments: Pass command-line arguments to the script
Output capture: Returns stdout, stderr, and exit code
PARAMETERS:
skill_name: The name of the skill directory (e.g., 'weather-skill')
script_path: Relative path to the script (e.g., 'scripts/fetch_weather.py', 'bin/process.sh')
args: Optional list of command-line arguments to pass to the script (e.g., ['--verbose', 'input.txt'])
working_dir: Optional working directory for execution (relative to skill root)
BEHAVIOR:
Python scripts with PEP 723 metadata are detected automatically and run with 'uv run'
Environment variables from skill's .env file are available to the script
Script must be executable or have proper shebang line
Script path is relative to the skill directory
RETURNS: Script execution result with:
Exit code (0 = success, non-zero = failure)
STDOUT (standard output)
STDERR (error output)
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| args | No | Optional command-line arguments to pass to the script | |
| script_path | Yes | Relative path to the script within the skill directory | |
| skill_name | Yes | Name of the skill | |
| working_dir | No | Optional working directory for script execution |
Implementation Reference
- The core handler function for the 'run_skill_script' tool. It invokes ScriptService.run_script with the provided input parameters and formats the execution result including exit code, STDOUT, and STDERR into a TextContent response.async def run_skill_script(input_data: RunSkillScriptInput) -> list[types.TextContent]: """Execute a skill script.""" try: result = await ScriptService.run_script( input_data.skill_name, input_data.script_path, input_data.args, input_data.working_dir, input_data.timeout, ) output = f"Script: {input_data.skill_name}/{input_data.script_path}\n" output += f"Exit code: {result.exit_code}\n\n" if result.stdout: output += f"STDOUT:\n{result.stdout}\n" if result.stderr: output += f"STDERR:\n{result.stderr}\n" if not result.stdout and not result.stderr: output += "(No output)\n" return [types.TextContent(type="text", text=output)] except SkillMCPException as e: return [types.TextContent(type="text", text=f"Error: {str(e)}")] except Exception as e: return [types.TextContent(type="text", text=f"Error running script: {str(e)}")]
- src/skill_mcp/models.py:56-71 (schema)Pydantic BaseModel defining the input schema for the 'run_skill_script' tool, including fields for skill_name, script_path, args, working_dir, and timeout.class RunSkillScriptInput(BaseModel): """Input for running a skill script.""" skill_name: str = Field(description="Name of the skill") script_path: str = Field(description="Relative path to the script within the skill directory") args: Optional[List[str]] = Field( default=None, description="Optional command-line arguments to pass to the script" ) working_dir: Optional[str] = Field( default=None, description="Optional working directory for script execution" ) timeout: Optional[int] = Field( default=None, description="Optional timeout in seconds (defaults to 30 seconds if not specified)", )
- src/skill_mcp/tools/script_tools.py:129-235 (registration)Tool registration within ScriptTools.get_script_tools(), defining the 'run_skill_script' tool with name, detailed description, and input schema reference.types.Tool( name="run_skill_script", description="""Execute a script within a skill directory. Skills are modular libraries with reusable code - scripts can import from their own modules or use external dependencies. IMPORTANT: ALWAYS use this tool to execute scripts. DO NOT use external bash/shell tools to execute scripts directly. This tool provides: - Automatic dependency management (Python PEP 723, npm packages) - Proper environment variable injection from .env files - Secure execution within skill directory boundaries - Proper error handling and output capture SKILLS AS LIBRARIES: Scripts within a skill can import from local modules naturally: ``` weather-skill/ ├── main.py # Script that imports from modules below ├── api_client.py # Reusable API client module ├── parsers.py # Data parsing utilities └── formatters.py # Output formatting ``` In main.py: ```python from api_client import WeatherAPI from formatters import format_temperature api = WeatherAPI() data = api.get_weather("London") print(format_temperature(data)) ``` Execute with: ```json { "skill_name": "weather-skill", "script_path": "main.py", "args": ["--city", "London"] } ``` SUPPORTED LANGUAGES: - Python: Automatically detects and installs PEP 723 inline dependencies via 'uv run' - JavaScript/Node.js: Automatically runs 'npm install' if package.json exists - Bash: Executes shell scripts (.sh files) - Other: Any executable file with proper shebang line FEATURES: - Module imports: Scripts can import from other files within the skill directory - **Automatic PEP 723 dependency detection**: Python scripts with inline metadata are automatically run with 'uv run' - Automatic npm dependency installation: Node.js scripts install dependencies from package.json - Environment variables: Loads skill-specific .env file and injects variables into script environment - Working directory: Can specify a subdirectory to run the script from - Arguments: Pass command-line arguments to the script - Output capture: Returns stdout, stderr, and exit code PEP 723 AUTOMATIC DEPENDENCY DETECTION: Python scripts with inline dependencies are automatically detected and executed with 'uv run': Example Python script with PEP 723 (e.g., weather-skill/fetch_weather.py): ```python #!/usr/bin/env python3 # /// script # dependencies = [ # "requests>=2.31.0", # "beautifulsoup4>=4.12.0", # ] # /// import requests from bs4 import BeautifulSoup response = requests.get("https://api.weather.com/data") print(response.json()) ``` Execute with automatic dependency handling: ```json { "skill_name": "weather-skill", "script_path": "fetch_weather.py", "args": ["--city", "London"] } ``` No manual dependency installation needed - the server automatically: 1. Detects the PEP 723 metadata in your script 2. Uses 'uv run' to create an isolated environment 3. Installs the declared dependencies 4. Executes your script with access to those dependencies PARAMETERS: - skill_name: The name of the skill directory (e.g., 'weather-skill') - script_path: Relative path to the script within skill directory (e.g., 'main.py', 'scripts/fetch_weather.py', 'bin/process.sh') - args: Optional list of command-line arguments (e.g., ['--verbose', 'input.txt']) - working_dir: Optional working directory relative to skill root (e.g., 'scripts') - timeout: Optional timeout in seconds (defaults to 30 seconds if not specified) IMPORTANT PATH NOTES: - All paths are RELATIVE to the skill directory, never absolute paths - Script path example: 'main.py' NOT '/Users/username/.skill-mcp/skills/my-skill/main.py' - Working dir example: 'scripts' NOT '/full/path/to/scripts' RETURNS: Script execution result with: - Exit code (0 = success, non-zero = failure) - STDOUT (standard output) - STDERR (error output)""", inputSchema=RunSkillScriptInput.model_json_schema(), ),
- src/skill_mcp/server.py:60-62 (registration)Dispatch logic in the MCP server's call_tool handler that validates input with RunSkillScriptInput and delegates execution to ScriptTools.run_skill_script.elif name == "run_skill_script": script_input = RunSkillScriptInput(**arguments) return await ScriptTools.run_skill_script(script_input)