@aaronsb/google-workspace-mcp 2.0.0-alpha.4
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 +21 -0
- package/README.md +193 -0
- package/build/__helpers__/testSetup.d.ts +1 -0
- package/build/__helpers__/testSetup.js +6 -0
- package/build/__helpers__/testSetup.js.map +1 -0
- package/build/__tests__/accounts/credentials.test.d.ts +1 -0
- package/build/__tests__/accounts/credentials.test.js +129 -0
- package/build/__tests__/accounts/credentials.test.js.map +1 -0
- package/build/__tests__/accounts/registry.test.d.ts +1 -0
- package/build/__tests__/accounts/registry.test.js +74 -0
- package/build/__tests__/accounts/registry.test.js.map +1 -0
- package/build/__tests__/executor/errors.test.d.ts +1 -0
- package/build/__tests__/executor/errors.test.js +42 -0
- package/build/__tests__/executor/errors.test.js.map +1 -0
- package/build/__tests__/executor/gws.test.d.ts +1 -0
- package/build/__tests__/executor/gws.test.js +178 -0
- package/build/__tests__/executor/gws.test.js.map +1 -0
- package/build/__tests__/executor/paths.test.d.ts +1 -0
- package/build/__tests__/executor/paths.test.js +60 -0
- package/build/__tests__/executor/paths.test.js.map +1 -0
- package/build/__tests__/executor/workspace.test.d.ts +1 -0
- package/build/__tests__/executor/workspace.test.js +117 -0
- package/build/__tests__/executor/workspace.test.js.map +1 -0
- package/build/__tests__/factory/generator.test.d.ts +1 -0
- package/build/__tests__/factory/generator.test.js +178 -0
- package/build/__tests__/factory/generator.test.js.map +1 -0
- package/build/__tests__/factory/patch-coverage.test.d.ts +10 -0
- package/build/__tests__/factory/patch-coverage.test.js +148 -0
- package/build/__tests__/factory/patch-coverage.test.js.map +1 -0
- package/build/__tests__/factory/safety.test.d.ts +1 -0
- package/build/__tests__/factory/safety.test.js +107 -0
- package/build/__tests__/factory/safety.test.js.map +1 -0
- package/build/__tests__/integration/executor.test.d.ts +5 -0
- package/build/__tests__/integration/executor.test.js +46 -0
- package/build/__tests__/integration/executor.test.js.map +1 -0
- package/build/__tests__/integration/handlers.test.d.ts +6 -0
- package/build/__tests__/integration/handlers.test.js +95 -0
- package/build/__tests__/integration/handlers.test.js.map +1 -0
- package/build/__tests__/integration/setup.d.ts +19 -0
- package/build/__tests__/integration/setup.js +61 -0
- package/build/__tests__/integration/setup.js.map +1 -0
- package/build/__tests__/server/formatting/markdown.test.d.ts +1 -0
- package/build/__tests__/server/formatting/markdown.test.js +149 -0
- package/build/__tests__/server/formatting/markdown.test.js.map +1 -0
- package/build/__tests__/server/formatting/next-steps.test.d.ts +1 -0
- package/build/__tests__/server/formatting/next-steps.test.js +42 -0
- package/build/__tests__/server/formatting/next-steps.test.js.map +1 -0
- package/build/__tests__/server/handler.test.d.ts +1 -0
- package/build/__tests__/server/handler.test.js +97 -0
- package/build/__tests__/server/handler.test.js.map +1 -0
- package/build/__tests__/server/handlers/__mocks__/executor.d.ts +147 -0
- package/build/__tests__/server/handlers/__mocks__/executor.js +114 -0
- package/build/__tests__/server/handlers/__mocks__/executor.js.map +1 -0
- package/build/__tests__/server/handlers/accounts.test.d.ts +1 -0
- package/build/__tests__/server/handlers/accounts.test.js +127 -0
- package/build/__tests__/server/handlers/accounts.test.js.map +1 -0
- package/build/__tests__/server/handlers/calendar.test.d.ts +1 -0
- package/build/__tests__/server/handlers/calendar.test.js +95 -0
- package/build/__tests__/server/handlers/calendar.test.js.map +1 -0
- package/build/__tests__/server/handlers/drive.test.d.ts +1 -0
- package/build/__tests__/server/handlers/drive.test.js +81 -0
- package/build/__tests__/server/handlers/drive.test.js.map +1 -0
- package/build/__tests__/server/handlers/email.test.d.ts +1 -0
- package/build/__tests__/server/handlers/email.test.js +99 -0
- package/build/__tests__/server/handlers/email.test.js.map +1 -0
- package/build/__tests__/server/handlers/validate.test.d.ts +1 -0
- package/build/__tests__/server/handlers/validate.test.js +88 -0
- package/build/__tests__/server/handlers/validate.test.js.map +1 -0
- package/build/__tests__/server/queue.test.d.ts +1 -0
- package/build/__tests__/server/queue.test.js +194 -0
- package/build/__tests__/server/queue.test.js.map +1 -0
- package/build/__tests__/server/server.test.d.ts +7 -0
- package/build/__tests__/server/server.test.js +135 -0
- package/build/__tests__/server/server.test.js.map +1 -0
- package/build/__tests__/server/tools.test.d.ts +1 -0
- package/build/__tests__/server/tools.test.js +91 -0
- package/build/__tests__/server/tools.test.js.map +1 -0
- package/build/accounts/auth.d.ts +24 -0
- package/build/accounts/auth.js +118 -0
- package/build/accounts/auth.js.map +1 -0
- package/build/accounts/credentials.d.ts +11 -0
- package/build/accounts/credentials.js +52 -0
- package/build/accounts/credentials.js.map +1 -0
- package/build/accounts/index.d.ts +6 -0
- package/build/accounts/index.js +4 -0
- package/build/accounts/index.js.map +1 -0
- package/build/accounts/registry.d.ts +11 -0
- package/build/accounts/registry.js +62 -0
- package/build/accounts/registry.js.map +1 -0
- package/build/executor/errors.d.ts +15 -0
- package/build/executor/errors.js +37 -0
- package/build/executor/errors.js.map +1 -0
- package/build/executor/file-output.d.ts +23 -0
- package/build/executor/file-output.js +67 -0
- package/build/executor/file-output.js.map +1 -0
- package/build/executor/gws.d.ts +23 -0
- package/build/executor/gws.js +144 -0
- package/build/executor/gws.js.map +1 -0
- package/build/executor/index.d.ts +4 -0
- package/build/executor/index.js +4 -0
- package/build/executor/index.js.map +1 -0
- package/build/executor/paths.d.ts +6 -0
- package/build/executor/paths.js +25 -0
- package/build/executor/paths.js.map +1 -0
- package/build/executor/workspace.d.ts +38 -0
- package/build/executor/workspace.js +146 -0
- package/build/executor/workspace.js.map +1 -0
- package/build/factory/defaults.d.ts +8 -0
- package/build/factory/defaults.js +101 -0
- package/build/factory/defaults.js.map +1 -0
- package/build/factory/generator.d.ts +23 -0
- package/build/factory/generator.js +253 -0
- package/build/factory/generator.js.map +1 -0
- package/build/factory/manifest.yaml +852 -0
- package/build/factory/patches.d.ts +6 -0
- package/build/factory/patches.js +13 -0
- package/build/factory/patches.js.map +1 -0
- package/build/factory/registry.d.ts +12 -0
- package/build/factory/registry.js +18 -0
- package/build/factory/registry.js.map +1 -0
- package/build/factory/safety.d.ts +68 -0
- package/build/factory/safety.js +157 -0
- package/build/factory/safety.js.map +1 -0
- package/build/factory/types.d.ts +102 -0
- package/build/factory/types.js +6 -0
- package/build/factory/types.js.map +1 -0
- package/build/factory/yaml.d.ts +2 -0
- package/build/factory/yaml.js +3 -0
- package/build/factory/yaml.js.map +1 -0
- package/build/index.d.ts +2 -0
- package/build/index.js +14 -0
- package/build/index.js.map +1 -0
- package/build/server/formatting/markdown.d.ts +21 -0
- package/build/server/formatting/markdown.js +324 -0
- package/build/server/formatting/markdown.js.map +1 -0
- package/build/server/formatting/next-steps.d.ts +9 -0
- package/build/server/formatting/next-steps.js +123 -0
- package/build/server/formatting/next-steps.js.map +1 -0
- package/build/server/handler.d.ts +3 -0
- package/build/server/handler.js +24 -0
- package/build/server/handler.js.map +1 -0
- package/build/server/handlers/accounts.d.ts +2 -0
- package/build/server/handlers/accounts.js +181 -0
- package/build/server/handlers/accounts.js.map +1 -0
- package/build/server/handlers/calendar.d.ts +2 -0
- package/build/server/handlers/calendar.js +93 -0
- package/build/server/handlers/calendar.js.map +1 -0
- package/build/server/handlers/drive.d.ts +2 -0
- package/build/server/handlers/drive.js +74 -0
- package/build/server/handlers/drive.js.map +1 -0
- package/build/server/handlers/email.d.ts +2 -0
- package/build/server/handlers/email.js +115 -0
- package/build/server/handlers/email.js.map +1 -0
- package/build/server/handlers/validate.d.ts +3 -0
- package/build/server/handlers/validate.js +22 -0
- package/build/server/handlers/validate.js.map +1 -0
- package/build/server/handlers/workspace.d.ts +9 -0
- package/build/server/handlers/workspace.js +110 -0
- package/build/server/handlers/workspace.js.map +1 -0
- package/build/server/index.d.ts +4 -0
- package/build/server/index.js +4 -0
- package/build/server/index.js.map +1 -0
- package/build/server/queue.d.ts +11 -0
- package/build/server/queue.js +141 -0
- package/build/server/queue.js.map +1 -0
- package/build/server/server.d.ts +3 -0
- package/build/server/server.js +214 -0
- package/build/server/server.js.map +1 -0
- package/build/server/tools.d.ts +13 -0
- package/build/server/tools.js +99 -0
- package/build/server/tools.js.map +1 -0
- package/build/services/calendar/patch.d.ts +11 -0
- package/build/services/calendar/patch.js +116 -0
- package/build/services/calendar/patch.js.map +1 -0
- package/build/services/drive/patch.d.ts +10 -0
- package/build/services/drive/patch.js +131 -0
- package/build/services/drive/patch.js.map +1 -0
- package/build/services/gmail/attachments.d.ts +19 -0
- package/build/services/gmail/attachments.js +90 -0
- package/build/services/gmail/attachments.js.map +1 -0
- package/build/services/gmail/patch.d.ts +10 -0
- package/build/services/gmail/patch.js +226 -0
- package/build/services/gmail/patch.js.map +1 -0
- package/package.json +34 -0
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workspace handler — file CRUD within the sandboxed workspace directory.
|
|
3
|
+
*
|
|
4
|
+
* The workspace is the exchange point between the MCP server and the agent.
|
|
5
|
+
* Files saved by getAttachment, download, and export land here. The agent
|
|
6
|
+
* can also read, write, and manage files directly.
|
|
7
|
+
*/
|
|
8
|
+
import * as fs from 'node:fs/promises';
|
|
9
|
+
import * as path from 'node:path';
|
|
10
|
+
import { ensureWorkspaceDir, resolveWorkspacePath, verifyPathSafety, getWorkspaceDir } from '../../executor/workspace.js';
|
|
11
|
+
import { isTextFile } from '../../executor/file-output.js';
|
|
12
|
+
export async function handleWorkspace(params) {
|
|
13
|
+
const operation = params.operation;
|
|
14
|
+
switch (operation) {
|
|
15
|
+
case 'list': {
|
|
16
|
+
const wsStatus = await ensureWorkspaceDir();
|
|
17
|
+
if (!wsStatus.valid) {
|
|
18
|
+
return { text: `Workspace invalid: ${wsStatus.warning}`, refs: { valid: false } };
|
|
19
|
+
}
|
|
20
|
+
const dir = getWorkspaceDir();
|
|
21
|
+
let files;
|
|
22
|
+
try {
|
|
23
|
+
files = await fs.readdir(dir);
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
files = [];
|
|
27
|
+
}
|
|
28
|
+
if (files.length === 0) {
|
|
29
|
+
return {
|
|
30
|
+
text: `## Workspace (empty)\n\n**Path:** ${dir}`,
|
|
31
|
+
refs: { count: 0, path: dir },
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
const entries = await Promise.all(files.map(async (name) => {
|
|
35
|
+
const filePath = path.join(dir, name);
|
|
36
|
+
const stat = await fs.stat(filePath);
|
|
37
|
+
const size = stat.isDirectory() ? 'dir' :
|
|
38
|
+
stat.size < 1024 ? `${stat.size} B` :
|
|
39
|
+
`${(stat.size / 1024).toFixed(1)} KB`;
|
|
40
|
+
return `${name} (${size})`;
|
|
41
|
+
}));
|
|
42
|
+
return {
|
|
43
|
+
text: `## Workspace (${files.length} files)\n\n**Path:** ${dir}\n\n${entries.map((e, i) => `${i + 1}. ${e}`).join('\n')}`,
|
|
44
|
+
refs: { count: files.length, path: dir, files },
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
case 'read': {
|
|
48
|
+
const filename = params.filename;
|
|
49
|
+
if (!filename)
|
|
50
|
+
throw new Error('filename is required');
|
|
51
|
+
const filePath = resolveWorkspacePath(filename);
|
|
52
|
+
await verifyPathSafety(filePath);
|
|
53
|
+
const stat = await fs.stat(filePath);
|
|
54
|
+
if (stat.size > 100_000) {
|
|
55
|
+
return {
|
|
56
|
+
text: `File too large to return inline (${(stat.size / 1024).toFixed(1)} KB). Use the file path directly:\n\n**Path:** ${filePath}`,
|
|
57
|
+
refs: { filename, path: filePath, size: stat.size },
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
const buffer = await fs.readFile(filePath);
|
|
61
|
+
if (isTextFile(filename)) {
|
|
62
|
+
const content = buffer.toString('utf-8');
|
|
63
|
+
const safeContent = content.replace(/```/g, '` ` `');
|
|
64
|
+
return {
|
|
65
|
+
text: `## ${filename}\n\n\`\`\`\n${safeContent}\n\`\`\``,
|
|
66
|
+
refs: { filename, path: filePath, size: stat.size, content },
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
return {
|
|
70
|
+
text: `Binary file: **${filename}** (${(stat.size / 1024).toFixed(1)} KB)\n\n**Path:** ${filePath}`,
|
|
71
|
+
refs: { filename, path: filePath, size: stat.size },
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
case 'write': {
|
|
75
|
+
const filename = params.filename;
|
|
76
|
+
const content = params.content;
|
|
77
|
+
if (!filename)
|
|
78
|
+
throw new Error('filename is required');
|
|
79
|
+
if (content === undefined)
|
|
80
|
+
throw new Error('content is required');
|
|
81
|
+
const wsStatus = await ensureWorkspaceDir();
|
|
82
|
+
if (!wsStatus.valid) {
|
|
83
|
+
throw new Error(`Workspace invalid: ${wsStatus.warning}`);
|
|
84
|
+
}
|
|
85
|
+
const filePath = resolveWorkspacePath(filename);
|
|
86
|
+
await verifyPathSafety(filePath);
|
|
87
|
+
await fs.mkdir(path.dirname(filePath), { recursive: true });
|
|
88
|
+
await fs.writeFile(filePath, content, 'utf-8');
|
|
89
|
+
return {
|
|
90
|
+
text: `File written: **${filename}** (${Buffer.byteLength(content)} bytes)\n\n**Path:** ${filePath}`,
|
|
91
|
+
refs: { filename, path: filePath, size: Buffer.byteLength(content) },
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
case 'delete': {
|
|
95
|
+
const filename = params.filename;
|
|
96
|
+
if (!filename)
|
|
97
|
+
throw new Error('filename is required');
|
|
98
|
+
const filePath = resolveWorkspacePath(filename);
|
|
99
|
+
await verifyPathSafety(filePath);
|
|
100
|
+
await fs.unlink(filePath);
|
|
101
|
+
return {
|
|
102
|
+
text: `File deleted: **${filename}**`,
|
|
103
|
+
refs: { filename, status: 'deleted' },
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
default:
|
|
107
|
+
throw new Error(`Unknown workspace operation: ${operation}`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=workspace.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace.js","sourceRoot":"","sources":["../../../src/server/handlers/workspace.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAExD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Queue handler — execute multiple operations sequentially with
|
|
3
|
+
* result references ($N.field) for chaining outputs.
|
|
4
|
+
*
|
|
5
|
+
* Handlers return { text, refs }. Queue uses refs for $N.field
|
|
6
|
+
* resolution and text for the final response.
|
|
7
|
+
*/
|
|
8
|
+
import type { HandlerResponse } from './handler.js';
|
|
9
|
+
type ToolHandler = (params: Record<string, unknown>) => Promise<HandlerResponse>;
|
|
10
|
+
export declare function handleQueue(params: Record<string, unknown>, handlers: Record<string, ToolHandler>): Promise<HandlerResponse>;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Queue handler — execute multiple operations sequentially with
|
|
3
|
+
* result references ($N.field) for chaining outputs.
|
|
4
|
+
*
|
|
5
|
+
* Handlers return { text, refs }. Queue uses refs for $N.field
|
|
6
|
+
* resolution and text for the final response.
|
|
7
|
+
*/
|
|
8
|
+
const NEXT_STEPS_SEPARATOR = '\n\n---\n**Next steps:**';
|
|
9
|
+
function stripNextSteps(text) {
|
|
10
|
+
const idx = text.indexOf(NEXT_STEPS_SEPARATOR);
|
|
11
|
+
return idx >= 0 ? text.slice(0, idx) : text;
|
|
12
|
+
}
|
|
13
|
+
export async function handleQueue(params, handlers) {
|
|
14
|
+
const operations = params.operations;
|
|
15
|
+
if (!Array.isArray(operations) || operations.length === 0) {
|
|
16
|
+
throw new Error('operations array is required and must not be empty');
|
|
17
|
+
}
|
|
18
|
+
const detail = params.detail ?? 'summary';
|
|
19
|
+
const results = [];
|
|
20
|
+
let bailedAt = -1;
|
|
21
|
+
let lastSuccessText = '';
|
|
22
|
+
for (let i = 0; i < operations.length; i++) {
|
|
23
|
+
const op = operations[i];
|
|
24
|
+
const errorStrategy = op.onError ?? 'bail';
|
|
25
|
+
if (bailedAt >= 0) {
|
|
26
|
+
results.push({ index: i, tool: op.tool, status: 'skipped' });
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
const handler = handlers[op.tool];
|
|
30
|
+
if (!handler) {
|
|
31
|
+
results.push({ index: i, tool: op.tool, status: 'error', error: `Unknown tool: ${op.tool}` });
|
|
32
|
+
if (errorStrategy === 'bail')
|
|
33
|
+
bailedAt = i;
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
// Resolve $N.field references
|
|
37
|
+
let resolvedArgs;
|
|
38
|
+
try {
|
|
39
|
+
resolvedArgs = resolveReferences(op.args, results);
|
|
40
|
+
}
|
|
41
|
+
catch (err) {
|
|
42
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
43
|
+
results.push({ index: i, tool: op.tool, status: 'error', error: msg });
|
|
44
|
+
if (errorStrategy === 'bail')
|
|
45
|
+
bailedAt = i;
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
try {
|
|
49
|
+
const response = await handler(resolvedArgs);
|
|
50
|
+
const text = stripNextSteps(response.text);
|
|
51
|
+
results.push({ index: i, tool: op.tool, status: 'success', text, refs: response.refs });
|
|
52
|
+
lastSuccessText = response.text; // keep next-steps from last success
|
|
53
|
+
}
|
|
54
|
+
catch (err) {
|
|
55
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
56
|
+
results.push({ index: i, tool: op.tool, status: 'error', error: msg });
|
|
57
|
+
if (errorStrategy === 'bail')
|
|
58
|
+
bailedAt = i;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
const succeeded = results.filter(r => r.status === 'success').length;
|
|
62
|
+
const failed = results.filter(r => r.status === 'error').length;
|
|
63
|
+
const skipped = results.filter(r => r.status === 'skipped').length;
|
|
64
|
+
// Build markdown output
|
|
65
|
+
const lines = [
|
|
66
|
+
`## Queue Results (${succeeded}/${results.length} succeeded)`,
|
|
67
|
+
'',
|
|
68
|
+
];
|
|
69
|
+
for (const r of results) {
|
|
70
|
+
const icon = r.status === 'success' ? '✓' : r.status === 'error' ? '✗' : '○';
|
|
71
|
+
const headline = r.status === 'error' ? r.error
|
|
72
|
+
: r.text ? firstLine(r.text)
|
|
73
|
+
: r.status;
|
|
74
|
+
lines.push(`${icon} ${r.tool} — ${headline}`);
|
|
75
|
+
// Full mode: include complete operation output below the summary line
|
|
76
|
+
if (detail === 'full' && r.status === 'success' && r.text) {
|
|
77
|
+
lines.push('', r.text, '');
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
// Append consolidated next-steps from last successful operation
|
|
81
|
+
const nextStepsSuffix = extractNextSteps(lastSuccessText);
|
|
82
|
+
const text = lines.join('\n') + nextStepsSuffix;
|
|
83
|
+
const refs = {
|
|
84
|
+
total: results.length,
|
|
85
|
+
succeeded,
|
|
86
|
+
failed,
|
|
87
|
+
skipped,
|
|
88
|
+
// Per-operation refs keyed by index for downstream access
|
|
89
|
+
results: results.map(r => ({
|
|
90
|
+
tool: r.tool,
|
|
91
|
+
status: r.status,
|
|
92
|
+
...(r.refs ?? {}),
|
|
93
|
+
})),
|
|
94
|
+
};
|
|
95
|
+
return { text, refs };
|
|
96
|
+
}
|
|
97
|
+
// --- Reference resolution ---
|
|
98
|
+
function resolveReferences(args, results) {
|
|
99
|
+
const resolved = {};
|
|
100
|
+
for (const [key, value] of Object.entries(args)) {
|
|
101
|
+
if (typeof value === 'string' && /\$\d+\./.test(value)) {
|
|
102
|
+
resolved[key] = resolveRef(value, results);
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
resolved[key] = value;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return resolved;
|
|
109
|
+
}
|
|
110
|
+
function resolveRef(value, results) {
|
|
111
|
+
return value.replace(/\$(\d+)\.(\w+)/g, (_match, indexStr, field) => {
|
|
112
|
+
const index = parseInt(indexStr, 10);
|
|
113
|
+
if (index >= results.length) {
|
|
114
|
+
throw new Error(`$${index}.${field}: operation ${index} hasn't run yet`);
|
|
115
|
+
}
|
|
116
|
+
const result = results[index];
|
|
117
|
+
if (result.status !== 'success') {
|
|
118
|
+
throw new Error(`$${index}.${field}: operation ${index} ${result.status}`);
|
|
119
|
+
}
|
|
120
|
+
const extracted = result.refs?.[field];
|
|
121
|
+
if (extracted === undefined) {
|
|
122
|
+
throw new Error(`$${index}.${field}: field '${field}' not found in result`);
|
|
123
|
+
}
|
|
124
|
+
return String(extracted);
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
function firstLine(text) {
|
|
128
|
+
// Skip markdown headings to get the first content line
|
|
129
|
+
for (const line of text.split('\n')) {
|
|
130
|
+
const trimmed = line.trim();
|
|
131
|
+
if (trimmed && !trimmed.startsWith('#') && !trimmed.startsWith('---')) {
|
|
132
|
+
return trimmed.length > 80 ? trimmed.slice(0, 79) + '…' : trimmed;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return text.split('\n')[0] ?? '';
|
|
136
|
+
}
|
|
137
|
+
function extractNextSteps(text) {
|
|
138
|
+
const idx = text.indexOf(NEXT_STEPS_SEPARATOR);
|
|
139
|
+
return idx >= 0 ? text.slice(idx) : '';
|
|
140
|
+
}
|
|
141
|
+
//# sourceMappingURL=queue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queue.js","sourceRoot":"","sources":["../../src/server/queue.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
2
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
3
|
+
import { CallToolRequestSchema, ListToolsRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
|
|
4
|
+
import { toolSchemas } from './tools.js';
|
|
5
|
+
import { handleToolCall } from './handler.js';
|
|
6
|
+
import { GwsError, GwsExitCode } from '../executor/errors.js';
|
|
7
|
+
import { nextSteps } from './formatting/next-steps.js';
|
|
8
|
+
import { manifest } from '../factory/registry.js';
|
|
9
|
+
import { checkWorkspaceStatus } from '../executor/workspace.js';
|
|
10
|
+
import { configurePolicies, getActivePolicies, draftOnlyEmail, noDelete, readOnly, auditLog, } from '../factory/safety.js';
|
|
11
|
+
function log(msg) {
|
|
12
|
+
process.stderr.write(`[gws-mcp] ${msg}\n`);
|
|
13
|
+
}
|
|
14
|
+
/** Configure safety policies from GWS_SAFETY_POLICY env var. */
|
|
15
|
+
function initSafetyPolicies() {
|
|
16
|
+
const policyEnv = process.env.GWS_SAFETY_POLICY || '';
|
|
17
|
+
if (!policyEnv)
|
|
18
|
+
return;
|
|
19
|
+
const policyMap = {
|
|
20
|
+
'draft-only-email': draftOnlyEmail,
|
|
21
|
+
'no-delete': noDelete,
|
|
22
|
+
'read-only': readOnly,
|
|
23
|
+
'audit': auditLog,
|
|
24
|
+
};
|
|
25
|
+
const names = policyEnv.split(',').map(s => s.trim()).filter(Boolean);
|
|
26
|
+
const unknown = names.filter(name => !policyMap[name]);
|
|
27
|
+
if (unknown.length > 0) {
|
|
28
|
+
const valid = Object.keys(policyMap).join(', ');
|
|
29
|
+
throw new Error(`Unknown safety policy(ies): ${unknown.join(', ')}. ` +
|
|
30
|
+
`Valid policies: ${valid}`);
|
|
31
|
+
}
|
|
32
|
+
const policies = names.map(name => policyMap[name]);
|
|
33
|
+
configurePolicies(policies);
|
|
34
|
+
}
|
|
35
|
+
export function createServer() {
|
|
36
|
+
initSafetyPolicies();
|
|
37
|
+
log(`startup: ${toolSchemas.length} tools loaded`);
|
|
38
|
+
const server = new Server({
|
|
39
|
+
name: '@aaronsb/google-workspace-mcp',
|
|
40
|
+
version: '2.0.0-alpha.1',
|
|
41
|
+
}, {
|
|
42
|
+
capabilities: {
|
|
43
|
+
tools: {},
|
|
44
|
+
resources: {},
|
|
45
|
+
},
|
|
46
|
+
});
|
|
47
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
48
|
+
return {
|
|
49
|
+
tools: toolSchemas.map(tool => ({
|
|
50
|
+
name: tool.name,
|
|
51
|
+
description: tool.description,
|
|
52
|
+
inputSchema: tool.inputSchema,
|
|
53
|
+
})),
|
|
54
|
+
};
|
|
55
|
+
});
|
|
56
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
57
|
+
const { name, arguments: args } = request.params;
|
|
58
|
+
try {
|
|
59
|
+
log(`call: ${name} ${JSON.stringify(args ?? {}).slice(0, 200)}`);
|
|
60
|
+
const result = await handleToolCall(name, (args ?? {}));
|
|
61
|
+
log(`done: ${name}`);
|
|
62
|
+
return {
|
|
63
|
+
content: [{ type: 'text', text: result.text }],
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
catch (err) {
|
|
67
|
+
if (err instanceof GwsError) {
|
|
68
|
+
// Append auth remediation guidance for auth errors
|
|
69
|
+
const email = args?.email;
|
|
70
|
+
const guidance = err.exitCode === GwsExitCode.AuthError
|
|
71
|
+
? nextSteps('accounts', 'auth_error', email ? { email } : undefined)
|
|
72
|
+
: '';
|
|
73
|
+
return {
|
|
74
|
+
content: [{ type: 'text', text: JSON.stringify({
|
|
75
|
+
error: err.message,
|
|
76
|
+
exitCode: err.exitCode,
|
|
77
|
+
reason: err.reason,
|
|
78
|
+
stderr: err.stderr,
|
|
79
|
+
}, null, 2) + guidance }],
|
|
80
|
+
isError: true,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
84
|
+
return {
|
|
85
|
+
content: [{ type: 'text', text: `Error: ${message}` }],
|
|
86
|
+
isError: true,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
// --- Resources ---
|
|
91
|
+
server.setRequestHandler(ListResourcesRequestSchema, async () => {
|
|
92
|
+
return {
|
|
93
|
+
resources: [
|
|
94
|
+
{
|
|
95
|
+
uri: 'gws://safety/policies',
|
|
96
|
+
name: 'Active Safety Policies',
|
|
97
|
+
description: 'Current safety policies controlling what operations are allowed, blocked, or audited',
|
|
98
|
+
mimeType: 'application/json',
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
uri: 'gws://config/services',
|
|
102
|
+
name: 'Available Services',
|
|
103
|
+
description: 'Google Workspace services and operations available through this server',
|
|
104
|
+
mimeType: 'application/json',
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
uri: 'gws://config/workspace',
|
|
108
|
+
name: 'Workspace Directory',
|
|
109
|
+
description: 'File I/O workspace directory status and path',
|
|
110
|
+
mimeType: 'application/json',
|
|
111
|
+
},
|
|
112
|
+
],
|
|
113
|
+
};
|
|
114
|
+
});
|
|
115
|
+
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
116
|
+
const { uri } = request.params;
|
|
117
|
+
switch (uri) {
|
|
118
|
+
case 'gws://safety/policies': {
|
|
119
|
+
const policies = getActivePolicies();
|
|
120
|
+
const content = {
|
|
121
|
+
active: policies.length > 0,
|
|
122
|
+
policies: policies.map(p => ({
|
|
123
|
+
name: p.name,
|
|
124
|
+
description: p.description,
|
|
125
|
+
})),
|
|
126
|
+
summary: policies.length === 0
|
|
127
|
+
? 'No safety policies active — all operations are allowed.'
|
|
128
|
+
: `${policies.length} policy(ies) active: ${policies.map(p => p.name).join(', ')}. ` +
|
|
129
|
+
'Operations that violate these policies will be blocked with an explanation.',
|
|
130
|
+
};
|
|
131
|
+
return {
|
|
132
|
+
contents: [{
|
|
133
|
+
uri,
|
|
134
|
+
mimeType: 'application/json',
|
|
135
|
+
text: JSON.stringify(content, null, 2),
|
|
136
|
+
}],
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
case 'gws://config/services': {
|
|
140
|
+
const services = Object.entries(manifest.services).map(([name, def]) => ({
|
|
141
|
+
service: name,
|
|
142
|
+
tool: def.tool_name,
|
|
143
|
+
operations: Object.keys(def.operations),
|
|
144
|
+
operationCount: Object.keys(def.operations).length,
|
|
145
|
+
}));
|
|
146
|
+
const content = {
|
|
147
|
+
totalServices: services.length,
|
|
148
|
+
totalOperations: services.reduce((sum, s) => sum + s.operationCount, 0),
|
|
149
|
+
services,
|
|
150
|
+
};
|
|
151
|
+
return {
|
|
152
|
+
contents: [{
|
|
153
|
+
uri,
|
|
154
|
+
mimeType: 'application/json',
|
|
155
|
+
text: JSON.stringify(content, null, 2),
|
|
156
|
+
}],
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
case 'gws://config/workspace': {
|
|
160
|
+
const status = checkWorkspaceStatus();
|
|
161
|
+
return {
|
|
162
|
+
contents: [{
|
|
163
|
+
uri,
|
|
164
|
+
mimeType: 'application/json',
|
|
165
|
+
text: JSON.stringify(status, null, 2),
|
|
166
|
+
}],
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
default:
|
|
170
|
+
throw new Error(`Unknown resource: ${uri}`);
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
return server;
|
|
174
|
+
}
|
|
175
|
+
/** Warm up credentials on startup — validates accounts and refreshes tokens. */
|
|
176
|
+
async function warmupAccounts() {
|
|
177
|
+
try {
|
|
178
|
+
const { listAccounts } = await import('../accounts/registry.js');
|
|
179
|
+
const accounts = await listAccounts();
|
|
180
|
+
if (accounts.length === 0) {
|
|
181
|
+
log('startup: no accounts configured');
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
log(`startup: warming ${accounts.length} account(s)`);
|
|
185
|
+
for (const account of accounts) {
|
|
186
|
+
const email = account.email;
|
|
187
|
+
try {
|
|
188
|
+
const { hasCredential } = await import('../accounts/credentials.js');
|
|
189
|
+
if (await hasCredential(email)) {
|
|
190
|
+
const { execute } = await import('../executor/gws.js');
|
|
191
|
+
await execute(['gmail', 'users', 'getProfile', '--params', JSON.stringify({ userId: 'me' })], { account: email });
|
|
192
|
+
log(`startup: ${email} — token valid`);
|
|
193
|
+
}
|
|
194
|
+
else {
|
|
195
|
+
log(`startup: ${email} — no credential file`);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
catch (err) {
|
|
199
|
+
log(`startup: ${email} — token invalid (${err.message})`);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
catch (err) {
|
|
204
|
+
log(`startup: warmup failed (${err.message})`);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
export async function startServer() {
|
|
208
|
+
const server = createServer();
|
|
209
|
+
const transport = new StdioServerTransport();
|
|
210
|
+
await server.connect(transport);
|
|
211
|
+
// Non-blocking warmup — don't delay MCP handshake
|
|
212
|
+
warmupAccounts().catch(() => { });
|
|
213
|
+
}
|
|
214
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/server/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool registry — combines factory-generated schemas with hand-coded tools.
|
|
3
|
+
*
|
|
4
|
+
* Factory tools come from the manifest (ADR-300). Hand-coded tools are
|
|
5
|
+
* manage_accounts (not a gws wrapper) and queue_operations (meta-tool).
|
|
6
|
+
*/
|
|
7
|
+
export interface ToolSchema {
|
|
8
|
+
name: string;
|
|
9
|
+
description: string;
|
|
10
|
+
inputSchema: Record<string, unknown>;
|
|
11
|
+
}
|
|
12
|
+
export declare const toolSchemas: ToolSchema[];
|
|
13
|
+
export declare function getToolSchema(name: string): ToolSchema | undefined;
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool registry — combines factory-generated schemas with hand-coded tools.
|
|
3
|
+
*
|
|
4
|
+
* Factory tools come from the manifest (ADR-300). Hand-coded tools are
|
|
5
|
+
* manage_accounts (not a gws wrapper) and queue_operations (meta-tool).
|
|
6
|
+
*/
|
|
7
|
+
import { generatedTools } from '../factory/registry.js';
|
|
8
|
+
// Hand-coded tools that don't go through the factory
|
|
9
|
+
const handCodedSchemas = [
|
|
10
|
+
{
|
|
11
|
+
name: 'manage_accounts',
|
|
12
|
+
description: 'Manage Google Workspace account lifecycle: list, authenticate, check status, refresh credentials, update scopes, or remove accounts.',
|
|
13
|
+
inputSchema: {
|
|
14
|
+
type: 'object',
|
|
15
|
+
properties: {
|
|
16
|
+
operation: {
|
|
17
|
+
type: 'string',
|
|
18
|
+
enum: ['list', 'authenticate', 'remove', 'status', 'refresh', 'scopes', 'capabilities'],
|
|
19
|
+
description: 'list: show all accounts | authenticate: add new account (opens browser) | remove: delete account and credentials | status: check token validity and scopes | refresh: re-export credentials from gws | scopes: re-auth with different services | capabilities: show available services, safety policies, and workspace status',
|
|
20
|
+
},
|
|
21
|
+
email: { type: 'string', description: 'Required for remove, status, refresh, scopes' },
|
|
22
|
+
category: { type: 'string', enum: ['personal', 'work', 'other'], description: 'For authenticate (default: personal)' },
|
|
23
|
+
description: { type: 'string', description: 'For authenticate — optional label' },
|
|
24
|
+
services: { type: 'string', description: 'For scopes — comma-separated service names (e.g. gmail,drive,calendar,sheets)' },
|
|
25
|
+
},
|
|
26
|
+
required: ['operation'],
|
|
27
|
+
additionalProperties: false,
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
name: 'manage_workspace',
|
|
32
|
+
description: 'Read, write, list, or delete files in the workspace directory. The workspace is the exchange point for file operations (attachments, downloads, exports).',
|
|
33
|
+
inputSchema: {
|
|
34
|
+
type: 'object',
|
|
35
|
+
properties: {
|
|
36
|
+
operation: {
|
|
37
|
+
type: 'string',
|
|
38
|
+
enum: ['list', 'read', 'write', 'delete'],
|
|
39
|
+
description: 'list: show files in workspace | read: get file content | write: save content to file | delete: remove a file',
|
|
40
|
+
},
|
|
41
|
+
filename: { type: 'string', description: 'File name (for read, write, delete)' },
|
|
42
|
+
content: { type: 'string', description: 'File content to write (for write)' },
|
|
43
|
+
},
|
|
44
|
+
required: ['operation'],
|
|
45
|
+
additionalProperties: false,
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
name: 'queue_operations',
|
|
50
|
+
description: 'Execute multiple operations in sequence. Operations run in order with result references ($0.field) to chain outputs. Use for multi-step workflows.',
|
|
51
|
+
inputSchema: {
|
|
52
|
+
type: 'object',
|
|
53
|
+
properties: {
|
|
54
|
+
operations: {
|
|
55
|
+
type: 'array',
|
|
56
|
+
items: {
|
|
57
|
+
type: 'object',
|
|
58
|
+
properties: {
|
|
59
|
+
tool: {
|
|
60
|
+
type: 'string',
|
|
61
|
+
enum: ['manage_email', 'manage_calendar', 'manage_drive', 'manage_accounts'],
|
|
62
|
+
description: 'Tool to call',
|
|
63
|
+
},
|
|
64
|
+
args: {
|
|
65
|
+
type: 'object',
|
|
66
|
+
description: 'Arguments for the tool. Use $N.field to reference results from earlier operations.',
|
|
67
|
+
},
|
|
68
|
+
onError: {
|
|
69
|
+
type: 'string',
|
|
70
|
+
enum: ['bail', 'continue'],
|
|
71
|
+
description: 'bail: stop on error (default) | continue: skip and proceed',
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
required: ['tool', 'args'],
|
|
75
|
+
},
|
|
76
|
+
maxItems: 10,
|
|
77
|
+
description: 'Operations to execute sequentially',
|
|
78
|
+
},
|
|
79
|
+
detail: {
|
|
80
|
+
type: 'string',
|
|
81
|
+
enum: ['summary', 'full'],
|
|
82
|
+
description: 'summary: one-line status per operation (default) | full: include complete output from each operation',
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
required: ['operations'],
|
|
86
|
+
additionalProperties: false,
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
];
|
|
90
|
+
// Factory-generated schemas from the shared registry
|
|
91
|
+
const factorySchemas = generatedTools.map(t => t.schema);
|
|
92
|
+
export const toolSchemas = [
|
|
93
|
+
...handCodedSchemas,
|
|
94
|
+
...factorySchemas,
|
|
95
|
+
];
|
|
96
|
+
export function getToolSchema(name) {
|
|
97
|
+
return toolSchemas.find(t => t.name === name);
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/server/tools.ts"],"names":[],"mappings":"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"}
|