workspace-mcp 1.1.3__tar.gz → 1.1.5__tar.gz
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.
- {workspace_mcp-1.1.3 → workspace_mcp-1.1.5}/PKG-INFO +79 -17
- {workspace_mcp-1.1.3 → workspace_mcp-1.1.5}/README.md +78 -16
- {workspace_mcp-1.1.3 → workspace_mcp-1.1.5}/auth/google_auth.py +6 -8
- {workspace_mcp-1.1.3 → workspace_mcp-1.1.5}/auth/oauth_callback_server.py +22 -8
- {workspace_mcp-1.1.3 → workspace_mcp-1.1.5}/auth/scopes.py +10 -1
- {workspace_mcp-1.1.3 → workspace_mcp-1.1.5}/auth/service_decorator.py +8 -2
- {workspace_mcp-1.1.3 → workspace_mcp-1.1.5}/core/server.py +4 -1
- workspace_mcp-1.1.5/gTasks/__init__.py +5 -0
- workspace_mcp-1.1.5/gTasks/tasks_tools.py +732 -0
- {workspace_mcp-1.1.3 → workspace_mcp-1.1.5}/gcalendar/calendar_tools.py +1 -1
- {workspace_mcp-1.1.3 → workspace_mcp-1.1.5}/gdocs/docs_tools.py +0 -1
- {workspace_mcp-1.1.3 → workspace_mcp-1.1.5}/gforms/forms_tools.py +17 -18
- {workspace_mcp-1.1.3 → workspace_mcp-1.1.5}/gmail/gmail_tools.py +0 -1
- {workspace_mcp-1.1.3 → workspace_mcp-1.1.5}/main.py +6 -4
- {workspace_mcp-1.1.3 → workspace_mcp-1.1.5}/pyproject.toml +2 -2
- workspace_mcp-1.1.5/tests/test_oauth_callback_server.py +39 -0
- {workspace_mcp-1.1.3 → workspace_mcp-1.1.5}/workspace_mcp.egg-info/PKG-INFO +79 -17
- {workspace_mcp-1.1.3 → workspace_mcp-1.1.5}/workspace_mcp.egg-info/SOURCES.txt +5 -0
- {workspace_mcp-1.1.3 → workspace_mcp-1.1.5}/workspace_mcp.egg-info/top_level.txt +1 -0
- {workspace_mcp-1.1.3 → workspace_mcp-1.1.5}/LICENSE +0 -0
- {workspace_mcp-1.1.3 → workspace_mcp-1.1.5}/auth/__init__.py +0 -0
- {workspace_mcp-1.1.3 → workspace_mcp-1.1.5}/auth/oauth_responses.py +0 -0
- {workspace_mcp-1.1.3 → workspace_mcp-1.1.5}/core/__init__.py +0 -0
- {workspace_mcp-1.1.3 → workspace_mcp-1.1.5}/core/comments.py +0 -0
- {workspace_mcp-1.1.3 → workspace_mcp-1.1.5}/core/context.py +0 -0
- {workspace_mcp-1.1.3 → workspace_mcp-1.1.5}/core/utils.py +0 -0
- {workspace_mcp-1.1.3 → workspace_mcp-1.1.5}/gcalendar/__init__.py +0 -0
- {workspace_mcp-1.1.3 → workspace_mcp-1.1.5}/gchat/__init__.py +0 -0
- {workspace_mcp-1.1.3 → workspace_mcp-1.1.5}/gchat/chat_tools.py +0 -0
- {workspace_mcp-1.1.3 → workspace_mcp-1.1.5}/gdocs/__init__.py +0 -0
- {workspace_mcp-1.1.3 → workspace_mcp-1.1.5}/gdrive/__init__.py +0 -0
- {workspace_mcp-1.1.3 → workspace_mcp-1.1.5}/gdrive/drive_tools.py +0 -0
- {workspace_mcp-1.1.3 → workspace_mcp-1.1.5}/gforms/__init__.py +0 -0
- {workspace_mcp-1.1.3 → workspace_mcp-1.1.5}/gmail/__init__.py +0 -0
- {workspace_mcp-1.1.3 → workspace_mcp-1.1.5}/gsheets/__init__.py +0 -0
- {workspace_mcp-1.1.3 → workspace_mcp-1.1.5}/gsheets/sheets_tools.py +0 -0
- {workspace_mcp-1.1.3 → workspace_mcp-1.1.5}/gslides/__init__.py +0 -0
- {workspace_mcp-1.1.3 → workspace_mcp-1.1.5}/gslides/slides_tools.py +0 -0
- {workspace_mcp-1.1.3 → workspace_mcp-1.1.5}/setup.cfg +0 -0
- {workspace_mcp-1.1.3 → workspace_mcp-1.1.5}/tests/test_auth.py +0 -0
- {workspace_mcp-1.1.3 → workspace_mcp-1.1.5}/workspace_mcp.egg-info/dependency_links.txt +0 -0
- {workspace_mcp-1.1.3 → workspace_mcp-1.1.5}/workspace_mcp.egg-info/entry_points.txt +0 -0
- {workspace_mcp-1.1.3 → workspace_mcp-1.1.5}/workspace_mcp.egg-info/requires.txt +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: workspace-mcp
|
3
|
-
Version: 1.1.
|
3
|
+
Version: 1.1.5
|
4
4
|
Summary: Comprehensive, highly performant Google Workspace Streamable HTTP & SSE MCP Server for Calendar, Gmail, Docs, Sheets, Slides & Drive
|
5
5
|
Author-email: Taylor Wilsdon <taylor@taylorwilsdon.com>
|
6
6
|
License: MIT
|
@@ -53,7 +53,9 @@ Dynamic: license-file
|
|
53
53
|
|
54
54
|
**This is the single most feature-complete Google Workspace MCP server**
|
55
55
|
|
56
|
-
*Full natural language control over Google Calendar, Drive, Gmail, Docs, Sheets, Slides, Forms, and Chat through all MCP clients, AI assistants and developer tools
|
56
|
+
*Full natural language control over Google Calendar, Drive, Gmail, Docs, Sheets, Slides, Forms, Tasks, and Chat through all MCP clients, AI assistants and developer tools.*
|
57
|
+
|
58
|
+
###### Support for all free Google accounts (Gmail, Docs, Drive etc) & Google Workspace plans (Starter, Standard, Plus, Enterprise, Non Profit etc) with their expanded app options like Chat & Spaces.
|
57
59
|
|
58
60
|
</div>
|
59
61
|
|
@@ -77,19 +79,21 @@ Dynamic: license-file
|
|
77
79
|
---
|
78
80
|
|
79
81
|
### A quick plug for AI-Enhanced Docs
|
82
|
+
<details>
|
83
|
+
<summary>But why?</summary>
|
80
84
|
|
81
|
-
|
85
|
+
**This README was written with AI assistance, and here's why that matters**
|
82
86
|
>
|
83
|
-
> As a solo
|
87
|
+
> As a solo dev building open source tools that many never see outside use, comprehensive documentation often wouldn't happen without AI help. Using agentic dev tools like **Roo** & **Claude Code** that understand the entire codebase, AI doesn't just regurgitate generic content - it extracts real implementation details and creates accurate, specific documentation.
|
84
88
|
>
|
85
|
-
> In this case, Sonnet 4 took a pass & a human (me) verified them
|
86
|
-
|
89
|
+
> In this case, Sonnet 4 took a pass & a human (me) verified them 7/10/25.
|
90
|
+
</details>
|
87
91
|
|
88
|
-
##
|
92
|
+
## Overview
|
89
93
|
|
90
94
|
A production-ready MCP server that integrates all major Google Workspace services with AI assistants. Built with FastMCP for optimal performance, featuring advanced authentication handling, service caching, and streamlined development patterns.
|
91
95
|
|
92
|
-
##
|
96
|
+
## Features
|
93
97
|
|
94
98
|
- **🔐 Advanced OAuth 2.0**: Secure authentication with automatic token refresh, transport-aware callback handling, session management, and centralized scope management
|
95
99
|
- **📅 Google Calendar**: Full calendar management with event CRUD operations
|
@@ -99,8 +103,9 @@ A production-ready MCP server that integrates all major Google Workspace service
|
|
99
103
|
- **📊 Google Sheets**: Comprehensive spreadsheet management with flexible cell operations and comment management
|
100
104
|
- **🖼️ Google Slides**: Presentation management with slide creation, updates, content manipulation, and comment management
|
101
105
|
- **📝 Google Forms**: Form creation, retrieval, publish settings, and response management
|
106
|
+
- **✓ Google Tasks**: Complete task and task list management with hierarchy, due dates, and status tracking
|
102
107
|
- **💬 Google Chat**: Space management and messaging capabilities
|
103
|
-
- **🔄
|
108
|
+
- **🔄 All Transports**: Stdio, Streamable HTTP & SSE, OpenAPI compatibility via `mcpo`
|
104
109
|
- **⚡ High Performance**: Service caching, thread-safe sessions, FastMCP integration
|
105
110
|
- **🧩 Developer Friendly**: Minimal boilerplate, automatic service injection, centralized configuration
|
106
111
|
|
@@ -108,7 +113,45 @@ A production-ready MCP server that integrates all major Google Workspace service
|
|
108
113
|
|
109
114
|
## 🚀 Quick Start
|
110
115
|
|
111
|
-
###
|
116
|
+
### 1. One-Click Claude Desktop Install (Recommended)
|
117
|
+
|
118
|
+
1. **Download:** Grab the latest `google_workspace_mcp.dxt` from the “Releases” page
|
119
|
+
2. **Install:** Double-click the file – Claude Desktop opens and prompts you to **Install**
|
120
|
+
3. **Configure:** In Claude Desktop → **Settings → Extensions → Google Workspace MCP**, paste your Google OAuth credentials
|
121
|
+
4. **Use it:** Start a new Claude chat and call any Google Workspace tool 🎉
|
122
|
+
|
123
|
+
>
|
124
|
+
**Why DXT?**
|
125
|
+
> Desktop Extensions (`.dxt`) bundle the server, dependencies, and manifest so users go from download → working MCP in **three clicks** – no terminal, no JSON editing, no version conflicts.
|
126
|
+
|
127
|
+
#### Required Configuration
|
128
|
+
<details>
|
129
|
+
<summary>Environment - you will configure these in Claude itself, see screenshot:</summary>
|
130
|
+
| Variable | Purpose |
|
131
|
+
|----------|---------|
|
132
|
+
| `GOOGLE_OAUTH_CLIENT_ID` | OAuth client ID from Google Cloud |
|
133
|
+
| `GOOGLE_OAUTH_CLIENT_SECRET` | OAuth client secret |
|
134
|
+
| `USER_GOOGLE_EMAIL` *(optional)* | Default email for single-user auth |
|
135
|
+
| `OAUTHLIB_INSECURE_TRANSPORT=1` | Development only (allows `http://` redirect) |
|
136
|
+
|
137
|
+
Claude Desktop stores these securely in the OS keychain; set them once in the extension pane.
|
138
|
+
</details>
|
139
|
+
Screenshot here
|
140
|
+
|
141
|
+
---
|
142
|
+
|
143
|
+
### 2. Advanced / Cross-Platform Installation
|
144
|
+
|
145
|
+
If you’re developing, deploying to servers, or using another MCP-capable client, keep reading.
|
146
|
+
|
147
|
+
#### Instant CLI (uvx)
|
148
|
+
|
149
|
+
```bash
|
150
|
+
# Requires Python 3.11+ and uvx
|
151
|
+
export GOOGLE_OAUTH_CLIENT_ID="xxx"
|
152
|
+
export GOOGLE_OAUTH_CLIENT_SECRET="yyy"
|
153
|
+
uvx workspace-mcp --tools gmail drive calendar
|
154
|
+
```
|
112
155
|
|
113
156
|
> Run instantly without manual installation - you must configure OAuth credentials when using uvx. You can use either environment variables (recommended for production) or set the `GOOGLE_CLIENT_SECRET_PATH` (or legacy `GOOGLE_CLIENT_SECRETS`) environment variable to point to your `client_secret.json` file.
|
114
157
|
|
@@ -121,7 +164,7 @@ export GOOGLE_OAUTH_CLIENT_SECRET="your-client-secret"
|
|
121
164
|
uvx workspace-mcp
|
122
165
|
|
123
166
|
# Start with specific tools only
|
124
|
-
uvx workspace-mcp --tools gmail drive calendar
|
167
|
+
uvx workspace-mcp --tools gmail drive calendar tasks
|
125
168
|
|
126
169
|
# Start in HTTP mode for debugging
|
127
170
|
uvx workspace-mcp --transport streamable-http
|
@@ -149,7 +192,7 @@ uv run main.py
|
|
149
192
|
|
150
193
|
1. **Google Cloud Setup**:
|
151
194
|
- Create OAuth 2.0 credentials (web application) in [Google Cloud Console](https://console.cloud.google.com/)
|
152
|
-
- Enable APIs: Calendar, Drive, Gmail, Docs, Sheets, Slides, Forms, Chat
|
195
|
+
- Enable APIs: Calendar, Drive, Gmail, Docs, Sheets, Slides, Forms, Tasks, Chat
|
153
196
|
- Add redirect URI: `http://localhost:8000/oauth2callback`
|
154
197
|
- Configure credentials using one of these methods:
|
155
198
|
|
@@ -184,9 +227,10 @@ uv run main.py
|
|
184
227
|
|
185
228
|
3. **Server Configuration**:
|
186
229
|
The server's base URL and port can be customized using environment variables:
|
187
|
-
- `WORKSPACE_MCP_BASE_URI`: Sets the base URI for the server (default: http://localhost). This affects the server_url used
|
230
|
+
- `WORKSPACE_MCP_BASE_URI`: Sets the base URI for the server (default: http://localhost). This affects the `server_url` used to construct the default `OAUTH_REDIRECT_URI` if `GOOGLE_OAUTH_REDIRECT_URI` is not set.
|
188
231
|
- `WORKSPACE_MCP_PORT`: Sets the port the server listens on (default: 8000). This affects the server_url, port, and OAUTH_REDIRECT_URI.
|
189
232
|
- `USER_GOOGLE_EMAIL`: Optional default email for authentication flows. If set, the LLM won't need to specify your email when calling `start_google_auth`.
|
233
|
+
- `GOOGLE_OAUTH_REDIRECT_URI`: Sets an override for OAuth redirect specifically, must include a full address (i.e. include port if necessary). Use this if you want to run your OAuth redirect separately from the MCP. This is not recommended outside of very specific cases
|
190
234
|
|
191
235
|
### Start the Server
|
192
236
|
|
@@ -201,7 +245,7 @@ uv run main.py --transport streamable-http
|
|
201
245
|
uv run main.py --single-user
|
202
246
|
|
203
247
|
# Selective tool registration (only register specific tools)
|
204
|
-
uv run main.py --tools gmail drive calendar
|
248
|
+
uv run main.py --tools gmail drive calendar tasks
|
205
249
|
uv run main.py --tools sheets docs
|
206
250
|
uv run main.py --single-user --tools gmail # Can combine with other flags
|
207
251
|
|
@@ -210,7 +254,7 @@ docker build -t workspace-mcp .
|
|
210
254
|
docker run -p 8000:8000 -v $(pwd):/app workspace-mcp --transport streamable-http
|
211
255
|
```
|
212
256
|
|
213
|
-
**Available Tools for `--tools` flag**: `gmail`, `drive`, `calendar`, `docs`, `sheets`, `forms`, `chat`
|
257
|
+
**Available Tools for `--tools` flag**: `gmail`, `drive`, `calendar`, `docs`, `sheets`, `forms`, `tasks`, `chat`
|
214
258
|
|
215
259
|
### Connect to Claude Desktop
|
216
260
|
|
@@ -218,7 +262,8 @@ The server supports two transport modes:
|
|
218
262
|
|
219
263
|
#### Stdio Mode (Default - Recommended for Claude Desktop)
|
220
264
|
|
221
|
-
**
|
265
|
+
**Guided Setup (Recommended if not using DXT)**
|
266
|
+
|
222
267
|
```bash
|
223
268
|
python install_claude.py
|
224
269
|
```
|
@@ -254,7 +299,7 @@ After running the script, just restart Claude Desktop and you're ready to go.
|
|
254
299
|
|
255
300
|
**Get Google OAuth Credentials** (if you don't have them):
|
256
301
|
- Go to [Google Cloud Console](https://console.cloud.google.com/)
|
257
|
-
- Create a new project and enable APIs: Calendar, Drive, Gmail, Docs, Sheets, Slides, Forms, Chat
|
302
|
+
- Create a new project and enable APIs: Calendar, Drive, Gmail, Docs, Sheets, Slides, Forms, Tasks, Chat
|
258
303
|
- Create OAuth 2.0 Client ID (Web application) with redirect URI: `http://localhost:8000/oauth2callback`
|
259
304
|
|
260
305
|
**Development Installation (For Contributors)**:
|
@@ -392,6 +437,23 @@ When calling a tool:
|
|
392
437
|
| `get_form_response` | Get individual form response details |
|
393
438
|
| `list_form_responses` | List all responses to a form with pagination |
|
394
439
|
|
440
|
+
### ✓ Google Tasks ([`tasks_tools.py`](gtasks/tasks_tools.py))
|
441
|
+
|
442
|
+
| Tool | Description |
|
443
|
+
|------|-------------|
|
444
|
+
| `list_task_lists` | List all task lists with pagination support |
|
445
|
+
| `get_task_list` | Retrieve details of a specific task list |
|
446
|
+
| `create_task_list` | Create new task lists with custom titles |
|
447
|
+
| `update_task_list` | Modify existing task list titles |
|
448
|
+
| `delete_task_list` | Remove task lists and all contained tasks |
|
449
|
+
| `list_tasks` | List tasks in a specific list with filtering options |
|
450
|
+
| `get_task` | Retrieve detailed information about a specific task |
|
451
|
+
| `create_task` | Create new tasks with title, notes, due dates, and hierarchy |
|
452
|
+
| `update_task` | Modify task properties including title, notes, status, and due dates |
|
453
|
+
| `delete_task` | Remove tasks from task lists |
|
454
|
+
| `move_task` | Reposition tasks within lists or move between lists |
|
455
|
+
| `clear_completed_tasks` | Hide all completed tasks from a list |
|
456
|
+
|
395
457
|
### 💬 Google Chat ([`chat_tools.py`](gchat/chat_tools.py))
|
396
458
|
|
397
459
|
| Tool | Description |
|
@@ -11,7 +11,9 @@
|
|
11
11
|
|
12
12
|
**This is the single most feature-complete Google Workspace MCP server**
|
13
13
|
|
14
|
-
*Full natural language control over Google Calendar, Drive, Gmail, Docs, Sheets, Slides, Forms, and Chat through all MCP clients, AI assistants and developer tools
|
14
|
+
*Full natural language control over Google Calendar, Drive, Gmail, Docs, Sheets, Slides, Forms, Tasks, and Chat through all MCP clients, AI assistants and developer tools.*
|
15
|
+
|
16
|
+
###### Support for all free Google accounts (Gmail, Docs, Drive etc) & Google Workspace plans (Starter, Standard, Plus, Enterprise, Non Profit etc) with their expanded app options like Chat & Spaces.
|
15
17
|
|
16
18
|
</div>
|
17
19
|
|
@@ -35,19 +37,21 @@
|
|
35
37
|
---
|
36
38
|
|
37
39
|
### A quick plug for AI-Enhanced Docs
|
40
|
+
<details>
|
41
|
+
<summary>But why?</summary>
|
38
42
|
|
39
|
-
|
43
|
+
**This README was written with AI assistance, and here's why that matters**
|
40
44
|
>
|
41
|
-
> As a solo
|
45
|
+
> As a solo dev building open source tools that many never see outside use, comprehensive documentation often wouldn't happen without AI help. Using agentic dev tools like **Roo** & **Claude Code** that understand the entire codebase, AI doesn't just regurgitate generic content - it extracts real implementation details and creates accurate, specific documentation.
|
42
46
|
>
|
43
|
-
> In this case, Sonnet 4 took a pass & a human (me) verified them
|
44
|
-
|
47
|
+
> In this case, Sonnet 4 took a pass & a human (me) verified them 7/10/25.
|
48
|
+
</details>
|
45
49
|
|
46
|
-
##
|
50
|
+
## Overview
|
47
51
|
|
48
52
|
A production-ready MCP server that integrates all major Google Workspace services with AI assistants. Built with FastMCP for optimal performance, featuring advanced authentication handling, service caching, and streamlined development patterns.
|
49
53
|
|
50
|
-
##
|
54
|
+
## Features
|
51
55
|
|
52
56
|
- **🔐 Advanced OAuth 2.0**: Secure authentication with automatic token refresh, transport-aware callback handling, session management, and centralized scope management
|
53
57
|
- **📅 Google Calendar**: Full calendar management with event CRUD operations
|
@@ -57,8 +61,9 @@ A production-ready MCP server that integrates all major Google Workspace service
|
|
57
61
|
- **📊 Google Sheets**: Comprehensive spreadsheet management with flexible cell operations and comment management
|
58
62
|
- **🖼️ Google Slides**: Presentation management with slide creation, updates, content manipulation, and comment management
|
59
63
|
- **📝 Google Forms**: Form creation, retrieval, publish settings, and response management
|
64
|
+
- **✓ Google Tasks**: Complete task and task list management with hierarchy, due dates, and status tracking
|
60
65
|
- **💬 Google Chat**: Space management and messaging capabilities
|
61
|
-
- **🔄
|
66
|
+
- **🔄 All Transports**: Stdio, Streamable HTTP & SSE, OpenAPI compatibility via `mcpo`
|
62
67
|
- **⚡ High Performance**: Service caching, thread-safe sessions, FastMCP integration
|
63
68
|
- **🧩 Developer Friendly**: Minimal boilerplate, automatic service injection, centralized configuration
|
64
69
|
|
@@ -66,7 +71,45 @@ A production-ready MCP server that integrates all major Google Workspace service
|
|
66
71
|
|
67
72
|
## 🚀 Quick Start
|
68
73
|
|
69
|
-
###
|
74
|
+
### 1. One-Click Claude Desktop Install (Recommended)
|
75
|
+
|
76
|
+
1. **Download:** Grab the latest `google_workspace_mcp.dxt` from the “Releases” page
|
77
|
+
2. **Install:** Double-click the file – Claude Desktop opens and prompts you to **Install**
|
78
|
+
3. **Configure:** In Claude Desktop → **Settings → Extensions → Google Workspace MCP**, paste your Google OAuth credentials
|
79
|
+
4. **Use it:** Start a new Claude chat and call any Google Workspace tool 🎉
|
80
|
+
|
81
|
+
>
|
82
|
+
**Why DXT?**
|
83
|
+
> Desktop Extensions (`.dxt`) bundle the server, dependencies, and manifest so users go from download → working MCP in **three clicks** – no terminal, no JSON editing, no version conflicts.
|
84
|
+
|
85
|
+
#### Required Configuration
|
86
|
+
<details>
|
87
|
+
<summary>Environment - you will configure these in Claude itself, see screenshot:</summary>
|
88
|
+
| Variable | Purpose |
|
89
|
+
|----------|---------|
|
90
|
+
| `GOOGLE_OAUTH_CLIENT_ID` | OAuth client ID from Google Cloud |
|
91
|
+
| `GOOGLE_OAUTH_CLIENT_SECRET` | OAuth client secret |
|
92
|
+
| `USER_GOOGLE_EMAIL` *(optional)* | Default email for single-user auth |
|
93
|
+
| `OAUTHLIB_INSECURE_TRANSPORT=1` | Development only (allows `http://` redirect) |
|
94
|
+
|
95
|
+
Claude Desktop stores these securely in the OS keychain; set them once in the extension pane.
|
96
|
+
</details>
|
97
|
+
Screenshot here
|
98
|
+
|
99
|
+
---
|
100
|
+
|
101
|
+
### 2. Advanced / Cross-Platform Installation
|
102
|
+
|
103
|
+
If you’re developing, deploying to servers, or using another MCP-capable client, keep reading.
|
104
|
+
|
105
|
+
#### Instant CLI (uvx)
|
106
|
+
|
107
|
+
```bash
|
108
|
+
# Requires Python 3.11+ and uvx
|
109
|
+
export GOOGLE_OAUTH_CLIENT_ID="xxx"
|
110
|
+
export GOOGLE_OAUTH_CLIENT_SECRET="yyy"
|
111
|
+
uvx workspace-mcp --tools gmail drive calendar
|
112
|
+
```
|
70
113
|
|
71
114
|
> Run instantly without manual installation - you must configure OAuth credentials when using uvx. You can use either environment variables (recommended for production) or set the `GOOGLE_CLIENT_SECRET_PATH` (or legacy `GOOGLE_CLIENT_SECRETS`) environment variable to point to your `client_secret.json` file.
|
72
115
|
|
@@ -79,7 +122,7 @@ export GOOGLE_OAUTH_CLIENT_SECRET="your-client-secret"
|
|
79
122
|
uvx workspace-mcp
|
80
123
|
|
81
124
|
# Start with specific tools only
|
82
|
-
uvx workspace-mcp --tools gmail drive calendar
|
125
|
+
uvx workspace-mcp --tools gmail drive calendar tasks
|
83
126
|
|
84
127
|
# Start in HTTP mode for debugging
|
85
128
|
uvx workspace-mcp --transport streamable-http
|
@@ -107,7 +150,7 @@ uv run main.py
|
|
107
150
|
|
108
151
|
1. **Google Cloud Setup**:
|
109
152
|
- Create OAuth 2.0 credentials (web application) in [Google Cloud Console](https://console.cloud.google.com/)
|
110
|
-
- Enable APIs: Calendar, Drive, Gmail, Docs, Sheets, Slides, Forms, Chat
|
153
|
+
- Enable APIs: Calendar, Drive, Gmail, Docs, Sheets, Slides, Forms, Tasks, Chat
|
111
154
|
- Add redirect URI: `http://localhost:8000/oauth2callback`
|
112
155
|
- Configure credentials using one of these methods:
|
113
156
|
|
@@ -142,9 +185,10 @@ uv run main.py
|
|
142
185
|
|
143
186
|
3. **Server Configuration**:
|
144
187
|
The server's base URL and port can be customized using environment variables:
|
145
|
-
- `WORKSPACE_MCP_BASE_URI`: Sets the base URI for the server (default: http://localhost). This affects the server_url used
|
188
|
+
- `WORKSPACE_MCP_BASE_URI`: Sets the base URI for the server (default: http://localhost). This affects the `server_url` used to construct the default `OAUTH_REDIRECT_URI` if `GOOGLE_OAUTH_REDIRECT_URI` is not set.
|
146
189
|
- `WORKSPACE_MCP_PORT`: Sets the port the server listens on (default: 8000). This affects the server_url, port, and OAUTH_REDIRECT_URI.
|
147
190
|
- `USER_GOOGLE_EMAIL`: Optional default email for authentication flows. If set, the LLM won't need to specify your email when calling `start_google_auth`.
|
191
|
+
- `GOOGLE_OAUTH_REDIRECT_URI`: Sets an override for OAuth redirect specifically, must include a full address (i.e. include port if necessary). Use this if you want to run your OAuth redirect separately from the MCP. This is not recommended outside of very specific cases
|
148
192
|
|
149
193
|
### Start the Server
|
150
194
|
|
@@ -159,7 +203,7 @@ uv run main.py --transport streamable-http
|
|
159
203
|
uv run main.py --single-user
|
160
204
|
|
161
205
|
# Selective tool registration (only register specific tools)
|
162
|
-
uv run main.py --tools gmail drive calendar
|
206
|
+
uv run main.py --tools gmail drive calendar tasks
|
163
207
|
uv run main.py --tools sheets docs
|
164
208
|
uv run main.py --single-user --tools gmail # Can combine with other flags
|
165
209
|
|
@@ -168,7 +212,7 @@ docker build -t workspace-mcp .
|
|
168
212
|
docker run -p 8000:8000 -v $(pwd):/app workspace-mcp --transport streamable-http
|
169
213
|
```
|
170
214
|
|
171
|
-
**Available Tools for `--tools` flag**: `gmail`, `drive`, `calendar`, `docs`, `sheets`, `forms`, `chat`
|
215
|
+
**Available Tools for `--tools` flag**: `gmail`, `drive`, `calendar`, `docs`, `sheets`, `forms`, `tasks`, `chat`
|
172
216
|
|
173
217
|
### Connect to Claude Desktop
|
174
218
|
|
@@ -176,7 +220,8 @@ The server supports two transport modes:
|
|
176
220
|
|
177
221
|
#### Stdio Mode (Default - Recommended for Claude Desktop)
|
178
222
|
|
179
|
-
**
|
223
|
+
**Guided Setup (Recommended if not using DXT)**
|
224
|
+
|
180
225
|
```bash
|
181
226
|
python install_claude.py
|
182
227
|
```
|
@@ -212,7 +257,7 @@ After running the script, just restart Claude Desktop and you're ready to go.
|
|
212
257
|
|
213
258
|
**Get Google OAuth Credentials** (if you don't have them):
|
214
259
|
- Go to [Google Cloud Console](https://console.cloud.google.com/)
|
215
|
-
- Create a new project and enable APIs: Calendar, Drive, Gmail, Docs, Sheets, Slides, Forms, Chat
|
260
|
+
- Create a new project and enable APIs: Calendar, Drive, Gmail, Docs, Sheets, Slides, Forms, Tasks, Chat
|
216
261
|
- Create OAuth 2.0 Client ID (Web application) with redirect URI: `http://localhost:8000/oauth2callback`
|
217
262
|
|
218
263
|
**Development Installation (For Contributors)**:
|
@@ -350,6 +395,23 @@ When calling a tool:
|
|
350
395
|
| `get_form_response` | Get individual form response details |
|
351
396
|
| `list_form_responses` | List all responses to a form with pagination |
|
352
397
|
|
398
|
+
### ✓ Google Tasks ([`tasks_tools.py`](gtasks/tasks_tools.py))
|
399
|
+
|
400
|
+
| Tool | Description |
|
401
|
+
|------|-------------|
|
402
|
+
| `list_task_lists` | List all task lists with pagination support |
|
403
|
+
| `get_task_list` | Retrieve details of a specific task list |
|
404
|
+
| `create_task_list` | Create new task lists with custom titles |
|
405
|
+
| `update_task_list` | Modify existing task list titles |
|
406
|
+
| `delete_task_list` | Remove task lists and all contained tasks |
|
407
|
+
| `list_tasks` | List tasks in a specific list with filtering options |
|
408
|
+
| `get_task` | Retrieve detailed information about a specific task |
|
409
|
+
| `create_task` | Create new tasks with title, notes, due dates, and hierarchy |
|
410
|
+
| `update_task` | Modify task properties including title, notes, status, and due dates |
|
411
|
+
| `delete_task` | Remove tasks from task lists |
|
412
|
+
| `move_task` | Reposition tasks within lists or move between lists |
|
413
|
+
| `clear_completed_tasks` | Hide all completed tasks from a list |
|
414
|
+
|
353
415
|
### 💬 Google Chat ([`chat_tools.py`](gchat/chat_tools.py))
|
354
416
|
|
355
417
|
| Tool | Description |
|
@@ -1,14 +1,16 @@
|
|
1
1
|
# auth/google_auth.py
|
2
2
|
|
3
|
-
import
|
3
|
+
import asyncio
|
4
4
|
import json
|
5
|
+
import jwt
|
5
6
|
import logging
|
6
|
-
import asyncio
|
7
|
-
from typing import List, Optional, Tuple, Dict, Any, Callable
|
8
7
|
import os
|
9
8
|
|
9
|
+
from datetime import datetime
|
10
|
+
from typing import List, Optional, Tuple, Dict, Any
|
11
|
+
|
10
12
|
from google.oauth2.credentials import Credentials
|
11
|
-
from google_auth_oauthlib.flow import Flow
|
13
|
+
from google_auth_oauthlib.flow import Flow
|
12
14
|
from google.auth.transport.requests import Request
|
13
15
|
from google.auth.exceptions import RefreshError
|
14
16
|
from googleapiclient.discovery import build
|
@@ -161,8 +163,6 @@ def load_credentials_from_file(
|
|
161
163
|
expiry = None
|
162
164
|
if creds_data.get("expiry"):
|
163
165
|
try:
|
164
|
-
from datetime import datetime
|
165
|
-
|
166
166
|
expiry = datetime.fromisoformat(creds_data["expiry"])
|
167
167
|
except (ValueError, TypeError) as e:
|
168
168
|
logger.warning(
|
@@ -789,8 +789,6 @@ async def get_authenticated_google_service(
|
|
789
789
|
# Try to get email from credentials if needed for validation
|
790
790
|
if credentials and credentials.id_token:
|
791
791
|
try:
|
792
|
-
import jwt
|
793
|
-
|
794
792
|
# Decode without verification (just to get email for logging)
|
795
793
|
decoded_token = jwt.decode(
|
796
794
|
credentials.id_token, options={"verify_signature": False}
|
@@ -5,15 +5,17 @@ In streamable-http mode: Uses the existing FastAPI server
|
|
5
5
|
In stdio mode: Starts a minimal HTTP server just for OAuth callbacks
|
6
6
|
"""
|
7
7
|
|
8
|
+
import os
|
8
9
|
import asyncio
|
9
10
|
import logging
|
10
11
|
import threading
|
11
12
|
import time
|
12
|
-
from typing import Optional, Dict, Any
|
13
13
|
import socket
|
14
|
+
import uvicorn
|
14
15
|
|
15
16
|
from fastapi import FastAPI, Request
|
16
|
-
import
|
17
|
+
from typing import Optional
|
18
|
+
from urllib.parse import urlparse
|
17
19
|
|
18
20
|
from auth.google_auth import handle_auth_callback, check_client_secrets
|
19
21
|
from auth.scopes import OAUTH_STATE_TO_SESSION_ID_MAP, SCOPES
|
@@ -73,10 +75,11 @@ class MinimalOAuthServer:
|
|
73
75
|
logger.warning(f"OAuth callback: No MCP session ID found for state '{state}'. Auth will not be tied to a specific session.")
|
74
76
|
|
75
77
|
# Exchange code for credentials
|
78
|
+
redirect_uri = get_oauth_redirect_uri(port=self.port, base_uri=self.base_uri)
|
76
79
|
verified_user_id, credentials = handle_auth_callback(
|
77
80
|
scopes=SCOPES,
|
78
81
|
authorization_response=str(request.url),
|
79
|
-
redirect_uri=
|
82
|
+
redirect_uri=redirect_uri,
|
80
83
|
session_id=mcp_session_id
|
81
84
|
)
|
82
85
|
|
@@ -105,7 +108,6 @@ class MinimalOAuthServer:
|
|
105
108
|
# Check if port is available
|
106
109
|
# Extract hostname from base_uri (e.g., "http://localhost" -> "localhost")
|
107
110
|
try:
|
108
|
-
from urllib.parse import urlparse
|
109
111
|
parsed_uri = urlparse(self.base_uri)
|
110
112
|
hostname = parsed_uri.hostname or 'localhost'
|
111
113
|
except Exception:
|
@@ -179,19 +181,31 @@ class MinimalOAuthServer:
|
|
179
181
|
# Global instance for stdio mode
|
180
182
|
_minimal_oauth_server: Optional[MinimalOAuthServer] = None
|
181
183
|
|
182
|
-
def get_oauth_redirect_uri(
|
184
|
+
def get_oauth_redirect_uri(port: int = 8000, base_uri: str = "http://localhost") -> str:
|
183
185
|
"""
|
184
|
-
Get the appropriate OAuth redirect URI
|
186
|
+
Get the appropriate OAuth redirect URI.
|
187
|
+
|
188
|
+
Priority:
|
189
|
+
1. GOOGLE_OAUTH_REDIRECT_URI environment variable
|
190
|
+
2. Constructed from port and base URI
|
185
191
|
|
186
192
|
Args:
|
187
|
-
transport_mode: "stdio" or "streamable-http"
|
188
193
|
port: Port number (default 8000)
|
189
194
|
base_uri: Base URI (default "http://localhost")
|
190
195
|
|
191
196
|
Returns:
|
192
197
|
OAuth redirect URI
|
193
198
|
"""
|
194
|
-
|
199
|
+
# Highest priority: Use the environment variable if it's set
|
200
|
+
env_redirect_uri = os.getenv("GOOGLE_OAUTH_REDIRECT_URI")
|
201
|
+
if env_redirect_uri:
|
202
|
+
logger.info(f"Using redirect URI from GOOGLE_OAUTH_REDIRECT_URI: {env_redirect_uri}")
|
203
|
+
return env_redirect_uri
|
204
|
+
|
205
|
+
# Fallback to constructing the URI based on server settings
|
206
|
+
constructed_uri = f"{base_uri}:{port}/oauth2callback"
|
207
|
+
logger.info(f"Constructed redirect URI: {constructed_uri}")
|
208
|
+
return constructed_uri
|
195
209
|
|
196
210
|
def ensure_oauth_callback_available(transport_mode: str = "stdio", port: int = 8000, base_uri: str = "http://localhost") -> bool:
|
197
211
|
"""
|
@@ -52,6 +52,10 @@ FORMS_RESPONSES_READONLY_SCOPE = 'https://www.googleapis.com/auth/forms.response
|
|
52
52
|
SLIDES_SCOPE = 'https://www.googleapis.com/auth/presentations'
|
53
53
|
SLIDES_READONLY_SCOPE = 'https://www.googleapis.com/auth/presentations.readonly'
|
54
54
|
|
55
|
+
# Google Tasks API scopes
|
56
|
+
TASKS_SCOPE = 'https://www.googleapis.com/auth/tasks'
|
57
|
+
TASKS_READONLY_SCOPE = 'https://www.googleapis.com/auth/tasks.readonly'
|
58
|
+
|
55
59
|
# Base OAuth scopes required for user identification
|
56
60
|
BASE_SCOPES = [
|
57
61
|
USERINFO_EMAIL_SCOPE,
|
@@ -104,5 +108,10 @@ SLIDES_SCOPES = [
|
|
104
108
|
SLIDES_READONLY_SCOPE
|
105
109
|
]
|
106
110
|
|
111
|
+
TASKS_SCOPES = [
|
112
|
+
TASKS_SCOPE,
|
113
|
+
TASKS_READONLY_SCOPE
|
114
|
+
]
|
115
|
+
|
107
116
|
# Combined scopes for all supported Google Workspace operations
|
108
|
-
SCOPES = list(set(BASE_SCOPES + CALENDAR_SCOPES + DRIVE_SCOPES + GMAIL_SCOPES + DOCS_SCOPES + CHAT_SCOPES + SHEETS_SCOPES + FORMS_SCOPES + SLIDES_SCOPES))
|
117
|
+
SCOPES = list(set(BASE_SCOPES + CALENDAR_SCOPES + DRIVE_SCOPES + GMAIL_SCOPES + DOCS_SCOPES + CHAT_SCOPES + SHEETS_SCOPES + FORMS_SCOPES + SLIDES_SCOPES + TASKS_SCOPES))
|
@@ -18,7 +18,8 @@ from auth.scopes import (
|
|
18
18
|
SHEETS_READONLY_SCOPE, SHEETS_WRITE_SCOPE,
|
19
19
|
CHAT_READONLY_SCOPE, CHAT_WRITE_SCOPE, CHAT_SPACES_SCOPE,
|
20
20
|
FORMS_BODY_SCOPE, FORMS_BODY_READONLY_SCOPE, FORMS_RESPONSES_READONLY_SCOPE,
|
21
|
-
SLIDES_SCOPE, SLIDES_READONLY_SCOPE
|
21
|
+
SLIDES_SCOPE, SLIDES_READONLY_SCOPE,
|
22
|
+
TASKS_SCOPE, TASKS_READONLY_SCOPE
|
22
23
|
)
|
23
24
|
|
24
25
|
# Service configuration mapping
|
@@ -30,7 +31,8 @@ SERVICE_CONFIGS = {
|
|
30
31
|
"sheets": {"service": "sheets", "version": "v4"},
|
31
32
|
"chat": {"service": "chat", "version": "v1"},
|
32
33
|
"forms": {"service": "forms", "version": "v1"},
|
33
|
-
"slides": {"service": "slides", "version": "v1"}
|
34
|
+
"slides": {"service": "slides", "version": "v1"},
|
35
|
+
"tasks": {"service": "tasks", "version": "v1"}
|
34
36
|
}
|
35
37
|
|
36
38
|
|
@@ -72,6 +74,10 @@ SCOPE_GROUPS = {
|
|
72
74
|
# Slides scopes
|
73
75
|
"slides": SLIDES_SCOPE,
|
74
76
|
"slides_read": SLIDES_READONLY_SCOPE,
|
77
|
+
|
78
|
+
# Tasks scopes
|
79
|
+
"tasks": TASKS_SCOPE,
|
80
|
+
"tasks_read": TASKS_READONLY_SCOPE,
|
75
81
|
}
|
76
82
|
|
77
83
|
# Service cache: {cache_key: (service, cached_time, user_email)}
|
@@ -49,6 +49,9 @@ from auth.scopes import (
|
|
49
49
|
SLIDES_SCOPE,
|
50
50
|
SLIDES_READONLY_SCOPE,
|
51
51
|
SLIDES_SCOPES,
|
52
|
+
TASKS_SCOPE,
|
53
|
+
TASKS_READONLY_SCOPE,
|
54
|
+
TASKS_SCOPES,
|
52
55
|
SCOPES
|
53
56
|
)
|
54
57
|
|
@@ -79,7 +82,7 @@ def set_transport_mode(mode: str):
|
|
79
82
|
|
80
83
|
def get_oauth_redirect_uri_for_current_mode() -> str:
|
81
84
|
"""Get OAuth redirect URI based on current transport mode."""
|
82
|
-
return get_oauth_redirect_uri(
|
85
|
+
return get_oauth_redirect_uri(WORKSPACE_MCP_PORT, WORKSPACE_MCP_BASE_URI)
|
83
86
|
|
84
87
|
# Health check endpoint
|
85
88
|
@server.custom_route("/health", methods=["GET"])
|