zero

repository·staging·Indexed 27 days ago

https://github.com/mail-0/zero

An open-source, AI-driven email solution designed for self-hosting. Zero allows users to unify multiple email providers, such as Gmail and Outlook, into a single inbox enhanced by LLMs and AI agents. It features a flexible WorkflowEngine for defining automated steps and actions, a PostgreSQL-based data layer, and integration support for Google OAuth, Autumn encryption, and Twilio SMS.

Tokens
10.3K
Snippets
27
Records
71
Agent score
90%

What's inside zero

  1. Zero MCP Capabilities Overview

    staging

    Zero MCP provides a suite of tools for managing email, labels, and utilizing AI features.

    Email Management

    • Retrieve email threads by ID
    • List emails within specific folders
    • Create and send new emails
    • Create and send email drafts
    • Delete emails
    • Mark emails as read or unread
    • Modify email labels
    • Perform bulk operations (delete or archive)

    Label Management

    • Retrieve all user labels
    • Create custom labels with specific colors
    • Delete existing labels

    AI-Powered Features

    • AI-assisted email composition
    • Query mailbox content via natural language
    • Query specific email threads
    • Perform web searches using Perplexity AI

    Search and Organization

    • Execute custom email search queries
    • Filter emails by labels
    • Manage organization via labels
    • Manage archive and trash folders
  2. Install and run Zero locally

    staging

    Follow these steps to set up a standard local development environment for Zero:

    1. Clone and Install Dependencies

      git clone https://github.com/Mail-0/Zero.git
      cd Zero
      pnpm install
    2. Start the Database

      pnpm docker:db:up
    3. Configure Environment Variables

      • Initialize your .env file: pnpm nizzy env
      • Sync environment variables and types: pnpm nizzy sync
    4. Initialize Database Schema

      pnpm db:push
    5. Start the Application

      pnpm dev

      The app will be available at http://localhost:3000.

    # Clone the repository
    git clone https://github.com/Mail-0/Zero.git
    cd Zero
    
    # Install dependencies
    pnpm install
    
    # Start database locally
    pnpm docker:db:up
    
    # Set Up Environment
    pnpm nizzy env
    pnpm nizzy sync
    
    # Initialize the database
    pnpm db:push
    
    # Start the App
    pnpm dev
  3. Add a new utility script to the system

    staging

    To add a new script, follow these three steps:

    1. Create the script file: Create a TypeScript file in apps/mail/scripts/ (or a subdirectory). Use the cmd-ts library to export a command object.
    2. Register the command: Import your command and add it to the subcommands object in apps/mail/scripts/run.ts.
    3. Run the script: Execute it via pnpm scripts <your-script-name> from the project root.

    The system relies on cmd-ts for type-safe command-line argument handling.

    // 1. Create apps/mail/scripts/my-script.ts
    import { command, option, string as stringType } from 'cmd-ts';
    
    export const myScriptCommand = command({
      name: 'my-script',
      description: 'Description of what my script does',
      args: {
        param1: option({
          type: stringType,
          long: 'param1',
          short: 'p',
          description: 'Description of param1',
        }),
      },
      handler: async (inputs) => {
        console.log(`Running my script with param1: ${inputs.param1}`);
      },
    });
    
    // 2. Register in apps/mail/scripts/run.ts
    import { seedStyleCommand } from '@zero/mail/scripts/seed-style/seeder';
    import { myScriptCommand } from '@zero/mail/scripts/my-script';
    import { subcommands, run } from 'cmd-ts';
    
    const app = subcommands({
      name: 'scripts',
      cmds: {
        'seed-style': seedStyleCommand,
        'my-script': myScriptCommand,
      },
    });
    
    await run(app, process.argv.slice(2));
    process.exit(0);
  4. Define a new Workflow

    staging

    Workflows are defined using the WorkflowDefinition type and registered with the WorkflowEngine instance. A workflow consists of a name, description, and an array of steps. Each step can include a condition (an async function that determines if the step should run) and an action (the logic to execute).

    const autoDraftWorkflow: WorkflowDefinition = {
      name: 'auto-draft-generation',
      description: 'Automatically generates drafts for threads that require responses',
      steps: [
        {
          id: 'check-draft-eligibility',
          name: 'Check Draft Eligibility',
          description: 'Determines if a draft should be generated for this thread',
          enabled: true,
          condition: async (context) => {
            return shouldGenerateDraft(context.thread, context.foundConnection);
          },
          action: async (context) => {
            console.log('[WORKFLOW_ENGINE] Thread eligible for draft generation', context);
            return { eligible: true };
          },
        },
        // ... more steps
      ],
    };
    
    engine.registerWorkflow(autoDraftWorkflow);
  5. Run utility scripts from the project root

    staging

    Utility scripts for the Zero email application can be executed from the project root using the pnpm scripts command. This command uses dotenv to load environment variables and executes the script runner located in the apps/mail directory.

    # Run a specific script with options
    pnpm scripts <script-name> [options]
    
    # Example: Run the seed-style script
    pnpm scripts seed-style
  6. Connect to Zero MCP using a Better Auth session token

    staging

    To connect to Zero MCP, you can use a Better Auth session token. You can either copy the entire session cookie field from your browser cookies used in the Zero webapp, or use the specific header format: better-auth-{env}.session_token={value}.

    For local development, replace {env} with dev. The {value} should be your actual session token.

  7. Configure environment variables

    staging

    Zero uses a utility called nizzy to manage environment variables. Run pnpm nizzy env to copy .env.example to .env and pre-fill variables. Use pnpm nizzy sync to ensure your environment variables and types are synchronized.

    Required Service Configurations

    Better Auth

    Set BETTER_AUTH_SECRET to a random 32-character hex string (e.g., generated via openssl rand -hex 32).

    Google OAuth (for Gmail integration)

    1. Enable People API, Gmail API, and Google OAuth2 API in the Google Cloud Console.
    2. Create OAuth 2.0 credentials (Web application).
    3. Add authorized redirect URIs:
      • Dev: http://localhost:8787/api/auth/callback/google
      • Prod: https://your-production-url/api/auth/callback/google
    4. Add GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET to .env.
    5. Add your email as a Test User in the Google Cloud Console.

    Autumn (for encryption)

    Generate an Autumn Secret Key from the Autumn sandbox or production dashboard and add it to .env as AUTUMN_SECRET_KEY.

    Twilio (for SMS integration)

    Add the following to .env:

    • TWILIO_ACCOUNT_SID
    • TWILIO_AUTH_TOKEN
    • TWILIO_PHONE_NUMBER
  8. Add a new Workflow Function to the registry

    staging

    To create a reusable logic block, add a new function to the workflowFunctions object in workflow-functions.ts. These functions implement the WorkflowFunction type. You can access results from previous steps using the context.results Map, where the key is the id of the previous step.

    export const workflowFunctions: Record<string, WorkflowFunction> = {
      // ... existing functions ...
    
      myNewFunction: async (context) => {
        // Your logic here
        console.log('[WORKFLOW_FUNCTIONS] Executing my new function');
    
        // Access previous step results
        const previousResult = context.results?.get('previous-step-id');
    
        // Return result for next steps
        return { success: true, data: 'some data' };
      },
    };
  9. Configure email sync environment variables

    staging

    When using Durable Objects and R2 for email storage, use these variables to control synchronization behavior:

    • DROP_AGENT_TABLES: Boolean. If true, the durable object drops the threads table before starting a sync.
    • THREAD_SYNC_MAX_COUNT: Integer. The maximum number of threads to sync per request (max 500).
    • THREAD_SYNC_LOOP: Boolean. If true, ensures all items in a folder are synced by looping until the folder is fully synced (recommended for production).
  10. Use the Nizzy CLI interactive mode

    staging

    If you run the nizzy command without any arguments, the CLI enters an interactive mode. It will greet you and present a selectable list of available commands based on their descriptions. You can navigate the list using your arrow keys and select a command to execute it. If you cancel the selection, the process will exit gracefully.

    pnpm nizzy
  11. Execute workflows dynamically

    staging

    The WorkflowEngine supports dynamic discovery. You can retrieve all registered workflow names and execute them in a loop without hardcoding specific workflow IDs.

    // Get all available workflow names from the engine
    const workflowNames = workflowEngine.getWorkflowNames();
    
    // Execute all workflows dynamically
    for (const workflowName of workflowNames) {
      const { results, errors } = await workflowEngine.executeWorkflow(workflowName, context);
    }
  12. Configure UI state and layout constants in apps/mail

    staging

    The apps/mail/lib/constants.tsx file defines several configuration constants used for managing UI state via cookies, sidebar dimensions, and email provider metadata.

    • I18N_LOCALE_COOKIE_NAME: 'i18n:locale'
    • SIDEBAR_COOKIE_NAME: 'sidebar:state'
    • AI_SIDEBAR_COOKIE_NAME: 'ai-sidebar:state'
    • SIDEBAR_WIDTH: '14rem'
    • SIDEBAR_WIDTH_MOBILE: '14rem'
    • SIDEBAR_WIDTH_ICON: '3rem'
    • SIDEBAR_COOKIE_MAX_AGE: 2592000 (30 days in seconds)
    • SIDEBAR_KEYBOARD_SHORTCUT: 'b'

    Email Provider Configuration

    • emailProviders: An array containing available providers. Currently supports Gmail with providerId: 'google'.
    • GMAIL_COLORS: A collection of textColor and backgroundColor pairs used for Gmail-related UI elements.