gws-admin-mcp
A local MCP server that provides a safe Google Workspace admin console, enabling AI agents to read users, groups, devices, and reports, with optional write operations gated by explicit confirmation.
README
gws-admin-mcp
A local Model Context Protocol (MCP) server that gives your AI agent (Cursor, Claude Desktop, or any MCP client) a safe Google Workspace admin console. It talks to the Admin SDK (Directory, Reports, Groups Settings) through a service account with domain-wide delegation, so the agent can answer questions like "which users haven't logged in for 90 days?" or "who is in the Finance group?" — and, only when you explicitly allow it, make changes.
MCP client ──stdio──► gws-admin-mcp ──service account JWT (impersonates an admin)──► admin.googleapis.com / groupssettings.googleapis.com
Runs entirely on your machine. No third-party service, no telemetry, no data leaves your laptop except the Google API calls themselves.
Safety model
This server assumes the agent driving it is fallible. Three layers:
- Read-only by default. Out of the box only the 17 read tools are
registered — write tools are not hidden behind a runtime check, they simply
do not exist in the tool list, so the agent cannot call them. Mutations
require starting the server with
--allow-write(orGWS_ADMIN_ALLOW_WRITE=1). - Confirm gate on destructive calls. Even with writes enabled, the
irreversible operations —
users_delete,groups_delete,orgunits_delete,role_assignment_delete, mobile device wipe actions, and ChromeOS deprovision — are refused unless the call includes"confirm": true. The agent has to make the destructive intent explicit a second time. - Audit log. Every tool call is appended as JSON lines to
~/.config/gws-admin-mcp/audit.log(mode 600), with passwords and secrets redacted. Disable withGWS_ADMIN_AUDIT=0if you must.
Recommended pattern: run the read-only instance permanently, and start a second, write-enabled instance only for the duration of a change window.
Tools (40 total; 17 in read-only mode)
| Area | Read-only tools | Write tools (require --allow-write) |
|---|---|---|
| Users | users_list, users_get |
users_create, users_update, users_suspend, users_unsuspend, users_reset_password, users_make_admin, users_move_ou, users_delete* |
| Groups | groups_list, groups_get, groups_list_members |
groups_create, groups_update, groups_delete*, groups_add_member, groups_remove_member, groups_update_member |
| Org units | orgunits_list, orgunits_get |
orgunits_create, orgunits_update, orgunits_delete* |
| Roles | roles_list, role_assignments_list |
role_assignment_create, role_assignment_delete* |
| Domains / customer | domains_list, customer_get |
— |
| Devices | devices_list_mobile, devices_list_chromeos |
devices_action_mobile, devices_action_chromeos, devices_move_chromeos |
| Reports | reports_activities (audit log), reports_usage_user, reports_usage_customer |
— |
| Group settings | groupsettings_get |
groupsettings_update |
* Destructive — additionally requires "confirm": true in the call
(device tools only for wipe/deprovision actions).
List tools auto-paginate up to a maxResults cap, and users_list supports
the full Admin SDK search syntax (orgUnitPath='/Sales', isAdmin=true,
email:jdoe*, ...).
Requirements
- Node.js >= 20
- Super-admin access to a Google Workspace domain (to grant domain-wide delegation)
- A Google Cloud project (free — the Admin SDK has no usage cost)
Google Cloud setup
You need a service account whose key the server uses to impersonate a Workspace super-admin. Two paths:
Path A — scripted (needs gcloud)
gcloud auth login admin@yourdomain.com
scripts/setup-service-account.sh admin@yourdomain.com your-project-id
The script creates/reuses the project, enables the Admin SDK + Groups
Settings APIs, creates the service account, writes the key and config to
~/.config/gws-admin-mcp/, and prints the client ID + scope string for the
final manual step (step 5 below — Google provides no API for that part).
Path B — manual (Cloud console)
- Create a project at console.cloud.google.com (or reuse one dedicated to admin tooling).
- Enable APIs: Admin SDK API and Groups Settings API (APIs & Services → Library).
- Create a service account (IAM & Admin → Service Accounts → Create). No project-level IAM roles are needed — its power comes entirely from the delegation grant in the next steps.
- Create a JSON key for it (Keys tab → Add key → JSON) and save it as
~/.config/gws-admin-mcp/service-account.jsonwithchmod 600. - Grant domain-wide delegation — this is the step people miss:
- Copy the service account's OAuth 2 client ID (a long number, shown on the service account details page).
- In the Admin console (admin.google.com): Security → Access and data control → API controls → Domain-wide delegation → Add new.
- Paste the client ID, and paste this exact scope list as one comma-separated line:
https://www.googleapis.com/auth/admin.directory.user,https://www.googleapis.com/auth/admin.directory.group,https://www.googleapis.com/auth/admin.directory.group.member,https://www.googleapis.com/auth/admin.directory.orgunit,https://www.googleapis.com/auth/admin.directory.rolemanagement,https://www.googleapis.com/auth/admin.directory.domain.readonly,https://www.googleapis.com/auth/admin.directory.customer.readonly,https://www.googleapis.com/auth/admin.directory.device.mobile,https://www.googleapis.com/auth/admin.directory.device.chromeos,https://www.googleapis.com/auth/admin.reports.audit.readonly,https://www.googleapis.com/auth/admin.reports.usage.readonly,https://www.googleapis.com/auth/apps.groups.settings
- Tell the server which admin to impersonate. Create
~/.config/gws-admin-mcp/config.json:
{
"delegatedAdmin": "admin@yourdomain.com",
"customerId": "my_customer"
}
delegatedAdmin must be a super-admin of the domain. my_customer
resolves to that admin's own organization.
Environment variables override the config files: GOOGLE_SA_KEY (key path),
DELEGATED_ADMIN, CUSTOMER_ID, GWS_ADMIN_CONFIG_DIR (alternate config
directory). See .env.example.
Build and verify
npm install
npm run build
node dist/cli.js doctor
doctor checks the key, mints a delegated token, and runs sample reads
against users, domains, roles, and the audit reports API. All four should say
PASS. Then optionally:
npm run smoke # spawns the real server over stdio, checks tool registration + live reads
MCP client configuration
Cursor (~/.cursor/mcp.json)
Read-only — the recommended default:
{
"mcpServers": {
"gws-admin": {
"command": "node",
"args": ["/ABSOLUTE/PATH/TO/gws-admin-mcp/dist/cli.js", "serve"]
}
}
}
Write-enabled (use deliberately, ideally as a second entry you toggle on):
{
"mcpServers": {
"gws-admin-write": {
"command": "node",
"args": ["/ABSOLUTE/PATH/TO/gws-admin-mcp/dist/cli.js", "serve", "--allow-write"]
}
}
}
Claude Desktop (claude_desktop_config.json)
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json ·
Windows: %APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"gws-admin": {
"command": "node",
"args": ["/ABSOLUTE/PATH/TO/gws-admin-mcp/dist/cli.js", "serve"]
}
}
}
Restart the client after editing. You should see the gws-admin server with
17 tools (read-only) or 40 (write-enabled).
Troubleshooting
| Symptom | Cause / fix |
|---|---|
unauthorized_client when minting a token |
The domain-wide delegation grant is missing, uses the wrong client ID, or its scope list doesn't cover every scope the server requests. Re-paste the full scope string from above against the SA's OAuth2 client ID. Grants can take a few minutes to propagate. |
Service-account key not found at ... |
Put the JSON key at ~/.config/gws-admin-mcp/service-account.json or set GOOGLE_SA_KEY to its path. |
DELEGATED_ADMIN ... is not set |
Add delegatedAdmin to config.json or set the DELEGATED_ADMIN env var. |
403 Not Authorized to access this resource/api |
The impersonated user is not a super-admin, or the Admin SDK API isn't enabled in the Cloud project. |
404 from Groups Settings calls |
The Groups Settings API isn't enabled in the project (it's separate from the Admin SDK). |
| Write tools don't appear in the client | Working as intended — start the server with --allow-write or GWS_ADMIN_ALLOW_WRITE=1. |
A delete/wipe call returns Refused: ... destructive/irreversible |
Working as intended — re-issue the call with "confirm": true. |
| Client shows the server as failed on startup | Run node dist/cli.js doctor in a terminal; it prints the exact failing check. Also confirm the args path in your MCP config is absolute. |
Security notes
- The service-account key impersonates a super-admin with org-wide power.
Treat
service-account.jsonlike a domain-admin password: keep it out of git (this repo's.gitignorealready excludes key files,.env, andconfig.json), keep itchmod 600, and rotate it periodically. - Prefer a dedicated Cloud project for this service account so the key is easy to audit and revoke.
- Keep the permanent instance read-only. Enable writes in a separate instance only when you actually intend to change things, and turn it off after.
License & purchase
This repository is source-available, not open source: the code is public so you can read and audit every line before trusting it with a super-admin credential, but using it requires a license.
- Buy a license ($34): antchoutine.gumroad.com/l/gws-admin-mcp — perpetual, includes the full write-enabled edition and updates.
- Try it free: the read-only edition (17 tools, no mutating code) is on
npm as
gws-admin-mcp.
See LICENSE for the exact terms (no redistribution, no offering it as a hosted service).
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.
E2B
Using MCP to run code via e2b.