This MCP server allows Claude to interact with your Google Calendar, enabling capabilities like listing events, creating meetings, and finding free time slots.
- Node.js (v16 or higher)
- Claude Desktop App
- A Google Cloud Project
- Google Calendar API enabled
- OAuth 2.0 credentials
- Go to the Google Cloud Console
- Create a new project or select an existing one
- Enable the Google Calendar API:
- Go to "APIs & Services" > "Library"
- Search for "Google Calendar API"
- Click "Enable"
- Go to "APIs & Services" > "OAuth consent screen"
- Select "External" user type (unless you have a Google Workspace organization)
- Fill in the required information:
- App name
- User support email
- Developer contact information
- Add the following scopes:
https://www.googleapis.com/auth/calendar
https://www.googleapis.com/auth/calendar.events
- Add your email address as a test user
- Go to "APIs & Services" > "Credentials"
- Click "Create Credentials" > "OAuth client ID"
- Select "Desktop app" as the application type
- Name your client (e.g., "MCP Calendar Client")
- Click "Create"
- Download the client configuration file (you'll need the client ID and client secret)
- Create a new file named
getToken.js
:
const { google } = require('googleapis');
const http = require('http');
const url = require('url');
// Replace these with your OAuth 2.0 credentials
const CLIENT_ID = 'your-client-id';
const CLIENT_SECRET = 'your-client-secret';
const REDIRECT_URI = 'http://localhost:3000/oauth2callback';
// Configure OAuth2 client
const oauth2Client = new google.auth.OAuth2(
CLIENT_ID,
CLIENT_SECRET,
REDIRECT_URI
);
// Define scopes
const scopes = [
'https://www.googleapis.com/auth/calendar',
'https://www.googleapis.com/auth/calendar.events'
];
async function getRefreshToken() {
return new Promise((resolve, reject) => {
try {
// Create server to handle OAuth callback
const server = http.createServer(async (req, res) => {
try {
const queryParams = url.parse(req.url, true).query;
if (queryParams.code) {
// Get tokens from code
const { tokens } = await oauth2Client.getToken(queryParams.code);
console.log('\n=================');
console.log('Refresh Token:', tokens.refresh_token);
console.log('=================\n');
console.log('Save this refresh token in your configuration!');
// Send success response
res.end('Authentication successful! You can close this window.');
// Close server
server.close();
resolve(tokens);
}
} catch (error) {
console.error('Error getting tokens:', error);
res.end('Authentication failed! Please check console for errors.');
reject(error);
}
}).listen(3000, () => {
// Generate auth url
const authUrl = oauth2Client.generateAuthUrl({
access_type: 'offline',
scope: scopes,
prompt: 'consent' // Force consent screen to ensure refresh token
});
console.log('1. Copy this URL and paste it in your browser:');
console.log('\n', authUrl, '\n');
console.log('2. Follow the Google authentication process');
console.log('3. Wait for the refresh token to appear here');
});
} catch (error) {
console.error('Server creation error:', error);
reject(error);
}
});
}
// Run the token retrieval
getRefreshToken().catch(console.error);
- Install required dependency:
npm install googleapis
-
Update the script with your OAuth credentials:
- Replace
your-client-id
with your actual client ID - Replace
your-client-secret
with your actual client secret
- Replace
-
Run the script:
node getToken.js
- Follow the instructions in the console:
- Copy the provided URL
- Paste it into your browser
- Complete the Google authentication process
- Copy the refresh token that appears in the console
- Open your Claude Desktop configuration file:
For MacOS:
code ~/Library/Application\ Support/Claude/claude_desktop_config.json
For Windows:
code %AppData%\Claude\claude_desktop_config.json
- Add or update the configuration:
{
"mcpServers": {
"google-calendar": {
"command": "node",
"args": [
"/ABSOLUTE/PATH/TO/YOUR/build/index.js"
],
"env": {
"GOOGLE_CLIENT_ID": "your_client_id_here",
"GOOGLE_CLIENT_SECRET": "your_client_secret_here",
"GOOGLE_REDIRECT_URI": "http://localhost",
"GOOGLE_REFRESH_TOKEN": "your_refresh_token_here"
}
}
}
}
- Save the file and restart Claude Desktop
- Create a new directory for your project:
mkdir google-calendar-mcp
cd google-calendar-mcp
- Initialize a new npm project:
npm init -y
- Install dependencies:
npm install @modelcontextprotocol/sdk googleapis google-auth-library zod
npm install -D @types/node typescript
- Create a tsconfig.json file:
{
"compilerOptions": {
"target": "ES2022",
"module": "Node16",
"moduleResolution": "Node16",
"outDir": "./build",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
},
"include": ["src/**/*"],
"exclude": ["node_modules"]
}
- Update package.json:
{
"type": "module",
"scripts": {
"build": "tsc && node -e \"require('fs').chmodSync('build/index.js', '755')\""
}
}
- Create your source directory:
mkdir src
- Create a .env file for local development (don't commit this file):
GOOGLE_CLIENT_ID=your_client_id_here
GOOGLE_CLIENT_SECRET=your_client_secret_here
GOOGLE_REDIRECT_URI=http://localhost
GOOGLE_REFRESH_TOKEN=your_refresh_token_here
- Build the server:
npm run build
- The server will automatically start when you open Claude Desktop
The server provides the following tools:
list_events
: List calendar events within a specified time rangecreate_event
: Create a new calendar eventupdate_event
: Update an existing calendar eventdelete_event
: Delete a calendar eventfind_free_time
: Find available time slots in the calendar
After setup, you can use commands like:
- "Show me my calendar events for next week"
- "Schedule a meeting with [email_id] tomorrow at 2 PM for 1 hour"
- "Find a free 30-minute slot this afternoon"
- "Update my 3 PM meeting to 4 PM"
- "Cancel my meeting with ID [event_id]"
-
Tools not appearing in Claude:
- Check Claude Desktop logs:
tail -f ~/Library/Logs/Claude/mcp*.log
- Verify all environment variables are set correctly
- Ensure the path to index.js is absolute and correct
- Check Claude Desktop logs:
-
Authentication Errors:
- Verify your OAuth credentials are correct
- Check if refresh token is valid
- Ensure required scopes are enabled
-
Server Connection Issues:
- Check if the server built successfully
- Verify file permissions on build/index.js (should be 755)
- Try running the server directly:
node /path/to/build/index.js
To view server logs:
# For MacOS/Linux:
tail -n 20 -f ~/Library/Logs/Claude/mcp*.log
# For Windows:
Get-Content -Path "$env:AppData\Claude\Logs\mcp*.log" -Wait -Tail 20
If you're getting environment variable errors, verify each one:
- GOOGLE_CLIENT_ID: Should start with something like "123456789-..."
- GOOGLE_CLIENT_SECRET: Usually ends in ".apps.googleusercontent.com"
- GOOGLE_REDIRECT_URI: Should be "http://localhost"
- GOOGLE_REFRESH_TOKEN: A long string that doesn't expire
- Keep your OAuth credentials secure
- Don't commit credentials to version control
- Use environment variables for sensitive data
- Regularly rotate refresh tokens
- Monitor API usage in Google Cloud Console
MIT License - See LICENSE file for details.
If you encounter any issues:
- Check the troubleshooting section above
- Review Claude Desktop logs
- Open an issue on GitHub
- Contact the maintainer