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,

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