npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

gws-mcp

v0.2.0

Published

MCP server wrapping the local `gws` (Google Workspace) CLI, so sandboxed agents (Claude Cowork, etc.) can use Google Workspace through your host-side OAuth credentials.

Downloads

184

Readme

gws-mcp

CI License: MIT Node.js MCP

🌐 Ngôn ngữ: English · Tiếng Việt (file này)

MCP server wrap gws (Google Workspace CLI) trên host, cho Claude Desktop / Claude Code / Claude Cowork dùng Google Workspace mà không phải copy OAuth token hay chạy gws auth login lại.

Lý do tồn tại: gws lưu OAuth token trong keyring của user. Bản thân Claude Cowork là Claude Desktop chạy local nên có thể spawn gws thẳng — nhưng làm thế model phải tự nhớ gws drive files list --params '...' qua Bash, dễ sai cú pháp và không có schema introspection. MCP server này cho model một interface có structured schema (gws_schema, gws_call), audit log đầy đủ, và policy whitelist/denylist — sạch hơn nhiều so với để LLM gõ shell.


1. Yêu cầu

  • gws CLI đã cài và đã gws auth login thành công.
    gws --version           # >= 0.22.x
    gws drive files list --params '{"pageSize": 1}'   # phải trả JSON, không lỗi auth
  • Node.js >= 20.

2. Cài đặt

git clone <repo> gws-mcp
cd gws-mcp
npm install
npm run build
npm link        # exposes `gws-mcp` globally

Verify:

which gws-mcp   # -> /opt/homebrew/bin/gws-mcp (hoặc tương đương)
gws-mcp --help

3. Đăng ký với Claude Desktop / Cowork / Code (stdio — recommended)

Edit ~/Library/Application Support/Claude/claude_desktop_config.json (Claude Desktop / Cowork trên macOS):

{
  "mcpServers": {
    "gws": {
      "command": "gws-mcp",
      "args": ["stdio"],
      "env": {
        "GWS_MCP_ALLOWED_SERVICES": "drive,sheets,docs,calendar,gmail,tasks",
        "GWS_MCP_DENIED_METHODS": "drive.files.delete,gmail.users.messages.send",
        "GWS_MCP_AUDIT_LOG": "/Users/<you>/.cache/gws-mcp/audit.log"
      }
    }
  }
}

Nếu không npm link, dùng absolute path:

{
  "mcpServers": {
    "gws": {
      "command": "node",
      "args": ["/Users/<you>/Projects/gws-mcp/dist/index.js", "stdio"]
    }
  }
}

Restart Claude Desktop → trong chat thấy gws server kèm 4 tool (gws_list_services, gws_help, gws_schema, gws_call).

Cho Claude Code CLI

claude mcp add gws -- gws-mcp stdio

4. Tool / Resource / Prompt MCP expose

Tools

| Tool | Mục đích | |---|---| | gws_list_services | Liệt kê service (drive, sheets, gmail, …) được host cho phép. | | gws_help | Run gws <args…> --help để khám phá resource và method. | | gws_schema | Trả JSON schema cho service.resource.method — gọi trước khi gws_call. | | gws_call | Dispatch tới gws với service, resource, method, params, json, …. | | gws_list_skills | Liệt kê skill guide đã load từ ~/.agents/skills/gws-*. | | gws_get_skill | Đọc nội dung đầy đủ của một skill guide (markdown). |

Flow chuẩn cho LLM:

gws_list_services
  → gws_help args:["drive"]              # khám phá resource
  → gws_schema target:"drive.files.list" # đọc param shape
  → gws_call service:drive resource:files method:list params:{"pageSize":10}

Debugging body shape an toàn: thêm dryRun:true vào gws_call — server sẽ in HTTP body + URL sẽ-được-gửi mà không gọi Google. Hữu ích cho method có complex --json body (docs.documents.batchUpdate, sheets.spreadsheets.batchUpdate, calendar.events.insert, …).

Lưu ý về json arg: gửi object/array JS thẳng (preferred), KHÔNG JSON.stringify trước khi gọi tool — server tự stringify một lần. Wrapper có defensive logic: nếu LLM lỡ gửi string đã JSON-encode, server detect và pass-through verbatim (không double-encode).

Resources

| URI | Nội dung | |---|---| | gws://services | JSON list service đang được phép. | | gws-skill://_index | JSON index toàn bộ skill (name, description, version, URI). | | gws-skill://<name> | Raw SKILL.md của từng skill, ví dụ gws-skill://gws-drive. |

Prompts

Mỗi skill được expose thành một MCP prompt cùng tên (gws-drive, gws-sheets, gws-tasks, …). Claude Desktop hiện list này trong UI "Attach from MCP" / prompt picker — user click một phát là skill được inject vào conversation như authoritative reference.

Skills layer (giải bài toán "Cowork không thấy ~/.agents/skills")

gws CLI đi kèm 12 skill guide trong ~/.agents/skills/gws-*/SKILL.md (gws-drive, gws-sheets, gws-gmail-triage, gws-calendar-insert, …). Claude Desktop / Cowork không tự đọc được path này, nhưng MCP server chạy trên host thì đọc được — và nó re-expose qua resources + prompts + tools cho client.

Nghĩa là khi user prompt "đọc danh sách file Drive", model trong Cowork có thể:

  1. Gọi gws_list_skills để biết có guide nào.
  2. Gọi gws_get_skill name:"gws-drive" → đọc guide chi tiết (~13KB markdown, có ví dụ thật).
  3. Áp guide đó vào gws_call thay vì đoán params.

Override skills dir (mặc định ~/.agents/skills):

  • GWS_MCP_SKILLS_DIR=/path/to/skills
  • GWS_MCP_SKILLS_PREFIX=gws- (đổi nếu muốn mount tên khác)
  • GWS_MCP_SKILLS_DISABLED=1 (tắt hẳn layer này)

5. Biến môi trường

Xem .env.example cho danh sách đầy đủ. Quan trọng:

| Env | Mặc định | Ý nghĩa | |---|---|---| | GWS_MCP_GWS_BIN | gws | Path tới binary nếu không có trong PATH. | | GWS_MCP_CALL_TIMEOUT_MS | 60000 | Hard timeout cho mỗi gws call. | | GWS_MCP_MAX_OUTPUT_BYTES | 1048576 | Giới hạn stdout, vượt thì truncate. | | GWS_MCP_ALLOWED_SERVICES | empty=all | Whitelist, ví dụ drive,sheets,docs,calendar. | | GWS_MCP_DENIED_METHODS | empty | Denylist, ví dụ gmail.users.messages.send,drive.files.delete. | | GWS_MCP_AUDIT_LOG | empty=stderr | File NDJSON ghi mọi tool call. | | GWS_MCP_SKILLS_DIR | ~/.agents/skills | Thư mục chứa skill guides để mount qua MCP. | | GWS_MCP_SKILLS_PREFIX | gws- | Prefix subdir để filter (gws-*). | | GWS_MCP_SKILLS_DISABLED | unset | 1 để tắt skills layer. |

6. Bảo mật

  1. Least-privilege: GWS_MCP_ALLOWED_SERVICES chỉ mở service cần dùng. Ví dụ chỉ Drive + Sheets cho phiên Cowork: GWS_MCP_ALLOWED_SERVICES=drive,sheets.
  2. Denylist destructive ops: GWS_MCP_DENIED_METHODS=drive.files.delete,gmail.users.messages.send,calendar.events.delete.
  3. Audit log: GWS_MCP_AUDIT_LOG=~/.cache/gws-mcp/audit.log — NDJSON trail cho audit / compliance / forensics.
  4. Upload paths là host paths: upload/output trỏ tới file trên máy host. LLM trong Cowork nếu tạo file tạm thì file đó nằm trên cùng máy host (vì Cowork = Desktop local) — vẫn ổn.

7. (Optional) HTTP mode — cho true remote sandbox

Chỉ dùng khi client MCP không thể spawn child process tới host (Vercel Sandbox, Docker worker, remote container, agent chạy trên server khác).

export GWS_MCP_AUTH_TOKEN=$(openssl rand -hex 32)
gws-mcp http
# -> [gws-mcp] HTTP transport ready at http://127.0.0.1:8765/mcp

Expose qua tunnel:

| Cách | Lệnh | |---|---| | Cloudflare Tunnel | cloudflared tunnel --url http://127.0.0.1:8765 | | ngrok | ngrok http 8765 | | Tailscale | GWS_MCP_HTTP_HOST=0.0.0.0 gws-mcp http |

Client config:

{
  "mcpServers": {
    "gws": {
      "url": "https://<tunnel>/mcp",
      "headers": { "Authorization": "Bearer <GWS_MCP_AUTH_TOKEN>" }
    }
  }
}

Token này = quyền Google Workspace của tài khoản gws auth login. Rotate thường xuyên. Không bao giờ set GWS_MCP_HTTP_INSECURE=1 cho endpoint public.

Env riêng cho HTTP mode: GWS_MCP_HTTP_HOST, GWS_MCP_HTTP_PORT (default 8765), GWS_MCP_HTTP_PATH (default /mcp), GWS_MCP_HTTP_CORS_ORIGINS. Xem .env.example.

8. Smoke test

npm run build
GWS_MCP_AUTH_TOKEN=test gws-mcp http &
node test/smoke-http.mjs
kill %1

Kỳ vọng: health 200, no-auth 401, auth init 200 + session id, gws_list_services trả ra 18 service.

9. Troubleshooting

| Triệu chứng | Khả năng cao | |---|---| | Tool call trả exit code 2 | Auth hết hạn trên host. Chạy gws auth login lại. | | exit code 3 | Param JSON sai shape. Gọi gws_schema trước, đối chiếu lại. | | exit code 4 | gws chưa fetch được discovery API — kiểm tra mạng host. | | Claude Desktop không thấy server | Sai path command, hoặc chưa restart Desktop. Xem ~/Library/Logs/Claude/mcp*.log. | | Stdout truncated | Tăng GWS_MCP_MAX_OUTPUT_BYTES hoặc dùng pageAll:true với pageLimit nhỏ. |

10. Đóng góp

Xem CONTRIBUTING.md. Tóm tắt:

  • Conventional Commits (feat:, fix:, chore:…), commit nhỏ và rõ ràng.
  • npm run typecheck, npm run build, và toàn bộ test/*.mjs phải pass trước khi mở PR.
  • Thay đổi surgical — không refactor code lân cận trong cùng commit.

Code of Conduct: CODE_OF_CONDUCT.md. Báo lỗ hổng bảo mật: SECURITY.md.

11. License

MIT. Không phải sản phẩm chính thức của Google.