gogcli-mcp 1.0.0
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/settings.local.json +35 -0
- package/.github/workflows/ci.yml +22 -0
- package/.github/workflows/release.yml +76 -0
- package/.github/workflows/tag-and-bump.yml +67 -0
- package/.mcp.json +12 -0
- package/CLAUDE.md +61 -0
- package/README.md +165 -0
- package/SKILL.md +69 -0
- package/dist/index.js +30298 -0
- package/docs/superpowers/plans/2026-04-12-gogcli-mcp.md +758 -0
- package/docs/superpowers/specs/2026-04-12-gogcli-mcp-design.md +102 -0
- package/manifest.json +95 -0
- package/package.json +28 -0
- package/skills/gogcli/SKILL.md +69 -0
- package/src/index.ts +14 -0
- package/src/runner.ts +61 -0
- package/src/tools/sheets.ts +151 -0
- package/tests/runner.test.ts +220 -0
- package/tests/tools/sheets.test.ts +183 -0
- package/tsconfig.json +15 -0
- package/vitest.config.ts +17 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"permissions": {
|
|
3
|
+
"allow": [
|
|
4
|
+
"Read(//Users/chris/git/ofw-mcp/**)",
|
|
5
|
+
"Read(//Users/chris/git/**)",
|
|
6
|
+
"Bash(gog --help)",
|
|
7
|
+
"Bash(gog agent:*)",
|
|
8
|
+
"Bash(gog schema:*)",
|
|
9
|
+
"Bash(python3 -c \"import json,sys; d=json.load\\(sys.stdin\\); cmds=[c['name'] for c in d['command'].get\\('subcommands',[]\\)]; print\\('\\\\n'.join\\(cmds\\)\\)\")",
|
|
10
|
+
"Bash(python3 -c ':*)",
|
|
11
|
+
"Bash(gog sheets:*)",
|
|
12
|
+
"Bash(git add:*)",
|
|
13
|
+
"Bash(git commit -m ':*)",
|
|
14
|
+
"Bash(xargs cat:*)",
|
|
15
|
+
"Bash(git:*)",
|
|
16
|
+
"Bash(npm install:*)",
|
|
17
|
+
"Bash(npm list:*)",
|
|
18
|
+
"Bash(npm --version)",
|
|
19
|
+
"Bash(python3 -c \"import json,sys; d=json.load\\(sys.stdin\\); print\\('lockfileVersion:', d.get\\('lockfileVersion'\\)\\); pkgs=d.get\\('packages',{}\\); mcp=pkgs.get\\('node_modules/@modelcontextprotocol/sdk',{}\\); zod=pkgs.get\\('node_modules/zod',{}\\); ts=pkgs.get\\('node_modules/typescript',{}\\); vitest=pkgs.get\\('node_modules/vitest',{}\\); esbuild=pkgs.get\\('node_modules/esbuild',{}\\); print\\('MCP SDK resolved:', mcp.get\\('version'\\)\\); print\\('zod resolved:', zod.get\\('version'\\)\\); print\\('typescript resolved:', ts.get\\('version'\\)\\); print\\('vitest resolved:', vitest.get\\('version'\\)\\); print\\('esbuild resolved:', esbuild.get\\('version'\\)\\)\")",
|
|
20
|
+
"Bash(npm test:*)",
|
|
21
|
+
"Bash(npx tsc:*)",
|
|
22
|
+
"Bash(python3 -c \"import sys,json; d=json.load\\(sys.stdin\\); print\\(d.get\\('version','?'\\)\\)\")",
|
|
23
|
+
"Bash(node_modules/.bin/tsc --version)",
|
|
24
|
+
"Bash(node_modules/.bin/tsc --noEmit)",
|
|
25
|
+
"Bash(cat /Users/chris/git/gogcli-mcp/vitest.config.*)",
|
|
26
|
+
"Bash(node:*)",
|
|
27
|
+
"Bash(npm run:*)",
|
|
28
|
+
"Bash(tsc:*)",
|
|
29
|
+
"Bash(ls /Users/chris/git/gogcli-mcp/*.json)",
|
|
30
|
+
"Bash(ls /Users/chris/git/gogcli-mcp/*.md)",
|
|
31
|
+
"Bash(python3 -c \"import json,sys; d=json.load\\(sys.stdin\\); print\\(json.dumps\\(d, indent=2\\)\\)\")",
|
|
32
|
+
"Bash(gh repo:*)"
|
|
33
|
+
]
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
workflow_call:
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
ci:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/checkout@v6.0.2
|
|
14
|
+
|
|
15
|
+
- uses: actions/setup-node@v6.3.0
|
|
16
|
+
with:
|
|
17
|
+
node-version: 22
|
|
18
|
+
cache: npm
|
|
19
|
+
|
|
20
|
+
- run: npm ci
|
|
21
|
+
- run: npm run build
|
|
22
|
+
- run: npm test
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- 'v*'
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
ci:
|
|
10
|
+
uses: ./.github/workflows/ci.yml
|
|
11
|
+
|
|
12
|
+
release:
|
|
13
|
+
needs: ci
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
permissions:
|
|
16
|
+
contents: write
|
|
17
|
+
id-token: write
|
|
18
|
+
|
|
19
|
+
steps:
|
|
20
|
+
- uses: actions/checkout@v6.0.2
|
|
21
|
+
|
|
22
|
+
- uses: actions/setup-node@v6.3.0
|
|
23
|
+
with:
|
|
24
|
+
node-version: 24
|
|
25
|
+
cache: npm
|
|
26
|
+
registry-url: https://registry.npmjs.org
|
|
27
|
+
|
|
28
|
+
# Strip always-auth from .npmrc (set by setup-node, deprecated in npm 11)
|
|
29
|
+
- run: sed -i '/always-auth/d' "$NPM_CONFIG_USERCONFIG"
|
|
30
|
+
|
|
31
|
+
- run: npm ci
|
|
32
|
+
- run: npm run build
|
|
33
|
+
|
|
34
|
+
- name: Extract version
|
|
35
|
+
run: |
|
|
36
|
+
VERSION=$(node -p "require('./package.json').version")
|
|
37
|
+
echo "VERSION=${VERSION}" >> "$GITHUB_ENV"
|
|
38
|
+
|
|
39
|
+
# Package the .skill file
|
|
40
|
+
- name: Package skill
|
|
41
|
+
run: |
|
|
42
|
+
python3 - <<'EOF'
|
|
43
|
+
import zipfile, pathlib, os
|
|
44
|
+
|
|
45
|
+
version = os.environ["VERSION"]
|
|
46
|
+
skill_name = "gogcli-mcp"
|
|
47
|
+
out = pathlib.Path(f"{skill_name}-{version}.skill")
|
|
48
|
+
|
|
49
|
+
with zipfile.ZipFile(out, "w", zipfile.ZIP_DEFLATED) as zf:
|
|
50
|
+
zf.write(pathlib.Path("SKILL.md"), f"{skill_name}/SKILL.md")
|
|
51
|
+
|
|
52
|
+
print(f"Packaged {out} ({out.stat().st_size} bytes)")
|
|
53
|
+
EOF
|
|
54
|
+
|
|
55
|
+
# Sync manifest.json version from package.json and build .mcpb
|
|
56
|
+
- name: Build .mcpb bundle
|
|
57
|
+
run: |
|
|
58
|
+
node -e "
|
|
59
|
+
const fs = require('fs');
|
|
60
|
+
const m = JSON.parse(fs.readFileSync('manifest.json', 'utf8'));
|
|
61
|
+
m.version = '$VERSION';
|
|
62
|
+
fs.writeFileSync('manifest.json', JSON.stringify(m, null, 2) + '\n');
|
|
63
|
+
"
|
|
64
|
+
npx @anthropic-ai/mcpb pack
|
|
65
|
+
mv gogcli-mcp.mcpb "gogcli-mcp-${VERSION}.mcpb"
|
|
66
|
+
|
|
67
|
+
- name: Publish to npm
|
|
68
|
+
run: npm publish --access public --provenance
|
|
69
|
+
|
|
70
|
+
- name: Create GitHub Release
|
|
71
|
+
uses: softprops/action-gh-release@v3.0.0
|
|
72
|
+
with:
|
|
73
|
+
files: |
|
|
74
|
+
gogcli-mcp-${{ env.VERSION }}.skill
|
|
75
|
+
gogcli-mcp-${{ env.VERSION }}.mcpb
|
|
76
|
+
generate_release_notes: true
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
name: Tag & Bump
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
|
|
6
|
+
jobs:
|
|
7
|
+
ci:
|
|
8
|
+
uses: ./.github/workflows/ci.yml
|
|
9
|
+
|
|
10
|
+
tag-and-bump:
|
|
11
|
+
needs: ci
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
permissions:
|
|
14
|
+
contents: write
|
|
15
|
+
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v6.0.2
|
|
18
|
+
with:
|
|
19
|
+
# PAT required — GITHUB_TOKEN pushes don't trigger other workflows
|
|
20
|
+
token: ${{ secrets.RELEASE_PAT }}
|
|
21
|
+
|
|
22
|
+
- uses: actions/setup-node@v6.3.0
|
|
23
|
+
with:
|
|
24
|
+
node-version: 22
|
|
25
|
+
cache: npm
|
|
26
|
+
|
|
27
|
+
- run: npm ci
|
|
28
|
+
|
|
29
|
+
- name: Configure git
|
|
30
|
+
run: |
|
|
31
|
+
git config user.name "github-actions[bot]"
|
|
32
|
+
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
33
|
+
|
|
34
|
+
# Tag the current commit with the current version
|
|
35
|
+
- name: Tag current version
|
|
36
|
+
run: |
|
|
37
|
+
CURRENT=$(node -p "require('./package.json').version")
|
|
38
|
+
git tag "v${CURRENT}"
|
|
39
|
+
echo "TAGGED_VERSION=${CURRENT}" >> "$GITHUB_ENV"
|
|
40
|
+
|
|
41
|
+
# Bump patch version in all four locations
|
|
42
|
+
- name: Bump patch version
|
|
43
|
+
run: |
|
|
44
|
+
npm version patch --no-git-tag-version
|
|
45
|
+
NEXT=$(node -p "require('./package.json').version")
|
|
46
|
+
echo "NEXT_VERSION=${NEXT}" >> "$GITHUB_ENV"
|
|
47
|
+
|
|
48
|
+
# src/index.ts — MCP server version
|
|
49
|
+
sed -i "s/version: '${TAGGED_VERSION}'/version: '${NEXT}'/" src/index.ts
|
|
50
|
+
|
|
51
|
+
# manifest.json
|
|
52
|
+
node -e "
|
|
53
|
+
const fs = require('fs');
|
|
54
|
+
const m = JSON.parse(fs.readFileSync('manifest.json', 'utf8'));
|
|
55
|
+
m.version = '${NEXT}';
|
|
56
|
+
fs.writeFileSync('manifest.json', JSON.stringify(m, null, 2) + '\n');
|
|
57
|
+
"
|
|
58
|
+
|
|
59
|
+
- name: Rebuild
|
|
60
|
+
run: npm run build
|
|
61
|
+
|
|
62
|
+
- name: Commit and push
|
|
63
|
+
run: |
|
|
64
|
+
git add -A
|
|
65
|
+
git commit -m "chore: bump version to v${NEXT_VERSION}"
|
|
66
|
+
git push origin main
|
|
67
|
+
git push origin "v${TAGGED_VERSION}"
|
package/.mcp.json
ADDED
package/CLAUDE.md
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# gogcli-mcp
|
|
2
|
+
|
|
3
|
+
MCP server wrapping [gogcli](https://github.com/steipete/gogcli) — provides Claude with read/write access to Google Sheets, with a scaffold for Gmail, Calendar, Drive, and more.
|
|
4
|
+
|
|
5
|
+
## Build & Test
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm run build # tsc --noEmit (type check) + esbuild bundle → dist/index.js
|
|
9
|
+
npm test # vitest run (all tests)
|
|
10
|
+
npm run test:watch # vitest in watch mode
|
|
11
|
+
npm run test:coverage # vitest with 100% coverage enforcement
|
|
12
|
+
npm run typecheck # tsc --noEmit only
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Versioning
|
|
16
|
+
|
|
17
|
+
Version appears in FOUR places — all must match:
|
|
18
|
+
|
|
19
|
+
1. `package.json` → `"version"`
|
|
20
|
+
2. `package-lock.json` → run `npm install --package-lock-only` after changing package.json
|
|
21
|
+
3. `src/index.ts` → `McpServer` constructor `version` field
|
|
22
|
+
4. `manifest.json` → `"version"`
|
|
23
|
+
|
|
24
|
+
### Release workflow
|
|
25
|
+
|
|
26
|
+
Main is always one version ahead of the latest tag. To release, run the **Tag & Bump** GitHub Action (`tag-and-bump.yml`) which:
|
|
27
|
+
|
|
28
|
+
1. Runs CI (build + test)
|
|
29
|
+
2. Tags the current commit with the current version
|
|
30
|
+
3. Bumps patch in all four files
|
|
31
|
+
4. Rebuilds, commits, and pushes main + tag
|
|
32
|
+
5. The tag push triggers the **Release** workflow (CI + npm publish + .mcpb + .skill + GitHub release)
|
|
33
|
+
|
|
34
|
+
Do NOT manually bump versions or create tags unless the user explicitly asks.
|
|
35
|
+
|
|
36
|
+
## Architecture
|
|
37
|
+
|
|
38
|
+
- `src/runner.ts` — only module touching `child_process`. Exports `run(args, options)` with `Spawner` DI for testing. Injects `--json --no-input --color=never`, handles `--account` from `options.account` → `GOG_ACCOUNT` env var → omit. 30-second timeout kills stalled processes.
|
|
39
|
+
- `src/tools/sheets.ts` — registers 8 Sheets MCP tools via `registerSheetsTools(server)`. Imports `run()` from runner. Errors are caught and returned as text content so the model can read gogcli's error messages.
|
|
40
|
+
- `src/index.ts` — MCP server entry point. Creates `McpServer`, calls `registerXxxTools(server)` for each service, connects via `StdioServerTransport`.
|
|
41
|
+
- `tests/runner.test.ts` — unit tests for runner using mock `Spawner` DI (no real processes)
|
|
42
|
+
- `tests/tools/sheets.test.ts` — unit tests for sheets tools, runner mocked via `vi.mock`
|
|
43
|
+
|
|
44
|
+
## Adding a New Google Service
|
|
45
|
+
|
|
46
|
+
To add Gmail, Calendar, Drive, etc.:
|
|
47
|
+
|
|
48
|
+
1. Create `src/tools/<service>.ts` — export `registerXxxTools(server: McpServer)`
|
|
49
|
+
2. Implement curated tools for common ops + a `gog_<service>_run` escape hatch (see `sheets.ts` for the pattern)
|
|
50
|
+
3. Create `tests/tools/<service>.test.ts` — mock `runner.run` via `vi.mock('../../src/runner.js')`
|
|
51
|
+
4. In `src/index.ts`, import and call `registerXxxTools(server)`
|
|
52
|
+
5. Add tools to `manifest.json` tools list
|
|
53
|
+
6. No changes to `runner.ts` or `.mcp.json` required
|
|
54
|
+
|
|
55
|
+
## gogcli Notes
|
|
56
|
+
|
|
57
|
+
- `gog schema --json` outputs machine-readable command/flag schema for all subcommands
|
|
58
|
+
- `gog sheets update` and `gog sheets append` accept `--values-json=<JSON 2D array>` for structured input
|
|
59
|
+
- All commands support `--account <email>` for multi-account targeting
|
|
60
|
+
- `--no-input` prevents interactive prompts; `--json` ensures parseable output; `--color=never` strips ANSI codes
|
|
61
|
+
- `gog agent exit-codes` documents stable exit codes for automation
|
package/README.md
ADDED
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
# gogcli-mcp
|
|
2
|
+
|
|
3
|
+
A [Model Context Protocol](https://modelcontextprotocol.io) server that gives Claude natural-language access to Google Sheets (and more) via [gogcli](https://github.com/steipete/gogcli).
|
|
4
|
+
|
|
5
|
+
> [!WARNING]
|
|
6
|
+
> **AI-developed project.** This codebase was entirely built and is actively maintained by [Claude Sonnet 4.6](https://www.anthropic.com/claude). No human has audited the implementation. Review all code and tool permissions before use.
|
|
7
|
+
|
|
8
|
+
## What you can do
|
|
9
|
+
|
|
10
|
+
Ask Claude things like:
|
|
11
|
+
|
|
12
|
+
- *"Read the data in Sheet1!A1:D20 of my budget spreadsheet"*
|
|
13
|
+
- *"Append this week's expenses to my tracking sheet"*
|
|
14
|
+
- *"Create a new spreadsheet called Q2 Planning"*
|
|
15
|
+
- *"Find all instances of 'TBD' in my project sheet and replace with 'Done'"*
|
|
16
|
+
- *"What tabs are in spreadsheet ID xyz?"*
|
|
17
|
+
|
|
18
|
+
## Requirements
|
|
19
|
+
|
|
20
|
+
- [gogcli](https://github.com/steipete/gogcli) installed and authenticated (`gog --help` works)
|
|
21
|
+
- [Claude Desktop](https://claude.ai/download) or [Claude Code](https://claude.ai/code)
|
|
22
|
+
- Node.js 18 or later
|
|
23
|
+
|
|
24
|
+
Install gogcli via Homebrew:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
brew install gogcli
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Then authenticate:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
gog auth add
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Installation
|
|
37
|
+
|
|
38
|
+
### 1. Clone and build
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
git clone https://github.com/chrischall/gogcli-mcp.git
|
|
42
|
+
cd gogcli-mcp
|
|
43
|
+
npm install
|
|
44
|
+
npm run build
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### 2. Add to Claude Desktop
|
|
48
|
+
|
|
49
|
+
Edit your Claude Desktop config file:
|
|
50
|
+
|
|
51
|
+
- **Mac:** `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
52
|
+
- **Windows:** `%APPDATA%\Claude\claude_desktop_config.json`
|
|
53
|
+
|
|
54
|
+
Add the `gogcli` entry inside `"mcpServers"`:
|
|
55
|
+
|
|
56
|
+
```json
|
|
57
|
+
{
|
|
58
|
+
"mcpServers": {
|
|
59
|
+
"gogcli": {
|
|
60
|
+
"command": "node",
|
|
61
|
+
"args": ["/absolute/path/to/gogcli-mcp/dist/index.js"],
|
|
62
|
+
"env": {
|
|
63
|
+
"GOG_ACCOUNT": "you@gmail.com"
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Replace `/absolute/path/to/gogcli-mcp` with the actual path. On Mac, run `pwd` inside the cloned directory to get it.
|
|
71
|
+
|
|
72
|
+
`GOG_ACCOUNT` is optional — omit it to use gogcli's configured default account.
|
|
73
|
+
|
|
74
|
+
### 3. Add to Claude Code
|
|
75
|
+
|
|
76
|
+
The repo includes `.mcp.json`. From the project directory:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
# The .mcp.json is already configured — just set your account
|
|
80
|
+
export GOG_ACCOUNT=you@gmail.com
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Or add `GOG_ACCOUNT` to your shell profile.
|
|
84
|
+
|
|
85
|
+
## Tools
|
|
86
|
+
|
|
87
|
+
Read-only tools run automatically. Write tools ask for confirmation first.
|
|
88
|
+
|
|
89
|
+
| Tool | What it does | Permission |
|
|
90
|
+
|------|-------------|------------|
|
|
91
|
+
| `gog_sheets_get` | Read values from a range | Auto |
|
|
92
|
+
| `gog_sheets_metadata` | Get title, tabs, and named ranges | Auto |
|
|
93
|
+
| `gog_sheets_update` | Write values to a range | Confirm |
|
|
94
|
+
| `gog_sheets_append` | Append rows after existing data | Confirm |
|
|
95
|
+
| `gog_sheets_clear` | Clear values in a range | Confirm |
|
|
96
|
+
| `gog_sheets_create` | Create a new spreadsheet | Confirm |
|
|
97
|
+
| `gog_sheets_find_replace` | Find and replace across a spreadsheet | Confirm |
|
|
98
|
+
| `gog_sheets_run` | Run any `gog sheets` subcommand (escape hatch) | Confirm |
|
|
99
|
+
|
|
100
|
+
All tools accept an optional `account` parameter to target a specific Google account for that call, overriding `GOG_ACCOUNT`.
|
|
101
|
+
|
|
102
|
+
## Multiple Accounts
|
|
103
|
+
|
|
104
|
+
If you use multiple Google accounts with gogcli, you can target a specific account per-call:
|
|
105
|
+
|
|
106
|
+
```
|
|
107
|
+
Read Sheet1!A1:D10 from spreadsheet abc123 using my work account work@company.com
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Claude will pass `account: "work@company.com"` to the tool, which adds `--account work@company.com` to the gogcli command.
|
|
111
|
+
|
|
112
|
+
## Troubleshooting
|
|
113
|
+
|
|
114
|
+
**"gog not found"** — gogcli is not installed or not in your PATH. Run `gog --help` in your terminal to verify. Install with `brew install gogcli`.
|
|
115
|
+
|
|
116
|
+
**"not authenticated"** — run `gog auth add` to authenticate. Run `gog auth list` to see configured accounts.
|
|
117
|
+
|
|
118
|
+
**"Spreadsheet not found"** — verify the spreadsheet ID (the long string in the URL between `/d/` and `/edit`).
|
|
119
|
+
|
|
120
|
+
**Tools not appearing in Claude Desktop** — go to **Settings → Developer** to see connected servers. Fully quit and relaunch after editing the config.
|
|
121
|
+
|
|
122
|
+
**Can't find the config file on Mac** — in Finder press Cmd+Shift+G and paste `~/Library/Application Support/Claude/`.
|
|
123
|
+
|
|
124
|
+
## Security
|
|
125
|
+
|
|
126
|
+
- `GOG_ACCOUNT` is optional and only selects which authenticated account to use
|
|
127
|
+
- No credentials are stored or passed by this server — authentication is handled entirely by gogcli's own keyring
|
|
128
|
+
- All gogcli invocations use `--no-input` to prevent interactive prompts
|
|
129
|
+
- All arguments are passed as arrays to `child_process.spawn` — no shell injection risk
|
|
130
|
+
|
|
131
|
+
## Development
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
npm test # run the test suite (33 tests, 100% coverage)
|
|
135
|
+
npm run build # compile TypeScript → dist/index.js
|
|
136
|
+
npm run test:coverage # run with coverage report
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### Project structure
|
|
140
|
+
|
|
141
|
+
```
|
|
142
|
+
src/
|
|
143
|
+
runner.ts gog CLI executor (auth injection, timeout, error handling)
|
|
144
|
+
index.ts MCP server entry point
|
|
145
|
+
tools/
|
|
146
|
+
sheets.ts 8 Google Sheets tools
|
|
147
|
+
tests/
|
|
148
|
+
runner.test.ts
|
|
149
|
+
tools/
|
|
150
|
+
sheets.test.ts
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### Adding more Google services
|
|
154
|
+
|
|
155
|
+
gogcli supports Gmail, Calendar, Drive, Contacts, Tasks, Docs, Slides, Chat, and more. To add a service:
|
|
156
|
+
|
|
157
|
+
1. Create `src/tools/<service>.ts` with `registerXxxTools(server: McpServer)`
|
|
158
|
+
2. Create `tests/tools/<service>.test.ts` (mock runner via `vi.mock`)
|
|
159
|
+
3. Call `registerXxxTools(server)` in `src/index.ts`
|
|
160
|
+
|
|
161
|
+
See `CLAUDE.md` for the full pattern.
|
|
162
|
+
|
|
163
|
+
## License
|
|
164
|
+
|
|
165
|
+
MIT
|
package/SKILL.md
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gogcli-mcp
|
|
3
|
+
description: Use when the user asks to read, write, or manage Google Sheets. Also triggers for requests involving Google Sheets data like "read my spreadsheet", "update a cell", "append rows", "create a spreadsheet", or "find and replace in Sheets". Broader Google service support (Gmail, Calendar, Drive) can be added via future service modules.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# gogcli-mcp
|
|
7
|
+
|
|
8
|
+
MCP server wrapping [gogcli](https://github.com/steipete/gogcli) — provides Claude with access to Google Sheets (and a scaffold for Gmail, Calendar, Drive, and more).
|
|
9
|
+
|
|
10
|
+
- **Source:** [github.com/chrischall/gogcli-mcp](https://github.com/chrischall/gogcli-mcp)
|
|
11
|
+
|
|
12
|
+
## Requirements
|
|
13
|
+
|
|
14
|
+
- [gogcli](https://github.com/steipete/gogcli) installed and authenticated (`gog --help` works in your shell)
|
|
15
|
+
- Node.js 18 or later
|
|
16
|
+
|
|
17
|
+
## Setup
|
|
18
|
+
|
|
19
|
+
### Option A — Claude Code (direct MCP)
|
|
20
|
+
|
|
21
|
+
Add to `.mcp.json` in your project:
|
|
22
|
+
|
|
23
|
+
```json
|
|
24
|
+
{
|
|
25
|
+
"mcpServers": {
|
|
26
|
+
"gogcli": {
|
|
27
|
+
"command": "node",
|
|
28
|
+
"args": ["/path/to/gogcli-mcp/dist/index.js"],
|
|
29
|
+
"cwd": "/path/to/gogcli-mcp",
|
|
30
|
+
"env": {
|
|
31
|
+
"GOG_ACCOUNT": "you@gmail.com"
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Option B — npx
|
|
39
|
+
|
|
40
|
+
```json
|
|
41
|
+
{
|
|
42
|
+
"mcpServers": {
|
|
43
|
+
"gogcli": {
|
|
44
|
+
"command": "npx",
|
|
45
|
+
"args": ["-y", "gogcli-mcp"],
|
|
46
|
+
"env": {
|
|
47
|
+
"GOG_ACCOUNT": "you@gmail.com"
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
`GOG_ACCOUNT` is optional — omit it to use gogcli's configured default account. Pass it per-tool-call to target a specific account dynamically.
|
|
55
|
+
|
|
56
|
+
## Available Tools
|
|
57
|
+
|
|
58
|
+
| Tool | What it does |
|
|
59
|
+
|------|-------------|
|
|
60
|
+
| `gog_sheets_get` | Read values from a range |
|
|
61
|
+
| `gog_sheets_update` | Write values to a range |
|
|
62
|
+
| `gog_sheets_append` | Append rows after existing data |
|
|
63
|
+
| `gog_sheets_clear` | Clear values in a range |
|
|
64
|
+
| `gog_sheets_metadata` | Get title, tabs, named ranges |
|
|
65
|
+
| `gog_sheets_create` | Create a new spreadsheet |
|
|
66
|
+
| `gog_sheets_find_replace` | Find and replace across a spreadsheet |
|
|
67
|
+
| `gog_sheets_run` | Run any `gog sheets` subcommand (escape hatch) |
|
|
68
|
+
|
|
69
|
+
All tools accept an optional `account` parameter to override the default Google account for that call.
|