An MCP experiment to access google workspace
Google Workspace Code MCP
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:
- Primary skill: https://github.com/mitsuhiko/agent-stuff/tree/main/skills/google-workspace
This repository is an alternative code-first MCP experiment built around one execute tool.
It is intentionally aligned with the ideas in:
- Your MCP Doesn’t Need 30 Tools: It Needs Code — https://lucumr.pocoo.org/2025/8/18/code-mcps/
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.
What this server does
- Exposes one MCP tool:
execute - Runs user-provided JavaScript/TypeScript (async function body; TS types stripped)
- Automatically performs OAuth login on first use (browser flow)
- Reuses stored tokens on subsequent calls
- Provides a small runtime API inside executed code:
auth— Google OAuth clientgoogle—googleapisSDK rootworkspace— helper methods (call,service,whoAmI)state— persistent mutable object across calls
This follows a code-mode design: one flexible execution tool instead of many fixed tools.
Requirements
- Node.js 20+
- Local desktop/browser access for the initial OAuth sign-in
Install
npm install
Run
npm start
or:
node src/server.js
MCP configuration
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.
Tool contract
Tool name
execute
Input schema
script(string, required): JavaScript/TypeScript async function body (TS type syntax is stripped before execution)timeoutMs(number, optional): execution timeout in milliseconds (default30000, max300000)scopes(string[], optional): override OAuth scopes for the callresetState(boolean, optional): clears persistentstatebefore execution
Execution environment
Your script runs as an async function body with these variables in scope:
authgoogleworkspacestate
Return values are serialized and sent back as tool output.
Example scripts
1) Who am I + list Drive files
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
};
2) List today’s calendar events
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'
});
OAuth and token storage
- First call without token triggers browser login automatically
- Default config directory:
~/.pi/google-workspace - Default token path:
~/.pi/google-workspace/token.json - Default auth mode:
cloud(unless overridden)
Environment variables
GOOGLE_WORKSPACE_CONFIG_DIRGOOGLE_WORKSPACE_CREDENTIALSGOOGLE_WORKSPACE_TOKENGOOGLE_WORKSPACE_AUTH_MODE(cloudorlocal)GOOGLE_WORKSPACE_CLIENT_IDGOOGLE_WORKSPACE_CLOUD_FUNCTION_URLGOOGLE_WORKSPACE_CALLBACK_HOST
Security notes
- Uses Node
vmfor execution convenience, not a hardened sandbox. - Treat this as trusted local tooling.
- Do not expose this server to untrusted users or networks.