gmcp 0.1.0

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 ADDED
@@ -0,0 +1,183 @@
1
+ # GMCP
2
+
3
+ MCP (Model Context Protocol) server for Google services. Provides Gmail and Google Calendar integration with 19 tools for email management and calendar operations.
4
+
5
+ ## Gmail Tools
6
+
7
+ ### Email Operations
8
+
9
+ | Tool | Description |
10
+ |------|-------------|
11
+ | `gmcp_gmail_search_emails` | Search emails using Gmail query syntax |
12
+ | `gmcp_gmail_get_email` | Get single email by message ID |
13
+ | `gmcp_gmail_get_thread` | Get entire conversation thread |
14
+ | `gmcp_gmail_list_attachments` | List all attachments on a message |
15
+ | `gmcp_gmail_get_attachment` | Download attachment data by ID |
16
+ | `gmcp_gmail_send_email` | Send email (preview + confirm safety) |
17
+ | `gmcp_gmail_reply` | Reply to email in thread (preview + confirm) |
18
+ | `gmcp_gmail_create_draft` | Create draft message |
19
+
20
+ ### Label Management
21
+
22
+ | Tool | Description |
23
+ |------|-------------|
24
+ | `gmcp_gmail_list_labels` | List all Gmail labels (system + custom) |
25
+ | `gmcp_gmail_get_label` | Get label details and message counts |
26
+ | `gmcp_gmail_create_label` | Create custom label with visibility/color settings |
27
+ | `gmcp_gmail_update_label` | Update label name, visibility, or color |
28
+ | `gmcp_gmail_delete_label` | Delete custom label (system labels protected) |
29
+ | `gmcp_gmail_modify_labels` | Add/remove labels on a message |
30
+ | `gmcp_gmail_batch_modify` | Batch label operations on multiple messages |
31
+
32
+ ## Calendar Tools
33
+
34
+ | Tool | Description |
35
+ |------|-------------|
36
+ | `gmcp_calendar_list_calendars` | List all calendars for account |
37
+ | `gmcp_calendar_list_events` | List events with filters (time range, query, calendar) |
38
+ | `gmcp_calendar_get_event` | Get single event by ID |
39
+ | `gmcp_calendar_create_event` | Create event (supports recurring events, Google Meet) |
40
+
41
+ ## Setup
42
+
43
+ ### Prerequisites
44
+
45
+ 1. **Google Cloud Project** with Gmail API and Calendar API enabled
46
+ 2. **OAuth 2.0 Client ID** (Desktop Application type)
47
+ - Create at [Google Cloud Console](https://console.cloud.google.com/apis/credentials)
48
+ - Download credentials JSON file
49
+
50
+ ### Install & Configure
51
+
52
+ ```bash
53
+ # Install dependencies
54
+ bun install
55
+
56
+ # Copy environment template
57
+ cp .env.example .env
58
+
59
+ # Edit .env with your paths
60
+ # GOOGLE_CREDENTIALS_PATH=/path/to/credentials.json
61
+ # GOOGLE_TOKEN_PATH=/path/to/token.json
62
+ # GOOGLE_SCOPES=gmail.readonly,calendar.readonly
63
+ ```
64
+
65
+ ### Authenticate
66
+
67
+ Run the OAuth flow to obtain tokens:
68
+
69
+ ```bash
70
+ bun run auth
71
+ ```
72
+
73
+ Follow the prompts:
74
+ 1. Visit the authorization URL in your browser
75
+ 2. Authorize the app
76
+ 3. Copy the authorization code from the redirected URL
77
+ 4. Paste it in the terminal
78
+
79
+ The browser will show "connection refused" after authorization - **this is expected**. Just copy the `code=` parameter from the URL.
80
+
81
+ ### Run the Server
82
+
83
+ ```bash
84
+ bun run start
85
+ ```
86
+
87
+ The server runs via stdio and is ready to accept MCP requests.
88
+
89
+ ## Configuration
90
+
91
+ ### Environment Variables
92
+
93
+ | Variable | Description |
94
+ |----------|-------------|
95
+ | `GOOGLE_CREDENTIALS_PATH` | Path to OAuth2 credentials JSON from Google Cloud Console |
96
+ | `GOOGLE_TOKEN_PATH` | Path where OAuth2 tokens will be stored |
97
+ | `GOOGLE_SCOPES` | Comma-separated Gmail and Calendar API scopes (short names or full URLs) |
98
+
99
+ ### Gmail Scopes
100
+
101
+ | Short Name | Description | Required For |
102
+ |------------|-------------|--------------|
103
+ | `gmail.readonly` | Read-only access | Search, get email, get thread, list/get attachments, list labels, get label |
104
+ | `gmail.modify` | Read, create, update, delete | Modify labels, batch modify |
105
+ | `gmail.labels` | Manage labels | Create label, update label, delete label, modify labels, batch modify |
106
+ | `gmail.send` | Send messages | Send email, reply |
107
+ | `gmail.compose` | Create drafts and send | Send email, reply, create draft |
108
+
109
+ ### Calendar Scopes
110
+
111
+ | Short Name | Description | Required For |
112
+ |------------|-------------|--------------|
113
+ | `calendar.readonly` | Read-only calendar access | List calendars, list events, get event |
114
+ | `calendar.events.readonly` | Read-only events access | List events, get event |
115
+ | `calendar.events` | Manage events | Create event, list events, get event |
116
+ | `calendar` | Full calendar access | All calendar tools |
117
+
118
+ ### Scope Examples
119
+
120
+ ```bash
121
+ # Gmail read-only
122
+ GOOGLE_SCOPES=gmail.readonly
123
+
124
+ # Gmail and Calendar read-only
125
+ GOOGLE_SCOPES=gmail.readonly,calendar.readonly
126
+
127
+ # Gmail read/send + Calendar read/create
128
+ GOOGLE_SCOPES=gmail.readonly,gmail.send,calendar.events
129
+
130
+ # Full access (all tools)
131
+ GOOGLE_SCOPES=gmail.readonly,gmail.modify,gmail.send,gmail.labels,calendar
132
+ ```
133
+
134
+ ## Claude Desktop Integration
135
+
136
+ Add to your Claude Desktop config (`~/Library/Application Support/Claude/claude_desktop_config.json` on macOS):
137
+
138
+ ```json
139
+ {
140
+ "mcpServers": {
141
+ "gmcp": {
142
+ "command": "bun",
143
+ "args": ["run", "/path/to/gmcp/src/index.ts"],
144
+ "env": {
145
+ "GOOGLE_CREDENTIALS_PATH": "/path/to/credentials.json",
146
+ "GOOGLE_TOKEN_PATH": "/path/to/token.json",
147
+ "GOOGLE_SCOPES": "gmail.readonly,gmail.send,gmail.labels,calendar.events"
148
+ }
149
+ }
150
+ }
151
+ }
152
+ ```
153
+
154
+ ## Docker
155
+
156
+ Run with Docker:
157
+
158
+ ```bash
159
+ docker build -t gmcp-server .
160
+ docker run -i \
161
+ -v /path/to/credentials.json:/app/data/credentials.json:ro \
162
+ -v /path/to/token.json:/app/data/token.json \
163
+ -e GOOGLE_CREDENTIALS_PATH=/app/data/credentials.json \
164
+ -e GOOGLE_TOKEN_PATH=/app/data/token.json \
165
+ -e GOOGLE_SCOPES=gmail.readonly,gmail.labels,gmail.send,calendar.events \
166
+ gmcp-server
167
+ ```
168
+
169
+ ## Testing
170
+
171
+ Test with MCP Inspector:
172
+
173
+ ```bash
174
+ bunx @modelcontextprotocol/inspector bun run start
175
+ ```
176
+
177
+ ## Future Enhancements
178
+
179
+ Potential additions include Google Drive, Google Sheets, and other Google Workspace services.
180
+
181
+ ## License
182
+
183
+ MIT
@@ -0,0 +1,82 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ createOAuth2Client,
4
+ getAuthUrl,
5
+ getEnvConfig,
6
+ getTokensFromCode,
7
+ loadCredentials,
8
+ saveTokens
9
+ } from "./shared/chunk-n2k9eesp.js";
10
+
11
+ // src/auth-cli.ts
12
+ import { createInterface } from "node:readline";
13
+ function readLine() {
14
+ const rl = createInterface({
15
+ input: process.stdin,
16
+ output: process.stdout
17
+ });
18
+ return new Promise((resolve) => {
19
+ rl.on("line", (line) => {
20
+ rl.close();
21
+ resolve(line.trim());
22
+ });
23
+ });
24
+ }
25
+ async function main() {
26
+ console.log(`GMCP Server - OAuth2 Authentication
27
+ `);
28
+ const { credentialsPath, tokenPath, scopes } = getEnvConfig();
29
+ console.log(`Credentials file: ${credentialsPath}`);
30
+ console.log(`Token file: ${tokenPath}`);
31
+ console.log(`Scopes: ${scopes.join(", ")}
32
+ `);
33
+ console.log("Loading OAuth2 credentials...");
34
+ const credentials = await loadCredentials(credentialsPath);
35
+ const oauth2Client = createOAuth2Client(credentials);
36
+ const authUrl = getAuthUrl(oauth2Client, scopes);
37
+ console.log(`
38
+ ========================================`);
39
+ console.log("STEP 1: Visit this URL to authorize:");
40
+ console.log("========================================");
41
+ console.log("\x1B[36m%s\x1B[0m", authUrl);
42
+ console.log(`
43
+ ========================================`);
44
+ console.log("STEP 2: After authorizing:");
45
+ console.log("========================================");
46
+ console.log('You will be redirected to localhost (which will show "connection refused").');
47
+ console.log("This is EXPECTED! Look at the URL in your browser's address bar.");
48
+ console.log(`
49
+ The URL will look like:`);
50
+ console.log(" http://localhost:PORT/?code=YOUR_CODE_HERE&scope=...");
51
+ console.log(`
52
+ Copy the entire code after "code=" (the long string before "&scope")`);
53
+ console.log(`
54
+ ========================================`);
55
+ console.log("STEP 3: Paste the authorization code below:");
56
+ console.log("========================================");
57
+ const code = await readLine();
58
+ if (!code) {
59
+ console.error("Error: No authorization code provided");
60
+ process.exit(1);
61
+ }
62
+ console.log(`
63
+ Exchanging authorization code for tokens...`);
64
+ try {
65
+ const tokens = await getTokensFromCode(oauth2Client, code);
66
+ await saveTokens(tokenPath, tokens);
67
+ console.log("\x1B[32m%s\x1B[0m", `
68
+ Success! Tokens saved to`, tokenPath);
69
+ console.log(`
70
+ You can now run the MCP server with: npx gmcp`);
71
+ } catch (error) {
72
+ console.error("\x1B[31m%s\x1B[0m", `
73
+ Error exchanging code for tokens:`);
74
+ console.error(error);
75
+ process.exit(1);
76
+ }
77
+ }
78
+ main().catch((error) => {
79
+ console.error("\x1B[31m%s\x1B[0m", "Fatal error:");
80
+ console.error(error);
81
+ process.exit(1);
82
+ });