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,
Behavior2/5

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

With no annotations provided, the description carries full burden for behavioral disclosure. It mentions 'holder binding and proof generation', which hints at security features, but doesn't describe what the tool actually does (e.g., whether it returns a presentation object, makes an API call, or stores data), error conditions, rate limits, or side effects. For a complex tool with 5 parameters, this is insufficient.

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

Conciseness4/5

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

The description is concise (two sentences) and front-loaded with the core purpose. Every sentence contributes meaning: the first states what the tool does, and the second adds technical context. There's no wasted verbiage, though it could be slightly more structured for clarity.

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

Completeness2/5

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

Given the tool's complexity (5 parameters, nested objects, no output schema, and no annotations), the description is incomplete. It doesn't explain what the tool returns, error handling, or how parameters like 'challenge' and 'domain' interact with 'holder binding and proof generation'. For a tool that likely produces cryptographic outputs, more context is needed.

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 80%, so the schema already documents most parameters well. The description adds minimal value beyond the schemaβ€”it mentions 'evaluation results' which might relate to 'credentials', and 'DIF PEX v2.0 requirements' which maps to 'presentationDefinition', but doesn't explain parameter interactions or provide usage examples. This meets the baseline for high schema coverage.

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

Purpose4/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: 'Create and submit verifiable presentations from evaluation results.' It specifies the action (create and submit) and resource (presentations), and mentions compliance with DIF PEX v2.0. However, it doesn't explicitly differentiate from siblings like 'create_presentation_definition' or 'evaluate_presentation', which is why it doesn't achieve a perfect score.

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

Usage Guidelines2/5

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

The description provides no guidance on when to use this tool versus alternatives. It mentions building presentations that satisfy DIF PEX v2.0 requirements, but doesn't specify prerequisites, exclusions, or compare it to related tools like 'evaluate_presentation' or 'verify_presentation'. This leaves the agent without context for tool selection.

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