Skip to main content

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.
Parameter validation happens automatically—you just need to define constraints in your tool configuration. The server handles all validation logic.

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:
parameters:
  - name: max_rows
    type: integer
    description: "Maximum rows to return"
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:
parameters:
  - name: object_name
    type: string
    minLength: 1
    maxLength: 10
// ❌ 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"}
Numeric Constraints:
parameters:
  - name: months_unused
    type: integer
    min: 1
    max: 120
// ❌ 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}
Array Constraints:
parameters:
  - name: project_ids
    type: array
    itemType: string
    minLength: 1
    maxLength: 10
{
  "project_ids": []
}
// Error: Array length 0 is less than minimum 1

3. SQL Security

What it does: Parameters are bound securely using prepared statements to prevent SQL injection How it works:
Your YAML configuration:
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

4. Required Check

What it checks: Required parameters must be provided (unless they have default values) Examples:
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

Common Validation Errors

Type Mismatch Errors

Error MessageCauseSolution
Expected integer, got stringPassed "100" instead of 100Remove quotes from numbers
Expected string, got integerPassed 100 instead of "100"Add quotes around strings
Expected boolean, got stringPassed "true" instead of trueUse boolean literals
Expected array, got stringPassed "A,B,C" instead of ["A","B","C"]Use JSON array format

Range/Length Errors

Error MessageCauseSolution
Value X is less than minimum YNumber below min constraintIncrease value to meet minimum
Value X exceeds maximum YNumber above max constraintDecrease value to meet maximum
String length X is less than minimum YString too shortAdd more characters
String length X exceeds maximum YString too longShorten the string

Pattern/Enum Errors

Error MessageCauseSolution
Value does not match pattern: ...String doesn’t match regexFollow the required format
Value 'X' must be one of: ...Value not in enum listUse one of the allowed values

Required Parameter Errors

Error MessageCauseSolution
Required parameter 'X' not providedMissing required parameterInclude the parameter in request
Parameter 'X' is requiredNULL value for required paramProvide a non-NULL value

Security Benefits

SQL Injection Prevention

Parameter binding provides automatic SQL injection protection:
Malicious Input Attempt:
{
  "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

Type Safety

Type validation prevents data corruption and unexpected errors:
  • 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

Constraint Enforcement

Constraints protect against invalid business logic:
  • 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

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

1

Check the parameter type

Ensure you’re passing the correct JSON type (number vs. string, array vs. string)
2

Review constraints

Check min/max, length, pattern, and enum constraints in the tool definition
3

Verify required parameters

Confirm all required parameters are present in the request
4

Test with simple values

Try minimal valid values to isolate the issue
5

Check special characters

For pattern validation, ensure special characters are allowed

Testing Parameter Validation

Good practice: Test parameter validation before deploying tools:
# 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

Use Appropriate Constraints

  • 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

Provide Clear Descriptions

  • Explain validation rules in descriptions
  • Include examples of valid values
  • Document special values (*LIBL, etc.)
  • Mention units for numeric parameters

Test Edge Cases

  • Test minimum and maximum values
  • Test boundary conditions
  • Test with NULL values
  • Test with empty strings/arrays

Handle Optional Parameters

  • Use defaults for common values
  • Check for NULL in SQL when needed
  • Document optional parameter behavior
  • Consider making parameters required if critical

Examples

Complete Validated Tool

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:
{
  "name": "search_employees",
  "arguments": {
    "name_pattern": "JOHN%",
    "min_salary": 50000,
    "max_salary": 100000,
    "departments": ["A00", "B01"],
    "page_size": 20,
    "page_number": 1
  }
}

Next Steps