Array Patterns
Comprehensive array validation for MCP testing.
Quick Reference
"match:arrayLength:N"Validate exact array size
match:arrayElements:Validate all element structure
"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.
# 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
# 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.
# 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 validationKey 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
# 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 accessEnhanced Field Matching
Field syntax: "match:arrayContains:fieldName:value"
Dot notation: "match:arrayContains:nested.field:value"
With negation: "match:not:arrayContains:field:value"
Production Examples
# ✅ 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
# Use debug mode to see actual vs expected structure
aegis test.yml --config config.json --debug --verboseAdvanced 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:
# ✅ 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:
# ✅ 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:
# ✅ 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:
# ✅ 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
nameanddescription, but schemas vary - Product Catalogs: All products need
titleandprice, but features vary - File Listings: All files need
name, but permissions/metadata vary - User Data: All users need
idandemail, but profiles vary
Production Examples
Real examples from the MCP Aegis test suite:
# 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
# ❌ 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
- Object Field Patterns - Field extraction and partial matching
- Regex Patterns - Advanced pattern matching
- Examples - Real-world array pattern usage