Better Workspace Mcp

io.github.n24q02m由 GitHub 帳號 n24q02m 發布v0.6.0更新於 Oct 29, 2026

Google Workspace MCP — Docs, Drive, Calendar, Gmail, Sheets, Slides, Tasks, Chat, People, Forms

概覽

AI 產生的概覽

Google Workspace MCP 伺服器,讓助手在你自己的 Google 帳號下讀寫文件、雲端硬碟、日曆、Gmail、試算表、簡報、任務、Chat、聯絡人與表單。

可以做什麼
  • 處理文件與檔案:讀取和建立 Docs、取代與格式化文字,搜尋雲端硬碟、管理資料夾、移動、重新命名、移至垃圾桶和下載檔案、讀取留言
  • 管理郵件:搜尋和讀取 Gmail、寄送郵件與草稿、修改標籤和討論串、下載附件
  • 安排行程:列出日曆和活動,建立、更新、刪除和回覆活動,尋找空閒時間
  • 編輯試算表與簡報:讀取 Sheets 範圍和中介資料,操作 Slides 的文字、圖形、圖片、表格和備忘稿
  • 整理任務、聊天與表單:任務清單與任務、Chat 空間與訊息、個人資料查詢、建立表單並讀取回覆
  • 檢查設定與時間:憑證與多帳號管理、各工具說明、本機日期與時區輔助
適用情境
適合希望助手直接操作真實 Google Workspace 帳號的情境,例如起草和編輯文件、處理郵件、安排會議或填寫試算表,並從本機 MCP 用戶端呼叫。適用於使用自有 Google Cloud OAuth 用戶端的單一使用者桌面環境,或自行架設的多使用者 HTTP 部署。
執行需求
透過 npx 或 Docker 以 stdio 在本機執行,或自行架設 HTTP 模式。需要一個已啟用相關 Workspace API 的 Google Cloud 專案,以及 Desktop 類型的 OAuth 2.0 用戶端,透過 GOOGLE_OAUTH_CLIENT_ID 和 GOOGLE_OAUTH_CLIENT_SECRET 提供。首次執行會在瀏覽器開啟授權頁,更新權杖儲存在 ~/.better-workspace/ 下。HTTP 模式另需 CREDENTIAL_SECRET 和 WORKSPACE_USERS_FILE。
安裝前請注意
OAuth 用戶端密鑰屬於憑證,必須妥善保管;HTTP 模式另需 CREDENTIAL_SECRET,它用來衍生儲存權杖的加密金鑰。伺服器可以寄送郵件、建立和刪除日曆活動、將雲端硬碟檔案移至垃圾桶、在 Chat 發送訊息以及修改標籤,助手操作會改動真實資料。權杖儲存在本機磁碟。此專案已封存且不再維護,README 建議改用官方 Google Workspace API。

安裝

在 SourceWeft 中

  1. 開啟 儀表板中的 Better Workspace Mcp,將其新增到工作區。
  2. 為需要使用其工具的對話啟用該服務。

Desktop only,透過 STDIO。 STDIO 服務會啟動本機處理程序,因此需要 SourceWeft 桌面主機。

其他 MCP 客戶端

參照 儲存庫 中的啟動說明。

README

workspace

Google Workspace MCP — Docs, Drive, Calendar, Gmail, Sheets, Slides, Tasks, Chat, People, Forms

ARCHIVED 2026-09-13 — This repository is no longer maintained. Use the official Google Workspace APIs instead of this MCP server. Existing installations keep working but receive no updates or support.

[Mode: stdio · http remote oauth] [CI] [CD] [codecov] [Latest release] [semantic-release] [License: Apache-2.0]

Docs · Install · Quick start · Community

Sister projects from n24q02m (click to expand)
ProjectTaglineTag
agent-chat-pluginPeer AI agents chat in a shared folder — no human relay, no orchestrator, wor...Tooling
better-code-review-graphKnowledge graph for token-efficient code reviews -- semantic search and call-...MCP
better-drive2-way Google Drive sync with .driveignore filter — rclone engine, Windows trayTooling
better-email-mcpIMAP/SMTP email for AI agents -- read, send, organize folders, and manage att...MCP
better-godot-mcpComposite MCP server for Godot Engine -- 17 composite tools for AI-assisted g...MCP
better-notion-mcpMarkdown-first Notion for AI agents -- pages, databases, blocks, and comments...MCP
better-semantic-releaseDrop-in python-semantic-release fork with built-in release-safety guards (orp...Tooling
better-telegram-mcpTelegram for AI agents -- messages, chats, media, and contacts across both bo...MCP
better-workspace-mcpGoogle Workspace MCP server (Docs/Drive/Calendar/Gmail/Sheets/Slides/Tasks/Ch...MCP
claude-pluginsClaude Code plugin marketplace for the n24q02m MCP servers -- install web sea...Marketplace
imagine-mcpImage and video understanding + generation for AI agents -- across Gemini, Op...MCP
jules-task-archiverChrome Extension for bulk operations on Jules tasks via batchexecute API -- a...Tooling
mcp-coreShared foundation for building MCP servers -- Streamable HTTP transport, OAut...MCP
mnemo-mcpPersistent AI memory with hybrid search and embedded sync. Open, free, unlimi...MCP
qwen3-embedLightweight Qwen3 text embedding and reranking via ONNX Runtime and GGUFLibrary
skretSecrets without the server.CLI
tacetA self-distilling neuro-symbolic cascade that amortises LLM cost across knowl...Tooling
web-coreShared web infrastructure package for search, scraping, HTTP security, and st...Library
wet-mcpOpen-source MCP server for AI agents: web search, content extraction, and lib...MCP

Table of contents

Install

The server runs in two modes: stdio (default, single-user, one Google OAuth client of your own) and HTTP (multi-user, per-user bearer tokens). For stdio, add it to your MCP client config:

jsonc
{  "mcpServers": {    "workspace": {      "command": "npx",      "args": ["--yes", "@n24q02m/workspace@latest"],      "env": {        "GOOGLE_OAUTH_CLIENT_ID": "<your-client-id>.apps.googleusercontent.com",        "GOOGLE_OAUTH_CLIENT_SECRET": "<your-client-secret>"      }    }  }}

The package is @n24q02m/workspace (formerly @n24q02m/better-workspace-mcp; old package receives one final release then freezes). The MCP Registry id stays io.github.n24q02m/better-workspace-mcp, and the legacy better-workspace-mcp command is kept as an alias of workspace.

Those two values come from an OAuth 2.0 client of type Desktop app, created in the Google Cloud Console under APIs & Services → Credentials. Desktop is the right type because the server receives the consent redirect on a loopback address, not on a public URL. Enable the Workspace APIs you plan to call on the same project, and add yourself as a test user while the consent screen is unpublished.

The first run opens the Google consent screen in your browser; the refresh token is stored encrypted on your machine under ~/.better-workspace/ (a legacy ~/.better-workspace-mcp/ is read as a fallback), so later runs start without asking again.

The same server can also serve several people over HTTP -- see Remote (HTTP mode).

Install with an AI agent -- paste this to your AI coding agent:

Install MCP server workspace following the steps at https://raw.githubusercontent.com/n24q02m/claude-plugins/main/plugins/better-workspace-mcp/setup-with-agent.md

Remote (HTTP mode)

Besides stdio, the server runs as a multi-user HTTP service. Each request carries a bearer token from a users file (WORKSPACE_USERS_FILE), and each user's Google credentials are kept in their own bucket, keyed by that user's namespace, so one deployment serves several people without them sharing an account. Google consent for an HTTP account runs on the host, with workspace auth --user <namespace>.

Point your MCP client at the host you deployed it on:

jsonc
{  "mcpServers": {    "workspace": {      "type": "http",      "url": "https://<your-host>/mcp"    }  }}

Modes

Two, and only two. There is no proxy or daemon mode: stdio speaks the MCP stdio transport directly, with no HTTP hop inside it.

ModeSelected byServesGoogle OAuth client
stdiothe defaultone user, on their own machineDesktop app
http--http, MCP_TRANSPORT=http, or TRANSPORT_MODE=httpseveral users, one credential bucket per user namespaceWeb application

Two OAuth clients, not one

Google binds redirect URIs to the type of the OAuth client, so the two modes cannot share one. stdio uses a Desktop client, which may redirect to any loopback port. HTTP uses a Web client. Keep the two credentials under separate names: pointing GOOGLE_OAUTH_CLIENT_ID/_SECRET at the Web client on a machine that also runs stdio breaks every stdio install. That is why docker-compose.http.yml reads the Web pair as GOOGLE_OAUTH_WEB_CLIENT_ID/_SECRET and renames it on the way into the container.

Environment

VariableRequiredWhat it does
GOOGLE_OAUTH_CLIENT_IDyesWeb client id. The server refuses to start without it.
GOOGLE_OAUTH_CLIENT_SECRETyesWeb client secret. Same.
CREDENTIAL_SECRETyesDerives the encryption key of each user's credential store. The server refuses to start without it, rather than fail in the middle of a user's consent.
WORKSPACE_USERS_FILEyes in HTTPUsers file that maps each bearer token to a user namespace (hull multi auth). Unset uses hull's default location.
PORTnoListen port. 0 (the default) asks the OS for a free one.
HOSTnoBind address. Defaults to loopback, so a container needs 0.0.0.0.

Credentials are stored on local disk under ~/.better-workspace/, which is the data volume in the container. A legacy ~/.better-workspace-mcp/ is read as a fallback.

docker-compose.http.yml in this repo is these variables written out as a runnable overlay.

Tools

One composite tool per Workspace domain, plus config and help:

ToolWhat it covers
docsGoogle Docs -- getText, create, writeText, getSuggestions, replaceText, formatText
driveFiles and folders -- search, findFolder, createFolder, moveFile, renameFile, trashFile, downloadFile, getComments
calendarEvents -- listCalendars, listEvents, getEvent, createEvent, updateEvent, deleteEvent, respondToEvent, findFreeTime
gmailMail -- search, get, send, createDraft, sendDraft, modify, batchModify, modifyThread, downloadAttachment, listLabels, createLabel
sheetsSpreadsheets, read-only -- getText, getRange, getMetadata
slidesPresentations -- 19 actions covering slides, text, shapes, images, tables, and speaker notes
tasksTask lists and tasks -- listTaskLists, listTasks, createTask, updateTask, completeTask, deleteTask
chatGoogle Chat -- listSpaces, findSpaceByName, setUpSpace, getMessages, listThreads, sendMessage, sendDm, findDmByEmail
peopleProfile lookups -- getMe, getUserProfile, getUserRelations
formsForms -- create, get, batchUpdate, listResponses, getResponse
timeLocal date/time/timezone helpers (no Google account needed)
configCredential state and account management
helpFull documentation for any tool

Questions are added to a form with forms(action="batchUpdate"), not at create; responses are read-only, because the Forms API cannot write one. Listing or deleting forms goes through drive.

Quick start

Check that the credentials landed, with the config tool. Before the first consent this reports awaiting_setup; afterwards it names the account the server is acting as:

json
{ "action": "status" }

Then call a domain tool. On docs, create returns the new document's ID, which getText reads back:

json
{ "action": "create", "title": "Notes", "content": "First line." }{ "action": "getText", "documentId": "<id-from-create>" }

time, config, and help need no Google account, so they answer even before consent -- time is the quickest check that the server is wired up at all:

json
{ "action": "getCurrentTime" }

To act as a second Google account, see Multi-account.

Multi-account

Every domain tool takes an account parameter -- the email of the Google account the call acts as. Omit it and the call runs against the primary account.

json
{ "action": "search", "query": "is:unread", "account": "[email protected]" }{ "action": "search", "query": "is:unread" }

Those two gmail calls read two different mailboxes: the first [email protected], the second whichever account is primary.

Accounts are managed through the config tool:

CallEffect
config(action="account_add")In stdio, returns a URL to open; completing the Google consent there adds one more account. Over HTTP it returns the workspace auth --user <namespace> command to run on the host.
config(action="account_list")The configured accounts and which one is primary.
config(action="account_remove", account="<email>")Forget one account.
config(action="account_set_default", account="<email>")Make one account the primary.

The first account authorized becomes the primary. Removing the primary promotes one of the remaining accounts; removing the last one puts the server back to awaiting setup. Naming an account that is not configured is an error that names it -- the call is never rerouted to the primary, because a silent fallback would act on the wrong mailbox.

account_add chooses its flow by transport. In stdio it starts a temporary loopback consent server and returns the URL. Over HTTP it does not serve consent; it returns the workspace auth --user <namespace> command for the host.

value="primary" is stdio only; remote callers change the default with account_set_default.

Coming from an earlier single-account build

Credentials stored by a build from before multi-account support are one flat blob of tokens. The first run afterwards adopts that blob into the multi-account layout under the account's email. The email comes from the stored id_token when it is present -- no network needed, and that is the usual case. Otherwise the server asks Google's userinfo endpoint, which needs network access and a token that is still valid or refreshable.

If neither works, the server reports itself as awaiting setup and opens the browser OAuth flow even though the stored token may still be fine. Completing that consent works, and nothing is discarded: the account you just authorized is stored and becomes the primary, while the old tokens are carried across under the key (unidentified) rather than being overwritten. config(action="account_list") then shows two entries:

json
{ "accounts": ["(unidentified)", "[email protected]"], "primary": "[email protected]" }

Nothing routes to (unidentified): it is never promoted to primary while a real account remains, and no call reaches it unless you name it explicitly. It is there so a credential whose owner could not be determined is not silently thrown away. Remove it once the re-authorized account is working:

json
{ "action": "account_remove", "account": "(unidentified)" }

After a successful adoption -- the usual case -- config(action="account_list") shows exactly one account, and it is the primary.

Forms scopes and re-consent

The consent screen has requested the Google Forms scopes since before the forms tool existed, so it arrived without a second trip through consent.

Accounts authorized before those scopes were added are covered too, but by a different route: Google accepts https://www.googleapis.com/auth/drive in place of the Forms scopes for every Forms method this server calls, and full drive has been on the consent screen since the first release. Google never widens a token it has already issued, so if a grant covers neither -- a user may withhold individual restricted scopes at the consent screen -- the first forms call returns a 403 (Request had insufficient authentication scopes). Re-authorize just that account with config(action="account_add"), signing in as the same account; the record is replaced in place, so nothing else changes.

Documentation

Full docs at docs.n24q02m.com/servers/workspace/:

  • Setup -- plugin install, Docker stdio, and Docker HTTP methods

Every tool also documents itself at runtime: call help for the full reference on any of them, including the exact parameters each action takes.

Deployment

No hosted endpoint is operated for this server. The supported paths are the stdio install above and a self-hosted HTTP deployment of your own.

To self-host HTTP mode, run the compose overlay from this repository:

sh
docker compose -f docker-compose.yml -f docker-compose.http.yml up

It builds the http image locally and publishes it on host loopback only, at GOOGLE_OAUTH_WEB_CLIENT_ID, GOOGLE_OAUTH_WEB_CLIENT_SECRET, CREDENTIAL_SECRET, and WORKSPACE_USERS_FILE through your shell or an .env file (see Environment). The users file maps each bearer token to a user namespace; accounts are added on the host with workspace auth --user <namespace>. For use beyond the local machine, put your own TLS reverse proxy on the same host in front of it.

Each release also publishes multi-arch container images to Docker Hub and GHCR; their default stage is the http server.

Contributing

See CONTRIBUTING.md.

License

Apache-2.0 © n24q02m

來源:README.md,提交 4c7332d

工具

0
SourceWeft 曾在隔離沙箱中以無憑證方式啟動該軟體包一次,以列出其工具,但未能完成:伺服器未在限時內回應。

版本歷史

2
  1. v0.6.0最新Oct 29, 2026
  2. v0.5.0Sep 16, 2026

評分

已滿足適用檢查項的 50%

該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。

  • 近 30 天內可連通25 分

    請保持端點能夠回應 MCP 握手;SourceWeft 每 30 天探測一次。

  • 已宣告認證方式10 分

    請在註冊中心條目中宣告憑證請求標頭,或保持端點能夠回應探測,以便判定其認證方式。

  • 已列出工具15 分

    請讓伺服器在無憑證時回應 tools/list,或發布可在沙箱中無憑證啟動的軟體包。

  • 描述必需15 分
  • 圖示10 分
  • 文件15 分
  • 授權條款10 分