Smithery Logo
MCPsSkillsDocsPricing
Login
Smithery Logo

Accelerating the Agent Economy

Resources

DocumentationPrivacy PolicySystem Status

Company

PricingAboutBlog

Connect

© 2026 Smithery. All rights reserved.

    nathanielcrowell12-spec

    resend

    nathanielcrowell12-spec/resend
    Communication

    About

    SKILL.md

    Install

    Install via Skills CLI

    or add to your agent
    • Claude Code
      Claude Code
    • Codex
      Codex
    • OpenClaw
      OpenClaw
    • Cursor
      Cursor
    • Amp
      Amp
    • GitHub Copilot
      GitHub Copilot
    • Gemini CLI
      Gemini CLI
    • Kilo Code
      Kilo Code
    • Junie
      Junie
    • Replit
      Replit
    • Windsurf
      Windsurf
    • Cline
      Cline
    • Continue
      Continue
    • OpenCode
      OpenCode
    • OpenHands
      OpenHands
    • Roo Code
      Roo Code
    • Augment
      Augment
    • Goose
      Goose
    • Trae
      Trae
    • Zencoder
      Zencoder
    • Antigravity
      Antigravity
    ├─
    ├─
    └─

    About

    Implement email notifications for PhotoVault using Resend and React Email.

    SKILL.md

    ⚠️ MANDATORY WORKFLOW - DO NOT SKIP

    When this skill activates, you MUST follow the expert workflow before writing any code:

    1. Spawn Domain Expert using the Task tool with this prompt:

      Read the expert prompt at: C:\Users\natha\Stone-Fence-Brain\VENTURES\PhotoVault\claude\experts\resend-expert.md
      
      Then research the codebase and write an implementation plan to: docs/claude/plans/email-[task-name]-plan.md
      
      Task: [describe the user's request]
      
    2. Spawn QA Critic after expert returns, using Task tool:

      Read the QA critic prompt at: C:\Users\natha\Stone-Fence-Brain\VENTURES\PhotoVault\claude\experts\qa-critic-expert.md
      
      Review the plan at: docs/claude/plans/email-[task-name]-plan.md
      Write critique to: docs/claude/plans/email-[task-name]-critique.md
      
    3. Present BOTH plan and critique to user - wait for approval before implementing

    DO NOT read files and start coding. DO NOT rationalize that "this is simple." Follow the workflow.


    Resend Email Integration

    Core Principles

    Email HTML is NOT Web HTML

    Email clients strip <style> tags, ignore CSS classes, and render tables differently. Everything must be inline.

    // ❌ BAD: CSS classes don't work
    <div className="button">Click me</div>
    
    // ✅ GOOD: Inline styles
    <a href={url} style={{
      backgroundColor: '#f59e0b',
      color: '#000000',
      padding: '12px 24px',
      borderRadius: '8px',
      textDecoration: 'none',
      display: 'inline-block',
    }}>
      Click me
    </a>
    

    Mobile First (60%+ opens)

    Most emails are read on phones. Design for 320px width first.

    const container = {
      maxWidth: '600px',
      padding: '20px',
      margin: '0 auto',
    }
    

    Every Email Needs a Preview

    The preview text appears in the inbox next to the subject.

    import { Preview } from '@react-email/components'
    <Preview>Your gallery "Smith Wedding" is ready with 247 photos</Preview>
    

    Anti-Patterns

    Using CSS classes or external stylesheets

    // WRONG: Won't render
    <style>{`.button { background: blue; }`}</style>
    <a className="button">Click</a>
    
    // RIGHT: Inline everything
    <a style={{ backgroundColor: 'blue', padding: '12px 24px' }}>Click</a>
    

    Using flexbox or grid

    // WRONG: Not supported in most email clients
    <div style={{ display: 'flex' }}>
    
    // RIGHT: Use tables for layout
    import { Row, Column } from '@react-email/components'
    <Row>
      <Column>Left content</Column>
      <Column>Right content</Column>
    </Row>
    

    Forgetting alt text on images

    // WRONG: Images often blocked
    <Img src={url} />
    
    // RIGHT: Always include meaningful alt
    <Img src={url} alt="Preview of your wedding photos" />
    

    Generic subject lines

    // WRONG: Low open rate
    subject: 'Update from PhotoVault'
    
    // RIGHT: Specific and actionable
    subject: 'Your "Smith Wedding" gallery is ready - 247 photos inside'
    

    Not handling send failures

    // WRONG: Silent failure
    await resend.emails.send({ ... })
    
    // RIGHT: Handle errors
    const { data, error } = await resend.emails.send({ ... })
    if (error) {
      console.error('Email failed:', error)
    }
    

    Email Template Pattern

    // src/lib/email/templates/gallery-ready.tsx
    import {
      Body, Container, Head, Heading, Html,
      Img, Link, Preview, Section, Text,
    } from '@react-email/components'
    
    interface GalleryReadyEmailProps {
      clientName: string
      galleryName: string
      photoCount: number
      previewImageUrl: string
      galleryUrl: string
    }
    
    export function GalleryReadyEmail({
      clientName, galleryName, photoCount, previewImageUrl, galleryUrl,
    }: GalleryReadyEmailProps) {
      return (
        <Html>
          <Head />
          <Preview>Your "{galleryName}" gallery is ready - {photoCount} photos inside</Preview>
          <Body style={main}>
            <Container style={container}>
              <Img src="https://photovault.photo/logo.png" alt="PhotoVault" width={150} />
              <Heading style={heading}>Hi {clientName}!</Heading>
              <Text style={text}>
                Your photos from <strong>{galleryName}</strong> are ready.
                Your photographer has uploaded {photoCount} photos.
              </Text>
              {previewImageUrl && (
                <Img src={previewImageUrl} alt={`Preview from ${galleryName}`} width={560} />
              )}
              <Section style={{ textAlign: 'center', marginTop: '30px' }}>
                <Link href={galleryUrl} style={button}>View Your Photos</Link>
              </Section>
            </Container>
          </Body>
        </Html>
      )
    }
    
    const main = {
      backgroundColor: '#0a0a0a',
      fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
    }
    
    const container = { maxWidth: '600px', margin: '0 auto', padding: '40px 20px' }
    const heading = { color: '#ffffff', fontSize: '28px', fontWeight: 'bold' }
    const text = { color: '#a3a3a3', fontSize: '16px', lineHeight: '26px' }
    const button = {
      backgroundColor: '#f59e0b',
      color: '#000000',
      padding: '14px 28px',
      borderRadius: '8px',
      textDecoration: 'none',
      fontWeight: 'bold',
      display: 'inline-block',
    }
    

    Email Service

    // src/lib/email/email-service.ts
    import { Resend } from 'resend'
    
    const resend = new Resend(process.env.RESEND_API_KEY)
    
    interface SendEmailParams {
      to: string | string[]
      subject: string
      react: React.ReactElement
      replyTo?: string
    }
    
    export async function sendEmail({ to, subject, react, replyTo }: SendEmailParams) {
      try {
        const { data, error } = await resend.emails.send({
          from: 'PhotoVault <noreply@photovault.photo>',
          to: Array.isArray(to) ? to : [to],
          subject,
          react,
          replyTo: replyTo || 'support@photovault.photo',
        })
    
        if (error) {
          console.error('[Email] Send failed:', error)
          return { success: false, error }
        }
    
        console.log('[Email] Sent successfully:', data?.id)
        return { success: true, id: data?.id }
      } catch (error) {
        console.error('[Email] Unexpected error:', error)
        return { success: false, error }
      }
    }
    

    PhotoVault Configuration

    Templates Needed

    Template Trigger Recipient
    gallery-ready Photographer marks ready Client
    payment-success Checkout completed Client
    payment-failed Invoice failed Client
    invitation Photographer invites client Client
    commission-earned Client pays Photographer

    Branding

    Element Value
    Primary color #f59e0b (amber)
    Background #0a0a0a (near black)
    Text #a3a3a3 (gray)
    Headings #ffffff (white)

    Environment Variables

    RESEND_API_KEY=re_...
    FROM_EMAIL=PhotoVault <noreply@photovault.photo>
    

    Testing Emails

    # Preview locally
    npx react-email dev
    

    Deliverability Checklist

    1. ✅ Domain verified in Resend (DKIM, SPF)
    2. ✅ FROM address uses verified domain
    3. ✅ Subject line is specific, not spammy
    4. ✅ Alt text on all images
    5. ✅ No URL shorteners
    6. ✅ Reply-to address is valid
    Recommended Servers
    AgentMail
    AgentMail
    Repository
    nathanielcrowell12-spec/photo-vault
    Files