From 73b13a044d6a3a7826e302cd8bf871ac277f4b48 Mon Sep 17 00:00:00 2001 From: Mahesh Murag Date: Tue, 19 Nov 2024 19:49:33 -0500 Subject: [PATCH 1/6] Update README for GDrive --- src/gdrive/README.md | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/src/gdrive/README.md b/src/gdrive/README.md index b9d48738..97c1685a 100644 --- a/src/gdrive/README.md +++ b/src/gdrive/README.md @@ -2,13 +2,35 @@ This MCP server integrates with Google Drive to allow listing, reading, and searching over files. +## Components + +### Tools + +- **search** + - Search for files in Google Drive + - Input: `query` (string): Search query + - Returns file names and MIME types of matching files + +### Resources + +The server provides access to Google Drive files: + +- **Files** (`gdrive://`) + - Supports all file types + - Google Workspace files are automatically exported: + - Docs → Markdown + - Sheets → CSV + - Presentations → Plain text + - Drawings → PNG + - Other files are provided in their native format + ## Getting started -1. Create a new Google Cloud project -2. Enable the Google Drive API -3. Configure an OAuth consent screen ("internal" is fine for testing) +1. [Create a new Google Cloud project](https://console.cloud.google.com/projectcreate) +2. [Enable the Google Drive API](https://console.cloud.google.com/workspace-api/products) +3. [Configure an OAuth consent screen](https://console.cloud.google.com/apis/credentials/consent) ("internal" is fine for testing) 4. Add OAuth scope `https://www.googleapis.com/auth/drive.readonly` -5. Create an OAuth Client ID for application type "Desktop App" +5. [Create an OAuth Client ID](https://console.cloud.google.com/apis/credentials/oauthclient) for application type "Desktop App" 6. Download the JSON file of your client's OAuth keys 7. Rename the key file to `gcp-oauth.keys.json` and place into the root of this repo @@ -30,4 +52,4 @@ After authenticating: 1. Run the server normally: `node build/gdrive` 2. The server will load the saved credentials and start -Note: If you haven't authenticated yet, the server will prompt you to run with the `auth` argument first. +Note: If you haven't authenticated yet, the server will prompt you to run with the `auth` argument first. \ No newline at end of file From 4103932b00403787cfa8022d739423d0acb2cbd7 Mon Sep 17 00:00:00 2001 From: Justin Spahr-Summers Date: Wed, 20 Nov 2024 11:30:24 +0000 Subject: [PATCH 2/6] Fix paths to creds and in README --- src/gdrive/README.md | 6 +++--- src/gdrive/index.ts | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/gdrive/README.md b/src/gdrive/README.md index 97c1685a..70cc0195 100644 --- a/src/gdrive/README.md +++ b/src/gdrive/README.md @@ -40,7 +40,7 @@ Make sure to build the server with either `npm run build` or `npm run watch`. To authenticate and save credentials: -1. Run the server with the `auth` argument: `node build/gdrive auth` +1. Run the server with the `auth` argument: `node ./dist auth` 2. This will open an authentication flow in your system browser 3. Complete the authentication process 4. Credentials will be saved for future use @@ -49,7 +49,7 @@ To authenticate and save credentials: After authenticating: -1. Run the server normally: `node build/gdrive` +1. Run the server normally: `node ./dist` 2. The server will load the saved credentials and start -Note: If you haven't authenticated yet, the server will prompt you to run with the `auth` argument first. \ No newline at end of file +Note: If you haven't authenticated yet, the server will prompt you to run with the `auth` argument first. diff --git a/src/gdrive/index.ts b/src/gdrive/index.ts index 1a8ac82e..9c8bc229 100644 --- a/src/gdrive/index.ts +++ b/src/gdrive/index.ts @@ -175,7 +175,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => { const credentialsPath = path.join( path.dirname(new URL(import.meta.url).pathname), - "../../.gdrive-server-credentials.json", + "../../../.gdrive-server-credentials.json", ); async function authenticateAndSaveCredentials() { @@ -183,7 +183,7 @@ async function authenticateAndSaveCredentials() { const auth = await authenticate({ keyfilePath: path.join( path.dirname(new URL(import.meta.url).pathname), - "../../gcp-oauth.keys.json", + "../../../gcp-oauth.keys.json", ), scopes: ["https://www.googleapis.com/auth/drive.readonly"], }); From bfdb9e3c106059bb60a17116a2b5022ec8576739 Mon Sep 17 00:00:00 2001 From: Mahesh Murag Date: Wed, 20 Nov 2024 09:44:24 -0500 Subject: [PATCH 3/6] Updated GDrive --- src/gdrive/index.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/gdrive/index.ts b/src/gdrive/index.ts index 9c8bc229..e080aab0 100644 --- a/src/gdrive/index.ts +++ b/src/gdrive/index.ts @@ -149,14 +149,16 @@ server.setRequestHandler(ListToolsRequestSchema, async () => { server.setRequestHandler(CallToolRequestSchema, async (request) => { if (request.params.name === "search") { - const query = request.params.arguments?.query as string; - + const userQuery = request.params.arguments?.query as string; + const escapedQuery = userQuery.replace(/'/g, "\\'"); + const formattedQuery = `fullText contains '${escapedQuery}'`; + const res = await drive.files.list({ - q: query, + q: formattedQuery, pageSize: 10, fields: "files(id, name, mimeType, modifiedTime, size)", }); - + const fileList = res.data.files ?.map((file: any) => `${file.name} (${file.mimeType})`) .join("\n"); From 607845a1a635d249198f5ae36ef395b0bc5525f8 Mon Sep 17 00:00:00 2001 From: Mahesh Murag Date: Wed, 20 Nov 2024 09:45:37 -0500 Subject: [PATCH 4/6] Updated GDrive --- src/gdrive/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gdrive/README.md b/src/gdrive/README.md index 70cc0195..8e296a59 100644 --- a/src/gdrive/README.md +++ b/src/gdrive/README.md @@ -32,7 +32,7 @@ The server provides access to Google Drive files: 4. Add OAuth scope `https://www.googleapis.com/auth/drive.readonly` 5. [Create an OAuth Client ID](https://console.cloud.google.com/apis/credentials/oauthclient) for application type "Desktop App" 6. Download the JSON file of your client's OAuth keys -7. Rename the key file to `gcp-oauth.keys.json` and place into the root of this repo +7. Rename the key file to `gcp-oauth.keys.json` and place into the root of this repo (i.e. `servers/gcp-oauth.keys.json`) Make sure to build the server with either `npm run build` or `npm run watch`. From 0c5ec3120f6ed4398fb4ecf55336c12012d2a2f7 Mon Sep 17 00:00:00 2001 From: Mahesh Murag Date: Wed, 20 Nov 2024 09:49:00 -0500 Subject: [PATCH 5/6] Updated GDrive --- src/gdrive/README.md | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/gdrive/README.md b/src/gdrive/README.md index 8e296a59..a62094ee 100644 --- a/src/gdrive/README.md +++ b/src/gdrive/README.md @@ -43,13 +43,15 @@ To authenticate and save credentials: 1. Run the server with the `auth` argument: `node ./dist auth` 2. This will open an authentication flow in your system browser 3. Complete the authentication process -4. Credentials will be saved for future use +4. Credentials will be saved in the root of this repo (i.e. `servers/.gdrive-server-credentials.json`) -### Running the server +### Usage with Desktop App -After authenticating: +To integrate this server with the desktop app, add the following to your app's server configuration: -1. Run the server normally: `node ./dist` -2. The server will load the saved credentials and start - -Note: If you haven't authenticated yet, the server will prompt you to run with the `auth` argument first. +```json +{ + "mcp-server-gdrive": { + "command": "mcp-server-gdrive" + } +} \ No newline at end of file From dc455ee23a835b930620936b571f360d553c18cd Mon Sep 17 00:00:00 2001 From: Mahesh Murag Date: Wed, 20 Nov 2024 09:58:30 -0500 Subject: [PATCH 6/6] Updated GDrive --- src/gdrive/README.md | 2 +- src/gdrive/index.ts | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/gdrive/README.md b/src/gdrive/README.md index a62094ee..5fd0e0dc 100644 --- a/src/gdrive/README.md +++ b/src/gdrive/README.md @@ -15,7 +15,7 @@ This MCP server integrates with Google Drive to allow listing, reading, and sear The server provides access to Google Drive files: -- **Files** (`gdrive://`) +- **Files** (`gdrive:///`) - Supports all file types - Google Workspace files are automatically exported: - Docs → Markdown diff --git a/src/gdrive/index.ts b/src/gdrive/index.ts index e080aab0..b9c6d910 100644 --- a/src/gdrive/index.ts +++ b/src/gdrive/index.ts @@ -44,7 +44,7 @@ server.setRequestHandler(ListResourcesRequestSchema, async (request) => { return { resources: files.map((file) => ({ - uri: `gdrive://${file.id}`, + uri: `gdrive:///${file.id}`, mimeType: file.mimeType, name: file.name, })), @@ -53,7 +53,7 @@ server.setRequestHandler(ListResourcesRequestSchema, async (request) => { }); server.setRequestHandler(ReadResourceRequestSchema, async (request) => { - const fileId = request.params.uri.replace("gdrive://", ""); + const fileId = request.params.uri.replace("gdrive:///", ""); // First get file metadata to check mime type const file = await drive.files.get({ @@ -150,7 +150,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => { server.setRequestHandler(CallToolRequestSchema, async (request) => { if (request.params.name === "search") { const userQuery = request.params.arguments?.query as string; - const escapedQuery = userQuery.replace(/'/g, "\\'"); + const escapedQuery = userQuery.replace(/\\/g, "\\\\").replace(/'/g, "\\'"); const formattedQuery = `fullText contains '${escapedQuery}'`; const res = await drive.files.list({