HR-Assistant / docs /mcp /gmail_mcp_gcp_setup.md
owenkaplinsky
Clean initial commit for HuggingFace
363cda9
|
raw
history blame
10.4 kB
# ***`Gmail MCP – GCP Setup (Terraform + Bash)`***
This folder provisions the minimum GCP infrastructure to run the [Gmail MCP server](https://github.com/theposch/gmail-mcp/tree/main) without requiring billing:
- Creates (or adopts) a ***GCP project***
- Enables ***gmail.googleapis.com***
- Grants your user:
- `roles/editor`
- `roles/serviceusage.serviceUsageAdmin`
Prints console links to finish OAuth (consent screen + Desktop client)
> Billing is **not required** for Gmail API or OAuth Desktop client.
## ***Prerequisites***
- **Terraform** β‰₯ 1.6
- **gcloud** (optional but useful for verifying/importing projects)
- A Google account (you'll also add it as a **Test user** on the OAuth consent screen)
## Files
- `versions.tf` – provider & Terraform version pins
- `providers.tf` – Google provider config (uses project_id and region)
- `variables.tf` – input variables
- `main.tf` – project, Gmail API enablement, IAM bindings
- `outputs.tf` – project IDs and console URLs
- `terraform.tfvars` – team defaults (simple `key = "value"` pairs)
Example `terraform.tfvars`:
```python
project_id = "gradio-hackathon-25"
project_name = "Gradio Agent MCP Hackathon 25"
user_email = "hr.cjordan.agent.hack.winter25@gmail.com"
# region = "europe-west3" # optional
```
## ***Quick Start (recommended: use the scripts)**
From the ***repo root***:
1. **Authenticate gcloud + ADC**
```bash
chmod +x scripts/gcp_setup.sh
./scripts/gcp_setup.sh
```
2. **Apply Terraform with smart defaults + auto-import**
```bash
chmod +x scripts/terraform_apply.sh
./scripts/terraform_apply.sh
```
- The script **prompts** for `project_id`, `project_name`, `user_email`.
- Press ***Enter*** to use defaults from `terraform/terraform.tfvars`.
- If the project already exists, it is **auto-imported** to avoid `409 alreadyExists`.
---
## ***Manual Usage (alternative)***
Run these from this `terraform/` directory:
```bash
terraform init
# If the project already exists, import it so Terraform manages it:
# terraform import google_project.project <your-project-id>
terraform apply
```
Override values:
```bash
terraform apply \
-var="project_id=my-mcp-project" \
-var="project_name=My MCP Project" \
-var="user_email=you@example.com"
```
Or via env vars:
```bash
export TF_VAR_project_id="my-mcp-project"
export TF_VAR_project_name="My MCP Project"
export TF_VAR_user_email="you@example.com"
terraform apply
```
## **Outputs**
- `project_id` / `project_number`
- `gmail_api_service` β€” `"gmail.googleapis.com"` (resource present β‡’ enabled)
- `console_oauth_consent_screen_url` β€” configure consent (External, Test user, add scope)
- `console_oauth_credentials_url` β€” create ***OAuth 2.0 Client ID*** (Desktop app)
## **Final OAuth Setup (one-time, in Console)**
Terraform cannot create the **OAuth consent screen** or **Desktop OAuth client**, so you'll do these two steps once in the Google Cloud Console.
This setup allows your **local Gmail MCP server** to access Gmail via OAuth securely.
> πŸ’‘ **Tip:** In the new Google Cloud UI, the old β€œScopes” and β€œTest users” tabs are now under **Data access** and **Audience** in the left sidebar.
---
### 1️⃣ **Configure the OAuth Consent Screen**
**Purpose:** Identify your app to Google and specify who can use it during testing.
1. Open the link printed in Terraform outputs:
β†’ `console_oauth_consent_screen_url`
2. If prompted, choose **User type: External**, then click **Create**.
3. Fill out **App info**:
- **App name:** `Gmail MCP Local`
- **User support email:** your Gmail address
- **Developer contact email:** your Gmail address
- Click **Save and Continue**
4. In the left sidebar, go to **Data access**
- Click **Add or remove scopes**
- Add the following scopes:
```text
https://www.googleapis.com/auth/gmail.modify
openid
https://www.googleapis.com/auth/userinfo.email
```
βœ… *These provide read, send, and modify access β€” no extra Gmail scopes required.*
5. Go to **Audience** (left sidebar)
- Under **Test users**, click **Add users**
- Add your Gmail account address
- Click **Save**
6. Go to **Summary** and confirm:
- User type β†’ **External**
- Publishing status β†’ **Testing**
- Test users β†’ your Gmail account
- Scopes β†’ shows Gmail modify, openid, userinfo.email
---
### 2️⃣ **Create a Desktop OAuth Client**
**Purpose:** This provides the credentials your **local MCP server** uses to initiate the OAuth flow.
1. Open the second Terraform output link:
β†’ `console_oauth_credentials_url`
2. Click **Create credentials β†’ OAuth client ID**
3. Choose:
- **Application type:** `Desktop app`
- **Name:** `gmail-mcp-desktop`
4. Click **Create**, then **Download JSON**, and move it into the expected directory:
```bash
mkdir -p ~/.gmail-mcp
mv ~/Downloads/client_secret_*.json ~/.gmail-mcp/credentials.json
```
### ⚠️ ***Important: Two Different JSONs***
- The file from:
```bash
gcloud auth application-default login
```
is your ***Application Default Credentials (ADC)*** β€” used by Terraform and `gcloud`.
It is ***not*** the same as the Desktop OAuth client JSON.
The Gmail MCP server requires the ***Desktop OAuth client JSON*** you downloaded.
β†’ Place it at `~/.gmail-mcp/credentials.json`.
### πŸš€ ***When You Run the MCP Server***
The server will open a browser window asking you to sign in and approve access.
You'll see your app name (`Gmail MCP Local`) and the Gmail modify scope.
After approving, tokens are cached locally (usually `~/.gmail-mcp/token.json`), so you won't need to approve again.
---
### βš™οΈ **Install Required Tools**
Before testing or running the Gmail MCP server, make sure the following tools are installed:
#### 🟣 1. Install `uv`
`uv` is a fast Python package manager used to run the Gmail MCP server.
Check if it's already installed:
```bash
uv --version
```
If not, install it:
```bash
curl -LsSf https://astral.sh/uv/install.sh | sh
```
Verify:
```
uv --version
```
#### 🟠 2. Install Node.js (includes `npm` and `npx`)
npx is used to run the MCP Inspector, which lets you test your Gmail MCP server locally.
```bash
brew install node
```
### πŸ§ͺ ***Testing Locally with MCP Inspector***
Once toBefore connecting to Claude Desktop or a LangGraph agent, you can visually inspect and test your Gmail MCP server using the ***MCP Inspector*** web UI.
#### 1️⃣ **Run with simple path (direct server entry)**
Use this if you're already inside the ``gmail-mcp directory or the script path resolves cleanly:
```bash
npx @modelcontextprotocol/inspector uv run /Users/sebastianwefers/Desktop/development/recruitment-agent-mcp-hackathon-winter25/src/mcp_servers/gmail-mcp/src/gmail/server.py \
--creds-file-path ~/.gmail-mcp/credentials.json \
--token-path ~/.gmail-mcp/token.json
```
#### 2️⃣ **Run with full project context (recommended)**
This variant is more robust and works regardless of your working directory, because it explicitly tells `uv` which project directory to use and where your binaries are.
```bash
npx @modelcontextprotocol/inspector \
/Users/sebastianwefers/.local/bin/uv \
--directory /Users/sebastianwefers/Desktop/development/recruitment-agent-mcp-hackathon-winter25/src/mcp_servers/gmail-mcp \
run gmail \
--creds-file-path ~/.gmail-mcp/credentials.json \
--token-path ~/.gmail-mcp/token.json
```
#### πŸ” What Happens
When you run either command, you should see output similar to:
```bash
Starting MCP inspector...
βš™οΈ Proxy server listening on localhost:6277
πŸ”‘ Session token: 8498939effc01e03c1b879efa72768e45608056ef1ad45e5c80344a7d9362a72
Use this token to authenticate requests or set DANGEROUSLY_OMIT_AUTH=true to disable auth
πŸš€ MCP Inspector is up and running at:
http://localhost:6274/?MCP_PROXY_AUTH_TOKEN=8498939effc01e03c1b879efa72768e45608056ef1ad45e5c80344a7d9362a72
🌐 Opening browser...
```
This automatically opens a local browser window to the MCP Inspector UI, connected to your Gmail MCP server.
βœ… Expected behavior:
- On first run, a browser window will prompt you to log in and approve access.
- After successful OAuth, a token file will be created:
```bash
~/.gmail-mcp/token.json
```
- Subsequent runs reuse this token β€” no re-auth required.
- You can now explore, invoke, and inspect your Gmail MCP tools visually (e.g., `listEmails`, `sendEmail`, `modifyLabel`, etc.) right from the web UI.
### πŸ’» ***Connecting the Gmail MCP Server to Claude Desktop***
1. Open your Claude Desktop configuration file:
```bash
nano ~/Library/Application Support/Claude/claude_desktop_config.json
```
2. Add this block (update paths if necessary):
```json
{
"mcpServers": {
"gmail": {
"command": "uv",
"args": [
"--directory",
"/Users/sebastianwefers/Desktop/development/recruitment-agent-mcp-hackathon-winter25/src/mcp_servers/gmail-mcp",
"run",
"gmail",
"--creds-file-path",
"/Users/sebastianwefers/.gmail-mcp/credentials.json",
"--token-path",
"/Users/sebastianwefers/.gmail-mcp/token.json"
]
}
}
}
```
3. Save the file and restart Claude Desktop.
4. Open ***Settings β†’ Model Context Protocol β†’ Add Server***, then connect to gmail.
Claude will now be able to:
- πŸ“₯ Read emails
- βœ‰οΈ Compose drafts
- 🏷 Send and modify Gmail messages directly from your account.
β€” all directly via your Gmail MCP server.
## 🧩 Why Deleting token.json Fixes the β€œinvalid_grant” Error
The error occurs because the stored refresh token in token.json is expired or revoked, so Google rejects all refresh attempts.
Deleting the file forces the app to start a new OAuth flow, prompting you to log in again and generating a new, valid refresh token β€” which restores access to the Gmail API.
```bash
# 1. Remove the invalid cached token
rm /Users/sebastianwefers/Desktop/projects/recruitment-agent-mcp-hackathon-winter25/secrets/gmail-mcp/token.json
# 2. Re-run the Gmail MCP server (which triggers OAuth again)
python -m src.mcp_servers.gmail_mcp
```
Then, when the script printed a Google sign-in URL, you:
1. Opened it in your browser,
2. Logged in to your Google account,
3. Approved the Gmail API access,
4. And the new valid token.json was automatically recreated at:
```bash
~/.gmail-mcp/token.json
```