MCP

Aegisv1

Array Patterns

Comprehensive array validation for MCP testing.

Quick Reference

Length: "match:arrayLength:N"

Validate exact array size

Elements: match:arrayElements:

Validate all element structure

Contains: "match:arrayContains:value"

Check if array contains value

Array patterns are essential for testing API endpoints that return lists. All patterns are production-verified with real MCP servers and handle edge cases gracefully.

💡 Pro Tip

Start with arrayLength to validate size, then use arrayElements for structure, and arrayContains for specific content checks.

1. Array Length Validation

Validate that an array has exactly N elements. Essential for ensuring expected data counts without hardcoding specific values.

yaml
# Basic length validation
result:
  tools: "match:arrayLength:1"         # Exactly 1 tool
  content: "match:arrayLength:0"       # Empty array
  items: "match:arrayLength:100"       # Large datasets

# ✅ Production example - Simple Filesystem Server
- it: "should have exactly one tool"
  request: { method: "tools/list" }
  expect:
    response:
      result:
        tools: "match:arrayLength:1"

2. Array Elements Validation

Validate that every element in an array matches a specific structure. Perfect for ensuring consistency across all array items.

Basic Structure Validation

yaml
# Validate all elements have required keys and types
result:
  tools:
    match:arrayElements:
      name: "match:type:string"
      description: "match:type:string" 
      inputSchema: "match:type:object"

# ✅ Production example
- it: "should validate all tools have required structure"
  request: { method: "tools/list" }
  expect:
    response:
      result:
        tools:
          match:arrayElements:
            name: "match:type:string"
            description: "match:type:string"
            inputSchema: "match:type:object"

Advanced Key Validation

The match:arrayElements: pattern can validate complex key structures with pattern matching, ensuring both key presence and content validation.

yaml
# Advanced pattern-based key validation
result:
  tools:
    match:arrayElements:
      name: "match:regex:^[a-z][a-z0-9_]*
quot; # snake_case validation description: "match:regex:.{10,}" # Min 10 characters inputSchema: type: "match:type:string" # Nested structure validation properties: "match:type:object" required: "match:type:array" # Mixed exact and pattern matching result: tools: match:arrayElements: name: "read_file" # Exact name match description: "match:contains:file" # Must contain "file" inputSchema: "match:type:object" # Type validation

Key Validation Notes:

  • All Keys Required: Every array element must have ALL specified keys
  • Pattern Flexibility: Each key can use any supported pattern (regex, type, contains, etc.)
  • Nested Validation: Supports deep object structure validation
  • Extra Keys Allowed: Elements can have additional keys not specified
  • Failure on Missing: Test fails if any element lacks any specified key

3. Array Contains Validation

Check if an array contains specific values. Enhanced with field matching for direct object validation.

Basic Contains

yaml
# Traditional approach with field extraction
result:
  match:extractField: "tools.*.name"
  value: "match:arrayContains:read_file"    # Check extracted names

# Enhanced: Direct field matching (v1.0.11+)
result:
  tools: "match:arrayContains:name:read_file"          # Find by field value
  tools: "match:arrayContains:inputSchema.type:object" # Nested field access

Enhanced Field Matching

Field syntax: "match:arrayContains:fieldName:value"

Dot notation: "match:arrayContains:nested.field:value"

With negation: "match:not:arrayContains:field:value"

Production Examples

yaml
# ✅ Enhanced field matching - Simple Filesystem Server
- it: "should find tool by name"
  request: { method: "tools/list" }
  expect:
    response:
      result:
        tools: "match:arrayContains:name:read_file"

# ✅ Traditional approach with field extraction  
- it: "should validate tool names exist"
  expect:
    response:
      result:
        match:extractField: "tools.*.name"
        value: "match:arrayContains:read_file"

# ✅ Complex nested validation
- it: "should validate nested schema properties"
  expect:
    response:
      result:
        tools: "match:arrayContains:inputSchema.type:object"

Troubleshooting & Common Issues

Debug Tips

bash
# Use debug mode to see actual vs expected structure
aegis test.yml --config config.json --debug --verbose

Advanced Pattern Combination: Partial + Array Elements

One of the most powerful combinations in MCP Aegis is using match:partial: with match:arrayElements:. This allows you to validate that specific fields exist in all array elements while ignoring optional or varying properties.

🚀 Real-World Power Pattern

This combination is essential for testing APIs where array elements have core required fields (like title, id, name) but also have varying optional properties that you don't want to validate in every test.

Basic Partial Array Validation

Test that all tools have required fields while ignoring implementation-specific properties:

yaml
# ✅ Validate required fields, ignore optional ones
- it: "should validate all tools have required name field"
  request:
    method: "tools/list"
  expect:
    response:
      result:
        tools:
          match:arrayElements:
            match:partial:
              name: "match:type:string"  # Required: name must exist
              # Ignore: description, inputSchema, version, author, etc.

Multi-Field Partial Validation

Test multiple required fields while ignoring everything else:

yaml
# ✅ Validate core tool structure
- it: "should validate essential tool structure"
  request:
    method: "tools/list"
  expect:
    response:
      result:
        tools:
          match:arrayElements:
            match:partial:
              name: "match:regex:^[a-z][a-z0-9_]*
quot; # Required: valid snake_case description: "match:type:string" # Required: description exists # Ignore: inputSchema details, version, internal IDs, metadata, etc.

Response Structure Validation

Validate response content arrays while ignoring specific text content:

yaml
# ✅ Test response structure, ignore content details
- it: "should validate response content structure"
  request:
    method: "tools/call"
    params:
      name: "calculator"
      arguments:
        operation: "add"
        a: 5
        b: 3
  expect:
    response:
      result:
        content:
          match:arrayElements:
            match:partial:
              type: "text"              # Required: must be text type
              text: "match:type:string" # Required: text field exists
              # Ignore: specific text content, formatting, metadata, etc.

Nested Schema Validation

Validate nested object structures while ignoring complex implementation details:

yaml
# ✅ Validate tool schemas without implementation details
- it: "should validate tool schemas have required structure"
  request:
    method: "tools/list"
  expect:
    response:
      result:
        tools:
          match:arrayElements:
            match:partial:
              name: "match:type:string"
              inputSchema:
                match:partial:
                  type: "object"       # Required: schema type
                  # Ignore: properties, required, additionalProperties, 
                  # definitions, examples, etc.

Real-World Use Cases

🎯 When to Use This Pattern

  • API Evolution: Core fields stay stable, optional fields are added over time
  • Tool Validation: All tools need name and description, but schemas vary
  • Product Catalogs: All products need title and price, but features vary
  • File Listings: All files need name, but permissions/metadata vary
  • User Data: All users need id and email, but profiles vary

Production Examples

Real examples from the MCP Aegis test suite:

yaml
# Example from examples/multi-tool-server/patterns-partial-array-elements.test.mcp.yml

# ✅ API response validation - ensure core fields exist
- it: "should validate API responses with consistent required fields"
  request:
    method: "tools/call"
    params:
      name: "data_validator"
      arguments:
        type: "api_response"
        data: |
          [
            {"id": 1, "title": "Item 1", "category": "A", "tags": ["tag1"]},
            {"id": 2, "title": "Item 2", "description": "Some desc", "author": "User"},
            {"id": 3, "title": "Item 3", "priority": "high", "created": "2023-01-01"}
          ]
  expect:
    response:
      result:
        validation:
          match:partial:
            items:
              match:arrayElements:
                match:partial:
                  id: "match:type:number"      # Required: numeric ID
                  title: "match:type:string"   # Required: string title
                  # Ignore: category, tags, description, author, priority, created

✅ Production Verified

This pattern combination has been extensively tested with real MCP servers. See examples/multi-tool-server/patterns-partial-array-elements.test.mcp.yml for a complete working example with 7 test cases.

Common Mistakes

yaml
# ❌ Wrong: Mixing patterns in same object
result:
  tools: "match:arrayLength:1"
  tools:  # Duplicate key error!
    match:arrayElements: {...}

# ✅ Correct: Use separate tests
# Test 1: Length
result:
  tools: "match:arrayLength:1"

# Test 2: Structure (separate test case)  
result:
  tools:
    match:arrayElements:
      name: "match:type:string"

# ❌ Wrong: Array vs object confusion
result:
  content:
    match:arrayElements: {...}  # But response is single object!

# ✅ Correct: Match actual structure
result:
  content:
    - type: "text"
      text: "match:contains:data"

💡 Best Practices

  • Start with length validation, then add structure checks
  • Use enhanced field matching for simpler syntax
  • Separate complex validations into multiple test cases
  • Always check actual response structure with --debug first

✅ Production Verified

All array patterns including enhanced arrayContains field matching have been extensively tested with Simple Filesystem Server, Multi-Tool Server, and production MCP servers. The enhanced arrayContains handles complex nested objects, deep field traversal, and large arrays efficiently while maintaining full backward compatibility with existing tests.

Next Steps