Skip to main content
Glama
IBM
by IBM
validation.mdx14.1 kB
--- title: "Parameter Validation" description: "Understanding parameter validation, error handling, and SQL injection prevention in SQL tools" --- # Parameter Validation All parameters are validated before SQL execution to ensure type safety, constraint compliance, and security. This validation process prevents errors and protects against SQL injection attacks. <Note> Parameter validation happens automatically—you just need to define constraints in your tool configuration. The server handles all validation logic. </Note> ## Validation Process Parameters go through a four-step validation process before being bound to SQL statements: ### 1. Type Validation **What it checks:** Values must match the declared type (`string`, `integer`, `float`, `boolean`, or `array`) **Examples:** <CodeGroup> ```yaml Parameter Definition parameters: - name: max_rows type: integer description: "Maximum rows to return" ``` ```json ✅ Valid { "max_rows": 100 } ``` ```json ❌ Invalid { "max_rows": "100" // String instead of integer } ``` </CodeGroup> **Error Message:** ``` Expected integer, got string for parameter 'max_rows' ``` --- ### 2. Constraint Validation **What it checks:** Values must satisfy all defined constraints (min/max, length, pattern, enum) **String Constraints:** <Tabs> <Tab title="minLength / maxLength"> ```yaml parameters: - name: object_name type: string minLength: 1 maxLength: 10 ``` ```json // ❌ Too short {"object_name": ""} // Error: String length 0 is less than minimum 1 // ❌ Too long {"object_name": "VERYLONGOBJECTNAME"} // Error: String length 18 exceeds maximum 10 // ✅ Valid {"object_name": "MYOBJECT"} ``` </Tab> <Tab title="pattern"> ```yaml parameters: - name: library_name type: string pattern: "^[A-Z][A-Z0-9_]*$" ``` ```json // ❌ Invalid pattern {"library_name": "my_lib"} // Error: Value does not match pattern: ^[A-Z][A-Z0-9_]*$ // ✅ Valid {"library_name": "MY_LIB"} ``` </Tab> <Tab title="enum"> ```yaml parameters: - name: object_type type: string enum: [TABLE, VIEW, INDEX] ``` ```json // ❌ Invalid value {"object_type": "FUNCTION"} // Error: Value 'FUNCTION' must be one of: 'TABLE', 'VIEW', 'INDEX' // ✅ Valid {"object_type": "TABLE"} ``` </Tab> </Tabs> **Numeric Constraints:** <Tabs> <Tab title="Integer min/max"> ```yaml parameters: - name: months_unused type: integer min: 1 max: 120 ``` ```json // ❌ Below minimum {"months_unused": 0} // Error: Value 0 is less than minimum 1 // ❌ Above maximum {"months_unused": 150} // Error: Value 150 exceeds maximum 120 // ✅ Valid {"months_unused": 6} ``` </Tab> <Tab title="Float min/max"> ```yaml parameters: - name: cpu_threshold type: float min: 0.0 max: 100.0 ``` ```json // ❌ Out of range {"cpu_threshold": 150.5} // Error: Value 150.5 exceeds maximum 100.0 // ✅ Valid {"cpu_threshold": 85.5} ``` </Tab> </Tabs> **Array Constraints:** ```yaml parameters: - name: project_ids type: array itemType: string minLength: 1 maxLength: 10 ``` <CodeGroup> ```json ❌ Empty array { "project_ids": [] } // Error: Array length 0 is less than minimum 1 ``` ```json ❌ Too many items { "project_ids": ["P1", "P2", "P3", "P4", "P5", "P6", "P7", "P8", "P9", "P10", "P11"] } // Error: Array length 11 exceeds maximum 10 ``` ```json ✅ Valid { "project_ids": ["MA2100", "AD3100", "PL2100"] } ``` </CodeGroup> --- ### 3. SQL Security **What it does:** Parameters are bound securely using prepared statements to prevent SQL injection **How it works:** <Tabs> <Tab title="Parameter Binding"> **Your YAML configuration:** ```yaml statement: | SELECT * FROM SAMPLE.EMPLOYEE WHERE EMPNO = :employee_id AND WORKDEPT = :department ``` **What happens internally:** 1. SQL is prepared with placeholders: `SELECT * FROM SAMPLE.EMPLOYEE WHERE EMPNO = ? AND WORKDEPT = ?` 2. Parameters are bound safely: `employee_id` → first `?`, `department` → second `?` 3. Values never concatenated into SQL string 4. SQL injection attempts fail automatically </Tab> <Tab title="Array Expansion"> **Your YAML configuration:** ```yaml statement: | SELECT * FROM SAMPLE.PROJECT WHERE PROJNO IN (:project_ids) ``` **What happens internally:** 1. Input: `{"project_ids": ["MA2100", "AD3100", "PL2100"]}` 2. SQL prepared with multiple placeholders: `WHERE PROJNO IN (?, ?, ?)` 3. Each array element bound to a placeholder 4. Safe against injection even with dynamic array lengths </Tab> </Tabs> <Success> **Security Guarantee**: All parameters use prepared statement parameter binding. SQL injection is not possible through parameters, regardless of input values. </Success> --- ### 4. Required Check **What it checks:** Required parameters must be provided (unless they have default values) **Examples:** <CodeGroup> ```yaml Parameter Definition parameters: - name: library_name type: string required: true # Must be provided - name: max_rows type: integer required: false default: 100 # Optional with default - name: name_filter type: string required: false # Optional, NULL if not provided ``` ```json ❌ Missing required parameter { "max_rows": 50 } // Error: Required parameter 'library_name' not provided ``` ```json ✅ All required parameters present { "library_name": "MYLIB", "max_rows": 50 // name_filter omitted - will be NULL } ``` ```json ✅ Using defaults { "library_name": "MYLIB" // max_rows omitted - will be 100 (default) // name_filter omitted - will be NULL } ``` </CodeGroup> --- ## Common Validation Errors ### Type Mismatch Errors | Error Message | Cause | Solution | |---------------|-------|----------| | `Expected integer, got string` | Passed `"100"` instead of `100` | Remove quotes from numbers | | `Expected string, got integer` | Passed `100` instead of `"100"` | Add quotes around strings | | `Expected boolean, got string` | Passed `"true"` instead of `true` | Use boolean literals | | `Expected array, got string` | Passed `"A,B,C"` instead of `["A","B","C"]` | Use JSON array format | ### Range/Length Errors | Error Message | Cause | Solution | |---------------|-------|----------| | `Value X is less than minimum Y` | Number below `min` constraint | Increase value to meet minimum | | `Value X exceeds maximum Y` | Number above `max` constraint | Decrease value to meet maximum | | `String length X is less than minimum Y` | String too short | Add more characters | | `String length X exceeds maximum Y` | String too long | Shorten the string | ### Pattern/Enum Errors | Error Message | Cause | Solution | |---------------|-------|----------| | `Value does not match pattern: ...` | String doesn't match regex | Follow the required format | | `Value 'X' must be one of: ...` | Value not in enum list | Use one of the allowed values | ### Required Parameter Errors | Error Message | Cause | Solution | |---------------|-------|----------| | `Required parameter 'X' not provided` | Missing required parameter | Include the parameter in request | | `Parameter 'X' is required` | NULL value for required param | Provide a non-NULL value | --- ## Security Benefits ### SQL Injection Prevention Parameter binding provides automatic SQL injection protection: <Accordion title="How SQL Injection Attacks Fail"> **Malicious Input Attempt:** ```json { "employee_id": "000010' OR '1'='1" } ``` **What happens:** 1. Value treated as literal string: `'000010' OR '1'='1'` 2. Compared against `EMPNO` column as-is 3. No match found (no employee with that literal ID) 4. Query returns empty result set 5. **Attack fails** - SQL is never modified **Why it's safe:** - Parameters are bound, not concatenated - Special characters like `'` are escaped automatically - SQL structure cannot be altered through parameters </Accordion> ### Type Safety Type validation prevents data corruption and unexpected errors: <Accordion title="Type Safety Benefits"> - **Prevents crashes**: No runtime type errors from invalid data - **Ensures consistency**: Database columns receive correct data types - **Catches bugs early**: Invalid data rejected before query execution - **Improves debugging**: Clear error messages identify problems immediately </Accordion> ### Constraint Enforcement Constraints protect against invalid business logic: <Accordion title="Constraint Benefits"> - **Range limits**: Prevent nonsensical values (negative ages, 200% CPU usage) - **Format validation**: Ensure IBM i naming conventions are followed - **Enum restrictions**: Limit choices to valid options - **Length limits**: Prevent buffer overflows and excessive data </Accordion> --- ## Debugging Validation Errors ### Reading Error Messages Validation errors follow a consistent format: ``` [Parameter Name]: [Error Description] Example: months_unused: Value 150 exceeds maximum 120 ``` **Error components:** 1. **Parameter name**: Which parameter failed validation 2. **Error description**: Why validation failed 3. **Context**: Expected vs. actual values ### Common Debugging Steps <Steps> <Step title="Check the parameter type"> Ensure you're passing the correct JSON type (number vs. string, array vs. string) </Step> <Step title="Review constraints"> Check min/max, length, pattern, and enum constraints in the tool definition </Step> <Step title="Verify required parameters"> Confirm all required parameters are present in the request </Step> <Step title="Test with simple values"> Try minimal valid values to isolate the issue </Step> <Step title="Check special characters"> For pattern validation, ensure special characters are allowed </Step> </Steps> ### Testing Parameter Validation **Good practice:** Test parameter validation before deploying tools: ```bash # Test with invalid values to see error messages curl -X POST http://localhost:3010/mcp/tools/call \ -H "Content-Type: application/json" \ -d '{ "name": "my_tool", "arguments": { "months_unused": 999 # Intentionally invalid } }' ``` --- ## Best Practices <CardGroup cols={2}> <Card title="Use Appropriate Constraints" icon="sliders"> - Don't over-constrain: Allow reasonable ranges - Don't under-constrain: Prevent invalid business logic - Use enum for fixed value sets - Use pattern for format validation </Card> <Card title="Provide Clear Descriptions" icon="message"> - Explain validation rules in descriptions - Include examples of valid values - Document special values (*LIBL, etc.) - Mention units for numeric parameters </Card> <Card title="Test Edge Cases" icon="vial"> - Test minimum and maximum values - Test boundary conditions - Test with NULL values - Test with empty strings/arrays </Card> <Card title="Handle Optional Parameters" icon="toggle-off"> - Use defaults for common values - Check for NULL in SQL when needed - Document optional parameter behavior - Consider making parameters required if critical </Card> </CardGroup> --- ## Examples ### Complete Validated Tool ```yaml tools: search_employees: source: ibmi-system description: Search for employees with comprehensive validation statement: | SELECT EMPNO, FIRSTNME, LASTNAME, SALARY FROM SAMPLE.EMPLOYEE WHERE (:name_pattern IS NULL OR UPPER(FIRSTNME) LIKE UPPER(:name_pattern)) AND (:min_salary IS NULL OR SALARY >= :min_salary) AND (:max_salary IS NULL OR SALARY <= :max_salary) AND (:departments IS NULL OR WORKDEPT IN (:departments)) ORDER BY LASTNAME, FIRSTNME LIMIT :page_size OFFSET (:page_number - 1) * :page_size parameters: # String with pattern validation - name: name_pattern type: string description: "Name pattern (use % for wildcards)" required: false pattern: "^[A-Z%]+$" maxLength: 50 # Integer with range constraints - name: min_salary type: integer description: "Minimum salary filter" required: false min: 0 max: 999999 # Integer with range constraints - name: max_salary type: integer description: "Maximum salary filter" required: false min: 0 max: 999999 # Array with length constraints - name: departments type: array itemType: string description: "Filter by departments (e.g., ['A00', 'B01'])" required: false minLength: 1 maxLength: 10 # Pagination parameters - name: page_size type: integer description: "Results per page" default: 10 min: 1 max: 100 - name: page_number type: integer description: "Page number (1-based)" default: 1 min: 1 ``` **Valid request:** ```json { "name": "search_employees", "arguments": { "name_pattern": "JOHN%", "min_salary": 50000, "max_salary": 100000, "departments": ["A00", "B01"], "page_size": 20, "page_number": 1 } } ``` --- ## Next Steps <CardGroup cols={2}> <Card title="Parameters Reference" icon="list" href="/sql-tools/parameters"> Complete guide to all parameter types </Card> <Card title="Output Formats" icon="table" href="/sql-tools/output-formats"> Configure result table formatting </Card> <Card title="Building Tools" icon="hammer" href="/sql-tools/building-tools"> Step-by-step tool creation guide </Card> <Card title="Configuration" icon="gear" href="/configuration"> Server configuration options </Card> </CardGroup>

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/IBM/ibmi-mcp'

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