
Your agent needs to read and post in Google Chat on behalf of your users. Google now ships an official remote MCP server for Chat alongside the Chat API that integrations have used for years. They are not interchangeable. The MCP server is a small, LLM-shaped surface in Developer Preview; the API is the full platform, with two authentication types and four ways to use them. Here's how to pick, and what stays the same either way.
Both are maintained by Google. They differ in who they were designed for, how much of Chat they expose, and which credentials they accept.
Google hosts the Chat MCP server as a remote endpoint that speaks Streamable HTTP. It sits in the Google Workspace Developer Preview Program, so you need program membership. You also enable both the Google Chat API and the Google Chat MCP API in your Cloud project before any client can connect.
Its 7 tools are search_conversations, list_messages, search_messages, send_message, list_memberships, mark_as_read, and mark_as_unread; Google added the last three in a recent preview update. Responses are shaped for models: message bodies come back as Markdown, and each tool carries MCP annotations such as readOnlyHint. The server inherits the calling user's permissions.
The Chat API is Google's REST interface for spaces, memberships, messages, reactions, pins, attachments, read state, space events, and more. Google defines two authentication types. User authentication acts as a person, and it includes administrator privileges and domain-wide delegation. App authentication acts as your Chat app through a service account.
There are no LLM affordances. Your code owns filter syntax, update_mask semantics, pagination tokens, quota errors, and tool schemas a model can actually use. Scalekit's Google Chat connector wraps this surface as 54 tools, which is a fair measure of how much sits outside the MCP server.
Four dimensions decide production fit: what the agent can do, which auth path it lands on, what you operate, and which workloads each path suits.
The MCP server covers the conversational read path and plain-text replies. Anything structural, administrative, or event-driven exists only in the API. Where a Scalekit connector tool wraps an API capability, the table names it.
Take a standup digest agent. It reads yesterday's threads, posts a summary card, pins it, and reacts to open questions. On MCP, only the read and a plain-text post work. The card needs app authentication, and pins and reactions have no MCP tool.
The events gap matters more for background agents. The MCP server cannot tell an agent what changed in a space since its last run, so a scheduled agent re-reads time-filtered history and diffs the results itself. The API's space events give you a typed change feed, with one constraint: events are available for up to 28 days.
User OAuth is the common starting point. The paths diverge on who registers the client, which identities are available, and what a Workspace admin has to approve.
Google's setup guide has you create a Web application OAuth client in your own Cloud project and configure the consent screen. You then manually add five scopes: chat.spaces.readonly, chat.memberships.readonly, chat.messages.readonly, chat.messages.create, and chat.users.readstate. Each MCP host's callback goes into the client's authorized redirect URIs.
That makes your agent backend an OAuth client of Google, not just an MCP client. You hold an access token and a refresh token per user, and the Developer Preview gate applies before any of it works.
User authentication runs the same consent flow with whichever Chat scopes the task needs, and the agent never exceeds that user's access. App authentication uses a service account acting as your Chat app. Methods on the chat.bot scope need no extra approval, while chat.app.* scopes need one-time administrator approval. Outside the Developer Preview, app authentication is the only way to send cards.
Administrator privileges add use_admin_access to eligible calls, backed by admin scopes such as chat.admin.spaces.readonly. Domain-wide delegation lets a service account impersonate any user in a domain after a super admin authorizes its client ID and scopes. Google counts it as user authentication, because the service account acts as the person.
Google documents how Chat labels each path. App authentication shows your Chat app as the sender. User authentication shows the user as the sender and displays your Chat app's name as attribution. Administrator privileges surface as an action by the organization's administrator, naming neither the admin nor the app. Domain-wide delegation reads as the impersonated user acting via your app.
User auth fits a digest the user should own; app auth fits system alerts. Domain-wide delegation is tempting for background agents because nothing interactive is required, but one service account key can act as every user in the domain, for every scope the super admin approved.
Recommended reading: Slack MCP vs Slack API for AI Agents and Microsoft Teams MCP vs API for AI Agents
Google runs the server and maintains the tool schemas. You own the OAuth client, per-user token storage, refresh, and revocation. You also own prompt-injection defense. Google's guide tells you to screen prompts and responses, with Model Armor or a control of your own, because Chat messages are untrusted input that can carry hidden instructions.
Treat preview status as an operational dependency. The surface already moved during the preview: tools were added, and an earlier Google codelab required a configured Chat app for any use of the server, while the current guide requires one only for write operations like sending messages.
The Chat MCP server meters query cost rather than requests. list_messages costs 1; search_messages, search_conversations, and send_message cost 10 each. The budget is 3,000 per minute per project and 300 per minute per user. One user's agent can run 30 searches or sends a minute, and all of your users together get 300, because they share your project.
You own everything the MCP server abstracts, including quota handling. The Chat API allows 3,000 message writes and 300 message searches per minute per project, and 60 space writes per minute. Each space also allows one write per second, shared by every Chat app acting in it. A fan-out agent posting to one busy space hits that limit first, and Google answers with 429 errors that need exponential backoff.
Other edges only show up in production. Several are documented in Scalekit's connector reference:
Use Google Chat MCP when:
Use the Google Chat API when:
The comparison makes the two paths look far apart. Underneath, they share one infrastructure problem.
Both paths give you a Google OAuth token per user. Neither gives you a vault, rotation logic, or a revocation flow. Google access tokens last about an hour, so every long-running agent depends on a refresh token stored somewhere, encrypted at rest and isolated per tenant.
In a multi-tenant B2B agent, that is N refresh tokens across N customer Workspace domains. Users revoke grants. Workspace admins can block your OAuth client under API controls, which invalidates its refresh tokens. Your agent learns about either one when a call fails, unless something upstream tells it first. The token type is the same on both paths. So is the infrastructure. Learn more about how to handle token refresh for AI agents in production.
Google's MCP guide asks you to choose Internal or External, and the choice applies to any Chat OAuth client. Internal limits the app to users in your own Workspace organization, which rules out customers' domains. External in Testing status caps you at 100 test users, and their authorizations, refresh tokens included, expire seven days after consent. A scheduled agent works for a week, then fails with invalid_grant. The multi-tenant answer is a published External app, and publishing with sensitive scopes goes through Google's verification review.
Scalekit's Google Chat connector runs the OAuth flow, stores and refreshes each user's tokens, and injects the right one on every tool call. It doesn't return raw provider tokens in API responses by default, so credentials never touch the agent runtime. With bring your own credentials, users see your brand on Google's consent screen, admins allowlist your client ID, and your agent gets a dedicated quota instead of a shared one.
The same connected account backs direct tool calls and Virtual MCP sessions in AgentKit, so the MCP vs API decision stops changing your auth infrastructure. For a deeper look at secure token management for AI agents at scale, see our dedicated guide.
For Google Chat, Scalekit ships an API connector named googlechat: OAuth 2.0 with 54 prebuilt tools, documented in the Google Chat connector docs. There is no separate Google Chat MCP connector in the catalog today. The MCP option is a Virtual MCP server that serves the googlechat tools over MCP. One set of connected accounts powers both paths.
The examples use Python and LangChain, following the Scalekit LangChain guide. You need a Scalekit environment, a Google Chat connection in AgentKit > Connections, and an OpenAI API key. Connection names in code must match the dashboard connection name exactly; a mismatch is the most common integration error.
Each end user authorizes Google Chat once. get_or_create_connected_account looks up the user's connected account, and get_authorization_link returns a Google consent link when it isn't active. In production, deliver that link through your app and verify the user after the redirect, as the Authorize a user guide describes.
execute_tool is the deterministic path. Your code picks the tool and the input; Scalekit injects the user's token and calls the Chat API. Use it for pipeline steps that should never depend on model judgment, such as posting a digest. The request_id makes the post idempotent, so a retried job returns the existing message instead of posting twice. This continues the script above.
Before the agent loop, retrieve the tools authorized for this user's connected account. actions.langchain.get_tools wraps list_scoped_tools and returns native LangChain StructuredTool objects bound to this identifier, not a flat catalog. The connector has 54 tools, but a read-only research agent needs four, so tool_names narrows the list inside that call. Fewer tools in context means fewer wrong selections and fewer tokens burned before the agent does any work. For a complete breakdown of LangChain tool calling mechanics, see our dedicated guide.
Filtering tools per call works until a second agent, or a second team, forgets to. A Virtual MCP server fixes the allowlist in one server definition. You declare which connections and tools an agent role can see and get a static mcp_server_url. Omitting tools for a connection exposes all of them, so name them explicitly. Run this once per agent role, not once per user, as the Set up and connect a Virtual MCP server guide describes.
At runtime, confirm the user's connections are active, then mint a short-lived session token bound to that user. The default lifetime is about an hour; set expiry above the expected run time. There is no refresh endpoint, so call create_session_token again for the next run. The agent authenticates with the token as a bearer credential and never sees a Google token.
The server above spans two connectors behind one URL, with four tools instead of the 54 in the Google Chat connector alone. Scalekit's Virtual MCP docs put the cost in numbers: 40 tools at roughly 200 tokens each burns about 8,000 tokens before the agent does any work. Scoping to 5-10 tools cuts that overhead by 80%.
Multi-tenancy comes from the session token. One server definition serves every user in every customer org. Each run gets a token bound to one user's connected accounts, with no credential sharing between users. What the user can't do, the agent can't do. The same pattern extends to the connectors covered in Gmail MCP vs API and Google Calendar MCP vs API. Understanding access control for multi-tenant AI agents is essential when one endpoint serves many customer organizations.
When an agent posts in the wrong space, security asks which user authorized the call, under which connection, and when. In the Scalekit dashboard, AgentKit > Connected Accounts shows each account's status, refresh history, and tool execution logs. Every execute_tool response carries an execution_id to store next to your own trace IDs. Scalekit's auth logs trace authentication flows across users, agents, and machine clients, and stream to your SIEM.
Agent Webhooks push connected-account lifecycle events, auth signals, and token activity in real time. When a user disconnects Google Chat, pause the agent immediately instead of finding out from a failed call mid-task. For a broader look at agent tool observability and how to know if your agent is actually working, see our dedicated guide.
For internal agents inside a single Workspace domain, the Google Workspace (DWD) connector uses a service account with domain-wide delegation, so there is no per-user consent. It includes five Chat tools: googledwd_list_chat_spaces, googledwd_get_chat_space, googledwd_list_chat_members, googledwd_list_chat_messages, and googledwd_create_chat_message. Each connected account maps your identifier to a Workspace user through a subject email. For multi-tenant products, asking every customer's super admin for domain-wide delegation is a heavy trust request. The Google Workspace connector page lists the full tool set.
Scalekit's connector docs are explicit about where Google's API constrains the connector today. googlechat_upload_media is not functional, because Google's upload endpoint needs a true multipart request. The connector implements user OAuth only, so googlechat_get_attachment, which accepts only app authentication, fails through it, and the tool reference marks card fields as app-authentication only. For endpoints the prebuilt tools don't cover, actions.request proxies a raw Chat API call through the user's connected account, as the Custom tools guide explains.
If your agent is interactive, single-user, and read-heavy, and your organization can live on a Developer Preview surface, Google's Chat MCP server is a clean way to give an MCP host search and reply over a user's conversations. If it runs headless, posts cards, manages spaces, follows events, serves many tenants from one project, or has to be production-stable today, build on the Chat API.
Either way, you hold one Google token per user across every customer domain. That credential layer needs production-grade infrastructure, whichever transport the agent speaks.
Building a Google Chat agent that acts for users across customer Workspace domains? Talk to us for immediate help scoping connections, tools, and Virtual MCP servers. Start with the Google Chat connector docs.