Skip to main content
Glama
hanweg

mcp-tool-builder

by hanweg

create_tool

Build custom Python tools by defining their name, purpose, and implementation code to extend server functionality.

Instructions

Create a new Python tool with specified functionality

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
tool_nameYesName of the new tool
descriptionYesDescription of what the tool should do
codeYesPython code implementing the tool

Implementation Reference

  • Implements the core logic of the create_tool: validates Python code syntax, checks for duplicates, saves the tool code to a .py file, parses the function to extract parameters using AST, creates tool configuration, appends to tools_config, saves to tools.json, reloads tools, and returns a success message with restart instructions.
    async def _create_tool(self, tool_name: str, description: str, code: str) -> str:
        try:
            # Validate the code is Python
            try:
                ast.parse(code)
            except SyntaxError:
                return f"Error: Invalid Python syntax in the tool code for {tool_name}"
    
            if any(tool["name"] == tool_name for tool in self.tools_config):
                return f"Tool {tool_name} already exists"
    
            tool_path = self.tools_dir / f"{tool_name}.py"
            tool_path.write_text(code)
    
            # Parse the function definition
            tree = ast.parse(code)
            func_def = next(
                (node for node in ast.walk(tree) 
                if isinstance(node, ast.FunctionDef) and node.name == tool_name), 
                None
            )
    
            if not func_def:
                return f"Error: Could not find a function named {tool_name} in the provided code"
    
            # Extract parameters
            parameters = {
                arg.arg: "string" 
                for arg in func_def.args.args 
                if arg.arg != "self"
            }
    
            tool_config = {
                "name": tool_name,
                "description": description,
                "parameters": parameters,
                "file": f"{tool_name}.py",  # Store relative path
                "function": tool_name
            }
            self.tools_config.append(tool_config)
            
            tools_json_path = self.tools_dir / "tools.json"
            tools_json_path.write_text(json.dumps(self.tools_config, indent=4))
    
            self.reload_tools()
                        
            # Return success message with explicit restart instructions
            return (f"Tool '{tool_name}' has been successfully created and will be available after client restart.\n"
                f"Description: {description}\n"
                f"Status: Added to tools.json\n"
                "IMPORTANT: You must restart Claude Desktop before you can use this tool.\n"
                "Please restart the client before attempting to use the newly created tool.")
    
        except Exception as e:
            # Ensure a string is always returned, even in error cases
            return f"Error creating tool: {str(e)}" or "Unknown tool creation error"
  • Defines the Tool object for 'create_tool' including its name, description, and input schema specifying required parameters: tool_name (string), description (string), and code (string).
    types.Tool(
        name="create_tool",
        description="Create a new Python tool with specified functionality",
        inputSchema={
            "type": "object",
            "properties": {
                "tool_name": {
                    "type": "string",
                    "description": "Name of the new tool"
                },
                "description": {
                    "type": "string", 
                    "description": "Description of what the tool should do"
                },
                "code": {
                    "type": "string",
                    "description": "Python code implementing the tool"
                }
            },
            "required": ["tool_name", "description", "code"]
        }
    ),
  • In the handle_call_tool method (decorated with @self.server.call_tool()), checks if the requested tool name is 'create_tool' and dispatches to the _create_tool handler, returning the result as TextContent.
    if name == "create_tool":
        result = await self._create_tool(
            arguments["tool_name"],
            arguments["description"],
            arguments["code"]
        )
        return [types.TextContent(
            type="text",
            text=result
        )]

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/hanweg/mcp-tool-builder'

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