Spaces:
Sleeping
Sleeping
| # Contributing | |
| Thanks for your interest in contributing! This guide covers how to set up the project for local development, understand the architecture, and submit changes. | |
| ## Development Setup | |
| ### Prerequisites | |
| - Node.js 20+ ([nodejs.org](https://nodejs.org/)) | |
| - Git ([git-scm.com](https://git-scm.com/downloads)) | |
| - A Google Account with access to test documents | |
| ### Clone and Build | |
| ```bash | |
| git clone https://github.com/a-bonus/google-docs-mcp.git | |
| cd google-docs-mcp | |
| npm install | |
| npm run build | |
| ``` | |
| ### Authenticate | |
| You need Google OAuth credentials to test the server against real APIs. | |
| **Option A: credentials.json file** | |
| 1. Download your OAuth client JSON from [Google Cloud Console](https://console.cloud.google.com/) | |
| 2. Rename it to `credentials.json` and place it in the project root | |
| 3. Run `npm start auth` to open the browser-based OAuth flow | |
| **Option B: Environment variables** | |
| ```bash | |
| GOOGLE_CLIENT_ID="your-client-id" \ | |
| GOOGLE_CLIENT_SECRET="your-client-secret" \ | |
| npm start auth | |
| ``` | |
| Both options save the refresh token to `~/.config/google-docs-mcp/token.json`. OAuth client IDs and client secrets stay in your environment or `credentials.json`; they are not stored in the token file. | |
| ### Register Your Local Build | |
| Point your MCP client at the local build for testing: | |
| ```json | |
| { | |
| "mcpServers": { | |
| "google-docs": { | |
| "command": "node", | |
| "args": ["/absolute/path/to/mcp-googledocs-server/dist/index.js"] | |
| } | |
| } | |
| } | |
| ``` | |
| ### Scripts | |
| | Command | Description | | |
| | ---------------------- | ------------------------------ | | |
| | `npm start` | Start the MCP server | | |
| | `npm start auth` | Run the interactive OAuth flow | | |
| | `npm run build` | Compile TypeScript to `dist/` | | |
| | `npm test` | Run tests (Vitest) | | |
| | `npm run format` | Format code with Prettier | | |
| | `npm run format:check` | Check formatting | | |
| --- | |
| ## Project Architecture | |
| ### Entry Points | |
| ``` | |
| src/index.ts Entry point: CLI (auth subcommand) and MCP server startup | |
| src/auth.ts OAuth / service account authentication | |
| src/clients.ts Google API client singletons (Docs, Drive, Sheets) | |
| ``` | |
| ### Tools | |
| Tools live in `src/tools/`, organized by domain. Each tool is a single file exporting a `register(server: FastMCP)` function. | |
| ``` | |
| src/tools/ | |
| βββ index.ts Top-level router | |
| βββ docs/ Google Docs tools (13) | |
| β βββ comments/ Comment management (6) | |
| β βββ formatting/ Text and paragraph styling (2) | |
| βββ drive/ Google Drive tools (15) | |
| βββ sheets/ Google Sheets tools (37) | |
| βββ gmail/ Gmail tools (13) | |
| βββ calendar/ Google Calendar tools (5) | |
| βββ utils/ Cross-cutting utilities (3) | |
| ``` | |
| ### Helpers | |
| | File | Purpose | | |
| | ------------------------------- | ------------------------------------------------------------------ | | |
| | `src/googleDocsApiHelpers.ts` | Text range finding, batch update execution, style request builders | | |
| | `src/googleSheetsApiHelpers.ts` | A1 notation parsing, cell formatting, freeze, validation | | |
| | `src/markdown-transformer/` | Markdown parsing and bidirectional Google Docs conversion | | |
| | `src/types.ts` | Zod schemas, hex color validation, shared type definitions | | |
| | `src/logger.ts` | Leveled logger (debug/info/warn/error) writing to stderr | | |
| ### Authentication Flow | |
| The auth module (`src/auth.ts`) resolves credentials in this order: | |
| 1. `SERVICE_ACCOUNT_PATH` env var -- service account JWT | |
| 2. `GOOGLE_CLIENT_ID` + `GOOGLE_CLIENT_SECRET` env vars -- OAuth (for `npx` consumers) | |
| 3. `credentials.json` in the project root -- OAuth (for local dev) | |
| Tokens are persisted to `~/.config/google-docs-mcp/token.json` (respects `XDG_CONFIG_HOME`). The token file stores OAuth token credentials only, not OAuth client IDs or client secrets. | |
| --- | |
| ## Adding a New Tool | |
| 1. Create a new file in the appropriate domain folder (e.g., `src/tools/sheets/myNewTool.ts`) | |
| 2. Export a `register(server: FastMCP)` function that calls `server.addTool({...})` | |
| 3. Import and call it from the domain's `index.ts` router | |
| 4. Add tests if the tool involves non-trivial logic | |
| ### Tool Conventions | |
| - **Names:** camelCase, verb-first (e.g., `readDocument`, `formatCells`) | |
| - **Descriptions:** Start with what the tool does, mention when to use it, note any caveats | |
| - **Parameters:** Use Zod schemas with `.describe()` on every field | |
| - **Errors:** Throw `UserError` from `fastmcp` for user-facing errors | |
| - **Output:** Return `JSON.stringify`'d structured data for tools that return actionable information | |
| --- | |
| ## Testing | |
| Tests use [Vitest](https://vitest.dev/) and live alongside source files or in `src/`: | |
| ```bash | |
| npm test # Run all tests | |
| npm test -- --watch # Watch mode | |
| ``` | |
| Tests mock Google API clients -- they don't make real API calls. | |
| --- | |
| ## Code Style | |
| - TypeScript with strict mode | |
| - ESM modules (`.js` extensions in imports) | |
| - Prettier for formatting (`npm run format`) | |
| - All log output goes to stderr (stdout is reserved for MCP protocol) | |
| --- | |
| ## Releasing | |
| Releases are automated via GitHub Actions. To publish a new version: | |
| 1. Update the version in `package.json` | |
| 2. Commit and push to `main` | |
| 3. Tag the commit: `git tag v1.2.3 && git push origin v1.2.3` | |
| 4. The [release workflow](.github/workflows/release.yml) will run CI checks, publish to npm, and create a GitHub Release | |
| The npm package is published as `@a-bonus/google-docs-mcp`. | |