gogcli-mcp 2.27.1 → 2.28.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/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/README.md +3 -3
- package/SKILL.md +2 -2
- package/dist/index.js +25 -1
- package/dist/lib.js +26 -2
- package/manifest.json +5 -1
- package/mint.yaml +1 -1
- package/package.json +1 -1
- package/server.json +2 -2
- package/src/runner.ts +1 -1
- package/src/tools/chat.ts +36 -1
- package/src/worker.ts +1 -1
- package/tests/tools/chat.test.ts +61 -1
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
},
|
|
8
8
|
"metadata": {
|
|
9
9
|
"description": "Google Sheets (and more) for Claude via gogcli — read, write, and manage spreadsheets",
|
|
10
|
-
"version": "2.
|
|
10
|
+
"version": "2.28.0"
|
|
11
11
|
},
|
|
12
12
|
"plugins": [
|
|
13
13
|
{
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"displayName": "gogcli",
|
|
16
16
|
"source": "./",
|
|
17
17
|
"description": "Google Sheets (and more) for Claude via gogcli — read, write, and manage spreadsheets",
|
|
18
|
-
"version": "2.
|
|
18
|
+
"version": "2.28.0",
|
|
19
19
|
"author": {
|
|
20
20
|
"name": "Chris Hall"
|
|
21
21
|
},
|
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
> [!WARNING]
|
|
4
4
|
> **AI-developed project.** This codebase was built and is actively maintained by [Claude Code](https://www.anthropic.com/claude). Review all code and tool permissions before use.
|
|
5
5
|
|
|
6
|
-
Base [Model Context Protocol](https://modelcontextprotocol.io) server that gives Claude access to Google Workspace via [gogcli](https://github.com/openclaw/gogcli). Includes
|
|
6
|
+
Base [Model Context Protocol](https://modelcontextprotocol.io) server that gives Claude access to Google Workspace via [gogcli](https://github.com/openclaw/gogcli). Includes 115 tools across 13 services: Sheets, Docs, Gmail, Calendar, Drive, Slides, Classroom, Chat, Apps Script, Tasks, Contacts, the generic Discovery API escape hatch, and Auth.
|
|
7
7
|
|
|
8
8
|
For extended Sheets or Docs support, see [gogcli-mcp-sheets](https://www.npmjs.com/package/gogcli-mcp-sheets) and [gogcli-mcp-docs](https://www.npmjs.com/package/gogcli-mcp-docs).
|
|
9
9
|
|
|
@@ -46,7 +46,7 @@ Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
|
|
|
46
46
|
claude mcp add gogcli-mcp -- gogcli-mcp
|
|
47
47
|
```
|
|
48
48
|
|
|
49
|
-
## Tools (
|
|
49
|
+
## Tools (115)
|
|
50
50
|
|
|
51
51
|
| Service | Tools | Includes |
|
|
52
52
|
|---------|-------|----------|
|
|
@@ -57,7 +57,7 @@ claude mcp add gogcli-mcp -- gogcli-mcp
|
|
|
57
57
|
| **Drive** | 11 | ls, search, get, mkdir, rename, move, delete, share, extract-text, read-bytes, run |
|
|
58
58
|
| **Slides** | 7 | export, info, create, copy, list-slides, read-slide, run |
|
|
59
59
|
| **Classroom** | 25 | courses, students, teachers, roster, coursework, submissions (grade/return/turn-in/reclaim), announcements, topics, invitations, profile, run |
|
|
60
|
-
| **Chat** |
|
|
60
|
+
| **Chat** | 13 | spaces list/find/create, threads list, messages list/search/send, dm send/space, reactions list/create/delete, run |
|
|
61
61
|
| **Apps Script** | 8 | get, content, pull, create, deployments, versions, run-function, run |
|
|
62
62
|
| **Tasks** | 7 | lists, list, get, add, done, delete, run |
|
|
63
63
|
| **Contacts** | 5 | search, list, get, create, run |
|
package/SKILL.md
CHANGED
|
@@ -32,7 +32,7 @@ MCP server wrapping [gogcli](https://github.com/openclaw/gogcli) — provides Cl
|
|
|
32
32
|
|
|
33
33
|
`GOG_ACCOUNT` is optional — omit it to use gogcli's configured default account.
|
|
34
34
|
|
|
35
|
-
## Tools (
|
|
35
|
+
## Tools (115)
|
|
36
36
|
|
|
37
37
|
| Service | Tools |
|
|
38
38
|
|---------|-------|
|
|
@@ -43,7 +43,7 @@ MCP server wrapping [gogcli](https://github.com/openclaw/gogcli) — provides Cl
|
|
|
43
43
|
| **Drive** (11) | ls, search, get, mkdir, rename, move, delete, share, extract-text, read-bytes, run |
|
|
44
44
|
| **Slides** (7) | export, info, create, copy, list-slides, read-slide, run |
|
|
45
45
|
| **Classroom** (25) | courses, students, teachers, roster, coursework, submissions (grade/return/turn-in/reclaim), announcements, topics, invitations, profile, run |
|
|
46
|
-
| **Chat** (
|
|
46
|
+
| **Chat** (13) | spaces list/find/create, threads list, messages list/search/send, dm send/space, reactions list/create/delete, run |
|
|
47
47
|
| **Apps Script** (8) | get, content, pull, create, deployments, versions, run-function, run |
|
|
48
48
|
| **Tasks** (7) | lists, list, get, add, done, delete, run |
|
|
49
49
|
| **Contacts** (5) | search, list, get, create, run |
|
package/dist/index.js
CHANGED
|
@@ -32755,6 +32755,30 @@ function registerChatTools(server) {
|
|
|
32755
32755
|
pushPaginationFlags(args, { max, pageToken, page, all });
|
|
32756
32756
|
return runOrDiagnose(args, { account });
|
|
32757
32757
|
});
|
|
32758
|
+
server.registerTool("gog_chat_messages_search", {
|
|
32759
|
+
description: 'Search Chat messages ACROSS every space and DM the account can see (gog >= 0.39.0) \u2014 the tool to reach for when the user asks "where did we discuss X" without naming a room, since gog_chat_messages_list needs a space up front. The query is Google Chat filter syntax, so it takes plain keywords or filters like sender, space, date, mention, unread, link and attachment. It is a search, NOT an export: Chat excludes some conversations (muted spaces among them), so an empty result does not prove a message never existed. view="full" adds each hit\'s read state and space mute setting; read state works on an ordinary chat grant, but the mute setting needs chat.users.spacesettings, which gog\'s chat scope set does NOT request (re-auth with extraScopes to get it). Missing metadata is OMITTED rather than defaulted, so an absent `read` means unknown while an explicit false means unread.' + workspaceOnlyNote,
|
|
32760
|
+
annotations: { readOnlyHint: true },
|
|
32761
|
+
inputSchema: {
|
|
32762
|
+
query: external_exports.string().describe('Google Chat filter-syntax query \u2014 keywords, or filters such as "from:alice@example.com budget"'),
|
|
32763
|
+
order: external_exports.enum(["create_time desc", "relevance desc"]).optional().describe(
|
|
32764
|
+
`Sort order. NOTE the snake_case, which differs from gog_chat_messages_list's camelCase. "relevance desc" needs Google Developer Preview access and errors without it`
|
|
32765
|
+
),
|
|
32766
|
+
view: external_exports.enum(["basic", "full"]).optional().describe(
|
|
32767
|
+
'Result view (default "basic"). "full" also requests read state (covered by an ordinary chat grant) and space mute setting (needs chat.users.spacesettings, which that grant does not include)'
|
|
32768
|
+
),
|
|
32769
|
+
markup: external_exports.enum(["chat", "markdown"]).optional().describe("Syntax to render each hit's formatted text in"),
|
|
32770
|
+
...paginationParams,
|
|
32771
|
+
max: external_exports.number().int().min(1).max(100).optional().describe("Max results per page (1-100; Chat search caps a page at 100)"),
|
|
32772
|
+
account: accountParam
|
|
32773
|
+
}
|
|
32774
|
+
}, async ({ query, order, view, markup, max, pageToken, page, all, account }) => {
|
|
32775
|
+
const args = ["chat", "messages", "search", query];
|
|
32776
|
+
if (order) args.push(`--order=${order}`);
|
|
32777
|
+
if (view) args.push(`--view=${view}`);
|
|
32778
|
+
if (markup) args.push(`--markup=${markup}`);
|
|
32779
|
+
pushPaginationFlags(args, { max, pageToken, page, all });
|
|
32780
|
+
return runOrDiagnose(args, { account });
|
|
32781
|
+
});
|
|
32758
32782
|
server.registerTool("gog_chat_messages_send", {
|
|
32759
32783
|
description: "Post a message to a Chat space. THIS IS IMMEDIATELY VISIBLE TO EVERYONE IN THE SPACE and cannot be unsent through this tool, so treat it like sending mail, not like saving a draft. Pass `thread` to reply inside an existing conversation (from gog_chat_threads_list or a message's thread field); omit it to start a new one. Text supports Chat's markdown-ish formatting (*bold*, _italic_, `code`)." + workspaceOnlyNote,
|
|
32760
32784
|
inputSchema: {
|
|
@@ -34167,7 +34191,7 @@ function registerTasksTools(server) {
|
|
|
34167
34191
|
}
|
|
34168
34192
|
|
|
34169
34193
|
// src/server.ts
|
|
34170
|
-
var VERSION = true ? "2.
|
|
34194
|
+
var VERSION = true ? "2.28.0" : "0.0.0";
|
|
34171
34195
|
var BASE_TOOL_REGISTRARS = [
|
|
34172
34196
|
registerApiTools,
|
|
34173
34197
|
registerAppScriptTools,
|
package/dist/lib.js
CHANGED
|
@@ -23325,7 +23325,7 @@ function activeExecutor() {
|
|
|
23325
23325
|
return runExecutor.getStore() ?? defaultExecutor;
|
|
23326
23326
|
}
|
|
23327
23327
|
var TIMEOUT_MS = 3e4;
|
|
23328
|
-
var MIN_GOG_VERSION = "0.
|
|
23328
|
+
var MIN_GOG_VERSION = "0.39.0";
|
|
23329
23329
|
function readonlyEnvEnabled() {
|
|
23330
23330
|
return readEnvVar("GOG_READONLY") !== void 0 && parseBoolEnv("GOG_READONLY", { default: true });
|
|
23331
23331
|
}
|
|
@@ -24604,6 +24604,30 @@ function registerChatTools(server) {
|
|
|
24604
24604
|
pushPaginationFlags(args, { max, pageToken, page, all });
|
|
24605
24605
|
return runOrDiagnose(args, { account });
|
|
24606
24606
|
});
|
|
24607
|
+
server.registerTool("gog_chat_messages_search", {
|
|
24608
|
+
description: 'Search Chat messages ACROSS every space and DM the account can see (gog >= 0.39.0) \u2014 the tool to reach for when the user asks "where did we discuss X" without naming a room, since gog_chat_messages_list needs a space up front. The query is Google Chat filter syntax, so it takes plain keywords or filters like sender, space, date, mention, unread, link and attachment. It is a search, NOT an export: Chat excludes some conversations (muted spaces among them), so an empty result does not prove a message never existed. view="full" adds each hit\'s read state and space mute setting; read state works on an ordinary chat grant, but the mute setting needs chat.users.spacesettings, which gog\'s chat scope set does NOT request (re-auth with extraScopes to get it). Missing metadata is OMITTED rather than defaulted, so an absent `read` means unknown while an explicit false means unread.' + workspaceOnlyNote,
|
|
24609
|
+
annotations: { readOnlyHint: true },
|
|
24610
|
+
inputSchema: {
|
|
24611
|
+
query: external_exports.string().describe('Google Chat filter-syntax query \u2014 keywords, or filters such as "from:alice@example.com budget"'),
|
|
24612
|
+
order: external_exports.enum(["create_time desc", "relevance desc"]).optional().describe(
|
|
24613
|
+
`Sort order. NOTE the snake_case, which differs from gog_chat_messages_list's camelCase. "relevance desc" needs Google Developer Preview access and errors without it`
|
|
24614
|
+
),
|
|
24615
|
+
view: external_exports.enum(["basic", "full"]).optional().describe(
|
|
24616
|
+
'Result view (default "basic"). "full" also requests read state (covered by an ordinary chat grant) and space mute setting (needs chat.users.spacesettings, which that grant does not include)'
|
|
24617
|
+
),
|
|
24618
|
+
markup: external_exports.enum(["chat", "markdown"]).optional().describe("Syntax to render each hit's formatted text in"),
|
|
24619
|
+
...paginationParams,
|
|
24620
|
+
max: external_exports.number().int().min(1).max(100).optional().describe("Max results per page (1-100; Chat search caps a page at 100)"),
|
|
24621
|
+
account: accountParam
|
|
24622
|
+
}
|
|
24623
|
+
}, async ({ query, order, view, markup, max, pageToken, page, all, account }) => {
|
|
24624
|
+
const args = ["chat", "messages", "search", query];
|
|
24625
|
+
if (order) args.push(`--order=${order}`);
|
|
24626
|
+
if (view) args.push(`--view=${view}`);
|
|
24627
|
+
if (markup) args.push(`--markup=${markup}`);
|
|
24628
|
+
pushPaginationFlags(args, { max, pageToken, page, all });
|
|
24629
|
+
return runOrDiagnose(args, { account });
|
|
24630
|
+
});
|
|
24607
24631
|
server.registerTool("gog_chat_messages_send", {
|
|
24608
24632
|
description: "Post a message to a Chat space. THIS IS IMMEDIATELY VISIBLE TO EVERYONE IN THE SPACE and cannot be unsent through this tool, so treat it like sending mail, not like saving a draft. Pass `thread` to reply inside an existing conversation (from gog_chat_threads_list or a message's thread field); omit it to start a new one. Text supports Chat's markdown-ish formatting (*bold*, _italic_, `code`)." + workspaceOnlyNote,
|
|
24609
24633
|
inputSchema: {
|
|
@@ -26016,7 +26040,7 @@ function registerTasksTools(server) {
|
|
|
26016
26040
|
}
|
|
26017
26041
|
|
|
26018
26042
|
// src/server.ts
|
|
26019
|
-
var VERSION = true ? "2.
|
|
26043
|
+
var VERSION = true ? "2.28.0" : "0.0.0";
|
|
26020
26044
|
var BASE_TOOL_REGISTRARS = [
|
|
26021
26045
|
registerApiTools,
|
|
26022
26046
|
registerAppScriptTools,
|
package/manifest.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"manifest_version": "0.3",
|
|
4
4
|
"name": "gogcli-mcp",
|
|
5
5
|
"display_name": "gogcli",
|
|
6
|
-
"version": "2.
|
|
6
|
+
"version": "2.28.0",
|
|
7
7
|
"description": "Google Sheets (and more) for Claude via gogcli — read, write, and manage spreadsheets",
|
|
8
8
|
"author": {
|
|
9
9
|
"name": "Chris Hall",
|
|
@@ -452,6 +452,10 @@
|
|
|
452
452
|
"name": "gog_chat_messages_list",
|
|
453
453
|
"description": "Read messages in a space, with mentions and reaction summaries"
|
|
454
454
|
},
|
|
455
|
+
{
|
|
456
|
+
"name": "gog_chat_messages_search",
|
|
457
|
+
"description": "Search Chat messages across every space and DM the account can see"
|
|
458
|
+
},
|
|
455
459
|
{
|
|
456
460
|
"name": "gog_chat_messages_send",
|
|
457
461
|
"description": "Post a message to a Chat space (immediately visible; supports attachments)"
|
package/mint.yaml
CHANGED
package/package.json
CHANGED
package/server.json
CHANGED
|
@@ -7,12 +7,12 @@
|
|
|
7
7
|
"source": "github",
|
|
8
8
|
"subfolder": "packages/gogcli-mcp"
|
|
9
9
|
},
|
|
10
|
-
"version": "2.
|
|
10
|
+
"version": "2.28.0",
|
|
11
11
|
"packages": [
|
|
12
12
|
{
|
|
13
13
|
"registryType": "npm",
|
|
14
14
|
"identifier": "gogcli-mcp",
|
|
15
|
-
"version": "2.
|
|
15
|
+
"version": "2.28.0",
|
|
16
16
|
"transport": {
|
|
17
17
|
"type": "stdio"
|
|
18
18
|
},
|
package/src/runner.ts
CHANGED
|
@@ -217,7 +217,7 @@ const TIMEOUT_MS = 30_000;
|
|
|
217
217
|
// so the requirement change is surfaced in the release notes (see
|
|
218
218
|
// .github/release.yml). This is the single source of truth for the required
|
|
219
219
|
// version; keep the README/CLAUDE.md mention in sync.
|
|
220
|
-
export const MIN_GOG_VERSION = '0.
|
|
220
|
+
export const MIN_GOG_VERSION = '0.39.0';
|
|
221
221
|
|
|
222
222
|
// Interpret the GOG_READONLY kill-switch. `readEnvVar` already treats blank
|
|
223
223
|
// values, 'undefined'/'null' sentinels, and unresolved .mcpb placeholders
|
package/src/tools/chat.ts
CHANGED
|
@@ -11,7 +11,7 @@ import type { GogArg } from '../runner.js';
|
|
|
11
11
|
import { attachInlineParam, inlineAttachmentArgs } from '../attachments.js';
|
|
12
12
|
|
|
13
13
|
// Google Chat (gog >= 0.38.0 for the mention/reaction metadata in
|
|
14
|
-
// `messages list
|
|
14
|
+
// `messages list`, >= 0.39.0 for `messages search`; the rest is older).
|
|
15
15
|
//
|
|
16
16
|
// TWO NAMING SYSTEMS MEET HERE, and mixing them is the mistake this module's
|
|
17
17
|
// descriptions exist to prevent. Chat identifies everything by RESOURCE NAME —
|
|
@@ -135,6 +135,41 @@ export function registerChatTools(server: McpServer): void {
|
|
|
135
135
|
return runOrDiagnose(args, { account });
|
|
136
136
|
});
|
|
137
137
|
|
|
138
|
+
server.registerTool('gog_chat_messages_search', {
|
|
139
|
+
description:
|
|
140
|
+
'Search Chat messages ACROSS every space and DM the account can see (gog >= 0.39.0) — the tool to reach for when the '
|
|
141
|
+
+ 'user asks "where did we discuss X" without naming a room, since gog_chat_messages_list needs a space up front. '
|
|
142
|
+
+ 'The query is Google Chat filter syntax, so it takes plain keywords or filters like sender, space, date, mention, '
|
|
143
|
+
+ 'unread, link and attachment. It is a search, NOT an export: Chat excludes some conversations (muted spaces among '
|
|
144
|
+
+ 'them), so an empty result does not prove a message never existed. view="full" adds each hit\'s read state and space '
|
|
145
|
+
+ 'mute setting; read state works on an ordinary chat grant, but the mute setting needs chat.users.spacesettings, '
|
|
146
|
+
+ 'which gog\'s chat scope set does NOT request (re-auth with extraScopes to get it). Missing metadata is OMITTED '
|
|
147
|
+
+ 'rather than defaulted, so an absent `read` means unknown while an explicit false means unread.' + workspaceOnlyNote,
|
|
148
|
+
annotations: { readOnlyHint: true },
|
|
149
|
+
inputSchema: {
|
|
150
|
+
query: z.string().describe('Google Chat filter-syntax query — keywords, or filters such as "from:alice@example.com budget"'),
|
|
151
|
+
order: z.enum(['create_time desc', 'relevance desc']).optional().describe(
|
|
152
|
+
'Sort order. NOTE the snake_case, which differs from gog_chat_messages_list\'s camelCase. "relevance desc" needs '
|
|
153
|
+
+ 'Google Developer Preview access and errors without it',
|
|
154
|
+
),
|
|
155
|
+
view: z.enum(['basic', 'full']).optional().describe(
|
|
156
|
+
'Result view (default "basic"). "full" also requests read state (covered by an ordinary chat grant) and space '
|
|
157
|
+
+ 'mute setting (needs chat.users.spacesettings, which that grant does not include)',
|
|
158
|
+
),
|
|
159
|
+
markup: z.enum(['chat', 'markdown']).optional().describe('Syntax to render each hit\'s formatted text in'),
|
|
160
|
+
...paginationParams,
|
|
161
|
+
max: z.number().int().min(1).max(100).optional().describe('Max results per page (1-100; Chat search caps a page at 100)'),
|
|
162
|
+
account: accountParam,
|
|
163
|
+
},
|
|
164
|
+
}, async ({ query, order, view, markup, max, pageToken, page, all, account }) => {
|
|
165
|
+
const args = ['chat', 'messages', 'search', query];
|
|
166
|
+
if (order) args.push(`--order=${order}`);
|
|
167
|
+
if (view) args.push(`--view=${view}`);
|
|
168
|
+
if (markup) args.push(`--markup=${markup}`);
|
|
169
|
+
pushPaginationFlags(args, { max, pageToken, page, all });
|
|
170
|
+
return runOrDiagnose(args, { account });
|
|
171
|
+
});
|
|
172
|
+
|
|
138
173
|
server.registerTool('gog_chat_messages_send', {
|
|
139
174
|
description:
|
|
140
175
|
'Post a message to a Chat space. THIS IS IMMEDIATELY VISIBLE TO EVERYONE IN THE SPACE and cannot be unsent through '
|
package/src/worker.ts
CHANGED
|
@@ -38,7 +38,7 @@ import { gogAuth, CONNECTOR_INSTRUCTIONS, type GogProps } from './connector-auth
|
|
|
38
38
|
// connector with all ~360 tools at once. Add whichever paths you want as separate
|
|
39
39
|
// connectors in claude.ai (each authorizes with the same connector key).
|
|
40
40
|
|
|
41
|
-
const VERSION = '2.
|
|
41
|
+
const VERSION = '2.28.0'; // x-release-please-version
|
|
42
42
|
|
|
43
43
|
// Build an McpAgent subclass whose init() registers `registrars` onto its server,
|
|
44
44
|
// each handler wrapped in the ALS scope carrying the per-session Fly executor.
|
package/tests/tools/chat.test.ts
CHANGED
|
@@ -46,7 +46,7 @@ describe('gog_chat_spaces_list', () => {
|
|
|
46
46
|
return undefined as never;
|
|
47
47
|
});
|
|
48
48
|
registerChatTools(server);
|
|
49
|
-
expect(configs.size).toBe(
|
|
49
|
+
expect(configs.size).toBe(13);
|
|
50
50
|
for (const [name, config] of configs) {
|
|
51
51
|
expect(config.description, name).toMatch(/consumer accounts|Workspace/i);
|
|
52
52
|
}
|
|
@@ -132,6 +132,66 @@ describe('gog_chat_messages_list', () => {
|
|
|
132
132
|
});
|
|
133
133
|
});
|
|
134
134
|
|
|
135
|
+
describe('gog_chat_messages_search', () => {
|
|
136
|
+
it('searches across every space the account can see', async () => {
|
|
137
|
+
vi.mocked(runner.run).mockResolvedValue('{"results":[]}');
|
|
138
|
+
const harness = await setupHandlers();
|
|
139
|
+
await harness.callTool('gog_chat_messages_search', { query: 'project decision' });
|
|
140
|
+
expect(runner.run).toHaveBeenCalledWith(
|
|
141
|
+
['chat', 'messages', 'search', 'project decision'],
|
|
142
|
+
{ account: undefined },
|
|
143
|
+
);
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
it('passes view, markup, order and pagination flags', async () => {
|
|
147
|
+
vi.mocked(runner.run).mockResolvedValue('{"results":[]}');
|
|
148
|
+
const harness = await setupHandlers();
|
|
149
|
+
await harness.callTool('gog_chat_messages_search', {
|
|
150
|
+
query: 'from:alice@example.com budget',
|
|
151
|
+
view: 'full',
|
|
152
|
+
markup: 'markdown',
|
|
153
|
+
order: 'create_time desc',
|
|
154
|
+
max: 100,
|
|
155
|
+
pageToken: 'tok',
|
|
156
|
+
all: true,
|
|
157
|
+
});
|
|
158
|
+
expect(runner.run).toHaveBeenCalledWith(
|
|
159
|
+
['chat', 'messages', 'search', 'from:alice@example.com budget', '--order=create_time desc',
|
|
160
|
+
'--view=full', '--markup=markdown', '--max=100', '--page=tok', '--all'],
|
|
161
|
+
{ account: undefined },
|
|
162
|
+
);
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
// Chat's own ordering vocabulary is snake_case here and camelCase in
|
|
166
|
+
// `messages list`; a model that copies the list tool's "createTime desc"
|
|
167
|
+
// would get a gog error at runtime, so the enum has to reject it here.
|
|
168
|
+
it('rejects an order value search does not accept', async () => {
|
|
169
|
+
const harness = await setupHandlers();
|
|
170
|
+
const result = await harness.callTool('gog_chat_messages_search', {
|
|
171
|
+
query: 'x', order: 'createTime desc',
|
|
172
|
+
});
|
|
173
|
+
expect(result.isError).toBe(true);
|
|
174
|
+
expect(runner.run).not.toHaveBeenCalled();
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
// Chat caps a search page at 100; `messages list` allows more. Letting the
|
|
178
|
+
// larger number through would surface as a gog error on a call the tool
|
|
179
|
+
// already had enough information to refuse.
|
|
180
|
+
it('rejects a page size above Chat search\'s cap of 100', async () => {
|
|
181
|
+
const harness = await setupHandlers();
|
|
182
|
+
const result = await harness.callTool('gog_chat_messages_search', { query: 'x', max: 250 });
|
|
183
|
+
expect(result.isError).toBe(true);
|
|
184
|
+
expect(runner.run).not.toHaveBeenCalled();
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
it('returns error text on failure', async () => {
|
|
188
|
+
vi.mocked(runner.run).mockRejectedValue(new Error('Search failed'));
|
|
189
|
+
const harness = await setupHandlers();
|
|
190
|
+
const result = await harness.callTool('gog_chat_messages_search', { query: 'x' });
|
|
191
|
+
expect(result.content[0].text).toBe('Error: Search failed');
|
|
192
|
+
});
|
|
193
|
+
});
|
|
194
|
+
|
|
135
195
|
describe('gog_chat_messages_send', () => {
|
|
136
196
|
it('sends text to a space', async () => {
|
|
137
197
|
vi.mocked(runner.run).mockResolvedValue('{}');
|