loading…
Search for a command to run...
loading…
A code-first MCP server that provides a single tool to execute JavaScript or TypeScript with authenticated access to Google Workspace APIs. It enables flexible
A code-first MCP server that provides a single tool to execute JavaScript or TypeScript with authenticated access to Google Workspace APIs. It enables flexible interactions with services like Calendar and Drive by running user-provided scripts through a built-in runtime environment.
Important: This is an alternative experiment, not my primary setup
If you are looking for the Google Workspace integration I actually use day-to-day, use this skill instead:
This repository is an alternative code-first MCP experiment built around one execute tool.
It is intentionally aligned with the ideas in:
That post explores code-supported/code-first MCP design (fewer fixed tools, more programmable capability).
A local JavaScript/TypeScript MCP server with a single tool: execute.
execute runs JavaScript (or TypeScript with type stripping) and gives that code authenticated access to Google Workspace APIs.
executeauth — Google OAuth clientgoogle — googleapis SDK rootworkspace — helper methods (call, service, whoAmI)state — persistent mutable object across callsThis follows a code-mode design: one flexible execution tool instead of many fixed tools.
npm install
npm start
or:
node src/server.js
This repo already includes .mcp.json:
{
"mcpServers": {
"google-workspace-code": {
"type": "stdio",
"command": "node",
"args": [
"/Users/mitsuhiko/Development/workspace-mcp/src/server.js"
],
"env": {
"GOOGLE_WORKSPACE_AUTH_MODE": "cloud"
}
}
}
}
If you move the project, update the args path.
executescript (string, required): JavaScript/TypeScript async function body (TS type syntax is stripped before execution)timeoutMs (number, optional): execution timeout in milliseconds (default 30000, max 300000)scopes (string[], optional): override OAuth scopes for the callresetState (boolean, optional): clears persistent state before executionYour script runs as an async function body with these variables in scope:
authgoogleworkspacestateReturn values are serialized and sent back as tool output.
const me = await workspace.whoAmI();
const files = await workspace.call('drive', 'files.list', {
pageSize: 5,
fields: 'files(id,name,mimeType)'
});
state.lastEmail = me.email;
return {
user: me,
files: files.files,
remembered: state.lastEmail
};
const start = new Date();
start.setHours(0, 0, 0, 0);
const end = new Date(start);
end.setDate(end.getDate() + 1);
return await workspace.call('calendar', 'events.list', {
calendarId: 'primary',
timeMin: start.toISOString(),
timeMax: end.toISOString(),
singleEvents: true,
orderBy: 'startTime'
});
~/.pi/google-workspace~/.pi/google-workspace/token.jsoncloud (unless overridden)GOOGLE_WORKSPACE_CONFIG_DIRGOOGLE_WORKSPACE_CREDENTIALSGOOGLE_WORKSPACE_TOKENGOOGLE_WORKSPACE_AUTH_MODE (cloud or local)GOOGLE_WORKSPACE_CLIENT_IDGOOGLE_WORKSPACE_CLOUD_FUNCTION_URLGOOGLE_WORKSPACE_CALLBACK_HOSTvm for execution convenience, not a hardened sandbox.Добавь это в claude_desktop_config.json и перезапусти Claude Desktop.
{
"mcpServers": {
"google-workspace-code-mcp": {
"command": "npx",
"args": []
}
}
}