gogcli-mcp-contacts 2.30.0 → 3.0.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/dist/index.js +15017 -17810
- package/manifest.json +1 -1
- package/package.json +3 -3
- package/src/tools/contacts-extra.ts +25 -25
package/manifest.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"manifest_version": "0.3",
|
|
4
4
|
"name": "gogcli-mcp-contacts",
|
|
5
5
|
"display_name": "gogcli (Contacts)",
|
|
6
|
-
"version": "
|
|
6
|
+
"version": "3.0.0",
|
|
7
7
|
"description": "Extended Google Contacts for Claude via gogcli — auth + Contacts + Workspace directory (People API)",
|
|
8
8
|
"author": {
|
|
9
9
|
"name": "Chris Hall",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gogcli-mcp-contacts",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"mcpName": "io.github.chrischall/gogcli-mcp-contacts",
|
|
5
5
|
"description": "Extended Google Contacts + People MCP server via gogcli — auth + Contacts + Workspace directory (People API)",
|
|
6
6
|
"author": "Claude Code (AI) <https://www.anthropic.com/claude>",
|
|
@@ -24,8 +24,8 @@
|
|
|
24
24
|
"test:coverage": "vitest run --coverage"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@chrischall/mcp-utils": "^0.
|
|
28
|
-
"@modelcontextprotocol/
|
|
27
|
+
"@chrischall/mcp-utils": "^0.28.0",
|
|
28
|
+
"@modelcontextprotocol/server": "^2.0.0",
|
|
29
29
|
"zod": "^4.6.1"
|
|
30
30
|
},
|
|
31
31
|
"license": "MIT",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { McpServer } from '@modelcontextprotocol/
|
|
1
|
+
import { McpServer } from '@modelcontextprotocol/server';
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
import { accountParam, runOrDiagnose, pageTokenParam, pageAliasParam, resolvePageToken} from '../../../gogcli-mcp/src/lib.js';
|
|
4
4
|
|
|
@@ -8,9 +8,9 @@ export function registerExtraContactsTools(server: McpServer): void {
|
|
|
8
8
|
server.registerTool('gog_people_me', {
|
|
9
9
|
description: 'Show your own People profile (people/me).',
|
|
10
10
|
annotations: { readOnlyHint: true },
|
|
11
|
-
inputSchema: {
|
|
11
|
+
inputSchema: z.object({
|
|
12
12
|
account: accountParam,
|
|
13
|
-
},
|
|
13
|
+
}),
|
|
14
14
|
}, async ({ account }) => {
|
|
15
15
|
return runOrDiagnose(['people', 'me'], { account });
|
|
16
16
|
});
|
|
@@ -18,10 +18,10 @@ export function registerExtraContactsTools(server: McpServer): void {
|
|
|
18
18
|
server.registerTool('gog_people_get', {
|
|
19
19
|
description: 'Get a People profile by resource name.',
|
|
20
20
|
annotations: { readOnlyHint: true },
|
|
21
|
-
inputSchema: {
|
|
21
|
+
inputSchema: z.object({
|
|
22
22
|
userId: z.string().describe('Person resource name (people/...) or email'),
|
|
23
23
|
account: accountParam,
|
|
24
|
-
},
|
|
24
|
+
}),
|
|
25
25
|
}, async ({ userId, account }) => {
|
|
26
26
|
return runOrDiagnose(['people', 'get', userId], { account });
|
|
27
27
|
});
|
|
@@ -29,14 +29,14 @@ export function registerExtraContactsTools(server: McpServer): void {
|
|
|
29
29
|
server.registerTool('gog_people_search', {
|
|
30
30
|
description: 'Search the Google Workspace directory (covers internal users, unlike contacts search which is limited to your personal contacts).',
|
|
31
31
|
annotations: { readOnlyHint: true },
|
|
32
|
-
inputSchema: {
|
|
32
|
+
inputSchema: z.object({
|
|
33
33
|
query: z.string().describe('Search query (name, email, etc.)'),
|
|
34
34
|
max: z.number().optional().describe('Max results (default: 50)'),
|
|
35
35
|
pageToken: pageTokenParam,
|
|
36
36
|
page: pageAliasParam,
|
|
37
37
|
all: z.boolean().optional().describe('Fetch all pages'),
|
|
38
38
|
account: accountParam,
|
|
39
|
-
},
|
|
39
|
+
}),
|
|
40
40
|
}, async ({ query, max, pageToken, page, all, account }) => {
|
|
41
41
|
const args = ['people', 'search', query];
|
|
42
42
|
if (max !== undefined) args.push(`--max=${max}`);
|
|
@@ -49,11 +49,11 @@ export function registerExtraContactsTools(server: McpServer): void {
|
|
|
49
49
|
server.registerTool('gog_people_relations', {
|
|
50
50
|
description: 'Get relations (manager, reports, etc.) for a user. Defaults to self when userId is omitted.',
|
|
51
51
|
annotations: { readOnlyHint: true },
|
|
52
|
-
inputSchema: {
|
|
52
|
+
inputSchema: z.object({
|
|
53
53
|
userId: z.string().optional().describe('Person resource name (defaults to self when omitted)'),
|
|
54
54
|
type: z.string().optional().describe('Filter to a specific relation type (e.g. "manager")'),
|
|
55
55
|
account: accountParam,
|
|
56
|
-
},
|
|
56
|
+
}),
|
|
57
57
|
}, async ({ userId, type, account }) => {
|
|
58
58
|
const args = ['people', 'relations'];
|
|
59
59
|
if (userId) args.push(userId);
|
|
@@ -63,7 +63,7 @@ export function registerExtraContactsTools(server: McpServer): void {
|
|
|
63
63
|
|
|
64
64
|
server.registerTool('gog_contacts_update', {
|
|
65
65
|
description: 'Update an existing Google Contact. Empty string clears a field; repeatable fields (url/address/custom/relation) take comma/semicolon-separated lists.',
|
|
66
|
-
inputSchema: {
|
|
66
|
+
inputSchema: z.object({
|
|
67
67
|
resourceName: z.string().describe('Contact resource name (people/...)'),
|
|
68
68
|
given: z.string().optional().describe('Given (first) name'),
|
|
69
69
|
family: z.string().optional().describe('Family (last) name'),
|
|
@@ -77,7 +77,7 @@ export function registerExtraContactsTools(server: McpServer): void {
|
|
|
77
77
|
birthday: z.string().optional().describe('Birthday in YYYY-MM-DD (empty string clears)'),
|
|
78
78
|
ignoreEtag: z.boolean().optional().describe('Allow update even if a supplied etag is stale (may overwrite concurrent changes)'),
|
|
79
79
|
account: accountParam,
|
|
80
|
-
},
|
|
80
|
+
}),
|
|
81
81
|
}, async ({ resourceName, given, family, email, phone, org, title, url, note, address, birthday, ignoreEtag, account }) => {
|
|
82
82
|
const args = ['contacts', 'update', resourceName];
|
|
83
83
|
if (given !== undefined) args.push(`--given=${given}`);
|
|
@@ -97,10 +97,10 @@ export function registerExtraContactsTools(server: McpServer): void {
|
|
|
97
97
|
server.registerTool('gog_contacts_delete', {
|
|
98
98
|
description: 'Delete a Google Contact by resource name.',
|
|
99
99
|
annotations: { destructiveHint: true },
|
|
100
|
-
inputSchema: {
|
|
100
|
+
inputSchema: z.object({
|
|
101
101
|
resourceName: z.string().describe('Contact resource name (people/...)'),
|
|
102
102
|
account: accountParam,
|
|
103
|
-
},
|
|
103
|
+
}),
|
|
104
104
|
}, async ({ resourceName, account }) => {
|
|
105
105
|
return runOrDiagnose(['contacts', 'delete', resourceName, '--force'], { account }); // gog gates this op; without --force the runner's --no-input makes it refuse
|
|
106
106
|
});
|
|
@@ -108,7 +108,7 @@ export function registerExtraContactsTools(server: McpServer): void {
|
|
|
108
108
|
server.registerTool('gog_contacts_export', {
|
|
109
109
|
description: 'Export contacts as vCard (.vcf). Provide a selector (resource name, email, or name), or use query / all to export multiple.',
|
|
110
110
|
annotations: { readOnlyHint: true },
|
|
111
|
-
inputSchema: {
|
|
111
|
+
inputSchema: z.object({
|
|
112
112
|
selector: z.string().optional().describe('Contact resource name (people/...), email, or name'),
|
|
113
113
|
query: z.string().optional().describe('Search query to export (max 30 results)'),
|
|
114
114
|
all: z.boolean().optional().describe('Export all personal contacts'),
|
|
@@ -117,7 +117,7 @@ export function registerExtraContactsTools(server: McpServer): void {
|
|
|
117
117
|
pageToken: pageTokenParam,
|
|
118
118
|
page: pageAliasParam,
|
|
119
119
|
account: accountParam,
|
|
120
|
-
},
|
|
120
|
+
}),
|
|
121
121
|
}, async ({ selector, query, all, out, max, pageToken, page, account }) => {
|
|
122
122
|
const args = ['contacts', 'export'];
|
|
123
123
|
if (selector) args.push(selector);
|
|
@@ -133,14 +133,14 @@ export function registerExtraContactsTools(server: McpServer): void {
|
|
|
133
133
|
server.registerTool('gog_contacts_dedupe', {
|
|
134
134
|
description: 'Find likely duplicate personal contacts. Defaults to a read-only preview of the merge plan; set apply to actually merge each duplicate group and delete the redundant contacts (etag-checked, with ambiguous or unmergeable groups refused). Scope a risky apply with resource. Always preview first.',
|
|
135
135
|
annotations: { destructiveHint: true },
|
|
136
|
-
inputSchema: {
|
|
136
|
+
inputSchema: z.object({
|
|
137
137
|
match: z.string().optional().describe('Match fields, comma-separated from email,phone,name (default: email,phone)'),
|
|
138
138
|
max: z.number().optional().describe('Max contacts to scan (0 = all). Mutually exclusive with resource — gog rejects passing both.'),
|
|
139
139
|
resource: z.array(z.string()).optional().describe('Limit dedupe to these exact contact resource names (e.g. people/c123), repeatable — useful to scope an apply to known duplicates. Mutually exclusive with max.'),
|
|
140
140
|
apply: z.boolean().optional().describe('Merge each duplicate group and DELETE the redundant contacts. Without this the tool only previews the plan. Destructive — preview first.'),
|
|
141
141
|
failEmpty: z.boolean().optional().describe('Exit with an error (code 3) when no duplicates are found, instead of succeeding empty.'),
|
|
142
142
|
account: accountParam,
|
|
143
|
-
},
|
|
143
|
+
}),
|
|
144
144
|
}, async ({ match, max, resource, apply, failEmpty, account }) => {
|
|
145
145
|
const args = ['contacts', 'dedupe'];
|
|
146
146
|
if (match) args.push(`--match=${match}`);
|
|
@@ -155,13 +155,13 @@ export function registerExtraContactsTools(server: McpServer): void {
|
|
|
155
155
|
server.registerTool('gog_contacts_directory_list', {
|
|
156
156
|
description: 'List people from the Google Workspace directory (domain shared contacts).',
|
|
157
157
|
annotations: { readOnlyHint: true },
|
|
158
|
-
inputSchema: {
|
|
158
|
+
inputSchema: z.object({
|
|
159
159
|
max: z.number().optional().describe('Max results (default: 50)'),
|
|
160
160
|
pageToken: pageTokenParam,
|
|
161
161
|
page: pageAliasParam,
|
|
162
162
|
all: z.boolean().optional().describe('Fetch all pages'),
|
|
163
163
|
account: accountParam,
|
|
164
|
-
},
|
|
164
|
+
}),
|
|
165
165
|
}, async ({ max, pageToken, page, all, account }) => {
|
|
166
166
|
const args = ['contacts', 'directory', 'list'];
|
|
167
167
|
if (max !== undefined) args.push(`--max=${max}`);
|
|
@@ -174,13 +174,13 @@ export function registerExtraContactsTools(server: McpServer): void {
|
|
|
174
174
|
server.registerTool('gog_contacts_other_list', {
|
|
175
175
|
description: 'List "other contacts" — auto-collected addresses (e.g. people you have emailed) that are not in your saved contacts.',
|
|
176
176
|
annotations: { readOnlyHint: true },
|
|
177
|
-
inputSchema: {
|
|
177
|
+
inputSchema: z.object({
|
|
178
178
|
max: z.number().optional().describe('Max results (default: 100)'),
|
|
179
179
|
pageToken: pageTokenParam,
|
|
180
180
|
page: pageAliasParam,
|
|
181
181
|
all: z.boolean().optional().describe('Fetch all pages'),
|
|
182
182
|
account: accountParam,
|
|
183
|
-
},
|
|
183
|
+
}),
|
|
184
184
|
}, async ({ max, pageToken, page, all, account }) => {
|
|
185
185
|
const args = ['contacts', 'other', 'list'];
|
|
186
186
|
if (max !== undefined) args.push(`--max=${max}`);
|
|
@@ -193,11 +193,11 @@ export function registerExtraContactsTools(server: McpServer): void {
|
|
|
193
193
|
server.registerTool('gog_contacts_other_search', {
|
|
194
194
|
description: 'Search "other contacts" — auto-collected addresses not in your saved contacts.',
|
|
195
195
|
annotations: { readOnlyHint: true },
|
|
196
|
-
inputSchema: {
|
|
196
|
+
inputSchema: z.object({
|
|
197
197
|
query: z.string().describe('Search query'),
|
|
198
198
|
max: z.number().optional().describe('Max results (default: 50)'),
|
|
199
199
|
account: accountParam,
|
|
200
|
-
},
|
|
200
|
+
}),
|
|
201
201
|
}, async ({ query, max, account }) => {
|
|
202
202
|
const args = ['contacts', 'other', 'search', query];
|
|
203
203
|
if (max !== undefined) args.push(`--max=${max}`);
|
|
@@ -207,12 +207,12 @@ export function registerExtraContactsTools(server: McpServer): void {
|
|
|
207
207
|
server.registerTool('gog_people_raw', {
|
|
208
208
|
description: 'Dump the raw People API response as JSON (lossless; for scripting and LLM consumption).',
|
|
209
209
|
annotations: { readOnlyHint: true },
|
|
210
|
-
inputSchema: {
|
|
210
|
+
inputSchema: z.object({
|
|
211
211
|
userId: z.string().describe('Person resource name (people/...) or email'),
|
|
212
212
|
personFields: z.string().optional().describe('People API personFields mask (default: broad set)'),
|
|
213
213
|
pretty: z.boolean().optional().describe('Pretty-print JSON (default: compact single-line)'),
|
|
214
214
|
account: accountParam,
|
|
215
|
-
},
|
|
215
|
+
}),
|
|
216
216
|
}, async ({ userId, personFields, pretty, account }) => {
|
|
217
217
|
const args = ['people', 'raw', userId];
|
|
218
218
|
if (personFields) args.push(`--person-fields=${personFields}`);
|