gmcp 0.2.0 → 0.3.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Johnie Hjelm
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,182 +1,234 @@
1
- # GMCP
1
+ <p align="center">
2
+ <h1 align="center">🔗<br/><code>gmcp</code></h1>
3
+ <p align="center">MCP server for Gmail and Google Calendar integration.
4
+ <br/>
5
+ by <a href="https://github.com/johnie">@johnie</a>
6
+ </p>
7
+ </p>
8
+ <br/>
2
9
 
3
- MCP (Model Context Protocol) server for Google services. Provides Gmail and Google Calendar integration with 19 tools for email management and calendar operations.
10
+ <p align="center">
11
+ <a href="https://www.npmjs.com/package/gmcp" rel="nofollow"><img src="https://img.shields.io/npm/v/gmcp.svg" alt="npm"></a>
12
+ <a href="https://hub.docker.com/r/johnie/gmcp" rel="nofollow"><img src="https://img.shields.io/docker/pulls/johnie/gmcp" alt="Docker Pulls"></a>
13
+ <a href="https://github.com/johnie/gmcp" rel="nofollow"><img src="https://img.shields.io/github/stars/johnie/gmcp" alt="stars"></a>
14
+ </p>
4
15
 
5
- ## Gmail Tools
16
+ <br/>
17
+ <br/>
6
18
 
7
- ### Email Operations
19
+ ## Overview
8
20
 
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 |
21
+ GMCP is a [Model Context Protocol](https://modelcontextprotocol.io/) server that enables LLMs to interact with Gmail and Google Calendar. It provides tools for searching emails, managing labels, sending messages, and working with calendar events—all through secure OAuth2 authentication.
19
22
 
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 |
23
+ ## Installation
31
24
 
32
- ## Calendar Tools
25
+ ### NPM (Recommended)
33
26
 
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
27
+ ```bash
28
+ # Install globally
29
+ npm install -g gmcp
44
30
 
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
31
+ # Or run directly
32
+ npx gmcp
33
+ bunx gmcp
34
+ ```
49
35
 
50
- ### Install & Configure
36
+ ### Docker
51
37
 
52
38
  ```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
39
+ docker pull johnie/gmcp:latest
63
40
  ```
64
41
 
65
- ### Authenticate
66
-
67
- Run the OAuth flow to obtain tokens:
42
+ ### From Source
68
43
 
69
44
  ```bash
70
- bun run auth
45
+ git clone https://github.com/johnie/gmcp.git
46
+ cd gmcp
47
+ bun install
71
48
  ```
72
49
 
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
50
+ ## Quick Start
51
+
52
+ ### 1. Google Cloud Setup
78
53
 
79
- The browser will show "connection refused" after authorization - **this is expected**. Just copy the `code=` parameter from the URL.
54
+ 1. Create a project in [Google Cloud Console](https://console.cloud.google.com/)
55
+ 2. Enable **Gmail API** and **Calendar API**
56
+ 3. Create **OAuth 2.0 Client ID** (Desktop Application type)
57
+ 4. Download the credentials JSON file
80
58
 
81
- ### Run the Server
59
+ ### 2. Authenticate
82
60
 
83
61
  ```bash
84
- bun run start
85
- ```
62
+ # If installed globally
63
+ gmcp auth
86
64
 
87
- The server runs via stdio and is ready to accept MCP requests.
65
+ # Or with npx
66
+ npx gmcp auth
88
67
 
89
- ## Configuration
68
+ # Or from source
69
+ bun run auth
70
+ ```
90
71
 
91
- ### Environment Variables
72
+ Follow the prompts to authorize. The browser will show "connection refused" after authorization - this is expected. Copy the `code=` parameter from the URL.
92
73
 
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) |
74
+ ### 3. Run
98
75
 
99
- ### Gmail Scopes
76
+ ```bash
77
+ # Globally installed
78
+ gmcp start
79
+ # or just: gmcp
100
80
 
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 |
81
+ # With npx
82
+ npx gmcp start
108
83
 
109
- ### Calendar Scopes
84
+ # From source
85
+ bun run start
86
+ ```
110
87
 
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 |
88
+ ## Claude Desktop Integration
117
89
 
118
- ### Scope Examples
90
+ ### Using npx (Recommended)
119
91
 
120
- ```bash
121
- # Gmail read-only
122
- GOOGLE_SCOPES=gmail.readonly
92
+ Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
123
93
 
124
- # Gmail and Calendar read-only
125
- GOOGLE_SCOPES=gmail.readonly,calendar.readonly
94
+ ```json
95
+ {
96
+ "mcpServers": {
97
+ "gmcp": {
98
+ "command": "npx",
99
+ "args": ["-y", "gmcp"],
100
+ "env": {
101
+ "GOOGLE_CREDENTIALS_PATH": "/path/to/credentials.json",
102
+ "GOOGLE_TOKEN_PATH": "/path/to/token.json",
103
+ "GOOGLE_SCOPES": "gmail.readonly,gmail.send,calendar.events"
104
+ }
105
+ }
106
+ }
107
+ }
108
+ ```
126
109
 
127
- # Gmail read/send + Calendar read/create
128
- GOOGLE_SCOPES=gmail.readonly,gmail.send,calendar.events
110
+ ### Using Docker
129
111
 
130
- # Full access (all tools)
131
- GOOGLE_SCOPES=gmail.readonly,gmail.modify,gmail.send,gmail.labels,calendar
112
+ ```json
113
+ {
114
+ "mcpServers": {
115
+ "gmcp": {
116
+ "command": "docker",
117
+ "args": [
118
+ "run", "-i", "--rm",
119
+ "-v", "/path/to/credentials.json:/app/data/credentials.json:ro",
120
+ "-v", "/path/to/token.json:/app/data/token.json",
121
+ "-e", "GOOGLE_CREDENTIALS_PATH=/app/data/credentials.json",
122
+ "-e", "GOOGLE_TOKEN_PATH=/app/data/token.json",
123
+ "-e", "GOOGLE_SCOPES=gmail.readonly,gmail.send,calendar.events",
124
+ "johnie/gmcp:latest"
125
+ ]
126
+ }
127
+ }
128
+ }
132
129
  ```
133
130
 
134
- ## Claude Desktop Integration
135
-
136
- Add to your Claude Desktop config (`~/Library/Application Support/Claude/claude_desktop_config.json` on macOS):
131
+ ### Using Bun (From Source)
137
132
 
138
133
  ```json
139
134
  {
140
135
  "mcpServers": {
141
136
  "gmcp": {
142
137
  "command": "bun",
143
- "args": ["run", "/path/to/gmcp/src/index.ts"],
138
+ "args": ["run", "/path/to/gmcp/src/cli.ts"],
144
139
  "env": {
145
140
  "GOOGLE_CREDENTIALS_PATH": "/path/to/credentials.json",
146
141
  "GOOGLE_TOKEN_PATH": "/path/to/token.json",
147
- "GOOGLE_SCOPES": "gmail.readonly,gmail.send,gmail.labels,calendar.events"
142
+ "GOOGLE_SCOPES": "gmail.readonly,gmail.send,calendar.events"
148
143
  }
149
144
  }
150
145
  }
151
146
  }
152
147
  ```
153
148
 
154
- ## Docker
149
+ ## Tools
150
+
151
+ ### Gmail (15 tools)
152
+
153
+ | Tool | Description |
154
+ |------|-------------|
155
+ | `gmcp_gmail_search_emails` | Search with Gmail query syntax |
156
+ | `gmcp_gmail_get_email` | Get message by ID |
157
+ | `gmcp_gmail_get_thread` | Get conversation thread |
158
+ | `gmcp_gmail_list_attachments` | List attachments on message |
159
+ | `gmcp_gmail_get_attachment` | Download attachment data |
160
+ | `gmcp_gmail_send_email` | Send new email |
161
+ | `gmcp_gmail_reply` | Reply to email in thread |
162
+ | `gmcp_gmail_create_draft` | Create draft message |
163
+ | `gmcp_gmail_list_labels` | List all labels |
164
+ | `gmcp_gmail_get_label` | Get label details |
165
+ | `gmcp_gmail_create_label` | Create custom label |
166
+ | `gmcp_gmail_update_label` | Update label settings |
167
+ | `gmcp_gmail_delete_label` | Delete custom label |
168
+ | `gmcp_gmail_modify_labels` | Add/remove labels on message |
169
+ | `gmcp_gmail_batch_modify` | Batch label operations |
170
+
171
+ ### Calendar (4 tools)
155
172
 
156
- Run with Docker:
173
+ | Tool | Description |
174
+ |------|-------------|
175
+ | `gmcp_calendar_list_calendars` | List all calendars |
176
+ | `gmcp_calendar_list_events` | List events with filters |
177
+ | `gmcp_calendar_get_event` | Get event by ID |
178
+ | `gmcp_calendar_create_event` | Create event (supports recurring, Google Meet) |
179
+
180
+ ## Configuration
181
+
182
+ ### Environment Variables
183
+
184
+ | Variable | Description |
185
+ |----------|-------------|
186
+ | `GOOGLE_CREDENTIALS_PATH` | Path to OAuth2 credentials JSON |
187
+ | `GOOGLE_TOKEN_PATH` | Path to store OAuth2 tokens |
188
+ | `GOOGLE_SCOPES` | Comma-separated API scopes |
189
+
190
+ ### Scopes
191
+
192
+ | Scope | Access |
193
+ |-------|--------|
194
+ | `gmail.readonly` | Read emails and labels |
195
+ | `gmail.send` | Send emails |
196
+ | `gmail.modify` | Read, modify labels |
197
+ | `gmail.labels` | Manage labels |
198
+ | `gmail.compose` | Create drafts and send |
199
+ | `calendar.readonly` | Read calendars and events |
200
+ | `calendar.events` | Manage events |
201
+ | `calendar` | Full calendar access |
202
+
203
+ **Examples:**
157
204
 
158
205
  ```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
206
+ # Read-only
207
+ GOOGLE_SCOPES=gmail.readonly,calendar.readonly
208
+
209
+ # Full access
210
+ GOOGLE_SCOPES=gmail.readonly,gmail.modify,gmail.send,calendar.events
167
211
  ```
168
212
 
169
- ## Testing
213
+ ## CLI Reference
170
214
 
171
- Test with MCP Inspector:
215
+ ```
216
+ gmcp [command]
172
217
 
173
- ```bash
174
- bunx @modelcontextprotocol/inspector bun run start
218
+ Commands:
219
+ start Start MCP server (default)
220
+ auth Run OAuth2 authentication flow
221
+
222
+ Options:
223
+ --help, -h Show usage
224
+ --version, -v Show version
175
225
  ```
176
226
 
177
- ## Future Enhancements
227
+ ## Testing
178
228
 
179
- Potential additions include Google Drive, Google Sheets, and other Google Workspace services.
229
+ ```bash
230
+ bunx @modelcontextprotocol/inspector bun run start
231
+ ```
180
232
 
181
233
  ## License
182
234
 
@@ -0,0 +1,2 @@
1
+ declare function runAuth(): Promise<void>;
2
+ export { runAuth };
package/dist/auth-cli.js CHANGED
@@ -7,22 +7,12 @@ import {
7
7
  loadCredentials,
8
8
  saveTokens
9
9
  } from "./shared/chunk-n2k9eesp.js";
10
+ import"./shared/chunk-3s189drz.js";
10
11
 
11
12
  // 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() {
13
+ import { input } from "@inquirer/prompts";
14
+ import kleur from "kleur";
15
+ async function runAuth() {
26
16
  console.log(`GMCP Server - OAuth2 Authentication
27
17
  `);
28
18
  const { credentialsPath, tokenPath, scopes } = getEnvConfig();
@@ -38,7 +28,7 @@ async function main() {
38
28
  ========================================`);
39
29
  console.log("STEP 1: Visit this URL to authorize:");
40
30
  console.log("========================================");
41
- console.log("\x1B[36m%s\x1B[0m", authUrl);
31
+ console.log(kleur.cyan(authUrl));
42
32
  console.log(`
43
33
  ========================================`);
44
34
  console.log("STEP 2: After authorizing:");
@@ -53,30 +43,34 @@ Copy the entire code after "code=" (the long string before "&scope")`);
53
43
  console.log(`
54
44
  ========================================`);
55
45
  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
- }
46
+ console.log(`========================================
47
+ `);
48
+ const code = await input({
49
+ message: "Authorization code:",
50
+ required: true,
51
+ validate: (value) => {
52
+ if (value.length < 10) {
53
+ return "Authorization code appears too short";
54
+ }
55
+ return true;
56
+ }
57
+ });
62
58
  console.log(`
63
59
  Exchanging authorization code for tokens...`);
64
60
  try {
65
61
  const tokens = await getTokensFromCode(oauth2Client, code);
66
62
  await saveTokens(tokenPath, tokens);
67
- console.log("\x1B[32m%s\x1B[0m", `
68
- Success! Tokens saved to`, tokenPath);
63
+ console.log(kleur.green(`
64
+ Success! Tokens saved to ${tokenPath}`));
69
65
  console.log(`
70
66
  You can now run the MCP server with: npx gmcp`);
71
67
  } catch (error) {
72
- console.error("\x1B[31m%s\x1B[0m", `
73
- Error exchanging code for tokens:`);
68
+ console.error(kleur.red(`
69
+ Error exchanging code for tokens:`));
74
70
  console.error(error);
75
71
  process.exit(1);
76
72
  }
77
73
  }
78
- main().catch((error) => {
79
- console.error("\x1B[31m%s\x1B[0m", "Fatal error:");
80
- console.error(error);
81
- process.exit(1);
82
- });
74
+ export {
75
+ runAuth
76
+ };
package/dist/cli.js ADDED
@@ -0,0 +1,57 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ getVersion
4
+ } from "./shared/chunk-f7kh3eqv.js";
5
+ import {
6
+ __require
7
+ } from "./shared/chunk-3s189drz.js";
8
+
9
+ // src/cli.ts
10
+ import { run } from "@stricli/core";
11
+
12
+ // src/cli/app.ts
13
+ import { buildApplication, buildRouteMap } from "@stricli/core";
14
+
15
+ // src/cli/commands/auth.ts
16
+ import { buildCommand } from "@stricli/core";
17
+ var authCommand = buildCommand({
18
+ func: async () => {
19
+ const { runAuth } = await import("./auth-cli.js");
20
+ await runAuth();
21
+ },
22
+ parameters: {},
23
+ docs: { brief: "Run OAuth2 authentication flow" }
24
+ });
25
+
26
+ // src/cli/commands/start.ts
27
+ import { buildCommand as buildCommand2 } from "@stricli/core";
28
+ var startCommand = buildCommand2({
29
+ func: async () => {
30
+ const { startServer } = await import("./index.js");
31
+ await startServer();
32
+ },
33
+ parameters: {},
34
+ docs: { brief: "Start the MCP server" }
35
+ });
36
+
37
+ // src/cli/app.ts
38
+ var routes = buildRouteMap({
39
+ routes: {
40
+ start: startCommand,
41
+ auth: authCommand
42
+ },
43
+ docs: { brief: "GMCP - Gmail and Calendar MCP Server" }
44
+ });
45
+ async function createApp() {
46
+ const version = await getVersion();
47
+ return buildApplication(routes, {
48
+ name: "gmcp",
49
+ versionInfo: { currentVersion: version }
50
+ });
51
+ }
52
+
53
+ // src/cli.ts
54
+ var app = await createApp();
55
+ var args = process.argv.slice(2);
56
+ var effectiveArgs = args.length === 0 ? ["start"] : args;
57
+ await run(app, effectiveArgs, { process });
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Main server initialization
3
+ */
4
+ declare function startServer(): Promise<void>;
5
+ export { startServer };
package/dist/index.js CHANGED
@@ -1,9 +1,13 @@
1
1
  #!/usr/bin/env node
2
+ import {
3
+ getVersion
4
+ } from "./shared/chunk-f7kh3eqv.js";
2
5
  import {
3
6
  createAuthenticatedClient,
4
7
  getEnvConfig,
5
8
  getHeader
6
9
  } from "./shared/chunk-n2k9eesp.js";
10
+ import"./shared/chunk-3s189drz.js";
7
11
 
8
12
  // src/index.ts
9
13
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
@@ -3193,9 +3197,10 @@ This tool modifies label properties. System labels (INBOX, SENT, etc.) can only
3193
3197
  - Requires \`gmail.labels\` or \`gmail.modify\` scope`;
3194
3198
 
3195
3199
  // src/index.ts
3196
- async function main() {
3200
+ async function startServer() {
3197
3201
  const logger = createLogger();
3198
- logger.info({ version: "1.0.0" }, "GMCP Server starting");
3202
+ const version = await getVersion();
3203
+ logger.info({ version }, "GMCP Server starting");
3199
3204
  const { credentialsPath, tokenPath, scopes } = getEnvConfig();
3200
3205
  logger.info({
3201
3206
  credentialsPath,
@@ -3210,7 +3215,7 @@ async function main() {
3210
3215
  logger.info("Gmail and Calendar clients initialized");
3211
3216
  const server = new McpServer({
3212
3217
  name: "gmcp-server",
3213
- version: "1.0.0"
3218
+ version
3214
3219
  });
3215
3220
  const tools = [
3216
3221
  {
@@ -3381,11 +3386,6 @@ async function main() {
3381
3386
  logger.info("MCP server connected via stdio");
3382
3387
  logger.info("Ready to accept requests");
3383
3388
  }
3384
- main().catch((error) => {
3385
- const logger = createLogger();
3386
- logger.error({
3387
- error: error instanceof Error ? error.message : String(error),
3388
- stack: error instanceof Error ? error.stack : undefined
3389
- }, "Fatal error");
3390
- process.exit(1);
3391
- });
3389
+ export {
3390
+ startServer
3391
+ };
@@ -0,0 +1,4 @@
1
+ import { createRequire } from "node:module";
2
+ var __require = /* @__PURE__ */ createRequire(import.meta.url);
3
+
4
+ export { __require };
@@ -0,0 +1,30 @@
1
+ // src/version.ts
2
+ import { readFile } from "node:fs/promises";
3
+ import { dirname, join } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ async function findPackageJson(startDir) {
6
+ let dir = startDir;
7
+ let prevDir = "";
8
+ while (dir !== prevDir) {
9
+ const candidate = join(dir, "package.json");
10
+ try {
11
+ const content = await readFile(candidate, "utf8");
12
+ const pkg = JSON.parse(content);
13
+ if (pkg.name === "gmcp") {
14
+ return candidate;
15
+ }
16
+ } catch {}
17
+ prevDir = dir;
18
+ dir = dirname(dir);
19
+ }
20
+ throw new Error("Could not find gmcp package.json");
21
+ }
22
+ async function getVersion() {
23
+ const __dirname2 = dirname(fileURLToPath(import.meta.url));
24
+ const packagePath = await findPackageJson(__dirname2);
25
+ const content = await readFile(packagePath, "utf8");
26
+ const pkg = JSON.parse(content);
27
+ return pkg.version;
28
+ }
29
+
30
+ export { getVersion };
package/package.json CHANGED
@@ -1,14 +1,13 @@
1
1
  {
2
2
  "name": "gmcp",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "GMCP Server for Google Workspace with OAuth2 authentication",
5
5
  "module": "src/index.ts",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",
8
8
  "type": "module",
9
9
  "bin": {
10
- "gmcp": "dist/index.js",
11
- "gmcp-auth": "dist/auth-cli.js"
10
+ "gmcp": "dist/cli.js"
12
11
  },
13
12
  "files": [
14
13
  "dist"
@@ -20,8 +19,8 @@
20
19
  }
21
20
  },
22
21
  "scripts": {
23
- "start": "bun run src/index.ts",
24
- "auth": "bun run src/auth-cli.ts",
22
+ "start": "bun run src/cli.ts",
23
+ "auth": "bun run src/cli.ts auth",
25
24
  "build": "bunup",
26
25
  "prepublishOnly": "bun run build",
27
26
  "prepare": "lefthook install",
@@ -45,9 +44,12 @@
45
44
  "anthropic"
46
45
  ],
47
46
  "dependencies": {
47
+ "@inquirer/prompts": "^8.2.0",
48
48
  "@modelcontextprotocol/sdk": "^1.25.3",
49
+ "@stricli/core": "^1.2.5",
49
50
  "googleapis": "^170.1.0",
50
51
  "json2md": "^2.0.3",
52
+ "kleur": "^4.1.5",
51
53
  "pino": "^9.7.0",
52
54
  "pino-pretty": "^13.0.0",
53
55
  "zod": "^4.3.6"