-
Notifications
You must be signed in to change notification settings - Fork 0
MCP Custom Tools Example
Status: ✅ Complete
Last Updated: December 6, 2025
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.
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"
}
]
}ricecoder tools listExpected 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
Create .ricecoder/permissions.yaml:
permissions:
# Allow all custom tools
- pattern: "calculate-*"
level: allow
- pattern: "format-*"
level: allow
- pattern: "validate-*"
level: allowricecoder tools invoke calculate-sum \
--a 10 \
--b 20Output:
{
"success": true,
"result": 30
}ricecoder tools invoke format-json \
--json '{"name":"Alice","age":30,"email":"alice@example.com"}' \
--indent 2Output:
{
"success": true,
"result": "{\n \"name\": \"Alice\",\n \"age\": 30,\n \"email\": \"alice@example.com\"\n}"
}ricecoder tools invoke validate-email \
--email "alice@example.com"Output:
{
"success": true,
"valid": true,
"email": "alice@example.com",
"domain": "example.com"
}ricecoder tools invoke validate-email \
--email "invalid-email"Output:
{
"success": true,
"valid": false,
"email": "invalid-email",
"error": "Invalid email format"
}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
objectThe 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)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());
}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?;{
"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"
}
]
}permissions:
# Allow all custom tools
- pattern: "calculate-*"
level: allow
- pattern: "format-*"
level: allow
- pattern: "validate-*"
level: allow{
"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"
}
]
}{
"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"
}
]
}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.jsonError: Invalid configuration: JSON parse error
Solutions:
- Validate JSON syntax:
jq . .ricecoder/custom-tools.json - Check for missing commas
- Check for unclosed braces
- Use JSON formatter to fix
Error: Handler 'math::sum' not found
Solutions:
- Verify handler name is correct
- Check handler is implemented
- Verify handler is in correct module
- Check handler is exported
- MCP Integration
- Custom Tool Definition
- Permission Configuration
- MCP Database Server Example
- MCP API Service Example
Last updated: December 6, 2025