Tool definition and parameter validation in MCP are critical for ensuring system stability and usability. Here are detailed implementation methods:
Tool Definition Structure
Each MCP tool needs to define the following properties:
python{ "name": "tool_name", "description": "Detailed description of the tool", "inputSchema": { "type": "object", "properties": { "param1": { "type": "string", "description": "Description of parameter 1" }, "param2": { "type": "number", "description": "Description of parameter 2", "minimum": 0, "maximum": 100 } }, "required": ["param1"] } }
1. Parameter Type Definitions
MCP supports the following parameter types:
- string: String type
- number: Number type (integer or float)
- integer: Integer type
- boolean: Boolean type
- array: Array type
- object: Object type
- null: Null value
python{ "name": "search_database", "inputSchema": { "type": "object", "properties": { "query": { "type": "string", "description": "Search query string", "minLength": 1, "maxLength": 500 }, "limit": { "type": "integer", "description": "Limit on number of results returned", "minimum": 1, "maximum": 100, "default": 10 }, "filters": { "type": "object", "description": "Filter conditions", "properties": { "category": {"type": "string"}, "date_range": { "type": "object", "properties": { "start": {"type": "string", "format": "date"}, "end": {"type": "string", "format": "date"} } } } }, "sort_by": { "type": "string", "enum": ["relevance", "date", "popularity"], "description": "Sort order" } }, "required": ["query"] } }
2. Parameter Validation Implementation
pythonfrom typing import Any, Dict, List import re class ParameterValidator: def __init__(self, schema: Dict[str, Any]): self.schema = schema def validate(self, params: Dict[str, Any]) -> tuple[bool, str]: """Validate parameters""" # Check required parameters required = self.schema.get("required", []) for param in required: if param not in params: return False, f"Missing required parameter: {param}" # Validate each parameter properties = self.schema.get("properties", {}) for param_name, param_value in params.items(): if param_name not in properties: return False, f"Unknown parameter: {param_name}" param_schema = properties[param_name] is_valid, error = self._validate_param( param_value, param_schema ) if not is_valid: return False, f"Parameter '{param_name}' validation failed: {error}" return True, "" def _validate_param(self, value: Any, schema: Dict[str, Any]) -> tuple[bool, str]: """Validate single parameter""" param_type = schema.get("type") # Type validation if param_type == "string": if not isinstance(value, str): return False, "Expected string type" # String length validation if "minLength" in schema and len(value) < schema["minLength"]: return False, f"String length cannot be less than {schema['minLength']}" if "maxLength" in schema and len(value) > schema["maxLength"]: return False, f"String length cannot exceed {schema['maxLength']}" # Regex validation if "pattern" in schema: if not re.match(schema["pattern"], value): return False, "Format mismatch" elif param_type == "number": if not isinstance(value, (int, float)): return False, "Expected number type" if "minimum" in schema and value < schema["minimum"]: return False, f"Value cannot be less than {schema['minimum']}" if "maximum" in schema and value > schema["maximum"]: return False, f"Value cannot be greater than {schema['maximum']}" elif param_type == "integer": if not isinstance(value, int): return False, "Expected integer type" elif param_type == "boolean": if not isinstance(value, bool): return False, "Expected boolean type" elif param_type == "array": if not isinstance(value, list): return False, "Expected array type" if "minItems" in schema and len(value) < schema["minItems"]: return False, f"Array length cannot be less than {schema['minItems']}" if "maxItems" in schema and len(value) > schema["maxItems"]: return False, f"Array length cannot exceed {schema['maxItems']}" elif param_type == "object": if not isinstance(value, dict): return False, "Expected object type" # Enum value validation if "enum" in schema and value not in schema["enum"]: return False, f"Value must be one of: {schema['enum']}" return True, ""
3. Tool Description Best Practices
python# Good tool description example { "name": "execute_sql_query", "description": """Execute SQL query in database and return results. This tool supports SELECT queries for retrieving, aggregating, and analyzing data. Query results are returned in tabular format with column names and data rows. Notes: - Only SELECT queries are supported, no INSERT, UPDATE, DELETE - Query timeout is 30 seconds - Maximum 1000 rows returned """, "inputSchema": { "type": "object", "properties": { "query": { "type": "string", "description": "SQL query statement (SELECT only)", "minLength": 1 }, "database": { "type": "string", "description": "Database name", "enum": ["production", "staging", "analytics"] } }, "required": ["query"] } }
4. Advanced Parameter Validation
pythonclass AdvancedValidator(ParameterValidator): def _validate_param(self, value: Any, schema: Dict[str, Any]) -> tuple[bool, str]: # Call parent validation is_valid, error = super()._validate_param(value, schema) if not is_valid: return False, error # Custom validation if "format" in schema: is_valid, error = self._validate_format(value, schema["format"]) if not is_valid: return False, error if "customValidator" in schema: is_valid, error = schema["customValidator"](value) if not is_valid: return False, error return True, "" def _validate_format(self, value: Any, format_type: str) -> tuple[bool, str]: """Validate format""" if format_type == "email": if not re.match(r'^[^@]+@[^@]+\.[^@]+$', value): return False, "Invalid email format" elif format_type == "uri": if not re.match(r'^https?://', value): return False, "Invalid URI format" elif format_type == "date": try: from datetime import datetime datetime.strptime(value, "%Y-%m-%d") except ValueError: return False, "Invalid date format (YYYY-MM-DD)" return True, ""
5. Error Handling
pythondef handle_tool_call(tool_name: str, params: Dict[str, Any]) -> Dict[str, Any]: """Handle tool call""" try: # Get tool definition tool = get_tool_definition(tool_name) # Validate parameters validator = ParameterValidator(tool["inputSchema"]) is_valid, error = validator.validate(params) if not is_valid: return { "success": False, "error": f"Parameter validation failed: {error}", "error_code": "INVALID_PARAMS" } # Execute tool result = execute_tool(tool_name, params) return { "success": True, "result": result } except Exception as e: return { "success": False, "error": f"Tool execution failed: {str(e)}", "error_code": "EXECUTION_ERROR" }
Through comprehensive tool definition and parameter validation mechanisms, you can ensure the stability and reliability of MCP systems.