---
url: https://bishop.agentdeployment.co/interfaces/email.md
description: >-
  Connecting Bishop to a Google Workspace mailbox, and which mail the agent
  never answers.
---

# Email

Bishop reads a Google Workspace mailbox and answers mail in the same thread. The agent needs its own Workspace user, say `salesforce-guy@example.com`. That address is what people write to, and its mailbox is what Bishop reads. Don't point this at a person's account.

## Setup

Create an OAuth client, once:

1. In the [Google Cloud console](https://console.cloud.google.com/), pick or create a project and **enable the Gmail API**.
2. Configure the OAuth consent screen with user type **Internal**. This is what lets you skip Google's app verification.
3. Create an OAuth client ID of type **Desktop app**.
4. Put both values in `.env`:

```sh
BISHOP_GMAIL_CLIENT_ID=...
BISHOP_GMAIL_CLIENT_SECRET=...
```

Then authorize the mailbox:

```sh
bishop gmail setup
```

A browser opens. Sign in **as the agent's Workspace user**, not as yourself, and approve. Bishop catches the redirect, writes `BISHOP_GMAIL_REFRESH_TOKEN` to `.env`, and tells you which mailbox it reached.

Re-running it later checks the credentials instead of authorizing again, so it doubles as a health check in a deploy script. It exits non-zero when the mailbox can't be reached.

**Set `gmail.allow` before pointing anyone at it.** Without it, every address that can reach the mailbox can use the agent, and a Workspace mailbox can be reached from anywhere.

```json
{ "gmail": { "allow": ["you@example.com", "@example.com"] } }
```

### Moving it to a server

The refresh token isn't tied to the machine you authorized on. Copy three lines to the server's `.env` and start Bishop there:

```sh
BISHOP_GMAIL_CLIENT_ID=...
BISHOP_GMAIL_CLIENT_SECRET=...
BISHOP_GMAIL_REFRESH_TOKEN=...
```

To set it up on the server directly instead, run `bishop gmail setup` there. It notices it's over SSH, prints a URL instead of opening one, and asks you to paste back where the browser ended up. The browser lands on a `http://127.0.0.1` address that fails to load, which is expected: the code is in the address bar, and pasting the whole address is enough. `--no-browser` forces that mode anywhere.

### When it stops working

Google revokes Gmail refresh tokens when the mailbox's password is reset. The agent goes quiet, the log says the token is no longer valid, and `bishop gmail setup` fixes it by authorizing again.

If that isn't acceptable, use domain-wide delegation instead. Nothing about it expires and no person is ever needed again, but it costs more to set up: a service account key, which most organizations now block by default, plus a Workspace super admin to grant the delegation. Set `BISHOP_GMAIL_USER` and `BISHOP_GMAIL_SERVICE_ACCOUNT` instead of the three OAuth variables, and run `bishop gmail setup` to check it. It prints the exact client ID and scope to paste into the admin console when the grant is missing.

## Using it

Anyone on the allow list emails the agent, and the reply arrives in the same thread. An email thread is an agent session, exactly as a Slack thread is: reply to the agent's answer and it picks up where it left off.

* **Nothing happens until the turn is over.** No streaming, no progress, no sign the agent is working. Then one plain-text reply arrives with everything it had to say. This makes a long turn fine, which it isn't in Slack.
* **The reply goes to everyone on the thread.** So Bishop refuses a thread with anyone on it who isn't on the allow list. If you're on the list and copied someone who isn't, it tells you why. If you're not on the list, it sends nothing at all.
* **Labels are the only progress you get.** Bishop marks each thread `Bishop/Working` while it runs, then `Bishop/Done`, `Bishop/Failed`, or `Bishop/Refused`. Open the mailbox to see what the agent is doing.
* **Attachments come through.** Bishop downloads what was attached and hands the agent the path, the same as in Slack.
* **No stop button.** Nothing in email can cancel a turn.

## Mail the agent never answers

Bishop never answers automated mail: autoresponders, mailing lists, bounces, its own address, or anything Gmail marked spam. It also refuses mail whose sender Gmail's own verdict doesn't clear, without writing back, since the from address is the one thing known to be untrustworthy there. That check reads DMARC rather than a bare SPF or DKIM pass, and only from the topmost `Authentication-Results` header, because a sender can write that header themselves and only Gmail's own copy means anything.

**Bishop only ever writes to an address on the allow list.** Someone not on it gets no reply, not even one explaining why. The thread is labelled `Bishop/Refused` and the reason goes in the log. Without this, pointing the agent at a mailbox that receives ordinary mail means it answers every stranger who writes in.

**Bishop never answers mail that arrived before you pointed it at the mailbox.** It records that moment the first time it connects and refuses anything older. Startup logs the cutoff as `answeringMailAfter`. Restarts still catch up on whatever arrived while it was down, because the cutoff is when it first attached, not when the process started. There is no setting that moves it earlier.

## Configuration

The `gmail` block takes `allow`, `pollSeconds`, `labelPrefix`, `markRead` and `internalDomains`. [Configuration](/reference/config#gmail) describes each.
