tool-design

Create custom tools for domain-specific agents using the @tool decorator.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "tool-design" with this command: npx skills add melodic-software/claude-code-plugins/melodic-software-claude-code-plugins-tool-design

Tool Design Skill

Create custom tools for domain-specific agents using the @tool decorator.

Purpose

Design and implement custom tools that give agents specialized capabilities for domain-specific operations.

When to Use

  • Agent needs capabilities beyond default tools

  • Domain requires specialized operations

  • Building focused, efficient agents

  • Creating reusable tool libraries

Prerequisites

  • Understanding of @tool decorator syntax

  • Knowledge of MCP server creation

  • Clear definition of tool purpose

Design Process

Step 1: Define Tool Purpose

Answer:

  • What operation does this tool perform?

  • What inputs does it need?

  • What output does it produce?

  • When should the agent use this tool?

Step 2: Design Tool Interface

Tool Signature:

@tool( "tool_name", # Unique identifier "Description for agent", # How agent knows when to use {"param1": type, "param2": type} # Parameter schema ) async def tool_implementation(args: dict) -> dict: pass

Naming Convention:

  • Use snake_case for tool names

  • Be descriptive: calculate_compound_interest not calc

  • Prefix with domain: db_query , api_call

Description Guidelines:

  • Explain WHEN to use the tool

  • Explain WHAT it does

  • Include any constraints

Step 3: Define Parameters

Parameter Types:

{ "text_param": str, # String "number_param": int, # Integer "decimal_param": float, # Float "flag_param": bool, # Boolean }

Required vs Optional:

async def my_tool(args: dict) -> dict: # Required - must exist required = args["required_param"]

# Optional - with default
optional = args.get("optional_param", "default")

Step 4: Implement Tool Logic

Basic Template:

@tool( "tool_name", "Description", {"param1": str, "param2": int} ) async def tool_name(args: dict) -> dict: try: # 1. Extract and validate inputs param1 = args["param1"] param2 = args.get("param2", 10)

    # 2. Perform operation
    result = perform_operation(param1, param2)

    # 3. Return success
    return {
        "content": [{"type": "text", "text": str(result)}]
    }

except Exception as e:
    # 4. Handle errors
    return {
        "content": [{"type": "text", "text": f"Error: {str(e)}"}],
        "is_error": True
    }

Step 5: Add Error Handling

Validation Pattern:

async def my_tool(args: dict) -> dict: # Validate required params if "required" not in args: return error_response("Missing required parameter")

# Validate types
if not isinstance(args["required"], str):
    return error_response("Parameter must be string")

# Validate values
if args.get("limit", 0) < 0:
    return error_response("Limit cannot be negative")

# Security validation
if is_dangerous(args["input"]):
    return error_response("Security: Operation blocked")

Error Response Helper:

def error_response(message: str) -> dict: return { "content": [{"type": "text", "text": message}], "is_error": True }

def success_response(result: str) -> dict: return { "content": [{"type": "text", "text": result}] }

Step 6: Create MCP Server

from claude_agent_sdk import create_sdk_mcp_server

Create server with tools

my_server = create_sdk_mcp_server( name="my_domain", version="1.0.0", tools=[ tool_one, tool_two, tool_three, ] )

Step 7: Configure Agent

options = ClaudeAgentOptions( mcp_servers={"my_domain": my_server}, allowed_tools=[ "mcp__my_domain__tool_one", "mcp__my_domain__tool_two", "mcp__my_domain__tool_three", ], # Disable unused default tools disallowed_tools=["WebFetch", "WebSearch", "TodoWrite"], system_prompt=system_prompt, model="opus", )

Tool Categories

Data Processing Tools

@tool("parse_json", "Parse JSON string", {"json_str": str}) @tool("transform_data", "Transform data format", {"data": str, "format": str}) @tool("validate_schema", "Validate against schema", {"data": str, "schema": str})

Domain Operation Tools

@tool("calculate_metric", "Calculate business metric", {"values": str, "metric": str}) @tool("lookup_reference", "Look up reference data", {"key": str}) @tool("process_record", "Process domain record", {"record": str})

Integration Tools

@tool("query_database", "Execute DB query", {"query": str}) @tool("call_api", "Call external API", {"endpoint": str, "method": str}) @tool("send_notification", "Send notification", {"channel": str, "message": str})

Output Format

When designing a tool:

Tool Design

Name: [tool_name] Purpose: [what it does] Domain: [where it's used]

Interface

@tool( "tool_name", "Description for agent usage", {"param1": str, "param2": int} )

Parameters

NameTypeRequiredDescription
param1strYes[description]
param2intNo[description], default: 10

Return Format

Success:

{"content": [{"type": "text", "text": "[result format]"}]}

Error:

{"content": [{"type": "text", "text": "Error: [message]"}], "is_error": true}

Implementation

[Full implementation code]

Usage Example

Agent prompt: "[example prompt that uses tool]" Tool call: tool_name(param1="value", param2=20) Result: "[expected result]"

Design Checklist

  • Tool name is descriptive

  • Description explains when to use

  • Parameter types are defined

  • Required vs optional is clear

  • Input validation is complete

  • Error handling is robust

  • Security checks are in place

  • Return format is consistent

Critical: Client vs Query

Warning: Custom tools require ClaudeSDKClient , not query()

WRONG

async for message in query(prompt, options=options): pass

CORRECT

async with ClaudeSDKClient(options=options) as client: await client.query(prompt) async for message in client.receive_response(): pass

Cross-References

  • @custom-tool-patterns.md - Tool creation patterns

  • @core-four-custom.md - Tools in Core Four

  • @custom-agent-design skill - Agent design workflow

Version History

  • v1.0.0 (2025-12-26): Initial release

Last Updated

Date: 2025-12-26 Model: claude-opus-4-5-20251101

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

design-thinking

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

plantuml-syntax

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

system-prompt-engineering

No summary provided by upstream source.

Repository SourceNeeds Review