google-workspace-mcp 2.0.0 → 2.0.1

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/dist/types.d.ts CHANGED
@@ -102,8 +102,8 @@ export declare const TextFindParameter: z.ZodObject<{
102
102
  textToFind: z.ZodString;
103
103
  matchInstance: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
104
104
  }, "strip", z.ZodTypeAny, {
105
- matchInstance: number;
106
105
  textToFind: string;
106
+ matchInstance: number;
107
107
  }, {
108
108
  textToFind: string;
109
109
  matchInstance?: number | undefined;
@@ -193,8 +193,8 @@ export declare const ApplyTextStyleToolParameters: z.ZodObject<{
193
193
  textToFind: z.ZodString;
194
194
  matchInstance: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
195
195
  }, "strip", z.ZodTypeAny, {
196
- matchInstance: number;
197
196
  textToFind: string;
197
+ matchInstance: number;
198
198
  }, {
199
199
  textToFind: string;
200
200
  matchInstance?: number | undefined;
@@ -262,8 +262,8 @@ export declare const ApplyTextStyleToolParameters: z.ZodObject<{
262
262
  startIndex: number;
263
263
  endIndex: number;
264
264
  } | {
265
- matchInstance: number;
266
265
  textToFind: string;
266
+ matchInstance: number;
267
267
  };
268
268
  style: {
269
269
  bold?: boolean | undefined;
@@ -325,8 +325,8 @@ export declare const ApplyParagraphStyleToolParameters: z.ZodObject<{
325
325
  textToFind: z.ZodString;
326
326
  matchInstance: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
327
327
  }, "strip", z.ZodTypeAny, {
328
- matchInstance: number;
329
328
  textToFind: string;
329
+ matchInstance: number;
330
330
  }, {
331
331
  textToFind: string;
332
332
  matchInstance?: number | undefined;
@@ -385,8 +385,8 @@ export declare const ApplyParagraphStyleToolParameters: z.ZodObject<{
385
385
  startIndex: number;
386
386
  endIndex: number;
387
387
  } | {
388
- matchInstance: number;
389
388
  textToFind: string;
389
+ matchInstance: number;
390
390
  } | {
391
391
  indexWithinParagraph: number;
392
392
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "google-workspace-mcp",
3
- "version": "2.0.0",
3
+ "version": "2.0.1",
4
4
  "description": "MCP server for Google Workspace: Docs, Sheets, Drive, Gmail, Calendar, Slides, and Forms",
5
5
  "type": "module",
6
6
  "main": "dist/cli.js",
@@ -15,9 +15,9 @@
15
15
  "LICENSE"
16
16
  ],
17
17
  "scripts": {
18
- "test": "node --test 'tests/**/*.test.js'",
19
- "test:coverage": "c8 --include='dist/**/*.js' --exclude='dist/cli.js' node --test 'tests/**/*.test.js'",
20
- "test:integration": "node --test 'tests/integration/**/*.test.js'",
18
+ "test": "node --test tests/*.test.js",
19
+ "test:coverage": "c8 --include='dist/**/*.js' --exclude='dist/cli.js' node --test tests/*.test.js",
20
+ "test:integration": "node --test tests/integration/*.test.js",
21
21
  "build": "tsc",
22
22
  "lint": "gts lint",
23
23
  "fix": "gts fix",
@@ -57,7 +57,7 @@
57
57
  "url": "https://github.com/pm990320/google-workspace-mcp/issues"
58
58
  },
59
59
  "engines": {
60
- "node": ">=18.0.0"
60
+ "node": ">=20.0.0"
61
61
  },
62
62
  "dependencies": {
63
63
  "commander": "^14.0.3",
package/dist/auth.d.ts DELETED
@@ -1,4 +0,0 @@
1
- import type { OAuth2Client } from 'google-auth-library';
2
- import { JWT } from 'google-auth-library';
3
- export declare function authorize(): Promise<OAuth2Client | JWT>;
4
- //# sourceMappingURL=auth.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAe,MAAM,qBAAqB,CAAC;AACrE,OAAO,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AA8M1C,wBAAsB,SAAS,IAAI,OAAO,CAAC,YAAY,GAAG,GAAG,CAAC,CAkB7D"}
package/dist/auth.js DELETED
@@ -1,206 +0,0 @@
1
- // src/auth.ts
2
- import { google } from 'googleapis';
3
- import { JWT } from 'google-auth-library'; // ADDED: Import for Service Account client
4
- import * as fs from 'fs/promises';
5
- import * as path from 'path';
6
- import * as readline from 'readline/promises';
7
- import * as http from 'http';
8
- import { fileURLToPath } from 'url';
9
- // --- Calculate paths relative to this script file (ESM way) ---
10
- const __filename = fileURLToPath(import.meta.url);
11
- const __dirname = path.dirname(__filename);
12
- const projectRootDir = path.resolve(__dirname, '..');
13
- const TOKEN_PATH = path.join(projectRootDir, 'token.json');
14
- const CREDENTIALS_PATH = path.join(projectRootDir, 'credentials.json');
15
- // --- End of path calculation ---
16
- const SCOPES = [
17
- 'https://www.googleapis.com/auth/documents',
18
- 'https://www.googleapis.com/auth/drive', // Full Drive access for listing, searching, and document discovery
19
- 'https://www.googleapis.com/auth/spreadsheets', // Google Sheets API access
20
- ];
21
- // --- NEW FUNCTION: Handles Service Account Authentication ---
22
- // This entire function is new. It is called only when the
23
- // SERVICE_ACCOUNT_PATH environment variable is set.
24
- // Supports domain-wide delegation via GOOGLE_IMPERSONATE_USER env var.
25
- async function authorizeWithServiceAccount() {
26
- const serviceAccountPath = process.env.SERVICE_ACCOUNT_PATH;
27
- if (!serviceAccountPath) {
28
- throw new Error('SERVICE_ACCOUNT_PATH environment variable is required');
29
- }
30
- const impersonateUser = process.env.GOOGLE_IMPERSONATE_USER; // Optional: email of user to impersonate
31
- try {
32
- // eslint-disable-next-line security/detect-non-literal-fs-filename -- serviceAccountPath from environment variable, admin-controlled
33
- const keyFileContent = await fs.readFile(serviceAccountPath, 'utf8');
34
- const serviceAccountKey = JSON.parse(keyFileContent);
35
- const auth = new JWT({
36
- email: serviceAccountKey.client_email,
37
- key: serviceAccountKey.private_key,
38
- scopes: SCOPES,
39
- subject: impersonateUser, // Enables domain-wide delegation when set
40
- });
41
- await auth.authorize();
42
- if (impersonateUser) {
43
- console.error(`Service Account authentication successful, impersonating: ${impersonateUser}`);
44
- }
45
- else {
46
- console.error('Service Account authentication successful!');
47
- }
48
- return auth;
49
- }
50
- catch (error) {
51
- const isNodeError = (e) => e instanceof Error && 'code' in e;
52
- if (isNodeError(error) && error.code === 'ENOENT') {
53
- console.error(`FATAL: Service account key file not found at path: ${serviceAccountPath}`);
54
- throw new Error('Service account key file not found. Please check the path in SERVICE_ACCOUNT_PATH.');
55
- }
56
- const message = error instanceof Error ? error.message : String(error);
57
- console.error('FATAL: Error loading or authorizing the service account key:', message);
58
- throw new Error('Failed to authorize using the service account. Ensure the key file is valid and the path is correct.');
59
- }
60
- }
61
- // --- END OF NEW FUNCTION---
62
- async function loadSavedCredentialsIfExist() {
63
- try {
64
- const content = await fs.readFile(TOKEN_PATH);
65
- const credentials = JSON.parse(content.toString());
66
- const { client_secret, client_id, redirect_uris } = await loadClientSecrets();
67
- const client = new google.auth.OAuth2(client_id, client_secret, redirect_uris[0]);
68
- client.setCredentials(credentials);
69
- return client;
70
- }
71
- catch {
72
- return null;
73
- }
74
- }
75
- async function loadClientSecrets() {
76
- const content = await fs.readFile(CREDENTIALS_PATH);
77
- const keys = JSON.parse(content.toString());
78
- const key = keys.installed ?? keys.web;
79
- if (!key)
80
- throw new Error('Could not find client secrets in credentials.json.');
81
- return {
82
- client_id: key.client_id,
83
- client_secret: key.client_secret,
84
- redirect_uris: key.redirect_uris ?? ['http://localhost:3000/'], // Default for web clients
85
- client_type: keys.web ? 'web' : 'installed',
86
- };
87
- }
88
- async function saveCredentials(client) {
89
- const { client_secret, client_id } = await loadClientSecrets();
90
- const payload = JSON.stringify({
91
- type: 'authorized_user',
92
- client_id: client_id,
93
- client_secret: client_secret,
94
- refresh_token: client.credentials.refresh_token,
95
- });
96
- await fs.writeFile(TOKEN_PATH, payload);
97
- console.error('Token stored to', TOKEN_PATH);
98
- }
99
- async function authenticate() {
100
- const { client_secret, client_id, redirect_uris, client_type } = await loadClientSecrets();
101
- // Use localhost redirect for desktop apps (OOB flow is deprecated)
102
- const redirectUri = client_type === 'web' ? redirect_uris[0] : 'http://localhost:3000';
103
- console.error(`DEBUG: Using redirect URI: ${redirectUri}`);
104
- console.error(`DEBUG: Client type: ${client_type}`);
105
- const oAuth2Client = new google.auth.OAuth2(client_id, client_secret, redirectUri);
106
- const authorizeUrl = oAuth2Client.generateAuthUrl({
107
- access_type: 'offline',
108
- scope: SCOPES.join(' '),
109
- });
110
- console.error('DEBUG: Generated auth URL:', authorizeUrl);
111
- console.error('Authorize this app by visiting this url:', authorizeUrl);
112
- // For desktop apps, start a local server to receive the OAuth callback
113
- if (client_type === 'installed') {
114
- return new Promise((resolve, reject) => {
115
- const server = http.createServer((req, res) => {
116
- void (async () => {
117
- try {
118
- const url = new URL(req.url || '', 'http://localhost:3000');
119
- const code = url.searchParams.get('code');
120
- if (code) {
121
- res.writeHead(200, { 'Content-Type': 'text/html' });
122
- res.end('<html><body><h1>Authentication successful!</h1><p>You can close this window.</p></body></html>');
123
- server.close();
124
- const { tokens } = await oAuth2Client.getToken(code);
125
- oAuth2Client.setCredentials(tokens);
126
- if (tokens.refresh_token) {
127
- await saveCredentials(oAuth2Client);
128
- }
129
- else {
130
- console.error('Did not receive refresh token. Token might expire.');
131
- }
132
- console.error('Authentication successful!');
133
- resolve(oAuth2Client);
134
- }
135
- else {
136
- res.writeHead(400, { 'Content-Type': 'text/html' });
137
- res.end('<html><body><h1>Error: No code received</h1></body></html>');
138
- }
139
- }
140
- catch (err) {
141
- console.error('Error retrieving access token', err);
142
- res.writeHead(500, { 'Content-Type': 'text/html' });
143
- res.end('<html><body><h1>Authentication failed</h1></body></html>');
144
- server.close();
145
- reject(new Error('Authentication failed'));
146
- }
147
- })();
148
- });
149
- server.listen(3000, () => {
150
- console.error('Local server started on http://localhost:3000');
151
- console.error('Waiting for OAuth callback...');
152
- });
153
- server.on('error', (err) => {
154
- console.error('Server error:', err);
155
- reject(err);
156
- });
157
- });
158
- }
159
- else {
160
- // For web clients, use readline to get the code manually
161
- const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
162
- const code = await rl.question('Enter the code from that page here: ');
163
- rl.close();
164
- try {
165
- const { tokens } = await oAuth2Client.getToken(code);
166
- oAuth2Client.setCredentials(tokens);
167
- if (tokens.refresh_token) {
168
- await saveCredentials(oAuth2Client);
169
- }
170
- else {
171
- console.error('Did not receive refresh token. Token might expire.');
172
- }
173
- console.error('Authentication successful!');
174
- return oAuth2Client;
175
- }
176
- catch (err) {
177
- console.error('Error retrieving access token', err);
178
- throw new Error('Authentication failed');
179
- }
180
- }
181
- }
182
- // --- MODIFIED: The Main Exported Function ---
183
- // This function now acts as a router. It checks for the environment
184
- // variable and decides which authentication method to use.
185
- export async function authorize() {
186
- // Check if the Service Account environment variable is set.
187
- if (process.env.SERVICE_ACCOUNT_PATH) {
188
- console.error('Service account path detected. Attempting service account authentication...');
189
- return authorizeWithServiceAccount();
190
- }
191
- else {
192
- // If not, execute the original OAuth 2.0 flow exactly as it was.
193
- console.error('No service account path detected. Falling back to standard OAuth 2.0 flow...');
194
- let client = await loadSavedCredentialsIfExist();
195
- if (client) {
196
- // Optional: Add token refresh logic here if needed, though library often handles it.
197
- console.error('Using saved credentials.');
198
- return client;
199
- }
200
- console.error('Starting authentication flow...');
201
- client = await authenticate();
202
- return client;
203
- }
204
- }
205
- // --- END OF MODIFIED: The Main Exported Function ---
206
- //# sourceMappingURL=auth.js.map
package/dist/auth.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"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"}