verify_email
Check email address validity using the Instantly MCP Server to ensure deliverability and maintain contact list accuracy.
Instructions
Verify if an email address is valid. IMPORTANT: This feature may require a premium Instantly plan or specific API permissions. If you receive a 403 Forbidden error, check: 1) Your Instantly plan includes email verification, 2) Your API key has the required scopes, 3) Contact Instantly support to confirm feature availability.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| Yes | Email address to verify (must be valid email format) |
Implementation Reference
- src/handlers/tool-executor.ts:743-883 (handler)Core handler implementation in executeToolDirectly switch statement. Validates input, calls Instantly API /email-verification POST, polls /email-verification/check-verification-status if pending (robust polling up to 45s for slow domains like gmail.com), handles timeout, returns full verification results including status, score, flags, catch_all, credits.case 'verify_email': { console.error('[Instantly MCP] 📧 Executing verify_email with complete workflow...'); // Validate parameters with Zod schema const validatedArgs = validateEmailVerificationData(args); const email = validatedArgs.email; console.error(`[Instantly MCP] 🔍 Initiating verification for: ${email}`); // Step 1: Initiate email verification const initialResult = await makeInstantlyRequest('/email-verification', { method: 'POST', body: { email: email } }, apiKey); console.error(`[Instantly MCP] 📊 Initial verification result: ${JSON.stringify(initialResult, null, 2)}`); // Step 2: Check if verification is complete or needs polling if (initialResult.verification_status === 'pending' || initialResult.status === 'pending') { console.error('[Instantly MCP] ⏳ Verification pending, starting polling process...'); // Domain-specific timeout handling for known slow-verifying domains const emailDomain = email.split('@')[1]?.toLowerCase(); const slowDomains = ['creatorbuzz.com', 'techrecruiterpro.net', 'topoffunnel.com', 'gmail.com', 'outlook.com', 'yahoo.com', 'lead411.io', 'instantly.ai']; const isSlowDomain = slowDomains.includes(emailDomain); // ROBUST polling configuration - wait for complete verification // Increased timeout to allow slow domains to complete verification const baseMaxPollingTime = 30000; // 30 seconds base maximum (allows most verifications to complete) const slowDomainExtension = 15000; // Add 15 seconds for slow domains const maxPollingTime = isSlowDomain ? (baseMaxPollingTime + slowDomainExtension) : baseMaxPollingTime; // 45s for slow domains, 30s for others const pollingInterval = 2000; // 2 seconds between polls (balance between responsiveness and API load) const startTime = Date.now(); let attempts = 0; const maxAttempts = Math.floor(maxPollingTime / pollingInterval); // ~15-22 attempts console.error(`[Instantly MCP] 🎯 ROBUST polling config: ${emailDomain} (slow: ${isSlowDomain}) - max time: ${maxPollingTime}ms (${maxPollingTime/1000}s), max attempts: ${maxAttempts}, interval: ${pollingInterval}ms`); while (Date.now() - startTime < maxPollingTime && attempts < maxAttempts) { attempts++; console.error(`[Instantly MCP] 🔄 Polling attempt ${attempts}/${maxAttempts}...`); // Wait before polling await new Promise(resolve => setTimeout(resolve, pollingInterval)); try { // Step 3: Check verification status const statusResult = await makeInstantlyRequest('/email-verification/check-verification-status', { params: { email: email } }, apiKey); console.error(`[Instantly MCP] 📋 Status check result: ${JSON.stringify(statusResult, null, 2)}`); // Check if verification is complete if (statusResult.verification_status && statusResult.verification_status !== 'pending') { console.error(`[Instantly MCP] ✅ Verification complete after ${attempts} attempts`); return { content: [ { type: 'text', text: JSON.stringify({ success: true, email: email, verification_status: statusResult.verification_status, deliverability: statusResult.deliverability || statusResult.verification_status, catch_all: statusResult.catch_all, credits: statusResult.credits || initialResult.credits, credits_used: statusResult.credits_used || initialResult.credits_used, polling_attempts: attempts, total_time_seconds: Math.round((Date.now() - startTime) / 1000), message: 'Email verification completed successfully' }, null, 2) } ] }; } } catch (pollError) { console.error(`[Instantly MCP] ⚠️ Polling attempt ${attempts} failed:`, pollError); // Continue polling unless it's the last attempt if (attempts >= maxAttempts) { throw pollError; } } } // Step 4: Handle timeout scenario - verification still pending after extended polling console.error(`[Instantly MCP] ⏰ Verification polling timed out after ${Math.round((Date.now() - startTime) / 1000)}s - verification still in progress`); return { content: [ { type: 'text', text: JSON.stringify({ success: false, // Changed to false - verification incomplete email: email, verification_status: 'timeout', deliverability: 'verification_in_progress', catch_all: initialResult.catch_all || 'pending', credits: initialResult.credits, credits_used: initialResult.credits_used, polling_attempts: attempts, total_time_seconds: Math.round((Date.now() - startTime) / 1000), max_polling_time_seconds: Math.round(maxPollingTime / 1000), polling_interval_seconds: Math.round(pollingInterval / 1000), message: `Verification timed out after ${Math.round((Date.now() - startTime) / 1000)} seconds of polling. The verification is still processing on Instantly's servers.`, verification_mode: 'extended_polling_timeout', domain: emailDomain, is_slow_domain: isSlowDomain, initial_result: initialResult, note: `This email domain (${emailDomain}) requires exceptionally long verification time (>${Math.round(maxPollingTime / 1000)}s). The verification was initiated successfully but has not completed yet.`, recommendation: 'Try verifying this email again in 1-2 minutes, or use the Instantly.ai web dashboard to check verification status.' }, null, 2) } ] }; } else { // Step 5: Verification completed immediately console.error('[Instantly MCP] ⚡ Verification completed immediately'); return { content: [ { type: 'text', text: JSON.stringify({ success: true, email: email, verification_status: initialResult.verification_status, deliverability: initialResult.deliverability || initialResult.verification_status, catch_all: initialResult.catch_all, credits: initialResult.credits, credits_used: initialResult.credits_used, polling_attempts: 0, total_time_seconds: 0, message: 'Email verification completed immediately' }, null, 2) } ] }; } }
- src/tools/email-tools.ts:87-100 (schema)Tool definition and input schema registration in emailTools array, exported to TOOLS_DEFINITION. Specifies name, description, readOnlyHint annotation, and inputSchema requiring single 'email' string parameter.{ name: 'verify_email', title: 'Verify Email', description: 'Verify email deliverability (5-45s). Returns status, score, flags.', annotations: { readOnlyHint: true }, inputSchema: { type: 'object', properties: { email: { type: 'string', description: 'Email to verify' } }, required: ['email'] } }, ];
- src/validation.ts:307-309 (schema)Zod schema for input validation: object with required 'email' field using EmailSchema (strict email format validator).export const VerifyEmailSchema = z.object({ email: EmailSchema });
- src/validation.ts:838-838 (registration)TOOL_VALIDATORS map entry registering validateEmailVerificationData function for 'verify_email' tool, used in handler for input validation.'verify_email': validateEmailVerificationData,
- src/error-handler.ts:63-69 (helper)Specialized error handling in handleInstantlyError for verify_email tool: provides plan-specific guidance for 403 Forbidden errors related to premium feature access.if (toolName === 'verify_email') { throw new McpError( ErrorCode.InvalidRequest, `Email verification access forbidden (403): ${error.message}. ` + `This feature requires a premium Instantly plan. Check: 1) Your plan includes email verification, 2) API key has required scopes, 3) Contact Instantly support.` ); }