Skip to main content
Glama
AlyssonM

HiveAuth MCP Server

by AlyssonM

validate_presentation_definition

Validate presentation definitions against DIF PEX v2.0 specification to ensure compliance, check best practices, and receive improvement recommendations.

Instructions

Validate presentation definitions against DIF PEX v2.0 specification. Performs comprehensive compliance checking, best practices validation, and provides improvement recommendations.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
presentationDefinitionYesDIF PEX Presentation Definition
strictNoWhether to perform strict DIF PEX v2.0 validation
checkSchemasNoWhether to validate referenced credential schemas

Implementation Reference

  • The primary handler function that executes the tool. It validates the input using Zod schema, performs comprehensive DIF PEX v2.0 compliance checks on presentation definitions including structure, IDs, constraints, schemas, and generates detailed reports with errors, warnings, and recommendations.
    export async function validatePresentationDefinition(args: unknown): Promise<CallToolResult> {
      const validation = validateAndSanitizeInput(
        TOOL_SCHEMAS.validate_presentation_definition,
        args,
        'validate_presentation_definition'
      );
    
      if (!validation.success) {
        return createValidationErrorResult(validation.error!);
      }
    
      const data = validation.data!;
      const startTime = Date.now();
    
      try {
        const validationIssues: string[] = [];
        const warnings: string[] = [];
        const recommendations: string[] = [];
        
        const { presentationDefinition, strict, checkSchemas } = data;
    
        // Basic structure validation (already validated by Zod, but we'll add business logic checks)
        
        // 1. ID validation
        if (!presentationDefinition.id || presentationDefinition.id.trim().length === 0) {
          validationIssues.push('Presentation definition ID is required and cannot be empty');
        } else if (!/^[a-zA-Z0-9_-]+$/.test(presentationDefinition.id)) {
          warnings.push('ID should only contain alphanumeric characters, underscores, and hyphens for maximum compatibility');
        }
    
        // 2. Input descriptors validation
        if (!presentationDefinition.input_descriptors || presentationDefinition.input_descriptors.length === 0) {
          validationIssues.push('At least one input descriptor is required');
        } else {
          // Check for duplicate input descriptor IDs
          const descriptorIds = presentationDefinition.input_descriptors.map(desc => desc.id);
          const duplicateIds = descriptorIds.filter((id, index) => descriptorIds.indexOf(id) !== index);
          if (duplicateIds.length > 0) {
            validationIssues.push(`Duplicate input descriptor IDs found: ${duplicateIds.join(', ')}`);
          }
    
          // Validate each input descriptor
          presentationDefinition.input_descriptors.forEach((descriptor, index) => {
            const prefix = `Input Descriptor ${index + 1} (${descriptor.id})`;
    
            // ID validation
            if (!descriptor.id || descriptor.id.trim().length === 0) {
              validationIssues.push(`${prefix}: ID is required and cannot be empty`);
            }
    
            // Purpose/Name recommendation
            if (!descriptor.purpose && !descriptor.name) {
              recommendations.push(`${prefix}: Consider adding a 'purpose' or 'name' for better user experience`);
            }
    
            // Constraints validation
            if (descriptor.constraints) {
              if (descriptor.constraints.fields && descriptor.constraints.fields.length > 0) {
                descriptor.constraints.fields.forEach((field, fieldIndex) => {
                  const fieldPrefix = `${prefix}, Field ${fieldIndex + 1}`;
    
                  // Path validation
                  if (!field.path || field.path.length === 0) {
                    validationIssues.push(`${fieldPrefix}: At least one path is required`);
                  } else {
                    // JSONPath validation
                    field.path.forEach((path, pathIndex) => {
                      if (!path.startsWith('$.')) {
                        warnings.push(`${fieldPrefix}, Path ${pathIndex + 1}: JSONPath should start with '$.' for clarity`);
                      }
                    });
                  }
    
                  // Filter validation
                  if (field.filter) {
                    const filterKeys = Object.keys(field.filter);
                    const validFilterKeys = ['type', 'const', 'contains', 'pattern', 'format', 'minimum', 'maximum', 'minLength', 'maxLength'];
                    const invalidKeys = filterKeys.filter(key => !validFilterKeys.includes(key));
                    
                    if (invalidKeys.length > 0) {
                      warnings.push(`${fieldPrefix}: Unrecognized filter keys: ${invalidKeys.join(', ')}`);
                    }
                  }
    
                  // Purpose recommendation
                  if (!field.purpose) {
                    recommendations.push(`${fieldPrefix}: Consider adding a 'purpose' to explain why this field is required`);
                  }
                });
              } else if (strict) {
                warnings.push(`${prefix}: No field constraints specified - this may accept any credential type`);
              }
    
              // Status validation
              if (descriptor.constraints.statuses) {
                const statuses = descriptor.constraints.statuses;
                Object.keys(statuses).forEach(statusType => {
                  if (!['active', 'suspended', 'revoked'].includes(statusType)) {
                    warnings.push(`${prefix}: Unrecognized status type '${statusType}'`);
                  }
                });
              }
            } else if (strict) {
              warnings.push(`${prefix}: No constraints specified - this may be overly permissive`);
            }
    
            // Schema validation
            if (descriptor.schema && descriptor.schema.length > 0) {
              descriptor.schema.forEach((schema, schemaIndex) => {
                const schemaPrefix = `${prefix}, Schema ${schemaIndex + 1}`;
                
                try {
                  new URL(schema.uri);
                } catch (error) {
                  validationIssues.push(`${schemaPrefix}: Invalid schema URI '${schema.uri}'`);
                }
    
                if (checkSchemas) {
                  // Note: In a real implementation, you would fetch and validate the schema
                  recommendations.push(`${schemaPrefix}: Schema validation not implemented - would validate ${schema.uri}`);
                }
              });
            }
          });
        }
    
        // 3. Submission requirements validation (if present)
        if (presentationDefinition.submission_requirements && presentationDefinition.submission_requirements.length > 0) {
          recommendations.push('Submission requirements detected - ensure they are properly structured according to DIF PEX v2.0 spec');
        }
    
        // 4. Overall recommendations
        if (!presentationDefinition.purpose) {
          recommendations.push('Consider adding a top-level purpose to explain the intent of this presentation request');
        }
    
        if (!presentationDefinition.name) {
          recommendations.push('Consider adding a name for better user identification of this presentation request');
        }
    
        const processingTime = Date.now() - startTime;
        const isValid = validationIssues.length === 0;
        const hasWarnings = warnings.length > 0;
        const hasRecommendations = recommendations.length > 0;
    
        return {
          content: [
            {
              type: 'text',
              text: `${isValid ? '✅' : '❌'} **Presentation Definition Validation ${isValid ? 'Passed' : 'Failed'}**
    
    **Validation Summary:**
    • **Status:** ${isValid ? 'Valid' : 'Invalid'}
    • **Processing Time:** ${processingTime}ms
    • **Strict Mode:** ${strict ? 'Enabled' : 'Disabled'}
    • **Schema Checking:** ${checkSchemas ? 'Enabled' : 'Disabled'}
    
    **📊 Results Overview:**
    • **Errors:** ${validationIssues.length}
    • **Warnings:** ${warnings.length}
    • **Recommendations:** ${recommendations.length}
    • **Input Descriptors:** ${presentationDefinition.input_descriptors?.length || 0}
    
    **🎯 Presentation Definition Details:**
    • **ID:** ${presentationDefinition.id}
    • **Name:** ${presentationDefinition.name || 'Not specified'}
    • **Purpose:** ${presentationDefinition.purpose || 'Not specified'}
    
    ${validationIssues.length > 0 ? `**❌ Validation Errors:**
    ${validationIssues.map((issue, index) => `${index + 1}. ${issue}`).join('\n')}
    
    ` : ''}${hasWarnings ? `**⚠️ Warnings:**
    ${warnings.map((warning, index) => `${index + 1}. ${warning}`).join('\n')}
    
    ` : ''}${hasRecommendations ? `**💡 Recommendations:**
    ${recommendations.map((rec, index) => `${index + 1}. ${rec}`).join('\n')}
    
    ` : ''}**📋 Input Descriptor Analysis:**
    ${presentationDefinition.input_descriptors?.map((desc, index) => {
      const fieldCount = desc.constraints?.fields?.length || 0;
      const hasConstraints = !!desc.constraints;
      const hasSchemas = desc.schema && desc.schema.length > 0;
      
      return `• **${desc.id}** ${desc.name ? `(${desc.name})` : ''}
      - Purpose: ${desc.purpose || 'Not specified'}
      - Fields: ${fieldCount} constraint${fieldCount !== 1 ? 's' : ''}
      - Schemas: ${hasSchemas ? desc.schema!.length : 0} referenced
      - Status: ${hasConstraints ? 'Has constraints' : 'No constraints'}`;
    }).join('\n') || '(No input descriptors)'}
    
    **🔍 DIF PEX v2.0 Compliance:**
    • **Structure:** ${isValid ? 'Compliant' : 'Non-compliant'}
    • **Required Fields:** ${presentationDefinition.id && presentationDefinition.input_descriptors ? 'Present' : 'Missing'}
    • **Best Practices:** ${hasWarnings ? 'Some issues found' : 'Following best practices'}
    
    ${isValid 
      ? '🎉 **This presentation definition is valid and ready for use in credential requests.**' 
      : '🔧 **Please address the validation errors before using this presentation definition.**'}
    
    ${hasRecommendations || hasWarnings 
      ? '\n💡 **Next Steps:** Consider implementing the recommendations above for better interoperability and user experience.' 
      : ''}
    `
            }
          ]
        };
    
      } catch (error: any) {
        const processingTime = Date.now() - startTime;
    
        return {
          content: [
            {
              type: 'text',
              text: `❌ **Presentation Definition Validation Error**
    
    **Error:** ${error.message}
    **Processing Time:** ${processingTime}ms
    **Tool:** validate_presentation_definition
    
    **📋 Input Summary:**
    • **Definition ID:** ${data.presentationDefinition.id}
    • **Input Descriptors:** ${data.presentationDefinition.input_descriptors?.length || 0}
    • **Strict Mode:** ${data.strict}
    
    **🔧 Troubleshooting:**
    1. **Definition Structure:** Ensure the presentation definition follows DIF PEX v2.0 format
    2. **Required Fields:** Verify all required fields (id, input_descriptors) are present
    3. **Field Constraints:** Check that constraint fields use valid JSONPath expressions
    4. **Schema References:** Ensure any referenced schemas are accessible if checkSchemas is enabled
    
    **📚 Reference:**
    • DIF Presentation Exchange v2.0: https://identity.foundation/presentation-exchange/spec/v2.0.0/
    • JSONPath specification: https://tools.ietf.org/rfc/rfc9535.txt
    
    For detailed validation requirements, consult the DIF PEX v2.0 specification.`
            }
          ],
          isError: true
        };
      }
    }
  • Zod input schema for the validate_presentation_definition tool, defining the expected parameters: presentationDefinition, strict mode, and schema checking options.
    export const ValidatePresentationDefinitionInputSchema = z.object({
      presentationDefinition: PresentationDefinitionSchema,
      strict: z.boolean().default(true).describe('Whether to perform strict DIF PEX v2.0 validation'),
      checkSchemas: z.boolean().default(false).describe('Whether to validate referenced credential schemas')
    });
  • Tool registration in TOOL_DEFINITIONS array used by createMCPTools() to generate the MCP Tool object with name, description, and inputSchema for the tools list.
      name: 'validate_presentation_definition',
      description: 'Validate presentation definitions against DIF PEX v2.0 specification. Performs comprehensive compliance checking, best practices validation, and provides improvement recommendations.',
      inputSchema: TOOL_SCHEMAS.validate_presentation_definition
    },
  • src/index.ts:116-117 (registration)
    Dispatch registration in the main switch statement that routes tool calls to the validatePresentationDefinition handler function.
    case 'validate_presentation_definition':
      return await validatePresentationDefinition(args);
  • Mapping of tool name to its input schema in the TOOL_SCHEMAS object for easy lookup.
    validate_presentation_definition: ValidatePresentationDefinitionInputSchema,
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden. It discloses the tool performs validation and provides recommendations, but lacks details on behavioral traits like error handling, performance characteristics, authentication requirements, or rate limits. For a validation tool with complex input, more operational context would be helpful.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is perfectly concise with two sentences that each earn their place. The first sentence states the core purpose, and the second elaborates on the validation scope. No wasted words, and information is front-loaded appropriately.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (3 parameters with nested objects) and lack of annotations/output schema, the description is adequate but has clear gaps. It explains what the tool does but doesn't provide enough context about how it behaves, what it returns, or how to interpret results. For a validation tool, more guidance on output format or error cases would improve completeness.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema fully documents all three parameters. The description adds no parameter-specific information beyond what's in the schema, such as examples or usage notes for the complex presentationDefinition object. Baseline 3 is appropriate when the schema does all the work.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose with specific verbs ('validate', 'performs') and resource ('presentation definitions'), distinguishing it from siblings like create_presentation_definition or evaluate_presentation. It specifies the standard (DIF PEX v2.0) and types of validation (compliance checking, best practices, improvement recommendations).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage for validating presentation definitions against a specific standard, but does not explicitly state when to use this tool versus alternatives like evaluate_presentation or verify_presentation. No exclusions or prerequisites are mentioned, leaving the agent to infer context from the tool name and description alone.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/AlyssonM/hiveauth-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server