๐ฏ What You’re Going to Build Link to heading
Imagine being able to ask your computer:
“Find all unread emails from this week about invoices” “Summarize yesterday’s important emails for me” “List suspicious emails received this month”
That’s exactly what you’ll build in this tutorial! We’re going to create a personal assistant that can analyze your Gmail emails using Claude Code, all in read-only mode for maximum security.
Why this tutorial? Link to heading
- โ Simple: 30-minute setup
- โ Secure: Read-only access only
- โ Free: Uses free Gmail API
- โ Powerful: Artificial intelligence to analyze your emails
- โ Revocable: You can cut access with 1 click
What you need Link to heading
- A Gmail account
- A Linux computer (Ubuntu, Debian, Fedora, etc.)
- 30 minutes of your time
- No programming skills required!
๐ Overview: How Does It Work? Link to heading
Your Gmail Emails
โ
[Gmail API - Read Only]
โ
[MCP Server]
โ
[Claude Code]
โ
Intelligent Analysis!
The idea: Claude can “read” your emails (but not modify them) and help you analyze them with artificial intelligence.
Important: We start with zero risk - Claude can ONLY read. No deletion, no sending, no modification.
๐ Part 1: Setting Up Google Cloud (15 minutes) Link to heading
Step 1.1: Create Your Project Link to heading
This is like creating a “folder” for your project in Google Cloud.
- Go to: console.cloud.google.com
- Log in with your Gmail account
- Click on the project dropdown menu (at the top)
- Click on “New project”
Fill in:
- Name:
My Email Assistant(or whatever you want) - Click “Create”
โฑ๏ธ Wait 20 seconds… and there you go, your project is created!
Step 1.2: Enable the Gmail API Link to heading
Now we “turn on” the Gmail API to be able to read your emails.
- In the menu โฐ โ Click “APIs & Services” โ “Library”
- Search for:
Gmail API - Click on it
- Click on the big blue “ENABLE” button
โ Done! You’ll see “API enabled”
Step 1.3: Configure Permissions (Important!) Link to heading
Here we tell Google: “I only want to READ my emails, nothing else”.
Navigation: Menu โฐ โ APIs & Services โ OAuth consent screen
Choose:
- Type: External โ
- Click “Create”
Page 1 - Basic info:
Simply fill in:
- Application name:
My Email Assistant - Support email: your.email@gmail.com
- Developer email: your.email@gmail.com
The rest? Leave it blank!
Click “Save and continue”
Page 2 - Permissions (THE important part!):
- Click “Add or remove scopes”
- A window opens
- Search for:
gmail.readonly - Check ONLY this box:
โ https://www.googleapis.com/auth/gmail.readonly
๐ด SUPER IMPORTANT: Only check that one! This is your guarantee that Claude can only READ.
- Click “Update”
- Click “Save and continue”
Page 3 - Add yourself as a tester:
- Click “+ Add users”
- Enter your Gmail address
- Click “Add”
- Click “Save and continue”
Page 4 - Summary:
Check that everything is correct, then “Back to dashboard”
Step 1.4: Download Your “Key” Link to heading
Now we get a file that allows your computer to connect.
- Menu โฐ โ APIs & Services โ Credentials
- Click the big “+ CREATE CREDENTIALS” button
- Choose “OAuth 2.0 Client ID”
Configure:
- Application type: Desktop app
- Name:
Local Email Assistant - Click “Create”
A window appears:
- Click “DOWNLOAD JSON”
- The file downloads (named something like
client_secret_xxx.json) - Click “OK”
๐ Congratulations! Google Cloud part finished. The hardest part is done!
๐ป Part 2: Installation on Your Computer (10 minutes) Link to heading
Step 2.1: Check Prerequisites Link to heading
Open a terminal and type:
# Check Node.js (should display v18 or higher)
node --version
# Check pnpm
pnpm --version
# Check Claude Code
claude --version
Not installed? Don’t panic:
# Install Node.js via nvm (recommended)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
source ~/.bashrc
nvm install --lts
# Install pnpm
curl -fsSL https://get.pnpm.io/install.sh | sh -
source ~/.bashrc
# Install Claude Code
npm install -g @anthropic-ai/claude-code
Step 2.2: Create the Folders Link to heading
We create a “home” for our project:
# Create folders
mkdir -p ~/my-email-assistant
mkdir -p ~/.config/gmail-assistant/creds
# Secure (no one else can see)
chmod 700 ~/.config/gmail-assistant
Step 2.3: Move the Downloaded File Link to heading
Remember the client_secret_xxx.json file? Let’s put it away:
# Move it (adjust the path if needed)
mv ~/Downloads/client_secret_*.json \
~/.config/gmail-assistant/creds/credentials.json
# Protect it (read-only for you)
chmod 600 ~/.config/gmail-assistant/creds/credentials.json
# Verify
ls -la ~/.config/gmail-assistant/creds/
# You should see: -rw------- credentials.json
Step 2.4: Create the Server Code Link to heading
We’re going to create a small program that bridges Claude and Gmail.
cd ~/my-email-assistant
# Create the configuration file
cat > package.json << 'EOF'
{
"name": "email-assistant",
"version": "1.0.0",
"type": "module",
"dependencies": {
"googleapis": "^140.0.0",
"@modelcontextprotocol/sdk": "^0.5.0"
}
}
EOF
# Install dependencies
pnpm install
Create the server (copy-paste this entire block):
cat > server.js << 'EOFSRV'
#!/usr/bin/env node
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { google } from 'googleapis';
import { readFile, writeFile } from 'fs/promises';
import { join } from 'path';
import { homedir } from 'os';
// READ ONLY - This is our security guarantee!
const SCOPES = ['https://www.googleapis.com/auth/gmail.readonly'];
const TOKEN_PATH = join(homedir(), '.config/gmail-assistant/creds/token.json');
const CREDENTIALS_PATH = join(homedir(), '.config/gmail-assistant/creds/credentials.json');
class EmailAssistant {
constructor() {
this.server = new Server(
{ name: 'email-assistant', version: '1.0.0' },
{ capabilities: { tools: {} } }
);
this.setupTools();
this.gmail = null;
}
async authorize() {
const credentials = JSON.parse(await readFile(CREDENTIALS_PATH));
const { client_secret, client_id, redirect_uris } = credentials.installed;
const oAuth2Client = new google.auth.OAuth2(client_id, client_secret, redirect_uris[0]);
try {
const token = await readFile(TOKEN_PATH);
oAuth2Client.setCredentials(JSON.parse(token));
} catch (err) {
return await this.getNewToken(oAuth2Client);
}
return oAuth2Client;
}
async getNewToken(oAuth2Client) {
const authUrl = oAuth2Client.generateAuthUrl({
access_type: 'offline',
scope: SCOPES,
});
console.error('\n๐ First connection - Authorization required\n');
console.error('1. Open this URL in your browser:');
console.error(` ${authUrl}\n`);
console.error('2. Log in and authorize');
console.error('3. Copy the code you receive\n');
console.error('Enter the code here: ');
const readline = await import('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stderr,
});
return new Promise((resolve, reject) => {
rl.question('', async (code) => {
rl.close();
try {
const { tokens } = await oAuth2Client.getToken(code);
oAuth2Client.setCredentials(tokens);
await writeFile(TOKEN_PATH, JSON.stringify(tokens));
console.error('\nโ
Perfect! You are connected.\n');
resolve(oAuth2Client);
} catch (err) {
console.error('\nโ Oops, error:', err.message);
reject(err);
}
});
});
}
setupTools() {
this.server.setRequestHandler('tools/list', async () => ({
tools: [
{
name: 'list_emails',
description: 'List your Gmail emails',
inputSchema: {
type: 'object',
properties: {
count: { type: 'number', description: 'Number of emails (max 100)', default: 10 },
query: { type: 'string', description: 'Gmail search query (e.g., "is:unread")' },
},
},
},
{
name: 'search_emails',
description: 'Search for specific emails',
inputSchema: {
type: 'object',
properties: {
query: { type: 'string', description: 'Your search query' },
count: { type: 'number', default: 10 },
},
required: ['query'],
},
},
],
}));
this.server.setRequestHandler('tools/call', async (request) => {
if (!this.gmail) {
const auth = await this.authorize();
this.gmail = google.gmail({ version: 'v1', auth });
}
const args = request.params.arguments;
const maxResults = Math.min(args.count || args.maxResults || 10, 100);
const query = args.query || '';
const res = await this.gmail.users.messages.list({
userId: 'me',
maxResults,
q: query,
});
const messages = res.data.messages || [];
const details = await Promise.all(
messages.map(async (msg) => {
const detail = await this.gmail.users.messages.get({
userId: 'me',
id: msg.id,
format: 'metadata',
metadataHeaders: ['From', 'Subject', 'Date'],
});
const headers = detail.data.payload.headers;
return {
id: msg.id,
from: headers.find((h) => h.name === 'From')?.value,
subject: headers.find((h) => h.name === 'Subject')?.value,
date: headers.find((h) => h.name === 'Date')?.value,
};
})
);
return {
content: [{ type: 'text', text: JSON.stringify(details, null, 2) }],
};
});
}
async run() {
const transport = new StdioServerTransport();
await this.server.connect(transport);
console.error('๐ Email Assistant ready (read-only)\n');
}
}
const assistant = new EmailAssistant();
assistant.run().catch(console.error);
EOFSRV
# Make executable
chmod +x server.js
๐ Part 3: Connect to Claude (5 minutes) Link to heading
Step 3.1: Just One Command! Link to heading
This is the simplest part. Just one command line:
claude mcp add gmail /usr/bin/node ~/my-email-assistant/server.js
Check that it worked:
claude mcp list
# You should see:
# gmail: /usr/bin/node /home/[you]/my-email-assistant/server.js
Step 3.2: First Connection Link to heading
Launch Claude:
claude
What will happen:
- A message displays with a long URL
- You copy this URL
- You open it in your browser
- You log in to Gmail
- Google tells you: “Warning, unverified application”
- Click “Advanced settings”
- Click “Go to [your app] (unsafe)”
- Google shows: “View your email” โ (this is READ ONLY)
- Click “Allow”
- Google gives you a code
- You copy it
- You paste it in the Claude terminal
- Press Enter
Success message:
โ
Perfect! You are connected.
๐ Email Assistant ready (read-only)
๐ฎ Part 4: Using Your Assistant (The Fun Part!) Link to heading
First Test: Simple List Link to heading
In Claude, simply type:
List my last 5 emails
Result: Claude shows you your last 5 emails with sender and subject!
Practical Examples Link to heading
๐ง Find an Email Link to heading
Find Marie's email from last week
๐ Daily Summary Link to heading
Summarize today's important emails for me
๐ Advanced Search Link to heading
Search all unread emails containing "invoice"
๐ Organization Link to heading
List this week's emails, grouped by sender
๐จ Simple Detection Link to heading
Are there any suspicious emails received today?
More Advanced Prompts Link to heading
Once comfortable, try:
Analyze my last 20 emails and tell me:
1. Which ones require an urgent response
2. Which ones are newsletters
3. Which ones contain attachments
Make a small summary for each category.
Or:
Among my emails from this week:
- Find those that mention meetings
- Extract the dates and times mentioned
- Make me a schedule
Format: clear and simple list
๐ก๏ธ Security: What You Need to Know Link to heading
โ What Claude CAN Do Link to heading
- Read your emails
- Search in your inbox
- Analyze content
- Make summaries for you
โ What Claude CANNOT Do Link to heading
- Send emails โ
- Delete emails โ
- Modify emails โ
- Forward emails โ
- Create drafts โ
Why? Because we configured gmail.readonly - read-only!
๐ Revoke Access (If Needed) Link to heading
Want to cut access? 2 clicks:
- Go to: myaccount.google.com/permissions
- Find “My Email Assistant”
- Click “Remove access”
โก Immediate effect - Claude can no longer read your emails.
๐ See What’s Happening Link to heading
Google shows you everything:
- When Claude accesses your emails
- How many times
- What type of access (always “read”)
Check it out at: console.cloud.google.com โ APIs & Services โ Dashboard
๐ Practical Use Cases Link to heading
1. Daily Productivity Link to heading
In the morning:
Summarize important emails received overnight
End of day:
Which emails are still waiting for a response?
2. Organization Link to heading
Find all emails from my boss this month and
summarize the action items requested
3. Historical Search Link to heading
In 2024, how many emails did I receive from [company]?
What was the main topic?
4. Cleanup Link to heading
List all newsletters I receive regularly.
Show me the ones I never open.
5. Simple Analysis Link to heading
Among my last 50 emails, which ones look weird or suspicious?
Explain why for each one.
๐ง Troubleshooting Link to heading
Problem: Claude doesn’t see Gmail Link to heading
Solution:
# Check the config
claude mcp list
# If empty, redo:
claude mcp add gmail /usr/bin/node ~/my-email-assistant/server.js
Problem: “Token expired” Link to heading
Solution:
# Delete the token
rm ~/.config/gmail-assistant/creds/token.json
# Restart Claude
claude
# The authorization process starts again
Problem: “Permission denied” Link to heading
Solution:
# Check permissions
chmod 600 ~/.config/gmail-assistant/creds/credentials.json
chmod +x ~/my-email-assistant/server.js
๐ก Tips and Tricks Link to heading
Make Claude More Effective Link to heading
Be specific:
- โ “Find my emails”
- โ “Find this week’s emails with ‘project’ in the subject”
Ask for formats:
List my emails in table format with:
- Date
- Sender
- Short subject
Iterate:
First request: "List my emails from today"
Refinement: "Now, show only those from client X"
Create Routines Link to heading
Morning routine:
Give me my email briefing for the day:
1. Total number of new emails
2. Top 3 most important ones
3. Those that require a quick response
4. Newsletters to read later
Format: concise and actionable
Friday routine:
Week summary:
- What topics came up often?
- Who emailed me the most?
- Are there any unanswered emails?
โ Final Checklist Link to heading
You succeeded if:
- Project created on Google Cloud
- Gmail API enabled
- OAuth configured (read-only only)
- Credentials downloaded and secured
- MCP server installed
- Claude connected (
claude mcp listworks) - First test successful (email list)
- You know how to revoke access if needed
๐ Congratulations! Link to heading
You’ve created your own email analysis assistant with AI!
You now know how to:
- โ Configure the Gmail API in read-only mode
- โ Connect Claude Code to your emails
- โ Analyze your emails with artificial intelligence
- โ Control access and security
Next steps:
- Experiment with different prompts
- Create your own routines
- Share your discoveries
Need help?
- Claude Documentation: docs.claude.com
- Gmail API: developers.google.com/gmail
- Community: Reddit r/ClaudeAI
Author: Xavier GUERET & claude Date: January 18, 2025 License: MIT
Tags: #tutorial #claude-code #gmail #ai #automation #beginner
This tutorial shows you how to access your own Gmail data securely. Always respect others’ privacy and the terms of service of the services.