{
 "$schema": "https://static.modelcontextprotocol.io/schemas/mcp-server-card/v1.json",
 "version": "1.0",
 "protocolVersion": "2025-06-18",
 "serverInfo": {
  "name": "bobwork-email-warmup",
  "title": "BobWork Email Warm-up",
  "version": "1.0.0"
 },
 "description": "Warm up mailboxes and run cold email from warmed mailboxes: connect Gmail/Zoho/IMAP, check the ready-for-outbound gate, SPF/DKIM/DMARC, campaigns, and get Stripe checkout links for the person to pay.",
 "documentationUrl": "https://emailwarmup.bobwork.ai/llms-full.txt",
 "iconUrl": "https://emailwarmup.bobwork.ai/logos/emailwarmup-mark.png",
 "transport": {
  "type": "streamable-http",
  "endpoint": "https://app-emailwarmup.bobwork.ai/mcp"
 },
 "capabilities": {
  "tools": {
   "listChanged": false
  }
 },
 "authentication": {
  "required": true,
  "schemes": [
   "bearer"
  ],
  "description": "Authorization: Bearer bwk_... . initialize and tools/list work without a key. No key yet? An agent can sign up without a browser: POST https://app-emailwarmup.bobwork.ai/api/v1/signup/code with the person's email (a 6-digit code is emailed to them), then POST https://app-emailwarmup.bobwork.ai/api/v1/signup/verify with the nonce and code to get a bwk_ key. Guide: https://emailwarmup.bobwork.ai/llms-full.txt"
 },
 "instructions": "Manage the user's BobWork Email Warm-up account: connect mailboxes (IMAP/SMTP, Zoho, or a Google sign-in link), watch warm-up health and spam rate, check SPF/DKIM/DMARC, and run Outbound campaigns from any connected mailbox. Mailboxes are ready for outbound after 7 days under 10% spam. Removing a mailbox deletes its stored login, so confirm with the user first. Starting a campaign sends real email and uses credits ($2 per 1,000): show the user the campaign and get a clear yes before calling start_campaign. If start_campaign answers warming:true, show the user the warning and pass accept_warming_risk=true only after they agree. Money: the user pays, you never do. Over the free mailbox limit or out of credits, call create_billing_checkout or create_credits_checkout, give the returned url to the user, then poll get_billing_status until it shows the payment. No key yet: sign up without a browser with POST https://app-emailwarmup.bobwork.ai/api/v1/signup/code then /signup/verify (a code is emailed to the user).",
 "tools": [
  {
   "name": "get_account",
   "description": "Your account: email, credit balance, free mailbox allowance (10, or 20 for accounts created before 27 October 2026, plus referral bonus), paid extras and your referral link.",
   "inputSchema": {
    "type": "object",
    "properties": {},
    "required": [],
    "additionalProperties": false
   }
  },
  {
   "name": "list_mailboxes",
   "description": "Every connected mailbox with warm-up day, status, 7-day spam rate, today's and last 7 days' numbers, and whether it is ready for outbound.",
   "inputSchema": {
    "type": "object",
    "properties": {},
    "required": [],
    "additionalProperties": false
   }
  },
  {
   "name": "get_mailbox",
   "description": "One mailbox's warm-up status and health.",
   "inputSchema": {
    "type": "object",
    "properties": {
     "email": {
      "type": "string",
      "description": "Mailbox address, e.g. sales@yourdomain.com"
     }
    },
    "required": [
     "email"
    ],
    "additionalProperties": false
   }
  },
  {
   "name": "mailbox_activity",
   "description": "The last 100 warm-up events for a mailbox (sent, received, replied, rescued from spam, errors).",
   "inputSchema": {
    "type": "object",
    "properties": {
     "email": {
      "type": "string",
      "description": "Mailbox address, e.g. sales@yourdomain.com"
     }
    },
    "required": [
     "email"
    ],
    "additionalProperties": false
   }
  },
  {
   "name": "warmup_stats",
   "description": "Totals across your mailboxes: today and last 7 days (sent, received, rescued, replied), active and ready counts.",
   "inputSchema": {
    "type": "object",
    "properties": {},
    "required": [],
    "additionalProperties": false
   }
  },
  {
   "name": "list_providers",
   "description": "IMAP/SMTP presets (Gmail app password, Yahoo, iCloud, Zoho, Lark, SES, SendGrid, Mailgun…) with hosts and ports, plus the Google and Zoho API routes.",
   "inputSchema": {
    "type": "object",
    "properties": {},
    "required": [],
    "additionalProperties": false
   }
  },
  {
   "name": "connect_imap_mailbox",
   "description": "Connect any mailbox with IMAP + SMTP. The login is tested before it is saved. Use an app password when two-factor sign-in is on. Give a preset (see list_providers) or the hosts. Warm-up starts the same day.",
   "inputSchema": {
    "type": "object",
    "properties": {
     "email": {
      "type": "string",
      "description": "Mailbox address, e.g. sales@yourdomain.com"
     },
     "password": {
      "type": "string",
      "description": "Mailbox password or app password"
     },
     "preset": {
      "type": "string",
      "description": "e.g. gmail-imap, yahoo, icloud, zoho, lark, aws-ses, sendgrid, mailgun, other"
     },
     "name": {
      "type": "string",
      "description": "Display name on sent mail"
     },
     "host": {
      "type": "string",
      "description": "IMAP host (if no preset)"
     },
     "port": {
      "type": "integer"
     },
     "smtp_host": {
      "type": "string"
     },
     "smtp_port": {
      "type": "integer"
     },
     "user": {
      "type": "string",
      "description": "Login if not the email"
     },
     "smtp_user": {
      "type": "string",
      "description": "Relay platforms only (SES/SendGrid/Mailgun)"
     },
     "smtp_password": {
      "type": "string"
     }
    },
    "required": [
     "email",
     "password"
    ],
    "additionalProperties": false
   }
  },
  {
   "name": "connect_zoho_mailbox",
   "description": "Connect a Zoho Mail mailbox through the Zoho API (works on Zoho's free plan). Needs a Self Client id, secret and a generated code from api-console.zoho.com.",
   "inputSchema": {
    "type": "object",
    "properties": {
     "email": {
      "type": "string",
      "description": "Mailbox address, e.g. sales@yourdomain.com"
     },
     "client_id": {
      "type": "string"
     },
     "client_secret": {
      "type": "string"
     },
     "code": {
      "type": "string",
      "description": "Self Client code (valid 10 minutes)"
     },
     "dc": {
      "type": "string",
      "description": "Zoho data centre: com, eu, in, com.au, jp, ca",
      "default": "com"
     },
     "name": {
      "type": "string"
     }
    },
    "required": [
     "email",
     "client_id",
     "client_secret",
     "code"
    ],
    "additionalProperties": false
   }
  },
  {
   "name": "google_connect_link",
   "description": "Get a link the user opens to connect Gmail / Google Workspace with Google sign-in (one click, any device). The mailbox appears in list_mailboxes a few minutes after they allow it.",
   "inputSchema": {
    "type": "object",
    "properties": {
     "renew": {
      "type": "boolean",
      "description": "Make a fresh link"
     }
    },
    "required": [],
    "additionalProperties": false
   }
  },
  {
   "name": "update_mailbox",
   "description": "Change a mailbox's display name, daily warm-up cap (1-100, null = default), time zone (IANA, e.g. Europe/London) or the signature added to its warm-up mail (empty = default: full name and company).",
   "inputSchema": {
    "type": "object",
    "properties": {
     "email": {
      "type": "string",
      "description": "Mailbox address, e.g. sales@yourdomain.com"
     },
     "name": {
      "type": "string"
     },
     "daily_cap": {
      "type": [
       "integer",
       "null"
      ]
     },
     "timezone": {
      "type": "string"
     },
     "signature": {
      "type": "string",
      "description": "Up to 500 characters; empty resets to the default"
     }
    },
    "required": [
     "email"
    ],
    "additionalProperties": false
   }
  },
  {
   "name": "pause_mailbox",
   "description": "Pause warm-up for a mailbox.",
   "inputSchema": {
    "type": "object",
    "properties": {
     "email": {
      "type": "string",
      "description": "Mailbox address, e.g. sales@yourdomain.com"
     }
    },
    "required": [
     "email"
    ],
    "additionalProperties": false
   }
  },
  {
   "name": "resume_mailbox",
   "description": "Resume warm-up for a mailbox.",
   "inputSchema": {
    "type": "object",
    "properties": {
     "email": {
      "type": "string",
      "description": "Mailbox address, e.g. sales@yourdomain.com"
     }
    },
    "required": [
     "email"
    ],
    "additionalProperties": false
   }
  },
  {
   "name": "test_mailbox",
   "description": "Sign in to the mailbox now and report whether the stored login still works.",
   "inputSchema": {
    "type": "object",
    "properties": {
     "email": {
      "type": "string",
      "description": "Mailbox address, e.g. sales@yourdomain.com"
     }
    },
    "required": [
     "email"
    ],
    "additionalProperties": false
   }
  },
  {
   "name": "remove_mailbox",
   "description": "Remove a mailbox and delete its stored login. Irreversible: ask the user first, then pass confirm=true.",
   "inputSchema": {
    "type": "object",
    "properties": {
     "email": {
      "type": "string",
      "description": "Mailbox address, e.g. sales@yourdomain.com"
     },
     "confirm": {
      "type": "boolean"
     }
    },
    "required": [
     "email",
     "confirm"
    ],
    "additionalProperties": false
   }
  },
  {
   "name": "set_pool_mode",
   "description": "Shared network (default: warm with every mailbox on the service) or private pool (only your own mailboxes write to each other; needs 2+).",
   "inputSchema": {
    "type": "object",
    "properties": {
     "private_pool": {
      "type": "boolean"
     }
    },
    "required": [
     "private_pool"
    ],
    "additionalProperties": false
   }
  },
  {
   "name": "set_warm_style",
   "description": "Teach warm-up mail how you write: paste up to 4,000 characters of your own sent emails (tone, length, sign-offs). Empty clears it. Used when the AI writes your warm-up conversations.",
   "inputSchema": {
    "type": "object",
    "properties": {
     "warm_style": {
      "type": "string",
      "description": "Writing samples, max 4,000 characters; empty clears"
     }
    },
    "required": [
     "warm_style"
    ],
    "additionalProperties": false
   }
  },
  {
   "name": "list_workspaces",
   "description": "Client workspaces (agencies): each client's mailboxes are kept separate under one login and one bill. Returns id, name and mailbox count. Each mailbox in list_mailboxes has a workspace id (null = My mailboxes).",
   "inputSchema": {
    "type": "object",
    "properties": {},
    "required": [],
    "additionalProperties": false
   }
  },
  {
   "name": "create_workspace",
   "description": "Create a client workspace, e.g. the client's company name (max 100 per account).",
   "inputSchema": {
    "type": "object",
    "properties": {
     "name": {
      "type": "string",
      "description": "Client name, up to 60 characters"
     }
    },
    "required": [
     "name"
    ],
    "additionalProperties": false
   }
  },
  {
   "name": "rename_workspace",
   "description": "Rename a client workspace.",
   "inputSchema": {
    "type": "object",
    "properties": {
     "workspace_id": {
      "type": "string",
      "description": "Workspace id (ws_…) from list_workspaces"
     },
     "name": {
      "type": "string"
     }
    },
    "required": [
     "workspace_id",
     "name"
    ],
    "additionalProperties": false
   }
  },
  {
   "name": "delete_workspace",
   "description": "Delete a client workspace. Its mailboxes are NOT deleted: they move back to My mailboxes and keep warming. The client's report link stops working.",
   "inputSchema": {
    "type": "object",
    "properties": {
     "workspace_id": {
      "type": "string",
      "description": "Workspace id (ws_…) from list_workspaces"
     }
    },
    "required": [
     "workspace_id"
    ],
    "additionalProperties": false
   }
  },
  {
   "name": "move_mailbox_to_workspace",
   "description": "Put a mailbox in a client workspace. Leave workspace_id out (or empty) to move it back to My mailboxes.",
   "inputSchema": {
    "type": "object",
    "properties": {
     "email": {
      "type": "string",
      "description": "Mailbox address, e.g. sales@yourdomain.com"
     },
     "workspace_id": {
      "type": "string",
      "description": "Workspace id (ws_…) from list_workspaces"
     }
    },
    "required": [
     "email"
    ],
    "additionalProperties": false
   }
  },
  {
   "name": "get_workspace_report",
   "description": "The public read-only report link for one client workspace (mailbox health, spam rate, SPF/DKIM/DMARC). The client opens it without a login; it shows no prices and nothing about other clients.",
   "inputSchema": {
    "type": "object",
    "properties": {
     "workspace_id": {
      "type": "string",
      "description": "Workspace id (ws_…) from list_workspaces"
     }
    },
    "required": [
     "workspace_id"
    ],
    "additionalProperties": false
   }
  },
  {
   "name": "domain_health",
   "description": "SPF, DKIM selector, DMARC policy and MX for every domain you have connected.",
   "inputSchema": {
    "type": "object",
    "properties": {},
    "required": [],
    "additionalProperties": false
   }
  },
  {
   "name": "check_spf",
   "description": "Look up a domain's SPF record.",
   "inputSchema": {
    "type": "object",
    "properties": {
     "domain": {
      "type": "string",
      "description": "Domain, e.g. yourdomain.com"
     }
    },
    "required": [
     "domain"
    ],
    "additionalProperties": false
   }
  },
  {
   "name": "check_dkim",
   "description": "Find a domain's DKIM key: tries the selector you give, selectors seen in real mail, then 45 common ones.",
   "inputSchema": {
    "type": "object",
    "properties": {
     "domain": {
      "type": "string",
      "description": "Domain, e.g. yourdomain.com"
     },
     "selector": {
      "type": "string"
     }
    },
    "required": [
     "domain"
    ],
    "additionalProperties": false
   }
  },
  {
   "name": "check_dmarc",
   "description": "Look up a domain's DMARC record and policy.",
   "inputSchema": {
    "type": "object",
    "properties": {
     "domain": {
      "type": "string",
      "description": "Domain, e.g. yourdomain.com"
     }
    },
    "required": [
     "domain"
    ],
    "additionalProperties": false
   }
  },
  {
   "name": "get_credits",
   "description": "Prepaid credit balance, prices and recent charges (Outbound emails, AI drafts).",
   "inputSchema": {
    "type": "object",
    "properties": {},
    "required": [],
    "additionalProperties": false
   }
  },
  {
   "name": "list_campaigns",
   "description": "Your Outbound campaigns with status and stats.",
   "inputSchema": {
    "type": "object",
    "properties": {},
    "required": [],
    "additionalProperties": false
   }
  },
  {
   "name": "get_campaign",
   "description": "One campaign: its emails, mailboxes, stats and time left.",
   "inputSchema": {
    "type": "object",
    "properties": {
     "campaign_id": {
      "type": "string",
      "description": "Campaign id from list_campaigns"
     }
    },
    "required": [
     "campaign_id"
    ],
    "additionalProperties": false
   }
  },
  {
   "name": "create_campaign",
   "description": "Create a draft Outbound campaign (nothing is sent). Emails can use {first_name}, {company} and any contact field. Any connected mailbox can send; one that is still warming shows a warning first.",
   "inputSchema": {
    "type": "object",
    "properties": {
     "name": {
      "type": "string"
     },
     "emails": {
      "type": "array",
      "description": "1-4 emails in order",
      "items": {
       "type": "object",
       "properties": {
        "subject": {
         "type": "string"
        },
        "body": {
         "type": "string"
        },
        "wait_days": {
         "type": "integer",
         "description": "Days after the previous email (ignored for the first)"
        }
       },
       "required": [
        "body"
       ]
      }
     },
     "mailboxes": {
      "type": "array",
      "items": {
       "type": "string"
      }
     },
     "daily_limit": {
      "type": "integer",
      "description": "Per mailbox per day"
     }
    },
    "required": [
     "name",
     "emails"
    ],
    "additionalProperties": false
   }
  },
  {
   "name": "update_campaign",
   "description": "Edit a paused or draft campaign. Fields you leave out keep their value.",
   "inputSchema": {
    "type": "object",
    "properties": {
     "campaign_id": {
      "type": "string",
      "description": "Campaign id from list_campaigns"
     },
     "name": {
      "type": "string"
     },
     "emails": {
      "type": "array",
      "items": {
       "type": "object"
      }
     },
     "mailboxes": {
      "type": "array",
      "items": {
       "type": "string"
      }
     },
     "daily_limit": {
      "type": "integer"
     }
    },
    "required": [
     "campaign_id"
    ],
    "additionalProperties": false
   }
  },
  {
   "name": "add_contacts",
   "description": "Add up to 1,000 contacts to a campaign. Each needs email; other fields (first_name, company…) fill the placeholders. Duplicates and unsubscribed addresses are skipped.",
   "inputSchema": {
    "type": "object",
    "properties": {
     "campaign_id": {
      "type": "string",
      "description": "Campaign id from list_campaigns"
     },
     "contacts": {
      "type": "array",
      "items": {
       "type": "object",
       "properties": {
        "email": {
         "type": "string"
        }
       },
       "required": [
        "email"
       ]
      }
     }
    },
    "required": [
     "campaign_id",
     "contacts"
    ],
    "additionalProperties": false
   }
  },
  {
   "name": "list_campaign_contacts",
   "description": "Contacts in a campaign and where each is in the sequence (first 200).",
   "inputSchema": {
    "type": "object",
    "properties": {
     "campaign_id": {
      "type": "string",
      "description": "Campaign id from list_campaigns"
     }
    },
    "required": [
     "campaign_id"
    ],
    "additionalProperties": false
   }
  },
  {
   "name": "start_campaign",
   "description": "Start or resume a campaign. This SENDS real email and uses credits. Confirm with the user first. accept_sending_rules=true means the user agrees to https://emailwarmup.bobwork.ai/terms#outbound-beta (only people who may receive it, honest sender, unsubscribe honoured). If a chosen mailbox is still warming the call fails with warming:true; show the user the message and set accept_warming_risk=true only after they explicitly agree. Without credits it fails with credits_required:true: use create_credits_checkout.",
   "inputSchema": {
    "type": "object",
    "properties": {
     "campaign_id": {
      "type": "string",
      "description": "Campaign id from list_campaigns"
     },
     "accept_sending_rules": {
      "type": "boolean"
     },
     "accept_warming_risk": {
      "type": "boolean",
      "description": "The user agreed to send from mailboxes that have not finished warm-up"
     }
    },
    "required": [
     "campaign_id"
    ],
    "additionalProperties": false
   }
  },
  {
   "name": "pause_campaign",
   "description": "Pause a running campaign.",
   "inputSchema": {
    "type": "object",
    "properties": {
     "campaign_id": {
      "type": "string",
      "description": "Campaign id from list_campaigns"
     }
    },
    "required": [
     "campaign_id"
    ],
    "additionalProperties": false
   }
  },
  {
   "name": "get_billing_status",
   "description": "Payment status after you gave the user a checkout link: credit balance, whether the extra-mailbox subscription is active, mailboxes vs the free limit, and checkouts still waiting for payment. Confirms a paid checkout straight away.",
   "inputSchema": {
    "type": "object",
    "properties": {},
    "required": [],
    "additionalProperties": false
   }
  },
  {
   "name": "create_billing_checkout",
   "description": "Get a Stripe Checkout url for extra mailboxes beyond the free limit (monthly, or yearly = 10 months' price for 12). The USER opens it and pays; you cannot. Then poll get_billing_status. Returns already:true when the account is subscribed. Prices come back in the result (prices).",
   "inputSchema": {
    "type": "object",
    "properties": {
     "yearly": {
      "type": "boolean",
      "description": "Bill yearly instead of monthly"
     }
    },
    "required": [],
    "additionalProperties": false
   }
  },
  {
   "name": "create_credits_checkout",
   "description": "Get a Stripe Checkout url to top up prepaid credits for Outbound sending and AI drafts (one-off $5, $10, $25 or $100; credits never expire). The USER opens it and pays; you cannot. Then poll get_billing_status.",
   "inputSchema": {
    "type": "object",
    "properties": {
     "usd": {
      "type": "integer",
      "enum": [
       5,
       10,
       25,
       100
      ]
     }
    },
    "required": [
     "usd"
    ],
    "additionalProperties": false
   }
  },
  {
   "name": "list_bought_domains",
   "description": "Domains bought in the domain shop, their hosted mailboxes, renewal date and price, plus IMAP/SMTP settings.",
   "inputSchema": {
    "type": "object",
    "properties": {},
    "required": [],
    "additionalProperties": false
   }
  },
  {
   "name": "search_domains",
   "description": "Find available lookalike domains for cold email, with first-term and renewal prices.",
   "inputSchema": {
    "type": "object",
    "properties": {
     "q": {
      "type": "string",
      "description": "Brand or domain, e.g. acme"
     }
    },
    "required": [
     "q"
    ],
    "additionalProperties": false
   }
  },
  {
   "name": "buy_domains",
   "description": "Buy domains with up to 3 mailboxes each. Returns a Stripe checkout link for the person to pay; setup starts once paid. Needs accept_sending_rules true.",
   "inputSchema": {
    "type": "object",
    "properties": {
     "domains": {
      "type": "array",
      "items": {
       "type": "object",
       "properties": {
        "domain": {
         "type": "string",
         "description": "Domain, e.g. yourdomain.com"
        },
        "mailboxes": {
         "type": "array",
         "items": {
          "type": "object",
          "properties": {
           "local": {
            "type": "string",
            "description": "Part before @, e.g. john"
           },
           "name": {
            "type": "string",
            "description": "Display name"
           }
          },
          "required": [
           "local"
          ]
         }
        }
       },
       "required": [
        "domain"
       ]
      }
     },
     "accept_sending_rules": {
      "type": "boolean"
     }
    },
    "required": [
     "domains",
     "accept_sending_rules"
    ],
    "additionalProperties": false
   }
  },
  {
   "name": "add_hosted_mailboxes",
   "description": "Add mailboxes to a domain you bought here ($3 per mailbox per month). Returns a Stripe checkout link.",
   "inputSchema": {
    "type": "object",
    "properties": {
     "domain": {
      "type": "string",
      "description": "Domain, e.g. yourdomain.com"
     },
     "mailboxes": {
      "type": "array",
      "items": {
       "type": "object",
       "properties": {
        "local": {
         "type": "string",
         "description": "Part before @, e.g. john"
        },
        "name": {
         "type": "string",
         "description": "Display name"
        }
       },
       "required": [
        "local"
       ]
      }
     }
    },
    "required": [
     "domain",
     "mailboxes"
    ],
    "additionalProperties": false
   }
  },
  {
   "name": "hosted_mailbox_login",
   "description": "Password, IMAP and SMTP settings for one of your hosted mailboxes.",
   "inputSchema": {
    "type": "object",
    "properties": {
     "email": {
      "type": "string",
      "description": "Mailbox address, e.g. sales@yourdomain.com"
     }
    },
    "required": [
     "email"
    ],
    "additionalProperties": false
   }
  },
  {
   "name": "list_dns_records",
   "description": "DNS records on a domain you bought here.",
   "inputSchema": {
    "type": "object",
    "properties": {
     "domain": {
      "type": "string",
      "description": "Domain, e.g. yourdomain.com"
     }
    },
    "required": [
     "domain"
    ],
    "additionalProperties": false
   }
  },
  {
   "name": "add_dns_record",
   "description": "Add a DNS record to a domain you bought here. name = subdomain ('' for the domain itself). Types A, AAAA, CNAME, ALIAS, MX, TXT, CAA, SRV.",
   "inputSchema": {
    "type": "object",
    "properties": {
     "domain": {
      "type": "string",
      "description": "Domain, e.g. yourdomain.com"
     },
     "type": {
      "type": "string"
     },
     "name": {
      "type": "string"
     },
     "content": {
      "type": "string"
     },
     "ttl": {
      "type": "integer"
     },
     "prio": {
      "type": "integer"
     }
    },
    "required": [
     "domain",
     "type",
     "content"
    ],
    "additionalProperties": false
   }
  },
  {
   "name": "delete_dns_record",
   "description": "Delete a DNS record by id (from list_dns_records). Deleting MX, SPF, DKIM or DMARC stops the mailboxes working.",
   "inputSchema": {
    "type": "object",
    "properties": {
     "domain": {
      "type": "string",
      "description": "Domain, e.g. yourdomain.com"
     },
     "record_id": {
      "type": "string"
     }
    },
    "required": [
     "domain",
     "record_id"
    ],
    "additionalProperties": false
   }
  }
 ]
}