Skip to main content
Glama
AlyssonM

HiveAuth MCP Server

by AlyssonM

submit_presentation

Create and submit verifiable presentations from evaluation results to satisfy DIF PEX v2.0 requirements with holder binding and proof generation.

Instructions

Create and submit verifiable presentations from evaluation results. Builds presentations that satisfy DIF PEX v2.0 requirements with holder binding and proof generation.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
presentationDefinitionYesDIF PEX Presentation Definition
credentialsYes
holderDidNoDID of the presentation holder
challengeNoChallenge for the presentation proof
domainNoDomain for the presentation proof

Implementation Reference

  • The primary handler function implementing the submit_presentation tool. Validates input using the schema, evaluates credentials against the presentation definition via API, submits the presentation, analyzes fulfillment status, and returns comprehensive results with markdown formatting.
    export async function submitPresentation(args: unknown): Promise<CallToolResult> { const validation = validateAndSanitizeInput( TOOL_SCHEMAS.submit_presentation, args, 'submit_presentation' ); if (!validation.success) { return createValidationErrorResult(validation.error!); } const data = validation.data!; const startTime = Date.now(); try { // First evaluate which credentials match the presentation definition const evaluationResponse = await fetch(`${process.env.HIVEAUTH_API_BASE_URL}/api/presentation/evaluate`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ presentationDefinition: data.presentationDefinition, credentials: data.credentials }) }); if (!evaluationResponse.ok) { const errorText = await evaluationResponse.text(); throw new Error(`Evaluation failed (${evaluationResponse.status}): ${errorText}`); } const evaluationResult = await evaluationResponse.json(); // Check if evaluation was successful if (!evaluationResult.success || !evaluationResult.data) { return { content: [ { type: 'text', text: `❌ **Presentation Submission Failed** **Error:** Credentials do not satisfy presentation definition requirements **Evaluation Result:** ${JSON.stringify(evaluationResult, null, 2)} **Resolution:** Ensure provided credentials match the input descriptors and constraints specified in the presentation definition.` } ], isError: true }; } // Now submit the presentation with the matching credentials const submissionResponse = await fetch(`${process.env.HIVEAUTH_API_BASE_URL}/api/presentation/submit`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ presentationDefinition: data.presentationDefinition, credentials: data.credentials, holderDid: data.holderDid, challenge: data.challenge, domain: data.domain }) }); if (!submissionResponse.ok) { const errorText = await submissionResponse.text(); throw new Error(`Submission failed (${submissionResponse.status}): ${errorText}`); } const submissionResult = await submissionResponse.json(); const processingTime = Date.now() - startTime; if (!submissionResult.success) { return { content: [ { type: 'text', text: `❌ **Presentation Submission Failed** **Error:** ${submissionResult.error || 'Unknown submission error'} **Processing Time:** ${processingTime}ms **Evaluation Results:** ${JSON.stringify(evaluationResult.data, null, 2)} **Debug Info:** Check that all required credentials are present and valid.` } ], isError: true }; } // Analyze the submitted presentation const presentation = submissionResult.data.presentation; const presentationSubmission = submissionResult.data.presentationSubmission; const credentialCount = Array.isArray(presentation.verifiableCredential) ? presentation.verifiableCredential.length : 1; const inputDescriptorIds = data.presentationDefinition.input_descriptors.map(desc => desc.id); const submittedDescriptors = presentationSubmission?.descriptor_map?.map((desc: any) => desc.id) || []; const fulfillmentStatus = inputDescriptorIds.map(id => ({ inputDescriptorId: id, fulfilled: submittedDescriptors.includes(id), descriptor: data.presentationDefinition.input_descriptors.find(desc => desc.id === id) })); const allRequirementsMet = fulfillmentStatus.every(status => status.fulfilled); return { content: [ { type: 'text', text: `✅ **Presentation Submission Successful** **Submission Status:** ${allRequirementsMet ? 'All requirements satisfied' : 'Partial fulfillment'} **Processing Time:** ${processingTime}ms **Credentials Included:** ${credentialCount} **Presentation ID:** ${presentation.id || 'Generated'} **📋 Requirement Fulfillment:** ${fulfillmentStatus.map(status => `• ${status.fulfilled ? '✅' : '❌'} **${status.inputDescriptorId}**: ${status.descriptor?.purpose || status.descriptor?.name || 'No description'}` ).join('\n')} **🎯 Presentation Submission Details:** • **Definition ID:** ${data.presentationDefinition.id} • **Definition Purpose:** ${data.presentationDefinition.purpose || 'Not specified'} • **Holder DID:** ${data.holderDid || presentation.holder || 'Not specified'} • **Challenge:** ${data.challenge ? 'Included' : 'Not provided'} • **Domain:** ${data.domain || 'Not specified'} **📊 Submission Summary:** • **Input Descriptors:** ${inputDescriptorIds.length} required • **Submitted Descriptors:** ${submittedDescriptors.length} fulfilled • **Success Rate:** ${Math.round((submittedDescriptors.length / inputDescriptorIds.length) * 100)}% **🔒 Security Features:** • **Holder Binding:** ${presentation.holder ? 'Verified' : 'Anonymous'} • **Challenge-Response:** ${data.challenge ? 'Protected' : 'Open'} • **Domain Binding:** ${data.domain ? 'Domain-specific' : 'Cross-domain'} • **Proof Type:** ${presentation.proof?.type || 'Not specified'} **📄 Generated Presentation:** \`\`\`json ${JSON.stringify(presentation, null, 2)} \`\`\` **📋 Presentation Submission:** \`\`\`json ${JSON.stringify(presentationSubmission, null, 2)} \`\`\` ${allRequirementsMet ? '🎉 **Ready for verification** - This presentation can now be submitted to verifiers for validation.' : '⚠️ **Partial fulfillment** - Some requirements may not be met. Review the fulfillment status above.'} ` } ] }; } catch (error: any) { const processingTime = Date.now() - startTime; return { content: [ { type: 'text', text: `❌ **Presentation Submission Error** **Error:** ${error.message} **Processing Time:** ${processingTime}ms **Tool:** submit_presentation **📋 Input Summary:** • **Definition ID:** ${data.presentationDefinition.id} • **Credentials Count:** ${data.credentials.length} • **Holder DID:** ${data.holderDid || 'Not specified'} **🔧 Troubleshooting:** 1. **API Connectivity:** Ensure HiveAuth API is accessible at ${process.env.HIVEAUTH_API_BASE_URL} 2. **Credential Validity:** Verify all credentials are valid and properly formatted 3. **Definition Compliance:** Check that credentials meet presentation definition requirements 4. **Network Issues:** Verify network connectivity and API endpoint availability **🌐 API Endpoints Used:** • Evaluation: \`/api/presentation/evaluate\` • Submission: \`/api/presentation/submit\` For detailed debugging, check the HiveAuth API logs and ensure all required services are running.` } ], isError: true }; } }
  • Zod schema defining the input structure and validation for the submit_presentation tool, including presentationDefinition, credentials array, and optional holderDid, challenge, domain fields.
    export const SubmitPresentationInputSchema = z.object({ presentationDefinition: PresentationDefinitionSchema, credentials: z.array(CredentialSchema).min(1, 'At least one credential is required'), holderDid: z.string().optional().describe('DID of the presentation holder'), challenge: z.string().optional().describe('Challenge for the presentation proof'), domain: z.string().optional().describe('Domain for the presentation proof') });
  • Tool definition registration in TOOL_DEFINITIONS array, which is used by createMCPTools() to generate the MCP Tool object with name, description, and JSON schema for the MCP server.
    { name: 'submit_presentation', description: 'Create and submit verifiable presentations from evaluation results. Builds presentations that satisfy DIF PEX v2.0 requirements with holder binding and proof generation.', inputSchema: TOOL_SCHEMAS.submit_presentation },
  • src/index.ts:113-114 (registration)
    Dispatch registration in the MCP server's CallToolRequest handler switch statement, routing submit_presentation calls to the submitPresentation handler function.
    case 'submit_presentation': return await submitPresentation(args);
  • Maps the SubmitPresentationInputSchema to 'submit_presentation' key in the TOOL_SCHEMAS object used across the codebase for schema lookup.
    submit_presentation: SubmitPresentationInputSchema,

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