String Patterns
Validate string content, length constraints, and text formatting for comprehensive string validation.
String patterns are essential for testing dynamic text content, input validation, and content constraints such as character limits, required fields, and format requirements. Test substrings, prefixes, suffixes, and length constraints. All patterns are production-verified with real MCP servers.
String Contains Pattern
Use "match:contains:substring" to check if the actual string value contains the specified substring anywhere within it. The match is case-sensitive.
Basic Contains Matching
# Use case: Verifying success messages
expect:
response:
result:
message: "match:contains:success" # Contains "success"
description: "match:contains:file" # Contains "file"
error: "match:contains:not found" # Contains "not found"Production Examples
Filesystem Server: File content validation
# ✅ Verified with Simple Filesystem Server
- it: "should match file content containing specific text"
request:
method: "tools/call"
params:
name: "read_file"
arguments:
path: "../shared-test-data/hello.txt"
expect:
response:
result:
content:
- type: "text"
text: "match:contains:MCP" # Must contain "MCP"
isError: falseError Message Validation:
# ✅ Error message validation
- it: "should match error messages containing specific text"
request:
method: "tools/call"
params:
name: "read_file"
arguments:
path: "../shared-test-data/nonexistent.txt"
expect:
response:
result:
content:
- type: "text"
text: "match:contains:not found" # Error contains "not found"
isError: trueTool Description Validation:
# ✅ Tool description keyword matching
- it: "should match tool description containing specific keywords"
request:
method: "tools/list"
expect:
response:
result:
tools:
- name: "read_file"
description: "match:contains:Reads" # Description contains "Reads"String Prefix Pattern
Use "match:startsWith:prefix" to check if the actual string starts with the specified prefix. Perfect for validating identifiers, URLs, or formatted strings.
Basic Prefix Matching
# Use case: Resource identifiers and URLs
expect:
response:
result:
name: "match:startsWith:get_" # Starts with "get_"
url: "match:startsWith:https://" # Starts with "https://"
greeting: "match:startsWith:Hello" # Starts with "Hello"
jsonrpc: "match:startsWith:2." # JSON-RPC version starts with "2."Production Examples
Content Validation:
# ✅ Verified with Simple Filesystem Server - Greeting validation
- it: "should match content starting with specific prefix"
request:
method: "tools/call"
params:
name: "read_file"
arguments:
path: "../shared-test-data/hello.txt"
expect:
response:
result:
content:
- type: "text"
text: "match:startsWith:Hello" # Must start with "Hello"
isError: falseJSON-RPC Version Validation:
# ✅ JSON-RPC version validation (works on any field)
- it: "should validate JSON-RPC version starts with correct value"
request:
method: "tools/list"
expect:
response:
jsonrpc: "match:startsWith:2." # Version starts with "2."
result:
tools:
- name: "read_file"
description: "Reads a file"Tool Name Patterns:
# ✅ Tool naming convention validation
expect:
response:
result:
tools:
- name: "match:startsWith:get_" # Getter tools start with "get_"
- name: "match:startsWith:create_" # Creator tools start with "create_"
- name: "match:startsWith:update_" # Updater tools start with "update_"String Suffix Pattern
Use "match:endsWith:suffix" to check if the actual string ends with the specified suffix. Ideal for file extensions, version numbers, or status indicators.
Basic Suffix Matching
# Use case: File extensions and endings
expect:
response:
result:
filename: "match:endsWith:.json" # Ends with ".json"
version: "match:endsWith:.0" # Ends with ".0"
message: "match:endsWith:Aegis!" # Ends with "Aegis!"
status: "match:endsWith:complete" # Ends with "complete"Production Examples
File Content Ending Validation:
# ✅ Verified with Simple Filesystem Server
- it: "should match content ending with specific suffix"
request:
method: "tools/call"
params:
name: "read_file"
arguments:
path: "../shared-test-data/hello.txt"
expect:
response:
result:
content:
- type: "text"
text: "match:endsWith:Aegis!" # Ends with "Aegis!"
isError: falseVersion Number Validation:
# ✅ API version checking
expect:
response:
result:
apiVersion: "match:endsWith:.0" # Stable versions end with ".0"
protocolVersion: "match:endsWith:18" # Protocol ends with specific buildCase Sensitivity
All string patterns are case-sensitive. This ensures precise matching and prevents false positives:
# Case-sensitive examples
text: "match:contains:Success" # Matches "Success" but NOT "success"
text: "match:startsWith:HTTP" # Matches "HTTPS" but NOT "https"
text: "match:endsWith:PDF" # Matches ".PDF" but NOT ".pdf"
# Case-insensitive examples
text: "match:containsIgnoreCase:success" # Matches "Success", "SUCCESS", "success"
text: "match:equalsIgnoreCase:OK" # Matches "ok", "Ok", "OK"
# Use regex for case-insensitive matching (legacy approach)
text: "match:regex:(?i)success" # Case-insensitive regexCase-Insensitive Patterns
MCP Aegis provides dedicated case-insensitive string patterns for flexible string matching without the complexity of regex patterns.
Contains Ignore Case Pattern
The containsIgnoreCase: pattern matches strings containing a substring, ignoring case differences:
# Basic usage
result:
status: "match:containsIgnoreCase:success" # Matches "Success", "SUCCESS", "success"
name: "match:containsIgnoreCase:john" # Matches "John", "JOHN", "johnny"
message: "match:containsIgnoreCase:error" # Matches "Error", "ERROR", "error message"
# Real-world example - Error message validation
- it: "should match error messages case-insensitively"
request:
method: "tools/call"
params:
name: "read_file"
arguments:
path: "nonexistent.txt"
expect:
response:
result:
content:
- type: "text"
text: "match:containsIgnoreCase:FILE" # Matches "file", "File", "FILE"
isError: trueEquals Ignore Case Pattern
The equalsIgnoreCase: pattern matches strings that are exactly equal, ignoring case differences:
# Basic usage
result:
status: "match:equalsIgnoreCase:OK" # Matches "ok", "Ok", "OK" but NOT "okay"
level: "match:equalsIgnoreCase:INFO" # Matches "info", "Info", "INFO"
response: "match:equalsIgnoreCase:SUCCESS" # Matches "success", "Success", "SUCCESS"
# Real-world example - Status validation
- it: "should match status values case-insensitively"
request:
method: "tools/call"
params:
name: "process_data"
expect:
response:
result:
status: "match:equalsIgnoreCase:COMPLETED" # Matches any case variation
level: "match:equalsIgnoreCase:INFO" # Exact match ignoring caseCase-Insensitive Patterns with Arrays
Case-insensitive patterns work with arrays, checking each element:
# Array element validation
result:
tools:
match:arrayElements:
name: "match:containsIgnoreCase:FILE" # Each tool name contains "file" (any case)
description: "match:containsIgnoreCase:READ" # Each description contains "read" (any case)
# Array contains with case-insensitive field matching
result:
logs: "match:arrayContains:level:INFO" # Case-sensitive field match
# Note: arrayContains field matching is case-sensitive by design
# Use containsIgnoreCase within individual field validation insteadCase-Insensitive Negation
Combine case-insensitive patterns with negation for exclusion validation:
# Negated case-insensitive patterns
result:
message: "match:not:containsIgnoreCase:ERROR" # Should NOT contain "error" (any case)
status: "match:not:equalsIgnoreCase:FAILURE" # Should NOT equal "failure" (any case)
level: "match:not:containsIgnoreCase:CRITICAL" # Should NOT contain "critical" (any case)
# Real-world example - Success validation
- it: "should not contain error indicators (case-insensitive)"
request:
method: "tools/call"
params:
name: "health_check"
expect:
response:
result:
message: "match:not:containsIgnoreCase:ERROR" # No error mentions
status: "match:not:containsIgnoreCase:FAIL" # No failure indicators
isError: falseString Length Patterns
MCP Aegis provides comprehensive string length validation patterns for validating text constraints, input limits, and content specifications. These patterns are essential for form validation, content moderation, and API parameter validation.
Exact Length Pattern
The stringLength: pattern validates that a string has exactly the specified number of characters:
# Basic exact length validation
result:
title: "match:stringLength:25" # Exactly 25 characters
username: "match:stringLength:8" # Exactly 8 characters
code: "match:stringLength:6" # Exactly 6 characters (like OTP)
emptyField: "match:stringLength:0" # Empty string (0 characters)
# Real-world example - User validation
- it: "should validate exact username length"
request:
method: "tools/call"
params:
name: "validate_user"
arguments:
username: "john_doe"
expect:
response:
result:
username: "match:stringLength:8" # Exactly 8 characters
status: "success"Length Comparison Patterns
Use comparison patterns for minimum and maximum length validation:
# Length comparison validation
result:
shortName: "match:stringLengthLessThan:10" # Less than 10 characters
description: "match:stringLengthGreaterThan:50" # More than 50 characters
nickname: "match:stringLengthGreaterThanOrEqual:2" # At least 2 characters
bio: "match:stringLengthLessThanOrEqual:500" # At most 500 characters
# Real-world example - Content validation
- it: "should validate content length constraints"
request:
method: "tools/call"
params:
name: "create_post"
arguments:
title: "Short title"
content: "This is a longer content that exceeds the minimum required length."
expect:
response:
result:
title: "match:stringLengthLessThan:50" # Title under 50 chars
content: "match:stringLengthGreaterThan:20" # Content over 20 chars
status: "created"Length Range Pattern
The stringLengthBetween: pattern validates that a string length falls within a specific range:
# Length range validation
result:
username: "match:stringLengthBetween:3:20" # Between 3-20 characters
password: "match:stringLengthBetween:8:128" # Between 8-128 characters
title: "match:stringLengthBetween:5:100" # Between 5-100 characters
comment: "match:stringLengthBetween:1:500" # Between 1-500 characters
# Real-world example - Form validation
- it: "should validate form field length ranges"
request:
method: "tools/call"
params:
name: "submit_form"
arguments:
name: "John Doe"
email: "[email protected]"
message: "Hello, this is a test message."
expect:
response:
result:
name: "match:stringLengthBetween:2:50" # Name: 2-50 chars
email: "match:stringLengthBetween:5:100" # Email: 5-100 chars
message: "match:stringLengthBetween:10:1000" # Message: 10-1000 chars
status: "validated"Empty and Non-Empty Patterns
Convenient patterns for empty string validation:
# Empty string validation
result:
emptyField: "match:stringEmpty" # Must be empty string ""
requiredField: "match:stringNotEmpty" # Must not be empty string
optionalField: "match:stringEmpty" # Optional field, should be empty
mandatoryField: "match:stringNotEmpty" # Mandatory field, must have content
# Real-world example - Required field validation
- it: "should validate required and optional fields"
request:
method: "tools/call"
params:
name: "process_user_data"
arguments:
name: "John Doe"
middleName: ""
email: "[email protected]"
expect:
response:
result:
name: "match:stringNotEmpty" # Required field
middleName: "match:stringEmpty" # Optional field
email: "match:stringNotEmpty" # Required field
status: "processed"Unicode and Special Character Length
String length patterns count Unicode code units, which means some emoji and special characters may count as multiple characters:
# Unicode character length examples
result:
emoji: "match:stringLength:9" # "🚀🎯✅💻🌟" = 9 characters (some emoji are multi-unit)
accented: "match:stringLength:5" # "café" = 4 visible chars, but check actual count
newlines: "match:stringLength:12" # "hello\nworld!" = 12 characters (\n counts as 1)
tabs: "match:stringLength:3" # "a\tb" = 3 characters (\t counts as 1)
# Real-world example - Text content validation
- it: "should handle special characters in length validation"
request:
method: "tools/call"
params:
name: "analyze_text"
arguments:
text: "Hello\nWorld! 🚀"
expect:
response:
result:
text: "match:stringLengthGreaterThan:10" # Account for special chars
analysis: "match:stringNotEmpty"
charCount: "match:type:number"String Length Pattern Negation
Combine string length patterns with negation for exclusion validation:
# Negated length patterns
result:
username: "match:not:stringLength:0" # Username should NOT be empty
password: "match:not:stringLengthLessThan:8" # Password should NOT be too short
title: "match:not:stringLengthGreaterThan:100" # Title should NOT be too long
description: "match:not:stringEmpty" # Description should NOT be empty
# Real-world example - Security validation
- it: "should reject invalid input lengths"
request:
method: "tools/call"
params:
name: "security_check"
arguments:
username: "validuser"
password: "securePassword123"
expect:
response:
result:
username: "match:not:stringLengthLessThan:3" # Not too short
username: "match:not:stringLengthGreaterThan:20" # Not too long
password: "match:not:stringLengthLessThan:8" # Meets minimum security
status: "valid"Array Elements Length Validation
Validate the length of strings within arrays using arrayElements combined with string length patterns:
# Validate all array elements meet length requirements
result:
usernames:
match:arrayElements:
name: "match:stringLengthBetween:3:15" # All usernames 3-15 chars
descriptions:
match:arrayElements:
text: "match:stringLengthGreaterThan:10" # All descriptions > 10 chars
tags:
match:arrayElements:
label: "match:stringLengthLessThan:20" # All tags < 20 chars
# Real-world example - Bulk validation
- it: "should validate all tool descriptions meet length requirements"
request:
method: "tools/list"
expect:
response:
result:
tools:
match:arrayElements:
name: "match:stringLengthGreaterThan:0" # All tools have names
description: "match:stringLengthBetween:10:200" # All descriptions 10-200 charsCombining String Patterns
You can use multiple string patterns in the same test to validate different aspects:
# Comprehensive string validation
expect:
response:
result:
content:
- type: "text"
text: "match:startsWith:Hello" # Must start with greeting
error:
message: "match:contains:validation" # Error contains validation
code: "match:endsWith:_ERROR" # Error code ends with _ERROR
apiVersion: "match:startsWith:v" # Version starts with "v"Common Use Cases
Form and Input Validation
# Comprehensive form validation
expect:
response:
result:
username: "match:stringLengthBetween:3:20" # Username constraints
email: "match:contains:@" # Basic email validation
password: "match:stringLengthGreaterThan:8" # Password minimum length
bio: "match:stringLengthLessThanOrEqual:500" # Bio character limit
displayName: "match:stringNotEmpty" # Required field
middleName: "match:stringEmpty" # Optional fieldLog Message Validation
# Validate log entries
expect:
response:
result:
logs:
- level: "INFO"
message: "match:contains:started" # Log contains "started"
- level: "ERROR"
message: "match:startsWith:Failed" # Error starts with "Failed"API Response Validation
# API endpoint response validation
expect:
response:
result:
status: "match:contains:success" # Status mentions success
endpoint: "match:startsWith:/api/v" # API version in URL
timestamp: "match:endsWith:Z" # UTC timestamp formatFile System Validation
# File operations validation
expect:
response:
result:
path: "match:startsWith:/" # Absolute path
filename: "match:endsWith:.txt" # Text file
content: "match:contains:data" # Contains dataDebugging String Patterns
Check Actual Values
# Use debug mode to see actual string values
aegis test.yml --config config.json --debug --verbose
# Output shows:
# Expected: "match:contains:MCP"
# Actual: "Hello, MCP Aegis testing!"
# ✅ Contains match foundCommon String Issues
# ❌ Common mistakes
text: "match:contains:Success" # Case mismatch - actual is "success"
text: "match:startsWith:HTTP" # Case mismatch - actual is "https://"
text: "match:endsWith: .txt" # Space issue - actual is ".txt"
username: "match:stringLength:5" # Length mismatch - actual is 8 characters
emoji: "match:stringLength:5" # Unicode issue - "🚀🎯✅💻🌟" is 9 code units
# ✅ Correct approaches
text: "match:contains:success" # Match exact case
text: "match:startsWith:https" # Match actual protocol
text: "match:endsWith:.txt" # No extra spaces
username: "match:stringLength:8" # Count actual characters
emoji: "match:stringLength:9" # Account for Unicode code unitsIncremental Testing
# Start simple and add complexity
# Step 1: Check if field exists
text: "match:exists"
# Step 2: Check type
text: "match:type:string"
# Step 3: Check basic length constraints
text: "match:stringNotEmpty"
# Step 4: Add specific length validation
text: "match:stringLengthBetween:5:50"
# Step 5: Add string pattern
text: "match:contains:expected"
# Step 6: Refine to specific pattern
text: "match:startsWith:Hello world"✅ Production Verified
All string patterns including length validation have been extensively tested with Simple Filesystem Server, Multi-Tool Server, and production MCP implementations. Case-sensitive matching and Unicode-aware length counting ensure reliable validation.
Next Steps
- Regex Patterns - Advanced pattern matching with regular expressions
- Array Patterns - Array validation and element matching
- Object Field Patterns - Field extraction and partial matching