Skip to content

MCP Custom Tools Example

Mo Abualruz edited this page Dec 6, 2025 · 1 revision

MCP Custom Tools Example

Status: ✅ Complete

Last Updated: December 6, 2025


Overview

This example demonstrates defining custom tools in RiceCoder without creating an MCP server. Custom tools are defined in JSON or Markdown format and are automatically registered.

Setup

1. Create Custom Tools Configuration

Create .ricecoder/custom-tools.json:

{
  "tools": [
    {
      "id": "calculate-sum",
      "name": "Calculate Sum",
      "description": "Add two numbers together",
      "category": "math",
      "parameters": [
        {
          "name": "a",
          "type": "number",
          "description": "First number",
          "required": true
        },
        {
          "name": "b",
          "type": "number",
          "description": "Second number",
          "required": true
        }
      ],
      "return_type": "number",
      "handler": "math::sum"
    },
    {
      "id": "format-json",
      "name": "Format JSON",
      "description": "Format and validate JSON",
      "category": "validation",
      "parameters": [
        {
          "name": "json",
          "type": "string",
          "description": "JSON string to format",
          "required": true
        },
        {
          "name": "indent",
          "type": "number",
          "description": "Indentation spaces",
          "required": false,
          "default": 2
        }
      ],
      "return_type": "string",
      "handler": "validation::format_json"
    },
    {
      "id": "validate-email",
      "name": "Validate Email",
      "description": "Validate email address",
      "category": "validation",
      "parameters": [
        {
          "name": "email",
          "type": "string",
          "description": "Email address to validate",
          "required": true
        }
      ],
      "return_type": "object",
      "handler": "validation::validate_email"
    }
  ]
}

2. Verify Tools Are Registered

ricecoder tools list

Expected output:

Available Tools:

calculate-sum (custom)
  Description: Add two numbers together
  Category: math
  Parameters: a (number, required), b (number, required)
  Returns: number

format-json (custom)
  Description: Format and validate JSON
  Category: validation
  Parameters: json (string, required), indent (number, optional)
  Returns: string

validate-email (custom)
  Description: Validate email address
  Category: validation
  Parameters: email (string, required)
  Returns: object

3. Configure Permissions

Create .ricecoder/permissions.yaml:

permissions:
  # Allow all custom tools
  - pattern: "calculate-*"
    level: allow
  
  - pattern: "format-*"
    level: allow
  
  - pattern: "validate-*"
    level: allow

Usage Examples

Example 1: Calculate Sum

ricecoder tools invoke calculate-sum \
  --a 10 \
  --b 20

Output:

{
  "success": true,
  "result": 30
}

Example 2: Format JSON

ricecoder tools invoke format-json \
  --json '{"name":"Alice","age":30,"email":"alice@example.com"}' \
  --indent 2

Output:

{
  "success": true,
  "result": "{\n  \"name\": \"Alice\",\n  \"age\": 30,\n  \"email\": \"alice@example.com\"\n}"
}

Example 3: Validate Email

ricecoder tools invoke validate-email \
  --email "alice@example.com"

Output:

{
  "success": true,
  "valid": true,
  "email": "alice@example.com",
  "domain": "example.com"
}

Example 4: Invalid Email

ricecoder tools invoke validate-email \
  --email "invalid-email"

Output:

{
  "success": true,
  "valid": false,
  "email": "invalid-email",
  "error": "Invalid email format"
}

Markdown Format Example

Alternatively, define custom tools in Markdown format:

Create .ricecoder/custom-tools.md:

# Custom Tools

## Calculate Sum

- **ID**: calculate-sum
- **Category**: math
- **Description**: Add two numbers together

### Parameters

- **a** (number, required): First number
- **b** (number, required): Second number

### Returns

number

---

## Format JSON

- **ID**: format-json
- **Category**: validation
- **Description**: Format and validate JSON

### Parameters

- **json** (string, required): JSON string to format
- **indent** (number, optional): Indentation spaces (default: 2)

### Returns

string

---

## Validate Email

- **ID**: validate-email
- **Category**: validation
- **Description**: Validate email address

### Parameters

- **email** (string, required): Email address to validate

### Returns

object

Integration with Agents

Code Generator Agent

The code generator can use custom tools to:

  • Validate generated code
  • Format code output
  • Validate configuration
// Generate code
let generated_code = generate_code(&spec);

// Format generated code
let formatted = agent.invoke_tool("format-json",
  json!({"json": generated_code})
).await?;

// Return formatted code
Ok(formatted)

Validation Agent

The validation agent can use custom tools to:

  • Validate email addresses
  • Validate JSON configuration
  • Validate data formats
// Validate email
let result = agent.invoke_tool("validate-email",
  json!({"email": user_email})
).await?;

if !result["valid"].as_bool().unwrap_or(false) {
  return Err("Invalid email address".into());
}

Data Processing Agent

The data processing agent can use custom tools to:

  • Calculate statistics
  • Format data
  • Validate data
// Calculate sum
let sum = agent.invoke_tool("calculate-sum",
  json!({"a": 100, "b": 200})
).await?;

// Format result
let formatted = agent.invoke_tool("format-json",
  json!({"json": sum.to_string()})
).await?;

Configuration Files

.ricecoder/custom-tools.json

{
  "tools": [
    {
      "id": "calculate-sum",
      "name": "Calculate Sum",
      "description": "Add two numbers together",
      "category": "math",
      "parameters": [
        {
          "name": "a",
          "type": "number",
          "description": "First number",
          "required": true
        },
        {
          "name": "b",
          "type": "number",
          "description": "Second number",
          "required": true
        }
      ],
      "return_type": "number",
      "handler": "math::sum"
    },
    {
      "id": "format-json",
      "name": "Format JSON",
      "description": "Format and validate JSON",
      "category": "validation",
      "parameters": [
        {
          "name": "json",
          "type": "string",
          "description": "JSON string to format",
          "required": true
        },
        {
          "name": "indent",
          "type": "number",
          "description": "Indentation spaces",
          "required": false,
          "default": 2
        }
      ],
      "return_type": "string",
      "handler": "validation::format_json"
    },
    {
      "id": "validate-email",
      "name": "Validate Email",
      "description": "Validate email address",
      "category": "validation",
      "parameters": [
        {
          "name": "email",
          "type": "string",
          "description": "Email address to validate",
          "required": true
        }
      ],
      "return_type": "object",
      "handler": "validation::validate_email"
    }
  ]
}

.ricecoder/permissions.yaml

permissions:
  # Allow all custom tools
  - pattern: "calculate-*"
    level: allow
  
  - pattern: "format-*"
    level: allow
  
  - pattern: "validate-*"
    level: allow

Advanced Examples

Example 1: Multiple Math Tools

{
  "tools": [
    {
      "id": "calculate-sum",
      "name": "Calculate Sum",
      "description": "Add two numbers",
      "category": "math",
      "parameters": [
        {"name": "a", "type": "number", "required": true},
        {"name": "b", "type": "number", "required": true}
      ],
      "return_type": "number",
      "handler": "math::sum"
    },
    {
      "id": "calculate-product",
      "name": "Calculate Product",
      "description": "Multiply two numbers",
      "category": "math",
      "parameters": [
        {"name": "a", "type": "number", "required": true},
        {"name": "b", "type": "number", "required": true}
      ],
      "return_type": "number",
      "handler": "math::product"
    },
    {
      "id": "calculate-average",
      "name": "Calculate Average",
      "description": "Calculate average of numbers",
      "category": "math",
      "parameters": [
        {"name": "numbers", "type": "array", "required": true}
      ],
      "return_type": "number",
      "handler": "math::average"
    }
  ]
}

Example 2: Validation Tools

{
  "tools": [
    {
      "id": "validate-email",
      "name": "Validate Email",
      "description": "Validate email address",
      "category": "validation",
      "parameters": [
        {"name": "email", "type": "string", "required": true}
      ],
      "return_type": "object",
      "handler": "validation::validate_email"
    },
    {
      "id": "validate-url",
      "name": "Validate URL",
      "description": "Validate URL",
      "category": "validation",
      "parameters": [
        {"name": "url", "type": "string", "required": true}
      ],
      "return_type": "object",
      "handler": "validation::validate_url"
    },
    {
      "id": "validate-json",
      "name": "Validate JSON",
      "description": "Validate JSON string",
      "category": "validation",
      "parameters": [
        {"name": "json", "type": "string", "required": true}
      ],
      "return_type": "object",
      "handler": "validation::validate_json"
    }
  ]
}

Troubleshooting

Tool Not Registered

Problem: Custom tool not appearing in tool list

Checklist:

  • Configuration file exists: .ricecoder/custom-tools.json
  • JSON syntax is valid
  • Tool ID is unique
  • All required fields are present

Debug:

# Validate configuration
ricecoder config validate

# List tools
ricecoder tools list

# Check configuration
cat .ricecoder/custom-tools.json

Invalid JSON

Error: Invalid configuration: JSON parse error

Solutions:

  1. Validate JSON syntax: jq . .ricecoder/custom-tools.json
  2. Check for missing commas
  3. Check for unclosed braces
  4. Use JSON formatter to fix

Handler Not Found

Error: Handler 'math::sum' not found

Solutions:

  1. Verify handler name is correct
  2. Check handler is implemented
  3. Verify handler is in correct module
  4. Check handler is exported

See Also


Last updated: December 6, 2025

Clone this wiki locally