batch_verify_credentials
Verify multiple verifiable credentials simultaneously with parallel processing, early error termination, and detailed statistics to ensure efficient validation within the HiveAuth ecosystem.
Instructions
Verify multiple verifiable credentials efficiently. Supports parallel processing, early termination on errors, and detailed verification statistics.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| credentials | Yes | ||
| parallel | No | Whether to process credentials in parallel | |
| stopOnFirstError | No | Whether to stop verification on first error |
Implementation Reference
- The main handler function that executes the batch credential verification. It validates input, processes credentials in parallel or sequentially via HiveAuth API, handles errors, generates detailed summaries, statistics, and JSON output.export async function batchVerifyCredentials(args: any): Promise<CallToolResult> { // Validate and sanitize input const validation = validateAndSanitizeInput(BatchVerifyCredentialsInputSchema, args, 'batch_verify_credentials'); if (!validation.success) { return createValidationErrorResult(validation.error!); } const data = validation.data!; const { credentials, parallel = true, stopOnFirstError = false } = data; const HIVEAUTH_API_BASE_URL = process.env.HIVEAUTH_API_BASE_URL || 'http://localhost:3000'; const VERIFY_ENDPOINT = `${HIVEAUTH_API_BASE_URL}/api/verify`; const startTime = Date.now(); const results: any[] = []; const errors: any[] = []; let stopped = false; try { console.log(`[BatchVerify] Starting batch verification of ${credentials.length} credentials`); console.log(`[BatchVerify] Config: parallel=${parallel}, stopOnFirstError=${stopOnFirstError}`); if (parallel && !stopOnFirstError) { // Process all credentials in parallel const promises = credentials.map(async (credential, index) => { try { const response = await fetch(VERIFY_ENDPOINT, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ credential }), }); if (!response.ok) { const errorData = await response.json().catch(() => ({ message: response.statusText })); throw new Error(`API Error: ${errorData.message}`); } const result = await response.json(); return { index, success: true, verified: result.verified, credential, result, credentialId: credential.id || `credential-${index + 1}` }; } catch (error: any) { return { index, success: false, verified: false, error: error.message, credentialId: credential.id || `credential-${index + 1}` }; } }); const allResults = await Promise.all(promises); // Separate results allResults.forEach(result => { if (result.success) { results.push(result); } else { errors.push(result); } }); } else { // Process sequentially or with early termination for (let index = 0; index < credentials.length; index++) { if (stopped) break; const credential = credentials[index]; try { const response = await fetch(VERIFY_ENDPOINT, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ credential }), }); if (!response.ok) { const errorData = await response.json().catch(() => ({ message: response.statusText })); throw new Error(`API Error: ${errorData.message}`); } const result = await response.json(); const verificationResult = { index, success: true, verified: result.verified, credential, result, credentialId: credential.id || `credential-${index + 1}` }; results.push(verificationResult); // Stop on first verification failure if requested if (stopOnFirstError && !result.verified) { stopped = true; console.log(`[BatchVerify] Stopping on first verification failure at index ${index}`); } } catch (error: any) { const errorResult = { index, success: false, verified: false, error: error.message, credentialId: credential.id || `credential-${index + 1}` }; errors.push(errorResult); // Stop on first error if requested if (stopOnFirstError) { stopped = true; console.log(`[BatchVerify] Stopping on first error at index ${index}`); } } } } const endTime = Date.now(); const duration = endTime - startTime; const totalProcessed = results.length + errors.length; const validCredentials = results.filter(r => r.verified).length; const invalidCredentials = results.filter(r => !r.verified).length; const apiErrors = errors.length; // Generate detailed summary const summary = [ `🔍 **Batch Credential Verification Results**`, ``, `• Total Processed: ${totalProcessed}/${credentials.length}`, `• Valid Credentials: ${validCredentials} ✅`, `• Invalid Credentials: ${invalidCredentials} ❌`, `• API Errors: ${apiErrors} 🚫`, `• Processing Mode: ${parallel ? 'Parallel' : 'Sequential'}`, `• Duration: ${duration}ms`, `• Average per credential: ${Math.round(duration / totalProcessed)}ms`, `` ]; if (stopped) { summary.push(`⚠️ **Early Termination**: Stopped processing due to stopOnFirstError setting`); summary.push(``); } // Valid credentials const validResults = results.filter(r => r.verified); if (validResults.length > 0) { summary.push(`**✅ Valid Credentials (${validResults.length}):**`); validResults.forEach(result => { const issuer = result.credential.issuer; const issuerInfo = typeof issuer === 'string' ? issuer : issuer?.id || 'Unknown'; const types = result.credential.type?.filter((t: string) => t !== 'VerifiableCredential').join(', ') || 'Unknown'; summary.push(`${result.index + 1}. **${result.credentialId}** - ${types} (Issuer: ${issuerInfo})`); }); summary.push(``); } // Invalid credentials const invalidResults = results.filter(r => !r.verified); if (invalidResults.length > 0) { summary.push(`**❌ Invalid Credentials (${invalidResults.length}):**`); invalidResults.forEach(result => { const reason = result.result?.message || 'Verification failed'; summary.push(`${result.index + 1}. **${result.credentialId}** - ${reason}`); }); summary.push(``); } // API errors if (apiErrors > 0) { summary.push(`**🚫 API Errors (${apiErrors}):**`); errors.forEach(error => { summary.push(`${error.index + 1}. **${error.credentialId}** - ${error.error}`); }); summary.push(``); } // Performance insights if (parallel && totalProcessed > 1) { const sequentialEstimate = duration * totalProcessed; const speedup = Math.round((sequentialEstimate / duration) * 10) / 10; summary.push(`**⚡ Performance:**`); summary.push(`• Parallel speedup: ~${speedup}x faster than sequential`); summary.push(`• Verification rate: ${Math.round(totalProcessed / (duration / 1000))} credentials/second`); } // Recommendations summary.push(`**💡 Recommendations:**`); if (invalidCredentials > 0) { summary.push(`• Review invalid credentials for common issues (expired, revoked, signature problems)`); } if (apiErrors > 0) { summary.push(`• Check network connectivity and HiveAuth API availability`); } if (validCredentials / totalProcessed < 0.8) { summary.push(`• Consider reviewing credential sources - low validation rate detected`); } return { content: [ { type: 'text', text: summary.join('\n') }, { type: 'text', text: `\`\`\`json\n${JSON.stringify({ summary: { totalProcessed, totalCredentials: credentials.length, validCredentials, invalidCredentials, apiErrors, duration, parallel, stopOnFirstError, stopped }, validCredentials: validResults.map(r => ({ index: r.index, credentialId: r.credentialId, verified: true, types: r.credential.type })), invalidCredentials: invalidResults.map(r => ({ index: r.index, credentialId: r.credentialId, verified: false, reason: r.result?.message })), errors: errors.map(e => ({ index: e.index, credentialId: e.credentialId, error: e.error })) }, null, 2)}\n\`\`\`` } ] }; } catch (error: any) { return { content: [ { type: 'text', text: `Failed to verify credentials in batch: ${error.message}` } ], isError: true }; } }
- src/schemas/toolSchemas.ts:133-137 (schema)Zod input schema definition for the batch_verify_credentials tool, defining structure for credentials array, parallel processing flag, and early termination option.export const BatchVerifyCredentialsInputSchema = z.object({ credentials: z.array(CredentialSchema).min(1).max(100, 'Maximum 100 credentials per batch'), parallel: z.boolean().default(true).describe('Whether to process credentials in parallel'), stopOnFirstError: z.boolean().default(false).describe('Whether to stop verification on first error') });
- src/index.ts:104-105 (registration)Tool registration in the main MCP server switch statement, dispatching calls to the batchVerifyCredentials handler function.case 'batch_verify_credentials': return await batchVerifyCredentials(args);
- src/utils/schemaConverter.ts:52-54 (registration)Tool registration in schema converter for MCP tool list generation, including name, description, and input schema reference used by createMCPTools().name: 'batch_verify_credentials', description: 'Verify multiple verifiable credentials efficiently. Supports parallel processing, early termination on errors, and detailed verification statistics.', inputSchema: TOOL_SCHEMAS.batch_verify_credentials
- src/schemas/toolSchemas.ts:185-185 (schema)Mapping of batch_verify_credentials to its input schema in the central TOOL_SCHEMAS object, enabling schema lookup and conversion.batch_verify_credentials: BatchVerifyCredentialsInputSchema,