Skip to main content
Glama
fkesheh
by fkesheh

skill_files_crud

Perform CRUD operations on skill files to read, create, update, or delete content within skill directories, supporting both single and bulk file management.

Instructions

Unified CRUD tool for skill file operations. Supports both single and bulk operations.

IMPORTANT PATH NOTES:

  • All file paths are RELATIVE to the skill directory (e.g., 'main.py', 'scripts/utils.py')

  • NEVER use absolute paths (e.g., NOT '/Users/username/.skill-mcp/skills/my-skill/main.py')

  • To execute scripts, use the 'run_skill_script' tool, NOT external bash/shell tools

Operations:

  • read: Read a file's content

  • create: Create one or more files (supports atomic mode for bulk)

  • update: Update one or more files

  • delete: Delete a file (SKILL.md is protected and cannot be deleted)

Single File Examples:

// Read a file {"operation": "read", "skill_name": "my-skill", "file_path": "script.py"} // Create a single file {"operation": "create", "skill_name": "my-skill", "file_path": "new.py", "content": "print('hello')"} // Update a single file {"operation": "update", "skill_name": "my-skill", "file_path": "script.py", "content": "print('updated')"} // Delete a file {"operation": "delete", "skill_name": "my-skill", "file_path": "old.py"}

Bulk File Examples:

// Read multiple files { "operation": "read", "skill_name": "my-skill", "file_paths": ["file1.py", "file2.py", "file3.py"] } // Create multiple files atomically (all-or-nothing) { "operation": "create", "skill_name": "my-skill", "files": [ {"path": "src/main.py", "content": "# Main"}, {"path": "src/utils.py", "content": "# Utils"}, {"path": "README.md", "content": "# Docs"} ], "atomic": true } // Update multiple files { "operation": "update", "skill_name": "my-skill", "files": [ {"path": "file1.py", "content": "new content 1"}, {"path": "file2.py", "content": "new content 2"} ] }

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
operationYesOperation to perform: 'read', 'create', 'update', 'delete'
skill_nameYesName of the skill
file_pathNoRelative path to file (for single file operations)
contentNoFile content (for single create/update)
filesNoList of files for bulk create/update operations
file_pathsNoList of file paths for bulk read operations
atomicNoAtomic mode: rollback all on error (for bulk create)

Implementation Reference

  • Primary handler method `skill_files_crud` that dispatches CRUD operations (read, create, update, delete) based on input.operation and handles errors.
    async def skill_files_crud(input_data: SkillFilesCrudInput) -> list[types.TextContent]: """Handle file CRUD operations.""" operation = input_data.operation try: if operation == "read": return await SkillFilesCrud._handle_read(input_data) elif operation == "create": return await SkillFilesCrud._handle_create(input_data) elif operation == "update": return await SkillFilesCrud._handle_update(input_data) elif operation == "delete": return await SkillFilesCrud._handle_delete(input_data) else: return [ types.TextContent( type="text", text=f"Unknown operation: {operation}. Valid operations: read, create, update, delete", ) ] except Exception as e: return [types.TextContent(type="text", text=f"Error: {str(e)}")]
  • Pydantic `BaseModel` defining the input schema for the `skill_files_crud` tool, including fields for operation, skill_name, single/bulk file paths, content, and atomic flag.
    class SkillFilesCrudInput(BaseModel): """Unified input for skill file CRUD operations.""" operation: str = Field(description="Operation to perform: 'read', 'create', 'update', 'delete'") skill_name: str = Field(description="Name of the skill") # Single file operations file_path: Optional[str] = Field( default=None, description="Relative path to file (for single file operations)" ) content: Optional[str] = Field( default=None, description="File content (for single create/update)" ) # Bulk file operations files: Optional[List[FileSpec]] = Field( default=None, description="List of files for bulk create/update operations" ) file_paths: Optional[List[str]] = Field( default=None, description="List of file paths for bulk read operations" ) atomic: bool = Field( default=True, description="Atomic mode: rollback all on error (for bulk create)" )
  • `get_tool_definition()` method returning the `mcp.types.Tool` object for 'skill_files_crud' with name, detailed description, and inputSchema from `SkillFilesCrudInput.model_json_schema()`.
    @staticmethod def get_tool_definition() -> list[types.Tool]: """Get tool definition.""" return [ types.Tool( name="skill_files_crud", description="""Unified CRUD tool for skill file operations. Supports both single and bulk operations. IMPORTANT PATH NOTES: - All file paths are RELATIVE to the skill directory (e.g., 'main.py', 'scripts/utils.py') - NEVER use absolute paths (e.g., NOT '/Users/username/.skill-mcp/skills/my-skill/main.py') - To execute scripts, use the 'run_skill_script' tool, NOT external bash/shell tools **Operations:** - **read**: Read a file's content - **create**: Create one or more files (supports atomic mode for bulk) - **update**: Update one or more files - **delete**: Delete a file (SKILL.md is protected and cannot be deleted) **Single File Examples:** ```json // Read a file {"operation": "read", "skill_name": "my-skill", "file_path": "script.py"} // Create a single file {"operation": "create", "skill_name": "my-skill", "file_path": "new.py", "content": "print('hello')"} // Update a single file {"operation": "update", "skill_name": "my-skill", "file_path": "script.py", "content": "print('updated')"} // Delete a file {"operation": "delete", "skill_name": "my-skill", "file_path": "old.py"} ``` **Bulk File Examples:** ```json // Read multiple files { "operation": "read", "skill_name": "my-skill", "file_paths": ["file1.py", "file2.py", "file3.py"] } // Create multiple files atomically (all-or-nothing) { "operation": "create", "skill_name": "my-skill", "files": [ {"path": "src/main.py", "content": "# Main"}, {"path": "src/utils.py", "content": "# Utils"}, {"path": "README.md", "content": "# Docs"} ], "atomic": true } // Update multiple files { "operation": "update", "skill_name": "my-skill", "files": [ {"path": "file1.py", "content": "new content 1"}, {"path": "file2.py", "content": "new content 2"} ] } ```""", inputSchema=SkillFilesCrudInput.model_json_schema(), ) ]
  • MCP server `list_tools()` handler that extends the tools list with `SkillFilesCrud.get_tool_definition()`, registering the tool.
    @app.list_tools() # type: ignore[misc] async def list_tools() -> list[types.Tool]: """List available tools.""" tools = [] tools.extend(SkillCrud.get_tool_definition()) tools.extend(SkillFilesCrud.get_tool_definition()) tools.extend(SkillEnvCrud.get_tool_definition()) tools.extend(ScriptTools.get_script_tools()) return tools
  • Dispatch branch in top-level `@app.call_tool()` handler that parses arguments into `SkillFilesCrudInput` and invokes `SkillFilesCrud.skill_files_crud()`.
    elif name == "skill_files_crud": files_input = SkillFilesCrudInput(**arguments) return await SkillFilesCrud.skill_files_crud(files_input)

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/fkesheh/skill-mcp'

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