Upload, publish, rollout, and manage Chrome extensions — a fast, lightweight, CLI powered by the latest V2 API.
or curl -fsSL https://vaughnbosu.github.io/cws-cli/install.sh | bash
Using an AI client? Add the optional MCP server.
Everything you need to manage Chrome Web Store extensions, nothing you don't.
No runtime, no npm install, no dependencies. Download and run.
Built directly on the current Chrome Web Store API.
cws init --global walks you through OAuth config — no more copy-pasting env vars from docs.
Upload, publish, status, staged rollouts, and submission cancellation — all from one tool.
Env vars, meaningful exit codes, and zero dependencies means it drops into any pipeline.
TOML file, env vars, CLI flags — use any combination. Local or global config, your choice.
Three steps to publish your extension.
cws init --global
Interactive wizard that stores OAuth2 credentials, refresh token, and Publisher ID in your global config.
cws upload ./dist
Zips the directory (excluding .git/, node_modules/, etc.) and uploads it.
cws publish
Before using cws, set up API access in the Google Cloud Console. Follow the official Chrome Web Store API guide:
The optional cws-mcp server uses the same credentials, project config, validation, and Chrome Web Store API service as the CLI.
brew install --cask
vaughnbosu/tap/cws-mcp
Run cws init --global first if you have not configured shared credentials yet.
For Codex, add this to ~/.codex/config.toml and replace the workspace path:
[mcp_servers.chrome-web-store]
command = "cws-mcp"
default_tools_approval_mode = "writes"
[mcp_servers.chrome-web-store.env]
CWS_WORKSPACE = "/absolute/path/to/extension"
Upload, publish, rollout, and cancellation tools require an explicit confirm: true. Source and output paths stay inside CWS_WORKSPACE.
Everything available in cws help
| Command | Description |
|---|---|
cws init [--global] | Interactive credential setup wizard (browser sign-in) |
cws login | Re-acquire a refresh token via browser sign-in |
cws validate [source] | Pre-flight validation (manifest, version, icons, size, policy flags) |
cws pack [source] | Zip an extension directory without uploading |
cws upload [source] | Validate, zip, and upload a package |
cws publish | Publish the latest uploaded version |
cws status | Check extension status, policy warnings, and takedowns |
cws rollout <pct> | Set deploy percentage (10k+ users required) |
cws cancel | Cancel a pending submission |
cws version | Print CLI version |
# Full validation (local + remote checks)
cws validate ./dist
# Local checks only (no credentials needed)
cws validate ./dist --local
# Validate a pre-built zip
cws validate extension.zip
Checks: manifest.json validity, required fields, version format, icon files, package size, version > published and submitted revisions, no pending submission, and policy warnings/takedowns. Also runs automatically before every cws upload.
# Upload a directory (zips automatically)
cws upload ./dist
# Upload a pre-built zip
cws upload extension.zip
# Upload and publish in one step
cws upload ./dist --publish
# Specify extension ID
cws upload ./dist -e abcdefghijklmnopabcdefghijklmnop
# Don't wait for processing
cws upload ./dist --wait=false
# Skip pre-upload validation
cws upload ./dist --skip-validate
# Publish immediately after review
cws publish
# Stage for review without auto-publishing
cws publish --staged
# Attempt to skip review (only some changes are eligible)
cws publish --skip-review
# Fail if the store reports validation warnings
cws publish --block-on-warnings
# Publish with an initial partial rollout
cws publish --deploy-percentage 10
Non-blocking store warnings are printed after every publish.
# Human-readable output
cws status
# Raw JSON (for scripting)
cws status --json
# Set to 50% rollout
cws rollout 50
# Full rollout
cws rollout 100
# Cancel a pending submission under review
cws cancel
# Cancel for a specific extension
cws cancel -e abcdefghijklmnopabcdefghijklmnop
# Recommended: keep credentials outside the project
cws init --global
# Optional: write a local config containing credentials
cws init
Interactive wizard that guides you through configuring OAuth2 Client ID, Client Secret, Refresh Token, and Publisher ID. Secrets are read without echoing, credentials are validated before saving, and a local cws.toml is added to .gitignore. Use cws login later to refresh an expired token.
| Exit Code | Meaning |
|---|---|
| 0 | Success |
| 1 | Error (API error, validation failure, invalid config, timeout, etc.) |
TOML file, env vars, and CLI flags — use any combination.
cws init --global writes credentials to ~/.config/cws/cws.toml. Keep only extension and packaging settings in the project:
[extensions.default]
id = "abcdefghijklmnopabcdefghijklmnop"
source = "./dist"
Running cws init without --global writes credentials to ./cws.toml. That file contains secrets and must not be committed.
| Variable | Description |
|---|---|
| CWS_CLIENT_ID | OAuth2 Client ID |
| CWS_CLIENT_SECRET | OAuth2 Client Secret |
| CWS_REFRESH_TOKEN | OAuth2 Refresh Token |
| CWS_PUBLISHER_ID | Publisher ID |
| CWS_EXTENSION_ID | Default Extension ID |
--extension-id, etc.)CWS_*)cws.toml (current directory)~/.config/cws/cws.tomlDrop the binary into any pipeline — zero dependencies.
# .github/workflows/publish.yml
- name: Upload and publish extension
uses: vaughnbosu/cws-cli@v1.3.1
with:
version: v1.3.1
args: upload ./dist --publish
client-id: ${{ secrets.CWS_CLIENT_ID }}
client-secret: ${{ secrets.CWS_CLIENT_SECRET }}
refresh-token: ${{ secrets.CWS_REFRESH_TOKEN }}
publisher-id: ${{ secrets.CWS_PUBLISHER_ID }}
extension-id: ${{ vars.EXTENSION_ID }}
The Action supports Linux and macOS runners on amd64 or arm64. Standalone Windows binaries are available from GitHub Releases.
- name: Install cws
run: curl -fsSL https://vaughnbosu.github.io/cws-cli/install.sh | bash
- name: Upload and publish extension
env:
CWS_CLIENT_ID: ${{ secrets.CWS_CLIENT_ID }}
CWS_CLIENT_SECRET: ${{ secrets.CWS_CLIENT_SECRET }}
CWS_REFRESH_TOKEN: ${{ secrets.CWS_REFRESH_TOKEN }}
CWS_PUBLISHER_ID: ${{ secrets.CWS_PUBLISHER_ID }}
run: cws upload ./dist -e ${{ vars.EXTENSION_ID }} --publish --json
Multiple ways to install — pick what works for you.
brew install --cask vaughnbosu/tap/cws
curl -fsSL https://vaughnbosu.github.io/cws-cli/install.sh | bash
go install github.com/vaughnbosu/cws-cli/cmd/cws@latest
Make sure $GOPATH/bin is in your PATH.
Download the latest binary for your platform from Releases.
Invoke-WebRequest -Uri https://github.com/vaughnbosu/cws-cli/releases/latest/download/cws_windows_amd64.zip -OutFile cws.zip
Expand-Archive cws.zip -DestinationPath .
Move-Item cws.exe C:\Windows\System32\