Skip to content

Commit 16c8b6a

Browse files
add google-workspace mcp to runner
Signed-off-by: Michael Clifford <mcliffor@redhat.com> add google drive integration to session frontend Signed-off-by: Michael Clifford <mcliffor@redhat.com> update operator to mount mcp configs Signed-off-by: Michael Clifford <mcliffor@redhat.com> update credentials file location and fields Signed-off-by: Michael Clifford <mcliffor@redhat.com> more config file wrangling Signed-off-by: Michael Clifford <mcliffor@redhat.com> google mcp docs update Signed-off-by: Michael Clifford <mcliffor@redhat.com>
1 parent 6674004 commit 16c8b6a

File tree

10 files changed

+352
-219
lines changed

10 files changed

+352
-219
lines changed
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# Google Drive Integration
2+
3+
Connect your Google Drive to agentic sessions so Claude can read and write files in your Drive.
4+
5+
## What It Does
6+
7+
Once connected, Claude can:
8+
- List files and folders in your Google Drive
9+
- Read file contents
10+
- Create new files
11+
- Update existing files
12+
- Search your Drive
13+
14+
## How to Use
15+
16+
### 1. Connect Google Drive to a Session
17+
18+
1. Open or create an agentic session
19+
2. In the left sidebar, expand **"MCP Integrations"**
20+
3. Click **"Connect"** on the Google Drive card
21+
4. Authorize in the popup window
22+
5. Close the popup when you see "Authorization Successful"
23+
24+
### 2. Use Drive in Your Prompts
25+
26+
Once connected, you can ask Claude things like:
27+
28+
- "List the files in my Google Drive"
29+
- "Read the contents of 'meeting-notes.txt' from my Drive"
30+
- "Create a new document in my Drive called 'project-summary.md' with this content..."
31+
- "Find all PDFs in my Drive from last month"
32+
33+
### 3. Disconnect (Optional)
34+
35+
Credentials are automatically removed when the session ends. To disconnect earlier, click "Disconnect" in the MCP Integrations accordion.
36+
37+
## First-Time Setup (Admin)
38+
39+
Administrators need to configure Google OAuth credentials once:
40+
41+
1. Create a Google Cloud project and OAuth 2.0 credentials
42+
2. Set authorized redirect URI to: `https://your-vteam-backend/oauth2callback`
43+
3. Create a Kubernetes Secret in the operator namespace:
44+
45+
```bash
46+
kubectl create secret generic google-workflow-app-secret \
47+
--from-literal=GOOGLE_OAUTH_CLIENT_ID='your-client-id' \
48+
--from-literal=GOOGLE_OAUTH_CLIENT_SECRET='your-client-secret'
49+
```
50+
51+
## Security & Privacy
52+
53+
- **Session-scoped**: Credentials only exist for the current session
54+
- **Automatic cleanup**: Credentials deleted when session ends
55+
- **No sharing**: Your credentials never accessible to other users or sessions
56+
- **You control access**: You must explicitly connect for each session
57+
58+
## Troubleshooting
59+
60+
**"Connect" button doesn't work**
61+
- Check that popup blockers aren't blocking the OAuth window
62+
63+
**Claude says it can't access Drive**
64+
- Verify you see "Connected" status in MCP Integrations accordion
65+
- Try disconnecting and reconnecting
66+
- Check the session logs for errors
67+
68+
**"Invalid scopes" error**
69+
- You may need to re-authorize with updated permissions
70+
- Click "Disconnect" then "Connect" again
71+
72+
## Questions?
73+
74+
See the [workspace-mcp documentation](https://github.com/taylorwilsdon/google_workspace_mcp) for details about what Drive operations are supported.

components/backend/OAUTH_INTEGRATION.md

Lines changed: 0 additions & 214 deletions
This file was deleted.

components/backend/handlers/oauth.go

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,11 @@ func getOAuthProvider(provider string) (*OAuthProvider, error) {
6565
ClientSecret: clientSecret,
6666
TokenURL: "https://oauth2.googleapis.com/token",
6767
Scopes: []string{
68+
"openid",
6869
"https://www.googleapis.com/auth/userinfo.email",
70+
"https://www.googleapis.com/auth/userinfo.profile",
71+
"https://www.googleapis.com/auth/drive",
72+
"https://www.googleapis.com/auth/drive.readonly",
6973
"https://www.googleapis.com/auth/drive.file",
7074
},
7175
}, nil
@@ -633,13 +637,25 @@ func writeCredentialsToSessionPVC(ctx context.Context, projectName, sessionName,
633637
func storeCredentialsInSecret(ctx context.Context, projectName, sessionName, provider, accessToken, refreshToken string, expiresIn int64) error {
634638
secretName := fmt.Sprintf("%s-%s-oauth", sessionName, provider)
635639

636-
// Prepare credentials JSON
640+
// Get OAuth provider config for client_id and client_secret
641+
providerConfig, err := getOAuthProvider(provider)
642+
if err != nil {
643+
return fmt.Errorf("failed to get OAuth provider config: %w", err)
644+
}
645+
646+
// Calculate expiry time in ISO 8601 format as expected by workspace-mcp
647+
// workspace-mcp expects timezone-naive format like Python's datetime.isoformat()
648+
expiryTime := time.Now().Add(time.Duration(expiresIn) * time.Second)
649+
650+
// Prepare credentials JSON in the format expected by workspace-mcp
637651
credentials := map[string]interface{}{
638-
"access_token": accessToken,
652+
"token": accessToken,
639653
"refresh_token": refreshToken,
640-
"token_type": "Bearer",
641-
"expires_in": expiresIn,
642-
"created_at": time.Now().Unix(),
654+
"token_uri": providerConfig.TokenURL,
655+
"client_id": providerConfig.ClientID,
656+
"client_secret": providerConfig.ClientSecret,
657+
"scopes": providerConfig.Scopes,
658+
"expiry": expiryTime.Format("2006-01-02T15:04:05"), // Timezone-naive format for Python compatibility
643659
}
644660

645661
credentialsJSON, err := json.MarshalIndent(credentials, "", " ")

0 commit comments

Comments
 (0)