MCP

Aegisv1

Basic Patterns

Fundamental validation for equality, types, and existence.

These are the foundational patterns in MCP Aegis, covering the most common validation needs. They form the building blocks for more complex assertions. All patterns have been production-verified with real MCP servers.

Deep Equality (Default)

If you do not specify a pattern, MCP Aegis performs a deep equality check by default. This means every field and value in your expectation must exactly match the server's response.

Exact Value Matching

yaml
# This expectation requires an exact match
expect:
  response:
    result:
      content:
        - type: "text"
          text: "Hello, MCP Aegis!"  # Must match exactly
      isError: false  # Must be exactly false
      status: "success"  # Must be exactly "success"
      count: 42  # Must be exactly 42

Nested Structure Matching

yaml
# Nested objects and arrays must match exactly
expect:
  response:
    result:
      tools:
        - name: "read_file"
          description: "Reads a file"
          inputSchema:
            type: "object"
            properties:
              path:
                type: "string"
            required:
              - "path"

Production Example: Filesystem Server file reading with exact content matching:

yaml
# ✅ Verified with Simple Filesystem Server
- it: "should match exact file content with deep equality"
  request:
    method: "tools/call"
    params:
      name: "read_file"
      arguments:
        path: "../shared-test-data/hello.txt"
  expect:
    response:
      result:
        content:
          - type: "text"
            text: "Hello, MCP Aegis!"  # Exact match required
        isError: false  # Exact boolean match

Use Cases: Static responses, configuration data, known file contents, status codes.

Type Validation

Use "match:type:<type>" to validate a field's data type without checking its specific value. This is ideal for dynamic values like IDs, timestamps, or calculated numbers.

Supported Types

  • string - Text values
  • number - Integer and decimal numbers
  • boolean - true or false values
  • object - Objects and null values
  • array - Array values (uses Array.isArray())
  • null - Null values specifically

Basic Type Validation

yaml
expect:
  response:
    id: "match:type:string"      # Any string is valid
    result:
      timestamp: "match:type:number"   # Any number is valid
      isActive: "match:type:boolean"   # Must be true or false
      data: "match:type:object"        # Must be an object
      items: "match:type:array"        # Must be an array
      nullable: "match:type:null"      # Must be null

Important: Array Type Detection

The match:type:array pattern correctly uses Array.isArray() for validation, as JavaScript arrays have typeof array === "object". This ensures reliable array type detection.

yaml
# ✅ This works correctly - MCP Aegis handles array detection properly
result:
  tools: "match:type:array"          # Uses Array.isArray() internally
  metadata: "match:type:object"      # Uses typeof === "object"

Production Examples: Filesystem Server response structure validation:

yaml
# ✅ Verified with Simple Filesystem Server
- it: "should validate response field types"
  expect:
    response:
      result:
        content: "match:type:array"     # Content must be array
        isError: "match:type:boolean"   # isError must be boolean

# ✅ Tools list structure validation
- it: "should validate tools list structure types"
  expect:
    response:
      result:
        tools: "match:type:array"       # Tools list is array

Use Cases: Dynamic responses, API validation, schema verification, data structure checks.

Length Validation

Use "match:length:N" to validate the exact length of strings or arrays. This is a generic pattern that works with any length-based data.

String Length Validation

yaml
expect:
  response:
    jsonrpc: "2.0"
    id: "test-1"
    result:
      content:
        - type: "text"
          text: "match:length:21"      # Text must have exactly 21 characters
      toolName: "match:length:9"      # "read_file" has 9 characters
      status: "match:length:7"        # "success" has 7 characters

Array Length Validation

yaml
expect:
  response:
    jsonrpc: "2.0"
    id: "test-2"
    result:
      content: "match:length:1"       # Content array has exactly 1 element
      tools: "match:length:3"         # Tools array has exactly 3 elements
      items: "match:length:0"         # Empty array validation

💡 Pattern Comparison

Generic length: vs Specific arrayLength::

  • match:length:N - Works with both strings and arrays
  • match:arrayLength:N - Only works with arrays (more specific)
  • • Use length: when you want flexibility
  • • Use arrayLength: for explicit array validation

Real-World Examples

yaml
# ✅ Verified with Simple Filesystem Server
expect:
  response:
    jsonrpc: "2.0"
    id: "read-test"
    result:
      content:
        - type: "text"
          text: "match:length:21"      # "Hello, MCP Aegis!" = 21 chars
      isError: false

Use Cases: Input validation, content size checks, array counting, string format validation, pagination limits.

Field Existence

Use "match:exists" to assert that a field is present in the response, regardless of its value (including null or undefined values).

Basic Existence Check

yaml
expect:
  response:
    result:
      # Ensure fields exist, value doesn't matter
      optionalData: "match:exists"
      metadata: "match:exists"
      serverInfo: "match:exists"

Existence with Boolean Values

You can also use explicit boolean values with "match:exists:true" and "match:exists:false":

yaml
expect:
  response:
    result:
      # Field must be present
      requiredField: "match:exists:true"
      
      # Field must NOT be present
      deprecatedField: "match:exists:false"

Nested Existence Checks

yaml
expect:
  response:
    result:
      serverInfo:
        name: "match:exists"           # Name field must exist
        version: "match:exists"        # Version field must exist
        protocolVersion: "match:exists" # Protocol version must exist
        capabilities: "match:exists"    # Capabilities must exist

Production Example: MCP handshake response validation:

yaml
# ✅ Verified with MCP Protocol Implementation
- it: "should validate handshake response has required fields"
  expect:
    response:
      result:
        protocolVersion: "match:exists"  # Must be present
        capabilities: "match:exists"     # Must be present  
        serverInfo: "match:exists"       # Must be present

Use Cases: Optional fields, API compatibility checks, schema validation, feature detection.

Combining Basic Patterns

You can combine basic patterns within the same test to create comprehensive validation:

yaml
expect:
  response:
    jsonrpc: "2.0"                    # Exact match
    id: "match:type:string"           # Any string
    result:
      content: "match:type:array"     # Must be array
      isError: "match:type:boolean"   # Must be boolean
      metadata: "match:exists"        # Must exist
      serverInfo:
        name: "match:type:string"     # Nested type validation
        version: "match:type:string"

Debugging Basic Patterns

Common Type Issues

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

Type Mismatch Debugging

yaml
# ❌ Wrong - expecting string but API returns number
result:
  count: "match:type:string"  # But count is actually a number!

# ✅ Correct - match actual data type
result:
  count: "match:type:number"
  name: "match:type:string"

Existence Debugging

yaml
# Start with existence checks, then add type validation
result:
  serverInfo: "match:exists"        # First: does it exist?
  
# Then validate type
result:
  serverInfo: "match:type:object"   # Second: is it an object?
  
# Finally validate structure
result:
  serverInfo:
    name: "match:type:string"       # Third: validate contents

✅ Production Verified

All basic patterns have been extensively tested with real-world MCP servers including Simple Filesystem Server, Multi-Tool Server, and production API servers.

Next Steps