google-tools-mcp 1.1.3 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -22,7 +22,28 @@ claude mcp add -s user google -- npx -y google-tools-mcp
22
22
 
23
23
  You can be up and running in under 5 minutes.
24
24
 
25
- ### Step 1: Create Google OAuth Credentials
25
+ ### Guided Setup (recommended)
26
+
27
+ Run the setup wizard — it opens the right Google Cloud Console pages for you and saves your credentials automatically:
28
+
29
+ ```bash
30
+ npx -y google-tools-mcp setup
31
+ ```
32
+
33
+ The wizard walks you through:
34
+ 1. Enabling all required Google APIs (opens in your browser)
35
+ 2. Configuring the OAuth consent screen
36
+ 3. Creating OAuth credentials
37
+ 4. Authenticating with Google
38
+
39
+ After setup, just add it to your MCP client (see [Step 3](#step-3-add-to-your-mcp-client) below).
40
+
41
+ ### Manual Setup
42
+
43
+ <details>
44
+ <summary>Click to expand manual setup instructions</summary>
45
+
46
+ #### Step 1: Create Google OAuth Credentials
26
47
 
27
48
  1. Go to the [Google Cloud Console](https://console.cloud.google.com/)
28
49
  2. Create a project (or use an existing one)
@@ -32,7 +53,7 @@ You can be up and running in under 5 minutes.
32
53
  6. Select **Desktop application** as the application type
33
54
  7. Download the credentials or note your **Client ID** and **Client Secret**
34
55
 
35
- ### Step 2: Provide Your Credentials
56
+ #### Step 2: Provide Your Credentials
36
57
 
37
58
  Choose **one** of the following methods (whichever you prefer):
38
59
 
@@ -84,6 +105,8 @@ Add the credentials directly to your MCP configuration:
84
105
 
85
106
  > **Credential lookup order:** env vars → `~/.config/google-tools-mcp/.env` → project root `.env` → `~/.config/google-tools-mcp/credentials.json` → project root `credentials.json`
86
107
 
108
+ </details>
109
+
87
110
  ### Step 3: Add to Your MCP Client
88
111
 
89
112
  #### Claude Code (recommended)
package/dist/auth.js CHANGED
@@ -166,6 +166,23 @@ async function loadSavedCredentialsIfExist() {
166
166
  const tokenPath = getTokenPath();
167
167
  const content = await fs.readFile(tokenPath, 'utf8');
168
168
  const credentials = JSON.parse(content);
169
+
170
+ // Check that the saved token covers all current SCOPES.
171
+ // Tokens without a scopes field (pre-upgrade) or with missing scopes
172
+ // are stale — delete and force re-auth via browser automatically.
173
+ if (!Array.isArray(credentials.scopes)) {
174
+ logger.info('Saved token has no scopes record (pre-upgrade token). Re-authentication required for new scopes.');
175
+ try { await fs.unlink(tokenPath); } catch {}
176
+ return null;
177
+ }
178
+ const saved = new Set(credentials.scopes);
179
+ const missing = SCOPES.filter(s => !saved.has(s));
180
+ if (missing.length > 0) {
181
+ logger.info(`Saved token is missing scope(s): ${missing.join(', ')}. Re-authentication required.`);
182
+ try { await fs.unlink(tokenPath); } catch {}
183
+ return null;
184
+ }
185
+
169
186
  const { client_secret, client_id } = await loadClientSecrets();
170
187
  const client = new google.auth.OAuth2(client_id, client_secret);
171
188
  client.setCredentials(credentials);
@@ -185,6 +202,7 @@ async function saveCredentials(client) {
185
202
  client_id,
186
203
  client_secret,
187
204
  refresh_token: client.credentials.refresh_token,
205
+ scopes: SCOPES,
188
206
  }, null, 2);
189
207
  await fs.writeFile(tokenPath, payload);
190
208
  logger.info('Token stored to', tokenPath);
package/dist/index.js CHANGED
@@ -7,10 +7,23 @@
7
7
  // Usage:
8
8
  // google-tools-mcp Start the MCP server (default)
9
9
  // google-tools-mcp auth Run the interactive OAuth flow
10
+ // google-tools-mcp setup Guided setup: enable APIs, create credentials, authenticate
10
11
  import { FastMCP } from 'fastmcp';
11
12
  import { registerAllTools } from './tools/index.js';
12
13
  import { logger } from './logger.js';
13
14
 
15
+ // --- Setup subcommand ---
16
+ if (process.argv[2] === 'setup') {
17
+ const { runSetup } = await import('./setup.js');
18
+ try {
19
+ await runSetup();
20
+ process.exit(0);
21
+ } catch (error) {
22
+ console.error('\nSetup failed:', error.message || error);
23
+ process.exit(1);
24
+ }
25
+ }
26
+
14
27
  // --- Auth subcommand ---
15
28
  if (process.argv[2] === 'auth') {
16
29
  const { runAuthFlow } = await import('./auth.js');
package/dist/setup.js ADDED
@@ -0,0 +1,132 @@
1
+ // Guided setup wizard for google-tools-mcp.
2
+ // Opens the right Google Cloud Console URLs and saves credentials.
3
+ import * as readline from 'readline';
4
+ import * as fs from 'fs/promises';
5
+ import * as path from 'path';
6
+ import * as os from 'os';
7
+ import { exec } from 'child_process';
8
+
9
+ // ---------------------------------------------------------------------------
10
+ // Config
11
+ // ---------------------------------------------------------------------------
12
+ const APIS = [
13
+ 'docs.googleapis.com',
14
+ 'sheets.googleapis.com',
15
+ 'drive.googleapis.com',
16
+ 'gmail.googleapis.com',
17
+ 'calendar-json.googleapis.com',
18
+ 'forms.googleapis.com',
19
+ 'slides.googleapis.com',
20
+ ];
21
+
22
+ const ENABLE_APIS_URL =
23
+ `https://console.cloud.google.com/flows/enableapi?apiid=${APIS.join(',')}`;
24
+
25
+ const CREATE_CREDENTIALS_URL =
26
+ 'https://console.cloud.google.com/apis/credentials/oauthclient';
27
+
28
+ const CONSENT_SCREEN_URL =
29
+ 'https://console.cloud.google.com/apis/credentials/consent';
30
+
31
+ // ---------------------------------------------------------------------------
32
+ // Helpers
33
+ // ---------------------------------------------------------------------------
34
+ function openBrowser(url) {
35
+ const platform = process.platform;
36
+ let cmd;
37
+ if (platform === 'win32') {
38
+ cmd = `start "" "${url}"`;
39
+ } else if (platform === 'darwin') {
40
+ cmd = `open "${url}"`;
41
+ } else {
42
+ cmd = `xdg-open "${url}"`;
43
+ }
44
+ exec(cmd, () => {});
45
+ }
46
+
47
+ function prompt(rl, question) {
48
+ return new Promise((resolve) => rl.question(question, resolve));
49
+ }
50
+
51
+ function getConfigDir() {
52
+ const xdg = process.env.XDG_CONFIG_HOME;
53
+ const base = xdg || path.join(os.homedir(), '.config');
54
+ const baseDir = path.join(base, 'google-tools-mcp');
55
+ const profile = process.env.GOOGLE_MCP_PROFILE;
56
+ return profile ? path.join(baseDir, profile) : baseDir;
57
+ }
58
+
59
+ // ---------------------------------------------------------------------------
60
+ // Setup flow
61
+ // ---------------------------------------------------------------------------
62
+ export async function runSetup() {
63
+ const rl = readline.createInterface({
64
+ input: process.stdin,
65
+ output: process.stdout,
66
+ });
67
+
68
+ console.log('\n🔧 google-tools-mcp setup\n');
69
+
70
+ // Step 1: Enable APIs
71
+ console.log('Step 1: Enable Google APIs');
72
+ console.log('─────────────────────────');
73
+ console.log('Opening Google Cloud Console to enable all required APIs.');
74
+ console.log('If you don\'t have a project yet, it will ask you to create one.\n');
75
+ openBrowser(ENABLE_APIS_URL);
76
+ await prompt(rl, 'Press Enter when done...');
77
+
78
+ // Step 2: OAuth consent screen
79
+ console.log('\nStep 2: Configure OAuth consent screen');
80
+ console.log('──────────────────────────────────────');
81
+ console.log('Opening the OAuth consent screen configuration.');
82
+ console.log(' • Choose "External" for the user type');
83
+ console.log(' • Fill in the app name (anything is fine, e.g. "MCP")');
84
+ console.log(' • Add your email as a test user\n');
85
+ openBrowser(CONSENT_SCREEN_URL);
86
+ await prompt(rl, 'Press Enter when done...');
87
+
88
+ // Step 3: Create OAuth credentials
89
+ console.log('\nStep 3: Create OAuth Client ID');
90
+ console.log('──────────────────────────────');
91
+ console.log('Opening the credentials page.');
92
+ console.log(' • Select "Desktop application" as the type');
93
+ console.log(' • Click Create, then copy the Client ID and Client Secret\n');
94
+ openBrowser(CREATE_CREDENTIALS_URL);
95
+ await prompt(rl, 'Press Enter when you have your Client ID and Secret...');
96
+
97
+ // Step 4: Collect credentials
98
+ console.log('');
99
+ const clientId = (await prompt(rl, 'Client ID: ')).trim();
100
+ const clientSecret = (await prompt(rl, 'Client Secret: ')).trim();
101
+
102
+ if (!clientId || !clientSecret) {
103
+ rl.close();
104
+ throw new Error('Client ID and Client Secret are required.');
105
+ }
106
+
107
+ // Save to config dir
108
+ const configDir = getConfigDir();
109
+ await fs.mkdir(configDir, { recursive: true });
110
+ const envPath = path.join(configDir, '.env');
111
+ const envContent = `GOOGLE_CLIENT_ID=${clientId}\nGOOGLE_CLIENT_SECRET=${clientSecret}\n`;
112
+ await fs.writeFile(envPath, envContent);
113
+ const displayPath = envPath.replace(os.homedir(), '~');
114
+ console.log(`\nCredentials saved to ${displayPath}`);
115
+
116
+ // Step 5: Run OAuth flow
117
+ console.log('\nStep 4: Authenticate with Google');
118
+ console.log('────────────────────────────────');
119
+ console.log('Opening browser for OAuth consent...\n');
120
+ rl.close();
121
+
122
+ // Set env vars so auth picks them up immediately
123
+ process.env.GOOGLE_CLIENT_ID = clientId;
124
+ process.env.GOOGLE_CLIENT_SECRET = clientSecret;
125
+
126
+ const { runAuthFlow } = await import('./auth.js');
127
+ await runAuthFlow();
128
+
129
+ console.log('\n✅ Setup complete! You\'re ready to use google-tools-mcp.');
130
+ console.log('\nAdd it to Claude Code:');
131
+ console.log(' claude mcp add -s user google -- npx -y google-tools-mcp\n');
132
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "google-tools-mcp",
3
- "version": "1.1.3",
3
+ "version": "1.2.0",
4
4
  "description": "The easiest MCP server for Google Workspace — Drive, Docs, Sheets, Gmail, Calendar, and Forms. 153 tools with one-click browser auth. Read Word docs, PDFs, and spreadsheets straight from Drive.",
5
5
  "type": "module",
6
6
  "bin": {