@piotr-agier/google-drive-mcp 1.7.3 → 1.7.5

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
@@ -194,7 +194,7 @@ Run the container with your credentials and tokens mounted:
194
194
  ```bash
195
195
  docker run -it \
196
196
  -v /path/to/gcp-oauth.keys.json:/config/gcp-oauth.keys.json:ro \
197
- -v ~/.config/google-drive-mcp/tokens.json:/config/tokens.json \
197
+ -v "$HOME/.config/google-drive-mcp/tokens.json":/config/tokens.json \
198
198
  google-drive-mcp
199
199
  ```
200
200
 
@@ -206,7 +206,35 @@ docker run -it \
206
206
 
207
207
  ### Docker Configuration for Claude Desktop
208
208
 
209
- Add this configuration to use the Docker container with Claude Desktop:
209
+ #### Option A: Reusable container (recommended)
210
+
211
+ Uses a wrapper script that keeps a single named container running and reuses it across client restarts — faster startup and no container churn:
212
+
213
+ ```json
214
+ {
215
+ "mcpServers": {
216
+ "google-drive": {
217
+ "command": "/path/to/google-drive-mcp/scripts/docker-mcp.sh",
218
+ "env": {
219
+ "GOOGLE_DRIVE_OAUTH_CREDENTIALS": "$HOME/gcp-oauth.keys.json",
220
+ "GOOGLE_DRIVE_MCP_TOKEN_PATH": "$HOME/.config/google-drive-mcp/tokens.json"
221
+ }
222
+ }
223
+ }
224
+ }
225
+ ```
226
+
227
+ The script will:
228
+ - Create the container on first run
229
+ - Reuse the existing container on subsequent runs
230
+ - Automatically restart it if it was stopped
231
+
232
+ **Note:** The container stays running in the background until explicitly stopped.
233
+ To stop it: `docker stop google-drive-mcp`
234
+
235
+ #### Option B: Fresh container each time
236
+
237
+ Creates and removes a new container on every client restart:
210
238
 
211
239
  ```json
212
240
  {
@@ -240,13 +268,20 @@ Add this configuration to use the Docker container with Claude Desktop:
240
268
 
241
269
  The server supports multiple methods for providing OAuth credentials (in order of priority):
242
270
 
243
- #### 1. **Environment Variable** (Recommended)
271
+ #### 1. **Environment Variable** (Highest Priority)
244
272
  ```bash
245
273
  export GOOGLE_DRIVE_OAUTH_CREDENTIALS="/path/to/your/gcp-oauth.keys.json"
246
274
  ```
247
275
 
248
- #### 2. **Default File Location**
249
- Place `gcp-oauth.keys.json` in the project root directory
276
+ #### 2. **Config Directory** (Recommended)
277
+ Place `gcp-oauth.keys.json` in the XDG config directory:
278
+ ```
279
+ ~/.config/google-drive-mcp/gcp-oauth.keys.json
280
+ ```
281
+ This is the recommended location — it works reliably with `npx`, global installs, and local setups.
282
+
283
+ #### 3. **Project Root** (Legacy Fallback)
284
+ Place `gcp-oauth.keys.json` in the project root directory. This still works for local development but is unreliable with `npx` or global installs.
250
285
 
251
286
  ### OAuth Scope Configuration
252
287
 
@@ -943,15 +978,15 @@ After revoking access, you'll need to re-authenticate the next time you use the
943
978
  #### "OAuth credentials not found"
944
979
  ```
945
980
  OAuth credentials not found. Please provide credentials using one of these methods:
946
- 1. Environment variable:
981
+ 1. Config directory (recommended):
982
+ Place your gcp-oauth.keys.json file in: ~/.config/google-drive-mcp/
983
+ 2. Environment variable:
947
984
  export GOOGLE_DRIVE_OAUTH_CREDENTIALS="/path/to/gcp-oauth.keys.json"
948
- 2. Default file path:
949
- Place your gcp-oauth.keys.json file in the package root directory.
950
985
  ```
951
986
 
952
987
  **Solution:**
953
988
  - Download credentials from Google Cloud Console
954
- - Either set the environment variable or place the file in the project root
989
+ - Place the file in `~/.config/google-drive-mcp/gcp-oauth.keys.json` (recommended), or set the environment variable
955
990
  - Ensure the file has proper read permissions
956
991
 
957
992
  #### "Authentication failed" or Browser doesn't open
@@ -1049,7 +1084,7 @@ ls -la ~/.config/google-drive-mcp/tokens.json
1049
1084
  # 3. Run Docker with tokens mounted
1050
1085
  docker run -it \
1051
1086
  -v $(pwd)/gcp-oauth.keys.json:/config/gcp-oauth.keys.json:ro \
1052
- -v ~/.config/google-drive-mcp/tokens.json:/config/tokens.json \
1087
+ -v "$HOME/.config/google-drive-mcp/tokens.json":/config/tokens.json \
1053
1088
  google-drive-mcp
1054
1089
  ```
1055
1090
 
@@ -1074,10 +1109,10 @@ The Dockerfile expects the `dist/` directory to exist from your local build.
1074
1109
  **Solution:** Ensure the token file is mounted with write permissions:
1075
1110
  ```bash
1076
1111
  # Correct: tokens can be updated
1077
- -v ~/.config/google-drive-mcp/tokens.json:/config/tokens.json
1112
+ -v "$HOME/.config/google-drive-mcp/tokens.json":/config/tokens.json
1078
1113
 
1079
1114
  # Wrong: read-only mount prevents token refresh
1080
- -v ~/.config/google-drive-mcp/tokens.json:/config/tokens.json:ro
1115
+ -v "$HOME/.config/google-drive-mcp/tokens.json":/config/tokens.json:ro
1081
1116
  ```
1082
1117
 
1083
1118
  ### Debug Mode
@@ -1156,7 +1191,8 @@ npm run typecheck # Type checking without compilation
1156
1191
  | Variable | Description | Example |
1157
1192
  |----------|-------------|---------|
1158
1193
  | `GOOGLE_DRIVE_OAUTH_CREDENTIALS` | Path to your OAuth credentials JSON file | `/home/user/secrets/oauth.json` |
1159
- | *(or place file at)* | Default location: `gcp-oauth.keys.json` in project root | `./gcp-oauth.keys.json` |
1194
+ | *(or place file at)* | Config directory (recommended): `~/.config/google-drive-mcp/gcp-oauth.keys.json` | `~/.config/google-drive-mcp/gcp-oauth.keys.json` |
1195
+ | *(or place file at)* | Project root (legacy fallback): `gcp-oauth.keys.json` | `./gcp-oauth.keys.json` |
1160
1196
 
1161
1197
  **Optional** (for customization):
1162
1198
  | Variable | Description | Default | Example |
package/dist/index.js CHANGED
@@ -29,14 +29,16 @@ function getProjectRoot() {
29
29
  const projectRoot = path.join(__dirname2, "..", "..");
30
30
  return path.resolve(projectRoot);
31
31
  }
32
+ function getConfigDir() {
33
+ const configHome = process.env.XDG_CONFIG_HOME || path.join(os.homedir(), ".config");
34
+ return path.join(configHome, "google-drive-mcp");
35
+ }
32
36
  function getSecureTokenPath() {
33
37
  const customTokenPath = process.env.GOOGLE_DRIVE_MCP_TOKEN_PATH;
34
38
  if (customTokenPath) {
35
39
  return path.resolve(customTokenPath);
36
40
  }
37
- const configHome = process.env.XDG_CONFIG_HOME || path.join(os.homedir(), ".config");
38
- const tokenDir = path.join(configHome, "google-drive-mcp");
39
- return path.join(tokenDir, "tokens.json");
41
+ return path.join(getConfigDir(), "tokens.json");
40
42
  }
41
43
  function getLegacyTokenPath() {
42
44
  const projectRoot = getProjectRoot();
@@ -49,26 +51,29 @@ function getAdditionalLegacyPaths() {
49
51
  path.join(process.cwd(), ".gcp-saved-tokens.json")
50
52
  ].filter(Boolean);
51
53
  }
52
- function getKeysFilePath() {
54
+ function getKeysFilePaths() {
55
+ const paths = [];
53
56
  const envCredentialsPath = process.env.GOOGLE_DRIVE_OAUTH_CREDENTIALS;
54
57
  if (envCredentialsPath) {
55
- return path.resolve(envCredentialsPath);
58
+ paths.push(path.resolve(envCredentialsPath));
56
59
  }
60
+ paths.push(path.join(getConfigDir(), "gcp-oauth.keys.json"));
57
61
  const projectRoot = getProjectRoot();
58
- const keysPath = path.join(projectRoot, "gcp-oauth.keys.json");
59
- return keysPath;
62
+ paths.push(path.join(projectRoot, "gcp-oauth.keys.json"));
63
+ return paths;
60
64
  }
61
65
  function generateCredentialsErrorMessage() {
66
+ const configDir = getConfigDir();
62
67
  return `
63
68
  OAuth credentials not found. Please provide credentials using one of these methods:
64
69
 
65
- 1. Environment variable:
70
+ 1. Config directory (recommended):
71
+ Place your gcp-oauth.keys.json file in: ${configDir}/
72
+
73
+ 2. Environment variable:
66
74
  Set GOOGLE_DRIVE_OAUTH_CREDENTIALS to the path of your credentials file:
67
75
  export GOOGLE_DRIVE_OAUTH_CREDENTIALS="/path/to/gcp-oauth.keys.json"
68
76
 
69
- 2. Default file path:
70
- Place your gcp-oauth.keys.json file in the package root directory.
71
-
72
77
  Token storage:
73
78
  - Tokens are saved to: ${getSecureTokenPath()}
74
79
  - To use a custom token location, set GOOGLE_DRIVE_MCP_TOKEN_PATH environment variable
@@ -83,9 +88,7 @@ To get OAuth credentials:
83
88
  }
84
89
 
85
90
  // src/auth/client.ts
86
- async function loadCredentialsFromFile() {
87
- const keysContent = await fs.readFile(getKeysFilePath(), "utf-8");
88
- const keys = JSON.parse(keysContent);
91
+ function parseCredentialsFile(keys) {
89
92
  if (keys.installed) {
90
93
  const { client_id, client_secret, redirect_uris } = keys.installed;
91
94
  return { client_id, client_secret, redirect_uris };
@@ -102,6 +105,21 @@ async function loadCredentialsFromFile() {
102
105
  throw new Error('Invalid credentials file format. Expected either "installed", "web" object or direct client_id field.');
103
106
  }
104
107
  }
108
+ async function loadCredentialsFromFile() {
109
+ const paths = getKeysFilePaths();
110
+ for (const keysPath of paths) {
111
+ try {
112
+ const keysContent = await fs.readFile(keysPath, "utf-8");
113
+ const keys = JSON.parse(keysContent);
114
+ return parseCredentialsFile(keys);
115
+ } catch (err) {
116
+ if (err instanceof SyntaxError || err instanceof Error && err.message.includes("Invalid credentials")) {
117
+ throw new Error(`Invalid credentials file at ${keysPath}: ${err.message}`);
118
+ }
119
+ }
120
+ }
121
+ throw new Error(`Credentials file not found. Searched: ${paths.join(", ")}`);
122
+ }
105
123
  async function loadCredentialsWithFallback() {
106
124
  try {
107
125
  return await loadCredentialsFromFile();