gogcli-mcp 2.8.0 → 2.18.1
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/dist/index.js +20218 -19700
- package/dist/lib.js +15845 -23331
- package/manifest.json +33 -1
- package/package.json +7 -6
- package/server.json +2 -2
- package/src/connector-auth.ts +46 -0
- package/src/connector-runtime.ts +177 -0
- package/src/index.ts +7 -5
- package/src/lib.ts +8 -7
- package/src/runner.ts +225 -30
- package/src/server.ts +21 -25
- package/src/tools/api.ts +65 -0
- package/src/tools/auth.ts +112 -15
- package/src/tools/calendar.ts +24 -9
- package/src/tools/docs.ts +28 -3
- package/src/tools/drive.ts +124 -1
- package/src/tools/gmail.ts +7 -3
- package/src/tools/sheets.ts +6 -3
- package/src/tools/slides.ts +9 -4
- package/src/tools/tasks.ts +3 -1
- package/src/tools/utils.ts +163 -27
- package/src/worker.ts +99 -0
- package/tests/connector-auth.test.ts +28 -0
- package/tests/connector-runtime.test.ts +474 -0
- package/tests/runner-file-args-failure.test.ts +94 -0
- package/tests/runner-file-args.test.ts +232 -0
- package/tests/runner.test.ts +221 -13
- package/tests/server.test.ts +28 -28
- package/tests/tools/api.test.ts +107 -0
- package/tests/tools/auth.test.ts +187 -31
- package/tests/tools/calendar.test.ts +115 -52
- package/tests/tools/classroom.test.ts +77 -77
- package/tests/tools/contacts.test.ts +24 -24
- package/tests/tools/docs.test.ts +84 -46
- package/tests/tools/drive.test.ts +226 -55
- package/tests/tools/gmail.test.ts +61 -28
- package/tests/tools/sheets.test.ts +81 -70
- package/tests/tools/slides.test.ts +56 -36
- package/tests/tools/tasks.test.ts +33 -33
- package/tests/tools/utils.test.ts +116 -2
- package/tests/worker.test.ts +142 -0
- package/tsconfig.json +4 -1
- package/vitest.config.ts +33 -2
- package/tests/helpers/test-harness.ts +0 -27
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.18.1",
|
|
7
7
|
"description": "Google Sheets (and more) for Claude via gogcli — read, write, and manage spreadsheets",
|
|
8
8
|
"author": {
|
|
9
9
|
"name": "Chris Hall",
|
|
@@ -56,10 +56,34 @@
|
|
|
56
56
|
}
|
|
57
57
|
},
|
|
58
58
|
"tools": [
|
|
59
|
+
{
|
|
60
|
+
"name": "gog_api_list",
|
|
61
|
+
"description": "List the Google Discovery APIs available for generic api calls."
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
"name": "gog_api_describe",
|
|
65
|
+
"description": "Describe a Google Discovery API or one of its methods (params, schema, scopes)."
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
"name": "gog_api_call",
|
|
69
|
+
"description": "Call any Discovery-described Google API method (escape hatch; write opt-in + dry-run)."
|
|
70
|
+
},
|
|
59
71
|
{
|
|
60
72
|
"name": "gog_auth_add",
|
|
61
73
|
"description": "Authorize a Google account via browser-based OAuth"
|
|
62
74
|
},
|
|
75
|
+
{
|
|
76
|
+
"name": "gog_auth_health",
|
|
77
|
+
"description": "Live per-account token health: validity, age, and pre-expiry warnings (detects invalid_grant)"
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
"name": "gog_auth_add_url",
|
|
81
|
+
"description": "Begin remote/headless OAuth (step 1): return a sign-in URL to open in any browser"
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
"name": "gog_auth_add_complete",
|
|
85
|
+
"description": "Complete remote/headless OAuth (step 2): exchange the pasted redirect URL and store the token"
|
|
86
|
+
},
|
|
63
87
|
{
|
|
64
88
|
"name": "gog_auth_list",
|
|
65
89
|
"description": "List all Google accounts stored in gogcli"
|
|
@@ -228,6 +252,14 @@
|
|
|
228
252
|
"name": "gog_drive_search",
|
|
229
253
|
"description": "Search Google Drive files"
|
|
230
254
|
},
|
|
255
|
+
{
|
|
256
|
+
"name": "gog_drive_extract_text",
|
|
257
|
+
"description": "Extract readable text from a Drive PDF/image/doc (OCR-converts, returns text; no host FS)"
|
|
258
|
+
},
|
|
259
|
+
{
|
|
260
|
+
"name": "gog_drive_read_bytes",
|
|
261
|
+
"description": "Fetch a Drive file's raw bytes as a base64 resource (local stdio only; connector returns text-only notice)"
|
|
262
|
+
},
|
|
231
263
|
{
|
|
232
264
|
"name": "gog_drive_get",
|
|
233
265
|
"description": "Get Google Drive file metadata"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gogcli-mcp",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.18.1",
|
|
4
4
|
"mcpName": "io.github.chrischall/gogcli-mcp",
|
|
5
5
|
"description": "MCP server wrapping gogcli for Google service access",
|
|
6
6
|
"author": "Claude Code (AI) <https://www.anthropic.com/claude>",
|
|
@@ -36,19 +36,20 @@
|
|
|
36
36
|
"build": "tsc --noEmit && npm run bundle",
|
|
37
37
|
"bundle": "node ../../scripts/bundle.js src/index.ts dist/index.js && node ../../scripts/bundle.js src/lib.ts dist/lib.js",
|
|
38
38
|
"typecheck": "tsc --noEmit",
|
|
39
|
-
"test": "vitest run",
|
|
39
|
+
"test": "vitest run --coverage",
|
|
40
40
|
"test:watch": "vitest",
|
|
41
41
|
"test:coverage": "vitest run --coverage"
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
|
+
"@chrischall/mcp-utils": "^0.13.3",
|
|
44
45
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
45
46
|
"zod": "^4.4.3"
|
|
46
47
|
},
|
|
47
48
|
"devDependencies": {
|
|
48
|
-
"@types/node": "^
|
|
49
|
+
"@types/node": "^26.1.1",
|
|
49
50
|
"@vitest/coverage-v8": "^4.1.8",
|
|
50
|
-
"esbuild": "^0.28.
|
|
51
|
-
"typescript": "^
|
|
52
|
-
"vitest": "^4.1.
|
|
51
|
+
"esbuild": "^0.28.1",
|
|
52
|
+
"typescript": "^7.0.2",
|
|
53
|
+
"vitest": "^4.1.10"
|
|
53
54
|
}
|
|
54
55
|
}
|
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.18.1",
|
|
11
11
|
"packages": [
|
|
12
12
|
{
|
|
13
13
|
"registryType": "npm",
|
|
14
14
|
"identifier": "gogcli-mcp",
|
|
15
|
-
"version": "2.
|
|
15
|
+
"version": "2.18.1",
|
|
16
16
|
"transport": {
|
|
17
17
|
"type": "stdio"
|
|
18
18
|
},
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { ConnectorAuth } from '@chrischall/mcp-connector';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* OAuth props stored per user by the Cloudflare connector's OAuth provider.
|
|
5
|
+
*
|
|
6
|
+
* The gogcli remote connector authenticates each user with a single long-lived
|
|
7
|
+
* personal "connector key" — a shared secret (the Fly backend's `RUNNER_KEY`)
|
|
8
|
+
* that authorizes calls to that user's own `gog` backend on Fly.io. There is no
|
|
9
|
+
* refresh cycle: `worker.ts`'s `buildClient` turns this key straight into a
|
|
10
|
+
* per-session Fly executor. These props are encrypted at rest in `OAUTH_KV` by
|
|
11
|
+
* the OAuth provider.
|
|
12
|
+
*
|
|
13
|
+
* NOTE: this is a FIELD LOGIN (a personal key), NOT Google OAuth. The Google
|
|
14
|
+
* OAuth handshake lives entirely inside the Fly backend's `gog` install; the
|
|
15
|
+
* connector never sees a Google token.
|
|
16
|
+
*
|
|
17
|
+
* The index signature satisfies `createConnector`'s
|
|
18
|
+
* `Props extends Record<string, unknown>` constraint.
|
|
19
|
+
*/
|
|
20
|
+
export interface GogProps {
|
|
21
|
+
key: string;
|
|
22
|
+
[k: string]: unknown;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* `ConnectorAuth` for the gogcli remote connector: the login page collects the
|
|
27
|
+
* user's connector key, verifies it by hitting the Fly backend's `/health`
|
|
28
|
+
* endpoint with the key as a bearer token (a bad key makes the backend answer
|
|
29
|
+
* non-2xx, which surfaces back on the login page), and stores `{ key }` as the
|
|
30
|
+
* OAuth props that `worker.ts`'s `buildClient` turns into a per-session Fly
|
|
31
|
+
* executor.
|
|
32
|
+
*/
|
|
33
|
+
export const gogAuth: ConnectorAuth<GogProps> = {
|
|
34
|
+
service: 'gogcli (Google Workspace)',
|
|
35
|
+
accent: '#4285F4',
|
|
36
|
+
privacyNote:
|
|
37
|
+
'Your connector key is stored encrypted and used only to reach your own gog backend.',
|
|
38
|
+
fields: [{ name: 'key', label: 'gogcli connector key', type: 'password' }],
|
|
39
|
+
async login(fields, env) {
|
|
40
|
+
const res = await fetch(`${(env as any).FLY_ENDPOINT}/health`, {
|
|
41
|
+
headers: { Authorization: `Bearer ${fields.key}` },
|
|
42
|
+
});
|
|
43
|
+
if (!res.ok) throw new Error('Invalid connector key (backend rejected it)');
|
|
44
|
+
return { key: fields.key };
|
|
45
|
+
},
|
|
46
|
+
};
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import { runExecutor } from './runner.js';
|
|
2
|
+
import type { GogArg, GogExecutor } from './runner.js';
|
|
3
|
+
|
|
4
|
+
// Runtime helpers for the Cloudflare connector (worker.ts), split out here so
|
|
5
|
+
// they can be unit-tested under the node pool — worker.ts itself imports the
|
|
6
|
+
// Worker-only `@chrischall/mcp-connector`/`agents` runtime and cannot load in
|
|
7
|
+
// node. These helpers touch only the `runExecutor` seam and global `fetch`.
|
|
8
|
+
|
|
9
|
+
// Mirrors runner.ts's TIMEOUT_MS: the budget the stdio path gives a `gog` call
|
|
10
|
+
// before it kills the child. Duplicated rather than imported to keep this module
|
|
11
|
+
// free of the spawn-side surface.
|
|
12
|
+
const DEFAULT_TIMEOUT_MS = 30_000;
|
|
13
|
+
|
|
14
|
+
// Headroom on top of the backend's own budget. The Fly runner kills `gog` and
|
|
15
|
+
// returns a real error; we only want the client deadline to fire when the
|
|
16
|
+
// backend cannot answer at all (scale-to-zero cold start that never wakes, or a
|
|
17
|
+
// wedged machine). Firing first would turn a useful "gog exited 1" into an
|
|
18
|
+
// opaque timeout.
|
|
19
|
+
//
|
|
20
|
+
// This grace is deliberately NOT widened for GogFileArg payloads. The deadline
|
|
21
|
+
// now covers a request body that carries the payload inline, so upload happens
|
|
22
|
+
// before `gog` starts — but the payloads that take this path are text (a mail
|
|
23
|
+
// body, slide notes), bounded by the MCP request that carried them, and the hop
|
|
24
|
+
// is Cloudflare edge → Fly datacenter, so upload is milliseconds, not seconds.
|
|
25
|
+
// Widening the grace would weaken the property this constant exists to protect:
|
|
26
|
+
// the backend must lose the race only when it genuinely cannot answer, and every
|
|
27
|
+
// extra second is a second of an opaque client timeout replacing a real error.
|
|
28
|
+
// If a payload class ever appears that does NOT upload in well under 5s, the fix
|
|
29
|
+
// is to raise the caller's `opts.timeout` (which this deadline tracks) rather
|
|
30
|
+
// than to inflate the grace, so the runner still gets to answer first.
|
|
31
|
+
const DEADLINE_GRACE_MS = 5_000;
|
|
32
|
+
|
|
33
|
+
// Status codes the Fly runner uses to classify its OWN failures. These must stay
|
|
34
|
+
// in sync with fly-gog-runner/server.mjs — they are the contract that lets this
|
|
35
|
+
// side tell "gog ran and failed" apart from "the request never arrived", without
|
|
36
|
+
// having to guess from the response body.
|
|
37
|
+
//
|
|
38
|
+
// 422: `gog` executed and exited non-zero. Deterministic — never retry.
|
|
39
|
+
// 503: the runner is draining (SIGINT from Fly's autostop). Transient — retry.
|
|
40
|
+
// Any other non-2xx: infrastructure, i.e. Fly's edge, not us.
|
|
41
|
+
const RUNNER_GOG_FAILED = 422;
|
|
42
|
+
const RUNNER_DRAINING = 503;
|
|
43
|
+
|
|
44
|
+
// Build a GogExecutor that forwards a fully-assembled `gog` arg-array to the Fly
|
|
45
|
+
// backend's `/run` endpoint.
|
|
46
|
+
//
|
|
47
|
+
// The backend (and the `gog` process it spawns) own timeout/interactive
|
|
48
|
+
// behaviour, so `opts` does not change what the backend does — but `timeout`
|
|
49
|
+
// still has to be honoured HERE as a client-side deadline. Workers' `fetch` has
|
|
50
|
+
// no default timeout, and the stdio path's kill lives in a child process this
|
|
51
|
+
// path never spawns, so without an explicit signal a cold or wedged backend
|
|
52
|
+
// hangs the MCP request indefinitely with nothing to interrupt it.
|
|
53
|
+
//
|
|
54
|
+
// GogFileArg elements pass through STRUCTURED, as objects inside the JSON body.
|
|
55
|
+
// Every other executor materializes them to a temp file itself; this one cannot
|
|
56
|
+
// and must not. A Worker has no filesystem and does not host the `gog` binary,
|
|
57
|
+
// so there is nowhere to put a file that the process which needs it could read.
|
|
58
|
+
// The Fly runner is the only box with both, so it owns materialization — this
|
|
59
|
+
// layer's whole job is to hand the elements over unaltered, in order. Anything
|
|
60
|
+
// clever here (flattening to `--flag=<inline>`, truncating, re-encoding) would
|
|
61
|
+
// put the payload straight back into argv and re-create the size cap this whole
|
|
62
|
+
// change exists to escape.
|
|
63
|
+
export function makeFlyExecutor(endpoint: string, key: string): GogExecutor {
|
|
64
|
+
return async (args: GogArg[], opts) => {
|
|
65
|
+
const deadlineMs = (opts?.timeout ?? DEFAULT_TIMEOUT_MS) + DEADLINE_GRACE_MS;
|
|
66
|
+
let res: Response;
|
|
67
|
+
try {
|
|
68
|
+
res = await fetch(endpoint + '/run', {
|
|
69
|
+
method: 'POST',
|
|
70
|
+
headers: {
|
|
71
|
+
Authorization: 'Bearer ' + key,
|
|
72
|
+
'Content-Type': 'application/json',
|
|
73
|
+
},
|
|
74
|
+
body: JSON.stringify({ args }),
|
|
75
|
+
signal: AbortSignal.timeout(deadlineMs),
|
|
76
|
+
});
|
|
77
|
+
} catch (err) {
|
|
78
|
+
// AbortSignal.timeout rejects with a TimeoutError; a caller-supplied abort
|
|
79
|
+
// surfaces as AbortError. Either way the bare message ("The operation was
|
|
80
|
+
// aborted") says nothing about which backend failed to answer.
|
|
81
|
+
const name = err instanceof Error ? err.name : '';
|
|
82
|
+
if (name === 'TimeoutError' || name === 'AbortError') {
|
|
83
|
+
throw new Error(
|
|
84
|
+
`gog-runner did not respond within ${deadlineMs}ms (${endpoint}) — the Fly backend may be cold or wedged`,
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
throw err;
|
|
88
|
+
}
|
|
89
|
+
if (!res.ok) {
|
|
90
|
+
// Two very different failures arrive as non-2xx, and collapsing them (as
|
|
91
|
+
// this used to) is what made a real bug look like random flakiness:
|
|
92
|
+
//
|
|
93
|
+
// a) The runner answered with its own JSON — `gog` actually ran on the
|
|
94
|
+
// box and failed. Deterministic: the same call will fail the same way.
|
|
95
|
+
// b) The body is NOT the runner's JSON (Fly's HTML error page, or empty).
|
|
96
|
+
// Then the request never reached `gog` at all; Fly's edge proxy is
|
|
97
|
+
// reporting that it could not reach the Machine — typically because
|
|
98
|
+
// the Machine was starting from scale-to-zero, or was mid-shutdown.
|
|
99
|
+
// Genuinely transient, and the only case worth retrying.
|
|
100
|
+
const body = (await res.json().catch(() => null)) as
|
|
101
|
+
| { error?: string; stderr?: string; retryable?: boolean }
|
|
102
|
+
| null;
|
|
103
|
+
const detail =
|
|
104
|
+
body && typeof body.error === 'string'
|
|
105
|
+
? body.stderr && body.stderr.trim() && body.stderr.trim() !== body.error.trim()
|
|
106
|
+
? `${body.error}\n${body.stderr}`
|
|
107
|
+
: body.error
|
|
108
|
+
: '';
|
|
109
|
+
|
|
110
|
+
// 422 is the runner's "gog ran and exited non-zero" status. It is only
|
|
111
|
+
// ever produced by our own handler, so reaching here proves the request
|
|
112
|
+
// was delivered and executed. Deterministic — say so, and say nothing
|
|
113
|
+
// that invites a retry.
|
|
114
|
+
if (res.status === RUNNER_GOG_FAILED) {
|
|
115
|
+
throw new Error(detail || 'gog failed on the runner (no detail supplied)');
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// The runner's drain response: it is up, but deliberately refusing new
|
|
119
|
+
// work while it shuts down. The one runner-authored failure worth retrying.
|
|
120
|
+
if (res.status === RUNNER_DRAINING || body?.retryable === true) {
|
|
121
|
+
throw new Error(
|
|
122
|
+
`gog-runner is restarting; retry this call.${detail ? ` ${detail}` : ''}`,
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Anything else non-2xx is infrastructure: Fly's edge could not reach the
|
|
127
|
+
// Machine, or the Machine answered with something that is not ours. Only
|
|
128
|
+
// claim the request never arrived when there is genuinely no runner body
|
|
129
|
+
// — a runner that did answer deserves to have its own words repeated.
|
|
130
|
+
//
|
|
131
|
+
// The status is deliberately NOT interpolated here. A runner body proves
|
|
132
|
+
// gog ran, so this is a deterministic failure; embedding the literal
|
|
133
|
+
// status would put "502" into the message, which matches
|
|
134
|
+
// TRANSIENT_ERROR_PATTERN (/\b5\d\d\b/) in tools/utils.ts and re-attaches
|
|
135
|
+
// the very "this is transient, retry the same call" hint this change
|
|
136
|
+
// exists to remove — reintroducing the bug during the rollout window this
|
|
137
|
+
// branch exists to cover. Anything genuinely transient in gog's own text
|
|
138
|
+
// (a Google 5xx, say) still matches on its own merits, which is correct.
|
|
139
|
+
if (detail) {
|
|
140
|
+
throw new Error(detail);
|
|
141
|
+
}
|
|
142
|
+
throw new Error(
|
|
143
|
+
`gog-runner HTTP ${res.status}: the response did not come from the runner, ` +
|
|
144
|
+
'so the request never reached gog. The backend Machine was most likely starting ' +
|
|
145
|
+
'or shutting down — this is transient, retry the same call.',
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
const { stdout } = (await res.json()) as { stdout: string };
|
|
149
|
+
return stdout;
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// Wrap an McpServer in a Proxy whose `registerTool` (and `tool`, if any
|
|
154
|
+
// registrar uses it) intercepts the tool handler so it runs inside the
|
|
155
|
+
// `runExecutor` ALS scope. This is the crux of the connector: it lets the
|
|
156
|
+
// UNCHANGED base registrars forward every `gog` call to the per-session Fly
|
|
157
|
+
// executor without any change to the registrars or `runner.ts` — when a
|
|
158
|
+
// handler's `run()` looks up `runExecutor.getStore()` it finds `executor` and
|
|
159
|
+
// forwards instead of spawning. Everything else proxies through via Reflect.
|
|
160
|
+
export function wrapServer<T extends object>(server: T, executor: GogExecutor): T {
|
|
161
|
+
return new Proxy(server, {
|
|
162
|
+
get(target, prop, receiver) {
|
|
163
|
+
if (prop === 'registerTool' || prop === 'tool') {
|
|
164
|
+
const orig = (target as Record<string | symbol, (...a: unknown[]) => unknown>)[prop].bind(target);
|
|
165
|
+
return (...args: unknown[]) => {
|
|
166
|
+
const handler = args[args.length - 1];
|
|
167
|
+
if (typeof handler === 'function') {
|
|
168
|
+
args[args.length - 1] = (...h: unknown[]) =>
|
|
169
|
+
runExecutor.run({ executor }, () => (handler as (...a: unknown[]) => unknown)(...h));
|
|
170
|
+
}
|
|
171
|
+
return orig(...args);
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
return Reflect.get(target, prop, receiver);
|
|
175
|
+
},
|
|
176
|
+
});
|
|
177
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { runMcp } from '@chrischall/mcp-utils';
|
|
3
|
+
import { BASE_TOOL_REGISTRARS, VERSION } from './server.js';
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
await runMcp({
|
|
6
|
+
name: 'gogcli',
|
|
7
|
+
version: VERSION,
|
|
8
|
+
tools: BASE_TOOL_REGISTRARS,
|
|
9
|
+
});
|
package/src/lib.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
export {
|
|
2
|
-
|
|
3
|
-
createBaseServer,
|
|
2
|
+
BASE_TOOL_REGISTRARS,
|
|
4
3
|
VERSION,
|
|
4
|
+
registerApiTools,
|
|
5
5
|
registerAuthTools,
|
|
6
|
+
authToolsFor,
|
|
6
7
|
registerCalendarTools,
|
|
7
8
|
registerClassroomTools,
|
|
8
9
|
registerContactsTools,
|
|
@@ -13,17 +14,17 @@ export {
|
|
|
13
14
|
registerSlidesTools,
|
|
14
15
|
registerTasksTools,
|
|
15
16
|
} from './server.js';
|
|
16
|
-
export { run, MIN_GOG_VERSION } from './runner.js';
|
|
17
|
-
export type { RunOptions, Spawner } from './runner.js';
|
|
17
|
+
export { run, runBinary, runExecutor, isGogFileArg, MIN_GOG_VERSION } from './runner.js';
|
|
18
|
+
export type { RunOptions, Spawner, GogExecutor, GogArg, GogFileArg } from './runner.js';
|
|
18
19
|
export {
|
|
20
|
+
PAYLOAD_INLINE_MAX,
|
|
21
|
+
payloadArg,
|
|
19
22
|
accountParam,
|
|
20
23
|
runOrDiagnose,
|
|
21
24
|
diagnose,
|
|
22
|
-
|
|
23
|
-
toError,
|
|
25
|
+
errorText,
|
|
24
26
|
ids,
|
|
25
27
|
paginationParams,
|
|
26
28
|
pushPaginationFlags,
|
|
27
29
|
registerRunTool,
|
|
28
30
|
} from './tools/utils.js';
|
|
29
|
-
export type { ToolResult } from './tools/utils.js';
|