Skip to main content
Glama
DavidOloyede

gmail-multi

by DavidOloyede

gmail-multi

Give Claude more than one Gmail account: a small server that runs on your own computer and lets Claude Code and Claude Desktop search and read several named Gmail inboxes.

Animated walkthrough: clone, install, connect two Gmail accounts, register with Claude, and ask about both inboxes

▶ Open the interactive walkthrough

Status: v0.1 · read-only · 4 tools · tested on macOS with Claude Code and Claude Desktop.


Why this exists

Claude's built-in Gmail connector holds one Google account at a time. If you have a personal inbox and a work inbox, you can only connect one of them.

gmail-multi runs locally and holds several accounts, each with a short name such as personal or work. Every tool requires the account name, so Claude always says which inbox it's reading and results from different accounts never get mixed up.

Related MCP server: gmail-mcp

How it works

flowchart LR
    CC["Claude Code"] -- "stdio" --> S
    CD["Claude Desktop"] -- "stdio" --> S
    S["gmail-multi<br/>(node src/index.js)"] --> TP["~/.gmail-mcp/token-personal.json"]
    S --> TW["~/.gmail-mcp/token-work.json"]
    S -- "HTTPS" --> G["Gmail API"]

gmail-multi is an MCP server, which is a program Claude starts on your computer and talks to through stdin/stdout ("stdio"). When Claude calls a tool such as gmail_search with account: "work", the server loads that account's token file from ~/.gmail-mcp and makes the request straight to Google's Gmail API. You create your own Google Cloud app, so the login keys belong to you and not to the author of this project. Your tokens never leave your computer, and nothing is sent to the author. The only network traffic goes to Google. The email content Claude reads becomes part of your Claude conversation, the same as with any other connector.

Requirements

  • macOS or Linux. These instructions use macOS menu names. Linux works the same way.

  • Node.js 18 or newer. Run node --version to check. If it isn't installed, get it from nodejs.org.

  • Claude Code and/or Claude Desktop.

  • One Google account per inbox you want to connect.

  • About 45 minutes the first time. Most of that is the Google Cloud setup, which you only do once.


Setup

Step 1: Clone and install

Open Terminal and run:

git clone https://github.com/DavidOloyede/gmail-multi-mcp.git ~/gmail-mcp-server
cd ~/gmail-mcp-server
npm install

npm install downloads the dependencies into a node_modules folder. If it finishes without errors, you're ready.

You can put the folder anywhere you like. Just run the later commands from inside it.

Step 2: Create your own Google Cloud app

This gives you a private "app" that is allowed to ask Google for read access to your Gmail. You only do it once, and the same app works for all of your accounts.

  1. Create a project. Go to console.cloud.google.com and sign in with any Google account. In the top bar, click the project picker (next to the Google Cloud logo), then New Project. Name it something like gmail-multi and click Create. When it's ready, make sure the project picker shows your new project.

  2. Enable the Gmail API. Open the ☰ menu → APIs & Services → Library. Search for Gmail API, click it, then click Enable.

  3. Branding. Open the ☰ menu → Google Auth Platform → Branding. (If you see a Get started button instead, click it. The wizard asks the same questions.) Enter an App name such as gmail-multi and choose your email as the User support email. Fill in the Developer contact information email and click Save (or Create in the wizard).

  4. Audience. Click Audience in the left sidebar. The user type should be External. Under Publishing status, click Publish app, then Confirm. Why publish? While an app is in Testing mode, Google expires its logins every 7 days, so you'd have to sign in again every week. A published app keeps working. Publishing does not make your app public or listed anywhere. It just means anyone with the link could sign in, and you're the only one with the link.

  5. Data Access. Click Data Access → Add or remove scopes. In the Manually add scopes box at the bottom, paste https://www.googleapis.com/auth/gmail.readonly and click Add to table. Make sure it's checked, click Update, then Save. Add only this scope.

  6. Clients. Click Clients → Create client. For Application type choose Desktop app, give it any name, and click Create. In the dialog that appears, click Download JSON. The file lands in your Downloads folder with a name like client_secret_1234…apps.googleusercontent.com.json. Download it now, because Google may not show the secret again later. If you lose it, create a new client.

Step 3: Store the key file privately

The JSON file you just downloaded is your app's key. Keep it in a private folder outside the project so it can never be committed to git:

mkdir -p ~/.gmail-mcp && chmod 700 ~/.gmail-mcp
mv ~/Downloads/client_secret_*.json ~/.gmail-mcp/credentials.json
chmod 600 ~/.gmail-mcp/credentials.json
ls -la ~/.gmail-mcp

(If mv complains that the target is not a directory, you have more than one client_secret_*.json in Downloads. Delete the old ones and try again.)

ls -la ~/.gmail-mcp should show something like this. drwx------ on the folder and -rw------- on the file mean only you can read them:

drwx------   3 you  staff   96 Oct  6 12:00 .
drwxr-x---+ 40 you  staff 1280 Oct  6 12:00 ..
-rw-------   1 you  staff  403 Oct  6 12:00 credentials.json

Step 4: Connect each inbox

From inside the project folder, run the login script once per account:

node src/auth.js personal

Here's what happens:

  1. The terminal prints a long link that starts with https://accounts.google.com/o/oauth2/v2/auth?.... Open it: hold ⌘ and click it, or copy and paste it into your browser. The script waits while you finish in the browser.

  2. Choose the Google account you want to call personal.

  3. You'll see "Google hasn't verified this app." This is expected. The app is the one you created in Step 2, and Google only verifies apps that go through its public review. Click Advanced, then Go to gmail-multi (unsafe) (it shows whatever app name you chose).

  4. On the next screen, if there's a checkbox next to View your email messages and settings, tick it. Then click Continue.

  5. The browser shows Done, and the terminal prints Saved token to /Users/you/.gmail-mcp/token-personal.json (chmod 600).

Now do the second account. Use a private/incognito window (⌘⇧N in Chrome or Safari) so Google doesn't quietly reuse the account you're already signed into:

node src/auth.js work

Copy the printed link, paste it into the incognito window, sign in with your work Google account, and repeat steps 3–5.

Step 5: Register with Claude

Claude Code and Claude Desktop keep separate lists of servers. Set up either one, or both.

Claude Code. From inside the project folder, run:

claude mcp add --scope user gmail-multi -- node "$(pwd)/src/index.js"

$(pwd) fills in the full path to the folder you're in. --scope user makes the server available in every project, not just this folder.

Claude Desktop:

  1. Open Claude Desktop → Settings → Extensions.

  2. Click Advanced settings.

  3. Under Extension Developer, click Install Unpacked Extension.

  4. Choose this project folder (gmail-mcp-server) and click Open. Claude Desktop reads manifest.json from it.

  5. gmail-multi now appears in your extensions list. Make sure it's enabled.

Step 6: Check it works

In Claude Code, start a session and type:

/mcp

You should see gmail-multi marked connected with 4 tools: gmail_search, gmail_get_message, gmail_list_labels, gmail_create_draft.

Then ask something like:

What's unread in both my personal and work inboxes from the last 7 days?

Claude should call gmail_search twice, once with account: "personal" and once with account: "work", and summarize each inbox separately.


Already using Claude's built-in Gmail connector?

If Claude's built-in Gmail connector is also turned on, Claude may use it instead of gmail-multi, and then it only sees one inbox. To fix this, stop the built-in connector from handling the overlapping tools:

  1. In Claude, go to Settings → Connectors → Gmail.

  2. Under tool permissions, set these four to Block (⊘):

    • Search email threads

    • Get email message

    • List labels

    • Create draft email

Now requests like "search both inboxes" go to gmail-multi.

Tools

Every tool requires account, which must be one of the names defined in ACCOUNTS in src/config.js ("personal" or "work" by default).

Tool

Parameters

What it does

gmail_search

account (string, required)query (string, required): Gmail search syntax, e.g. is:unread newer_than:7dmaxResults (integer 1–50, optional, default 10)

Searches the account and returns each match's id, threadId, subject, from, date and snippet. It does not return full bodies.

gmail_get_message

account (string, required)messageId (string, required): an id from gmail_search

Returns one message's subject, from, to, date and plain-text body. HTML-only emails come back with an empty body.

gmail_list_labels

account (string, required)

Lists the account's labels (INBOX, SENT, your custom labels, and so on).

gmail_create_draft

account (string, required)to (string, required)subject (string, required)body (string, required, plain text)

Creates a draft. It does not send.

gmail_create_draft needs the gmail.compose scope, which the default read-only setup doesn't grant. Until you add it, the tool returns a message explaining how. To enable drafting:

  1. Google Cloud Console → Google Auth Platform → Data Access → Add or remove scopes, add https://www.googleapis.com/auth/gmail.compose, then Update → Save.

  2. In src/config.js, add "https://www.googleapis.com/auth/gmail.compose", to the SCOPES list.

  3. Re-run node src/auth.js personal and node src/auth.js work (incognito for the second). Old logins only ever granted read access, so each account has to approve the new permission.

  4. Restart Claude (see Adding more accounts for how).

Adding more accounts

  1. Open src/config.js and add an entry to ACCOUNTS. The comment above it shows the format:

    side: {
      label: "Side project account",
      tokenPath: path.join(CONFIG_DIR, "token-side.json"),
    },

    The key (side) is the name you and Claude will use. Keep it short and lowercase.

  2. Connect it in an incognito window:

    node src/auth.js side
  3. Restart the server so Claude sees the new name. In Claude Code, start a new session or type /mcp and reconnect gmail-multi. In Claude Desktop, turn the extension off and on in Settings → Extensions, or quit and reopen the app.

Security and privacy

What's stored, and where. Everything lives in ~/.gmail-mcp/ on your computer, outside the project folder:

File

Contents

Permissions

~/.gmail-mcp/

the folder

700 (only you can open it)

credentials.json

your Google Cloud app's client ID and client secret (Step 3)

600 (only you can read it)

token-<account>.json

one per account: a refresh token and a short-lived access token

600, set automatically by auth.js

No secrets in this repo. Every user creates their own Google Cloud app and their own logins, so there's nothing secret to ship. .gitignore also blocks credentials.json, client_secret*.json, token*.json and .env files, in case one ever ends up in the folder by mistake.

Where data goes. The server talks only to Google (OAuth and the Gmail API). It has no analytics or telemetry and nothing is sent to the author. The login script (auth.js) briefly listens on 127.0.0.1:53682, which only your own computer can reach, to receive Google's sign-in redirect, and stops as soon as you've signed in. Messages Claude reads with these tools are sent to Claude as part of your conversation.

Scope. By default it asks for https://www.googleapis.com/auth/gmail.readonly only. That lets it read messages and labels. It cannot send, delete, archive or change settings. It's read-only on purpose: an assistant that can only read can't do anything you didn't expect. Drafting is opt-in (see Tools).

Revoke access. For each Google account you connected, go to myaccount.google.com/permissions, find your app's name, and click Delete all connections (or Remove access).

Delete local data:

rm -rf ~/.gmail-mcp
claude mcp remove gmail-multi --scope user   # if you registered with Claude Code

For Claude Desktop, remove the extension in Settings → Extensions. You can also delete the Google Cloud project at console.cloud.google.com → IAM & Admin → Settings → Shut down.

Troubleshooting

command not found: claude Claude Code isn't installed, or your terminal can't find it. Install Claude Code by following Anthropic's Claude Code setup instructions, then open a new terminal window and try again. If you only use Claude Desktop, skip the claude mcp add step entirely.

The server connects but shows no tools, or fails to connect Run the server by hand from the project folder to see the real error:

node src/index.js

If it's healthy it prints gmail-multi-mcp ready (accounts: personal, work) and then waits. Press Ctrl+C to stop it. If it prints an error instead, the usual causes are a skipped npm install (Cannot find package ...), Node older than 18 (node --version), or a typo in src/config.js. Fix that, then reconnect: /mcp in Claude Code, or turn the extension off and on in Claude Desktop.

No token for "work" yet. Run: node src/auth.js work That account hasn't been connected yet, or its token file was deleted. Run the command it suggests (Step 4).

invalid_grant Google has stopped accepting that account's saved login. Common reasons:

  • You changed that Google account's password.

  • Your Google Cloud app is still in Testing mode, where logins expire after 7 days. Publish it (Step 2, Audience).

  • The token wasn't used for about 6 months.

  • You removed the app's access at myaccount.google.com/permissions.

Fix: re-run node src/auth.js <account> for that account, then restart the server.

Error: listen EADDRINUSE ... 127.0.0.1:53682 (port already in use) Another copy of auth.js is probably still waiting in a different terminal tab. Press Ctrl+C there. To find whatever is holding the port:

lsof -i :53682
kill <PID>        # the number in the PID column

The wrong Gmail account got connected Your browser reused an account you were already signed into. Delete that account's token file and connect again in an incognito window:

rm ~/.gmail-mcp/token-work.json
node src/auth.js work

Can't find /Users/you/.gmail-mcp/credentials.json The key file from Step 2 isn't in place. Redo Step 3.

Roadmap

The interactive walkthrough shows today's from-source install and the planned one-click install paths.

  • v0.1 (now): search, read and list labels across named accounts. Drafting with an extra scope.

  • v0.2: send mail from a chosen account. The account list moves out of code into a config file.

  • v0.3: reply, forward, labels, trash.

  • v1.0: sign in to Google from inside a Claude chat instead of the terminal, and a one-click .mcpb install for Claude Desktop.

License

MIT © 2026 David Oloyede

Related MCP Connectors

  • Email inboxes for AI agents: send, receive, reply, search, and manage threaded email over MCP.

  • Email infrastructure for AI agents — send, receive, search, and reply to email over MCP.

  • Your mailboxes in ChatGPT and Claude: Gmail, iCloud, Fastmail, any IMAP. Passwords stay yours.

  • Your agent needs a mailbox of its own — to receive, thread, draft and send, with attachments, without borrowing your personal inbox or your company's SMTP. **What you can ask for** • "Create an inbox for this agent and tell me its address." • "Read the new messages in this thread and draft a reply." • "Send this message with the attachment and wait for the response." • "Search this inbox for everything from that domain." • "Show delivery metrics and the events on this inbox." **How to use it** Point any MCP client at https://mcp.aisa.one/mail/mcp and sign in with OAuth — there is no key to create or paste. 49 tools: create and delete inboxes, list and read messages, raw message bodies, attachments, threads, drafts and draft attachments, send and reply, message search, inbox events, metrics, and list entries — reads and writes. **Why this rather than the source** A real inbox an agent owns, rather than an SMTP credential it borrows from a human. **It is also a door to the rest** The same login reaches 26 sources and 580+ operations. Find the contact elsewhere in the catalogue, then write to them from here — without adding a second server. **What it costs** Finding and inspecting an operation is free. Running one is billed per call at API prices, with no seat and no monthly minimum, and every call takes max_price_usd so an agent cannot overspend by accident. **Where else it reaches** https://mcp.aisa.one/sales/mcp finds the person to write to.

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    Lets Claude Desktop manage multiple Gmail accounts simultaneously, supporting search, read, send, reply, and label organization via MCP tools.
    64 npm
    19
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    A read-only, multi-account Gmail MCP server for Claude Code that lets Claude search threads, read messages, and list labels across authorized Gmail accounts.
    2,341 npm
    MIT
  • A
    license
    A
    quality
    D
    maintenance
    Connects multiple Gmail accounts to Claude Desktop via MCP, enabling email search, labeling, drafts, and confirmed sending through natural language.
    13
    174 npm
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    A local MCP server that gives Claude access to multiple Gmail accounts simultaneously for search, read, draft, send, label, and a scheduled cross-inbox digest, with enforced send policies per mailbox.
    MIT