google-workspace-mcp 1.0.0__py3-none-any.whl

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.
Files changed (38) hide show
  1. google_workspace_mcp/__init__.py +3 -0
  2. google_workspace_mcp/__main__.py +43 -0
  3. google_workspace_mcp/app.py +8 -0
  4. google_workspace_mcp/auth/__init__.py +7 -0
  5. google_workspace_mcp/auth/gauth.py +62 -0
  6. google_workspace_mcp/config.py +60 -0
  7. google_workspace_mcp/prompts/__init__.py +3 -0
  8. google_workspace_mcp/prompts/calendar.py +36 -0
  9. google_workspace_mcp/prompts/drive.py +18 -0
  10. google_workspace_mcp/prompts/gmail.py +65 -0
  11. google_workspace_mcp/prompts/slides.py +40 -0
  12. google_workspace_mcp/resources/__init__.py +13 -0
  13. google_workspace_mcp/resources/calendar.py +79 -0
  14. google_workspace_mcp/resources/drive.py +93 -0
  15. google_workspace_mcp/resources/gmail.py +58 -0
  16. google_workspace_mcp/resources/sheets_resources.py +92 -0
  17. google_workspace_mcp/resources/slides.py +421 -0
  18. google_workspace_mcp/services/__init__.py +21 -0
  19. google_workspace_mcp/services/base.py +73 -0
  20. google_workspace_mcp/services/calendar.py +256 -0
  21. google_workspace_mcp/services/docs_service.py +388 -0
  22. google_workspace_mcp/services/drive.py +454 -0
  23. google_workspace_mcp/services/gmail.py +676 -0
  24. google_workspace_mcp/services/sheets_service.py +466 -0
  25. google_workspace_mcp/services/slides.py +959 -0
  26. google_workspace_mcp/tools/__init__.py +7 -0
  27. google_workspace_mcp/tools/calendar.py +229 -0
  28. google_workspace_mcp/tools/docs_tools.py +277 -0
  29. google_workspace_mcp/tools/drive.py +221 -0
  30. google_workspace_mcp/tools/gmail.py +344 -0
  31. google_workspace_mcp/tools/sheets_tools.py +322 -0
  32. google_workspace_mcp/tools/slides.py +478 -0
  33. google_workspace_mcp/utils/__init__.py +1 -0
  34. google_workspace_mcp/utils/markdown_slides.py +504 -0
  35. google_workspace_mcp-1.0.0.dist-info/METADATA +547 -0
  36. google_workspace_mcp-1.0.0.dist-info/RECORD +38 -0
  37. google_workspace_mcp-1.0.0.dist-info/WHEEL +4 -0
  38. google_workspace_mcp-1.0.0.dist-info/entry_points.txt +2 -0
@@ -0,0 +1,547 @@
1
+ Metadata-Version: 2.4
2
+ Name: google-workspace-mcp
3
+ Version: 1.0.0
4
+ Summary: MCP server for Google Workspace integration
5
+ Author-email: Arclio Team <info@arclio.com>
6
+ License: MIT
7
+ Requires-Python: >=3.10
8
+ Requires-Dist: beautifulsoup4>=4.12.0
9
+ Requires-Dist: google-api-python-client>=2.86.0
10
+ Requires-Dist: google-auth-httplib2>=0.1.0
11
+ Requires-Dist: google-auth-oauthlib>=1.0.0
12
+ Requires-Dist: google-auth>=2.22.0
13
+ Requires-Dist: markdown>=3.5.0
14
+ Requires-Dist: markdowndeck>=0.1.0
15
+ Requires-Dist: mcp>=1.7.0
16
+ Requires-Dist: python-dotenv>=1.0.0
17
+ Requires-Dist: pytz>=2023.3
18
+ Provides-Extra: dev
19
+ Description-Content-Type: text/markdown
20
+
21
+ # Google Workspace MCP
22
+
23
+ <div align="center">
24
+
25
+ **Google Workspace integration for AI assistants via Model Context Protocol (MCP)**
26
+
27
+ [![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
28
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
29
+
30
+ _Developed and maintained by [Arclio](https://arclio.com)_ - _Secure MCP service management for AI applications_
31
+
32
+ </div>
33
+
34
+ ---
35
+
36
+ ## 🚀 Quick Start
37
+
38
+ Test the server immediately using the Model Context Protocol (MCP) Inspector, or install and run it directly.
39
+
40
+ ### Option 1: Instant Setup with MCP Inspector (Recommended for Testing)
41
+
42
+ ```bash
43
+ npx @modelcontextprotocol/inspector \
44
+ -e GOOGLE_WORKSPACE_CLIENT_ID="your-client-id.apps.googleusercontent.com" \
45
+ -e GOOGLE_WORKSPACE_CLIENT_SECRET="your-client-secret" \
46
+ -e GOOGLE_WORKSPACE_REFRESH_TOKEN="your-refresh-token" \
47
+ -e GOOGLE_WORKSPACE_ENABLED_CAPABILITIES='["drive", "docs", "gmail", "calendar", "sheets", "slides"]' \
48
+ -- \
49
+ uvx --from google-workspace-mcp google-workspace-worker
50
+ ```
51
+
52
+ Replace placeholder credentials with your actual values.
53
+
54
+ ### Option 2: Direct Installation & Usage
55
+
56
+ 1. **Install the package:**
57
+
58
+ ```bash
59
+ pip install google-workspace-mcp
60
+ ```
61
+
62
+ 2. **Set Environment Variables:**
63
+
64
+ ```bash
65
+ export GOOGLE_WORKSPACE_CLIENT_ID="your-client-id.apps.googleusercontent.com"
66
+ export GOOGLE_WORKSPACE_CLIENT_SECRET="your-client-secret"
67
+ export GOOGLE_WORKSPACE_REFRESH_TOKEN="your-refresh-token"
68
+ export GOOGLE_WORKSPACE_ENABLED_CAPABILITIES='["drive", "docs", "gmail", "calendar", "sheets", "slides"]'
69
+ # Optional: For development/integration testing
70
+ # export RUN_INTEGRATION_TESTS="1"
71
+ ```
72
+
73
+ 3. **Run the MCP Server:**
74
+
75
+ ```bash
76
+ google-workspace-worker
77
+ ```
78
+
79
+ ### Option 3: Using `uvx` (Run without full installation)
80
+
81
+ ```bash
82
+ # Ensure GOOGLE_WORKSPACE_* environment variables are set as shown above
83
+ uvx --from google-workspace-mcp google-workspace-worker
84
+ ```
85
+
86
+ ## 📋 Overview
87
+
88
+ `google-workspace-mcp` is a Python package that enables AI models to interact with Google Workspace services (Drive, Docs, Gmail, Calendar, Sheets, and Slides) through the Model Context Protocol (MCP). It acts as a secure and standardized bridge, allowing AI assistants to leverage Google Workspace functionalities without direct API credential exposure.
89
+
90
+ ### What is MCP?
91
+
92
+ The Model Context Protocol (MCP) provides a standardized interface for AI models to discover and utilize external tools and services. This package implements an MCP server that exposes Google Workspace capabilities as discrete, callable "tools."
93
+
94
+ ### Key Benefits
95
+
96
+ - **AI-Ready Integration**: Purpose-built for AI assistants to naturally interact with Google Workspace.
97
+ - **Standardized Protocol**: Ensures seamless integration with MCP-compatible AI systems and hubs.
98
+ - **Enhanced Security**: Google API credentials remain on the server, isolated from the AI models.
99
+ - **Comprehensive Capabilities**: Offers a wide range of tools across core Google Workspace services.
100
+ - **Robust Error Handling**: Provides consistent error patterns for reliable operation.
101
+ - **Extensive Testing**: Underpinned by a comprehensive test suite for correctness and stability.
102
+
103
+ ## 🔑 Authentication Setup
104
+
105
+ Accessing Google Workspace APIs requires OAuth 2.0 credentials.
106
+
107
+ ### Step 1: Google Cloud Console Setup
108
+
109
+ 1. Navigate to the [Google Cloud Console](https://console.cloud.google.com/).
110
+ 2. Create a new project or select an existing one.
111
+ 3. Enable the following APIs for your project:
112
+ - Google Drive API
113
+ - Gmail API
114
+ - Google Calendar API
115
+ - Google Docs API
116
+ - Google Sheets API
117
+ - Google Slides API
118
+ 4. Go to "APIs & Services" -\> "Credentials".
119
+ 5. Click "Create Credentials" -\> "OAuth 2.0 Client ID".
120
+ 6. Select "Web application" as the application type.
121
+ 7. Under "Authorized redirect URIs", add `https://developers.google.com/oauthplayground` (for easy refresh token generation) and any other URIs required for your specific setup (e.g., `http://localhost:8080/callback` if using the Python script method locally).
122
+ 8. Note your `Client ID` and `Client Secret`.
123
+
124
+ ### Step 2: Obtain a Refresh Token
125
+
126
+ **Option A: Using OAuth 2.0 Playground (Recommended)**
127
+
128
+ 1. Go to the [OAuth 2.0 Playground](https://developers.google.com/oauthplayground/).
129
+ 2. Click the gear icon (⚙️) in the top right corner.
130
+ 3. Check the box "Use your own OAuth credentials."
131
+ 4. Enter the `Client ID` and `Client Secret` obtained from the Google Cloud Console.
132
+ 5. In "Step 1: Select & authorize APIs", input the following scopes (or select them from the list):
133
+ - `https://www.googleapis.com/auth/drive`
134
+ - `https://www.googleapis.com/auth/gmail.modify` (includes send, read, delete)
135
+ - `https://www.googleapis.com/auth/calendar`
136
+ - `https://www.googleapis.com/auth/docs`
137
+ - `https://www.googleapis.com/auth/spreadsheets`
138
+ - `https://www.googleapis.com/auth/presentations`
139
+ 6. Click "Authorize APIs." You will be prompted to sign in with the Google account you want the MCP server to act on behalf of and grant permissions.
140
+ 7. After authorization, you'll be redirected back. In "Step 2: Exchange authorization code for tokens," click "Exchange authorization code for tokens."
141
+ 8. Copy the `Refresh token` displayed.
142
+
143
+ **Option B: Using a Python Script (Advanced)**
144
+ You can adapt a Python script using the `google-auth-oauthlib` library to perform the OAuth flow and retrieve a refresh token. Ensure your script uses the correct client ID, client secret, redirect URI, and scopes as listed above.
145
+
146
+ ### Step 3: Configure Environment Variables
147
+
148
+ The MCP server requires the following environment variables to be set:
149
+
150
+ ```bash
151
+ # Essential for authentication
152
+ export GOOGLE_WORKSPACE_CLIENT_ID="your-client-id.apps.googleusercontent.com"
153
+ export GOOGLE_WORKSPACE_CLIENT_SECRET="your-client-secret"
154
+ export GOOGLE_WORKSPACE_REFRESH_TOKEN="your-refresh-token"
155
+
156
+ # Controls which services are active (see "Capabilities Configuration" below)
157
+ export GOOGLE_WORKSPACE_ENABLED_CAPABILITIES='["drive", "docs", "gmail", "calendar", "sheets", "slides"]'
158
+ ```
159
+
160
+ ## ⚙️ Capabilities Configuration
161
+
162
+ The `GOOGLE_WORKSPACE_ENABLED_CAPABILITIES` environment variable dictates which Google Workspace services are active and discoverable by AI models. It **must** be a JSON-formatted array of strings.
163
+
164
+ **Format Examples:**
165
+
166
+ ```bash
167
+ # Enable all currently supported services
168
+ export GOOGLE_WORKSPACE_ENABLED_CAPABILITIES='["drive", "docs", "gmail", "calendar", "sheets", "slides"]'
169
+
170
+ # Enable a subset of services
171
+ export GOOGLE_WORKSPACE_ENABLED_CAPABILITIES='["drive", "gmail", "calendar"]'
172
+
173
+ # Enable a single service
174
+ export GOOGLE_WORKSPACE_ENABLED_CAPABILITIES='["docs"]'
175
+
176
+ # Disable all services (server will run but offer no tools)
177
+ export GOOGLE_WORKSPACE_ENABLED_CAPABILITIES='[]'
178
+ ```
179
+
180
+ **Available Capability Values:**
181
+
182
+ - `"drive"`: Google Drive (file search, read, creation, etc.)
183
+ - `"docs"`: Google Docs (document creation, metadata, content operations)
184
+ - `"gmail"`: Gmail (email query, read, send, draft management, etc.)
185
+ - `"calendar"`: Google Calendar (event retrieval, creation, deletion)
186
+ - `"sheets"`: Google Sheets (spreadsheet creation, data read/write operations)
187
+ - `"slides"`: Google Slides (presentation creation from Markdown, slide listing)
188
+
189
+ **Important Notes:**
190
+
191
+ - The value **must** be a valid JSON array string. In bash, it's best to enclose the JSON string in single quotes.
192
+ - Service names within the array are case-insensitive but lowercase is conventional.
193
+ - An invalid JSON string or a JSON type other than an array will result in a warning, and the server may effectively disable all tools.
194
+ - If the `GOOGLE_WORKSPACE_ENABLED_CAPABILITIES` variable is not set, it defaults to an empty list (`"[]"`), meaning no services will be enabled by default.
195
+
196
+ ## 🛠️ Exposed Capabilities (Tools & Resources)
197
+
198
+ This package exposes a variety of tools and resources for AI interaction.
199
+
200
+ ### Google Drive Tools
201
+
202
+ - **`drive_search_files`**: Searches files in Google Drive.
203
+ - `query` (string): Drive query string.
204
+ - `page_size` (integer, optional): Max files to return.
205
+ - `shared_drive_id` (string, optional): ID of a shared drive to search within.
206
+ - **`drive_read_file_content`**: Reads content of a file.
207
+ - `file_id` (string): The ID of the file.
208
+ - **`drive_create_folder`**: Creates a new folder.
209
+ - `folder_name` (string): Name of the new folder.
210
+ - `parent_folder_id` (string, optional): ID of the parent folder.
211
+ - `shared_drive_id` (string, optional): ID of a shared drive.
212
+ - **`drive_list_shared_drives`**: Lists shared drives accessible by the user.
213
+ - `page_size` (integer, optional): Max shared drives to return.
214
+ - **`drive_upload_file`**: Uploads a local file to Google Drive. (Requires server access to the file path)
215
+ - `file_path` (string): Local path to the file.
216
+ - **`drive_delete_file`**: Deletes a file from Google Drive.
217
+ - `file_id` (string): The ID of the file to delete.
218
+
219
+ ### Google Drive Resources
220
+
221
+ - `drive://files/{file_id}/metadata`: Get metadata for a specific file.
222
+ - `drive://files/recent` or `drive://recent`: Get recently modified files. _(Note: `drive://recent` is the primary)_
223
+ - `drive://files/shared_with_me` or `drive://shared`: Get files shared with the user. _(Note: `drive://shared` is the primary)_
224
+
225
+ ### Google Docs Tools
226
+
227
+ - **`docs_create_document`**: Creates a new document.
228
+ - `title` (string): Title for the new document.
229
+ - **`docs_get_document_metadata`**: Retrieves metadata for a document.
230
+ - `document_id` (string): The ID of the document.
231
+ - **`docs_get_content_as_markdown`**: Retrieves document content as Markdown.
232
+ - `document_id` (string): The ID of the document.
233
+ - **`docs_append_text`**: Appends text to a document.
234
+ - `document_id` (string): The ID of the document.
235
+ - `text` (string): Text to append.
236
+ - `ensure_newline` (boolean, optional): Prepend a newline if document is not empty (default: True).
237
+ - **`docs_prepend_text`**: Prepends text to a document.
238
+ - `document_id` (string): The ID of the document.
239
+ - `text` (string): Text to prepend.
240
+ - `ensure_newline` (boolean, optional): Append a newline if document was not empty (default: True).
241
+ - **`docs_insert_text`**: Inserts text at a specific location.
242
+ - `document_id` (string): The ID of the document.
243
+ - `text` (string): Text to insert.
244
+ - `index` (integer, optional): 0-based index for insertion.
245
+ - `segment_id` (string, optional): Segment ID (e.g., header).
246
+ - **`docs_batch_update`**: Applies a list of raw Google Docs API update requests (advanced).
247
+ - `document_id` (string): The ID of the document.
248
+ - `requests` (list[dict]): List of Docs API request objects.
249
+
250
+ ### Gmail Tools
251
+
252
+ - **`query_gmail_emails`**: Searches emails using Gmail query syntax.
253
+ - `query` (string): Gmail search query.
254
+ - `max_results` (integer, optional): Maximum emails to return.
255
+ - **`gmail_get_message_details`**: Retrieves a complete email message.
256
+ - `email_id` (string): The ID of the Gmail message.
257
+ - **`gmail_get_attachment_content`**: Retrieves a specific email attachment.
258
+ - `message_id` (string): The ID of the email message.
259
+ - `attachment_id` (string): The ID of the attachment.
260
+ - **`create_gmail_draft`**: Creates a draft email.
261
+ - `to` (string): Recipient's email address.
262
+ - `subject` (string): Email subject.
263
+ - `body` (string): Email body content.
264
+ - `cc` (list[string], optional): CC recipients.
265
+ - `bcc` (list[string], optional): BCC recipients.
266
+ - **`delete_gmail_draft`**: Deletes a draft email.
267
+ - `draft_id` (string): The ID of the draft.
268
+ - **`gmail_send_draft`**: Sends an existing draft.
269
+ - `draft_id` (string): The ID of the draft.
270
+ - **`gmail_send_email`**: Composes and sends an email directly.
271
+ - `to` (list[string]): Primary recipients.
272
+ - `subject` (string): Email subject.
273
+ - `body` (string): Email body content.
274
+ - `cc` (list[string], optional): CC recipients.
275
+ - `bcc` (list[string], optional): BCC recipients.
276
+ - **`gmail_reply_to_email`**: Creates a reply to an email (saves as draft by default).
277
+ - `email_id` (string): ID of the message to reply to.
278
+ - `reply_body` (string): Content of the reply.
279
+ - `send` (boolean, optional): Send immediately if true (default: False, creates draft).
280
+ - `reply_all` (boolean, optional): Reply to all recipients if true (default: False).
281
+ - **`gmail_bulk_delete_messages`**: Deletes multiple emails.
282
+ - `message_ids` (list[string]): List of email message IDs.
283
+
284
+ ### Gmail Resources
285
+
286
+ - `gmail://labels`: List all Gmail labels.
287
+ - `gmail://unread_count`: Get count of unread emails in the inbox.
288
+ - _(Search functionality is primarily handled by the `query_gmail_emails` tool)_
289
+
290
+ ### Google Calendar Tools
291
+
292
+ - **`calendar_get_events`**: Retrieves events within a time range.
293
+ - `time_min` (string): Start time (RFC3339).
294
+ - `time_max` (string): End time (RFC3339).
295
+ - `calendar_id` (string, optional): Calendar ID (default: "primary").
296
+ - `max_results` (integer, optional): Max events.
297
+ - `show_deleted` (boolean, optional): Include deleted events.
298
+ - **`calendar_get_event_details`**: Retrieves details for a specific event.
299
+ - `event_id` (string): The ID of the event.
300
+ - `calendar_id` (string, optional): Calendar ID (default: "primary").
301
+ - **`Calendar`**: Creates a new event.
302
+ - `summary` (string): Event title.
303
+ - `start_time` (string): Start time (RFC3339).
304
+ - `end_time` (string): End time (RFC3339).
305
+ - `calendar_id` (string, optional): Calendar ID (default: "primary").
306
+ - `attendees` (list[string], optional): Attendee emails.
307
+ - _(Other optional parameters: `location`, `description`, `send_notifications`, `timezone`)_
308
+ - **`delete_calendar_event`**: Deletes an event.
309
+ - `event_id` (string): The ID of the event.
310
+ - `calendar_id` (string, optional): Calendar ID (default: "primary").
311
+ - `send_notifications` (boolean, optional): Notify attendees.
312
+
313
+ ### Google Calendar Resources
314
+
315
+ - `calendar://calendars/list`: Lists all accessible calendars.
316
+ - `calendar://events/today`: Get all events for today from the primary calendar.
317
+
318
+ ### Google Sheets Tools
319
+
320
+ - **`sheets_create_spreadsheet`**: Creates a new spreadsheet.
321
+ - `title` (string): Title for the new spreadsheet.
322
+ - **`sheets_read_range`**: Reads data from a range.
323
+ - `spreadsheet_id` (string): The ID of the spreadsheet.
324
+ - `range_a1` (string): Range in A1 notation (e.g., "Sheet1\!A1:C5").
325
+ - **`sheets_write_range`**: Writes data to a range.
326
+ - `spreadsheet_id` (string): The ID of the spreadsheet.
327
+ - `range_a1` (string): Range in A1 notation.
328
+ - `values` (list[list]): Data to write (list of rows, where each row is a list of cell values).
329
+ - `value_input_option` (string, optional): "USER_ENTERED" or "RAW" (default: "USER_ENTERED").
330
+ - **`sheets_append_rows`**: Appends rows to a sheet/table.
331
+ - `spreadsheet_id` (string): The ID of the spreadsheet.
332
+ - `range_a1` (string): Sheet or table range (e.g., "Sheet1").
333
+ - `values` (list[list]): Data rows to append.
334
+ - `value_input_option` (string, optional): "USER_ENTERED" or "RAW" (default: "USER_ENTERED").
335
+ - `insert_data_option` (string, optional): "INSERT_ROWS" or "OVERWRITE" (default: "INSERT_ROWS").
336
+ - **`sheets_clear_range`**: Clears values from a range.
337
+ - `spreadsheet_id` (string): The ID of the spreadsheet.
338
+ - `range_a1` (string): Range to clear.
339
+ - **`sheets_add_sheet`**: Adds a new sheet (tab).
340
+ - `spreadsheet_id` (string): The ID of the spreadsheet.
341
+ - `title` (string): Title for the new sheet.
342
+ - **`sheets_delete_sheet`**: Deletes a sheet.
343
+ - `spreadsheet_id` (string): The ID of the spreadsheet.
344
+ - `sheet_id` (integer): Numeric ID of the sheet to delete.
345
+
346
+ ### Google Sheets Resources
347
+
348
+ - `sheets://spreadsheets/{spreadsheet_id}/metadata`: Retrieves metadata for a specific Google Spreadsheet.
349
+ - `sheets://spreadsheets/{spreadsheet_id}/sheets/{sheet_identifier}/metadata`: Retrieves metadata for a specific sheet within a spreadsheet (identified by name or numeric ID).
350
+
351
+ ### Google Slides Tools
352
+
353
+ - **`create_presentation_from_markdown`**: Creates a presentation from Markdown content using the `markdowndeck` library. This is the primary tool for complex slide creation.
354
+ - `title` (string): Title for the new presentation.
355
+ - `markdown_content` (string): Markdown content. Refer to the `slides://markdown_formatting_guide` resource for syntax.
356
+ - **`get_presentation`**: Retrieves presentation details.
357
+ - `presentation_id` (string): The ID of the presentation.
358
+ - **`get_slides`**: Lists all slides in a presentation with their elements.
359
+ - `presentation_id` (string): The ID of the presentation.
360
+ - _(Other granular slide manipulation tools like `create_slide`, `add_text_to_slide`, `delete_slide` are available but are expected to be superseded by enhanced `markdowndeck` functionality in future updates.)_
361
+
362
+ ### Google Slides Resources
363
+
364
+ - `slides://markdown_formatting_guide`: Comprehensive guide on formatting Markdown for slide creation using the `markdowndeck` library.
365
+
366
+ ## 🏗️ Architecture
367
+
368
+ The `google-workspace-mcp` package is structured as follows:
369
+
370
+ ```
371
+ google-workspace-mcp/
372
+ └── src/
373
+ └── google_workspace_mcp/
374
+ ├── __init__.py # Package initializer
375
+ ├── __main__.py # Main entry point for the worker, registers components
376
+ ├── app.py # Central FastMCP application instance
377
+ ├── config.py # Configuration (e.g., GOOGLE_WORKSPACE_ENABLED_CAPABILITIES)
378
+ ├── auth/ # Authentication logic
379
+ │ └── gauth.py
380
+ ├── services/ # Modules interacting directly with Google APIs
381
+ │ ├── base.py # BaseGoogleService class
382
+ │ ├── drive.py
383
+ │ ├── docs_service.py
384
+ │ ├── gmail.py
385
+ │ ├── calendar.py
386
+ │ ├── sheets_service.py
387
+ │ └── slides.py
388
+ ├── tools/ # MCP Tool definitions
389
+ │ ├── drive_tools.py
390
+ │ ├── docs_tools.py
391
+ │ ├── gmail_tools.py
392
+ │ ├── calendar_tools.py
393
+ │ ├── sheets_tools.py
394
+ │ └── slides_tools.py
395
+ ├── resources/ # MCP Resource definitions
396
+ │ ├── drive.py
397
+ │ ├── gmail.py
398
+ │ ├── calendar.py
399
+ │ ├── sheets_resources.py
400
+ │ └── slides.py
401
+ └── prompts/ # MCP Prompt definitions (for LLM interaction patterns)
402
+ ├── drive.py
403
+ ├── gmail.py
404
+ ├── calendar.py
405
+ └── slides.py
406
+ ```
407
+
408
+ **Execution Flow:**
409
+
410
+ 1. An MCP Hub (or a tool like MCP Inspector) starts the `google-workspace-worker` process.
411
+ 2. `google_workspace_mcp.__main__.py` is executed. Importing modules from `tools/`, `resources/`, and `prompts/` causes the components (decorated with `@mcp.tool`, `@mcp.resource`, `@mcp.prompt`) to register themselves with the central `FastMCP` instance defined in `app.py`.
412
+ 3. The MCP server listens for requests (typically over stdio).
413
+ 4. Upon a discovery request, the server lists available tools/resources based on `GOOGLE_WORKSPACE_ENABLED_CAPABILITIES`.
414
+ 5. Upon a tool/resource call:
415
+ - The `FastMCP` server routes the request to the appropriate handler function in the `tools/` or `resources/` modules.
416
+ - The handler function validates arguments and calls methods on the relevant service class in `services/`.
417
+ - The service class interacts with the Google API, handling authentication (via `auth/gauth.py`) and error translation.
418
+ - Results are returned to the AI model via the MCP Hub.
419
+
420
+ ## 🧩 Development
421
+
422
+ ### Setup Development Environment
423
+
424
+ Ensure you are in the root of the `arclio-mcp-tooling` monorepo.
425
+
426
+ ```bash
427
+ # From the monorepo root
428
+ make setup-dev # Installs uv and sets up the virtual environment
429
+
430
+ # Install this package and its dependencies in editable mode
431
+ make install google-workspace-mcp
432
+ ```
433
+
434
+ ### Environment Variables for Development
435
+
436
+ Copy `.env.example` (if available in the package or monorepo root) to `.env` and populate it with your Google Cloud credentials and desired enabled capabilities.
437
+
438
+ ```bash
439
+ # Example:
440
+ # GOOGLE_WORKSPACE_CLIENT_ID="your-client-id.apps.googleusercontent.com"
441
+ # ... other variables ...
442
+ ```
443
+
444
+ Source the `.env` file before running the server locally: `source .env`
445
+
446
+ ### Adding New Tools or Resources (FastMCP Pattern)
447
+
448
+ 1. **Define the function** in the appropriate module within `tools/` or `resources/`.
449
+ 2. **Decorate it**: Use `@mcp.tool(...)` or `@mcp.resource(...)`.
450
+ - Provide `name` and `description`.
451
+ - Type hints in the function signature are used by `FastMCP` to generate the input schema.
452
+ 3. **Implement Logic**: The function should call the relevant service method.
453
+ 4. **Register**: Ensure the module containing the new tool/resource is imported in `google_workspace_mcp/__main__.py` (this is how `FastMCP` discovers it).
454
+
455
+ **Example Tool Definition:**
456
+
457
+ ```python
458
+ # In google_workspace_mcp/tools/your_new_tools.py
459
+ from google_workspace_mcp.app import mcp
460
+ from ..services.your_service import YourService # Assuming YourService exists
461
+
462
+ @mcp.tool(
463
+ name="your_service_action_name",
464
+ description="A brief description of what this tool does."
465
+ )
466
+ async def your_tool_function(parameter1: str, count: int = 5) -> dict:
467
+ """
468
+ More detailed docstring for your tool.
469
+ Args:
470
+ parameter1: Description of the first parameter.
471
+ count: Description of the optional count parameter.
472
+ Returns:
473
+ A dictionary containing the result of the operation.
474
+ """
475
+ # ... (input validation if needed beyond type hints)
476
+ service = YourService()
477
+ result = service.perform_action(param1=parameter1, num_items=count)
478
+ # ... (handle service result, raise ValueError on error, or return data)
479
+ return {"status": "success", "data": result}
480
+ ```
481
+
482
+ Remember to add a corresponding import in `google_workspace_mcp/__main__.py` for `your_new_tools`.
483
+
484
+ ### Running Tests
485
+
486
+ From the `arclio-mcp-tooling` monorepo root:
487
+
488
+ ```bash
489
+ # Run all tests for this package
490
+ make test google-workspace-mcp
491
+
492
+ # Run only unit tests for this package
493
+ make test-unit google-workspace-mcp
494
+
495
+ # Run integration tests for this package (ensure RUN_INTEGRATION_TESTS=1 is set in your environment)
496
+ export RUN_INTEGRATION_TESTS=1
497
+ make test-integration google-workspace-mcp
498
+ ```
499
+
500
+ ### Code Quality
501
+
502
+ From the `arclio-mcp-tooling` monorepo root:
503
+
504
+ ```bash
505
+ # Run linting (Ruff)
506
+ make lint
507
+
508
+ # Attempt to auto-fix linting issues
509
+ make fix
510
+
511
+ # Format code (Ruff Formatter)
512
+ make format
513
+ ```
514
+
515
+ ## 🔍 Troubleshooting
516
+
517
+ - **Authentication Errors**:
518
+ - Double-check `GOOGLE_WORKSPACE_CLIENT_ID`, `GOOGLE_WORKSPACE_CLIENT_SECRET`, and `GOOGLE_WORKSPACE_REFRESH_TOKEN`.
519
+ - Ensure the refresh token is valid and has not been revoked.
520
+ - Verify all required API scopes were granted during the OAuth flow.
521
+ - **Tool Not Found / Capability Disabled**:
522
+ - Confirm the desired service (e.g., `"drive"`) is included in the `GOOGLE_WORKSPACE_ENABLED_CAPABILITIES` JSON array in your environment.
523
+ - Check server logs for warnings about invalid capability configurations.
524
+ - **API Errors (403 Permission Denied, 404 Not Found, etc.)**:
525
+ - Ensure the authenticated Google account has the necessary permissions for the attempted operation on the specific resource (e.g., file access, calendar edit rights).
526
+ - Verify that the correct Google APIs are enabled in your Google Cloud Project.
527
+ - **Rate Limits**: Be mindful of Google API rate limits. If you encounter frequent 403 or 429 errors related to quotas, you may need to implement retry logic with backoff or request a quota increase from Google.
528
+
529
+ For detailed debugging, inspect the server's stdout/stderr logs.
530
+
531
+ ## 📝 Contributing
532
+
533
+ Contributions are welcome\! Please refer to the main `README.md` in the `arclio-mcp-tooling` monorepo for guidelines on contributing, setting up the development environment, and project-wide commands.
534
+
535
+ ## 📄 License
536
+
537
+ This package is licensed under the MIT License. See the `LICENSE` file in the monorepo root for full details.
538
+
539
+ ## 🏢 About Arclio
540
+
541
+ [Arclio](https://arclio.com) provides secure and robust Model Context Protocol (MCP) solutions, enabling AI applications to safely and effectively interact with enterprise systems and external services.
542
+
543
+ ---
544
+
545
+ <div align="center">
546
+ <p>Built with ❤️ by the Arclio team</p>
547
+ </div>
@@ -0,0 +1,38 @@
1
+ google_workspace_mcp/__init__.py,sha256=CppIQ682LvBlR1IPwBOsryB6rk-P4tDy9bPK1OYtUmM,109
2
+ google_workspace_mcp/__main__.py,sha256=O-RkpnVPmcUCUvYOLq7FhBppSA0tfR1J3nURu9s3iTI,1464
3
+ google_workspace_mcp/app.py,sha256=ajasCHBQ8dWiBoLKDibrkj6SsGyt1pNupwQO9fcsZzE,160
4
+ google_workspace_mcp/config.py,sha256=DNac38UANs0A2RX4fTi1sMaJ5mTrOaaWnPEusL6Id_M,2578
5
+ google_workspace_mcp/auth/__init__.py,sha256=4SNTCWZqUJGn20vj8j5WekpwNnm87-KeiKFfOGG4b1M,126
6
+ google_workspace_mcp/auth/gauth.py,sha256=2-djqz3hb6_QIhgcUTk9vxBlVH3pCjQYz_pPqOogf2E,2355
7
+ google_workspace_mcp/prompts/__init__.py,sha256=BG6Ol0ZgE5e85jHOd6MlvpbqkNwhRcuZaEGpDvjEvi4,61
8
+ google_workspace_mcp/prompts/calendar.py,sha256=i85Z9ZmyHkwkSwNA42lrwJn8MMtUvW0cpqfpEIQgA8s,1596
9
+ google_workspace_mcp/prompts/drive.py,sha256=_9xFFPramm3SZ7GPxq8n2uVTxuwqgTJunN6V3A7psqY,546
10
+ google_workspace_mcp/prompts/gmail.py,sha256=oUxZ6xbweDp6HljSQ_JMWp63hPGkE8a0LiFOzhEgrSo,2942
11
+ google_workspace_mcp/prompts/slides.py,sha256=vNz81CflWYLPZicdBuWFoEePFgadPyEMC2zrWeINWGI,1290
12
+ google_workspace_mcp/resources/__init__.py,sha256=syHSNoDe8OTBns_eTbQYvEbU-0fBuwopbgfT13nD_Fs,355
13
+ google_workspace_mcp/resources/calendar.py,sha256=j5PQ2Cdf0z3_5JFyh1FXDISsdve1peyaZJyICRHn51g,2178
14
+ google_workspace_mcp/resources/drive.py,sha256=rFQtoT7qz5OM5sErgrN5HfX7IlQyrfsmjpY9Qv3AFwE,2615
15
+ google_workspace_mcp/resources/gmail.py,sha256=gIIZkpZC4gS1-Zit2TPJIs-TrSPlAyS8F1Hl_fYbnbM,1557
16
+ google_workspace_mcp/resources/sheets_resources.py,sha256=AuNbR3uKMHhzYFBGZF9Nx0g8MMOS4g1ctuJuAuC0gxo,3183
17
+ google_workspace_mcp/resources/slides.py,sha256=m2KVCYUOJ9uKMVWXXw9lXNem3OFT438X04UxZ7IUZJo,14233
18
+ google_workspace_mcp/services/__init__.py,sha256=crw4YinYFi7QDfJZUCcUqPliRtlViSE7QSqAX8j33eE,473
19
+ google_workspace_mcp/services/base.py,sha256=uLtFB158kaY_n3JWKgW2kxQ2tx9SP9zxX-PWuPxydFI,2378
20
+ google_workspace_mcp/services/calendar.py,sha256=KfclfXF_70MWEhMsDpjlTtoLHSgx2lpXMy78PtRqsuc,8510
21
+ google_workspace_mcp/services/docs_service.py,sha256=KRNn4iAjeQJjC3loR3zCQQ-RV7S6-qaWwaT_SvT4onk,17297
22
+ google_workspace_mcp/services/drive.py,sha256=225UEdUbiN4odduQVK0CkFLEyz_QNxgPOkoMFQbSfxM,16803
23
+ google_workspace_mcp/services/gmail.py,sha256=M6trjL9uFOe5WnBORyic4Y7lU4Z0X9VnEq-yU7RY-No,24846
24
+ google_workspace_mcp/services/sheets_service.py,sha256=1jx-X6loVvGss9aWDOU320H4yNuAiMl9e5bj0SQ3MB4,19327
25
+ google_workspace_mcp/services/slides.py,sha256=qfXh6GBr2JkCGPgVmwvV4NapLlzF7A1_WlYQR8EXMEE,37310
26
+ google_workspace_mcp/tools/__init__.py,sha256=vwa7hV8HwrLqs3Sf7RTrt1MlVZ-KjptXuFDSJt5tWzA,107
27
+ google_workspace_mcp/tools/calendar.py,sha256=KX42ZHNMcO69GuU-Re-37HY1Kk0jGM0dwUSrkexi_So,7890
28
+ google_workspace_mcp/tools/docs_tools.py,sha256=_ZtsIfrXxpVp1Vyzf7B5IK1UaXaLjUxYY4Yd09J04tE,10511
29
+ google_workspace_mcp/tools/drive.py,sha256=CcGYf0itebp60L-WzXQlf2eOoDLN7Un4q_6-unH3O0g,6802
30
+ google_workspace_mcp/tools/gmail.py,sha256=nkbN6IC8yhSxrNwxUVRh9qAakomKJjGP4-MEKJoTnpA,11269
31
+ google_workspace_mcp/tools/sheets_tools.py,sha256=8_9x_d0xfdqIgDJrkYzEG9vTjM3p-41Y7plL4OIXxBo,12064
32
+ google_workspace_mcp/tools/slides.py,sha256=GTtkIaQf6GMtzaxu8wlAemWcY5n5Y6RMEwWILPoiMFo,15382
33
+ google_workspace_mcp/utils/__init__.py,sha256=jKEfO2DhR_lwsRSoUgceixDwzkGVlp_vmbrz_6AHOk0,50
34
+ google_workspace_mcp/utils/markdown_slides.py,sha256=G7EbK3DDki90hNilGzbczs2e345v-HjYB5GWhFbEtw4,21015
35
+ google_workspace_mcp-1.0.0.dist-info/METADATA,sha256=xUWuwmjmrDyVq02YR-agigi2U9D6pNGojXW1s-7Ht5c,25104
36
+ google_workspace_mcp-1.0.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
37
+ google_workspace_mcp-1.0.0.dist-info/entry_points.txt,sha256=t9eBYTnGzEBpiiRx_SCTqforubwM6Ebf5mszIj-MjeA,79
38
+ google_workspace_mcp-1.0.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.27.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ google-workspace-worker = google_workspace_mcp.__main__:main