
Google now hosts an official Slides MCP server in Developer Preview next to its other Workspace servers, and the OAuth-backed Slides API you have used for years is still there. They are not the same thing. The MCP server reads and edits existing decks; the API also creates them; neither one copies, exports, or shares a deck without Drive. This guide compares what each path lets an agent do, the scopes and verification each one puts you on, and how to run either across many customer domains in production.
Your agent needs to build and edit your customers' Google Slides: turn a weekly metrics pull into a QBR deck, rewrite speaker notes for a sales pitch, or audit 40 slides for an outdated product name. Google now hosts an official Slides MCP server next to its Gmail, Drive, Docs, and Sheets servers, and the same OAuth-backed Slides API you have used for years is still there. They are not the same thing. The MCP server reads and edits existing decks; the API also creates them; neither one copies, exports, or shares a deck without Drive. Here's how to pick.
Google's remote Model Context Protocol (MCP) server for Slides runs at https://slidesmcp.googleapis.com/mcp/v1 over Streamable HTTP with OAuth 2.0. It is in Developer Preview through the Google Workspace Developer Preview Program, and the configuration guide lists it alongside eight other Workspace servers. To use it, you enable both the Google Slides API (slides.googleapis.com) and the Google Slides MCP API (slidesmcp.googleapis.com) in a Google Cloud project, configure an OAuth consent screen, and create a Web application OAuth client with "Use this client for an AI-powered agent" selected.
The tool reference lists four tools, each a thin wrapper over one REST method. read_presentation maps to presentations.get, read_slide_page to presentations.pages.get, read_slide_page_thumbnail to presentations.pages.getThumbnail, and update_presentation to presentations.batchUpdate. The server acts with the signed-in user's permissions, and Google's own guide warns that it can read, modify, and delete data in that user's account.
The Slides API v1 has five methods. On presentations: create, get, and batchUpdate. On pages: get and getThumbnail. Everything about a deck's content, including slides, shapes, text, tables, images, linked Sheets charts, and comments, changes through batchUpdate, which accepts 49 request types in an ordered array and applies them atomically.
Auth is Google OAuth 2.0 with five scopes: presentations, presentations.readonly, drive, drive.readonly, and drive.file. Service accounts work on decks they own or that are shared with them, and Workspace admins can grant domain-wide delegation so a service account acts as users in their domain. There are no API keys for private presentation data.
The pattern is clear. On editing, the two paths are at parity, because update_presentation passes the same batchUpdate request vocabulary through. The gaps are at the edges of a deck's life: the MCP server cannot start one, and neither path can copy, export, share, or delete one without Drive.
batchUpdate is where Slides work gets hard. Every element needs an objectId that is unique and 5 to 50 characters. Positions are AffineTransform objects in EMU, where one inch is 914,400 units. A new slide built from a layout needs placeholderIdMappings before you can write text into its title and body. Google's MCP server hands the model a schema for all of it, and read_presentation returns structure the model can reason about, so "move the pricing table to slide 4 and shrink it" becomes a valid call without you writing a tool definition.
Writing the schema is the hard part. Not the API call.
The tradeoff is the payload. A presentations.get response for a 30-slide deck with tables and images runs to hundreds of kilobytes of JSON, and read_presentation returns that JSON into the model's context. The direct API lets you pass a fields mask and fetch only what the task needs.
The MCP server is hosted by Google, but the OAuth client is yours. Each MCP host signs the user in against a client in your Cloud project, requests some subset of drive.readonly, drive.file, presentations.readonly, and presentations, and holds the resulting tokens. Google's guide flags a common failure: if users are asked to sign in roughly every hour, the client is not receiving a refresh token, and the authorization request needs access_type=offline, plus prompt=consent for users who already granted access. The offline_access scope alone does not fix it.
That works for a person in Claude Desktop. In a multi-tenant agent, the MCP host is your backend, and your backend now stores a Google refresh token per user per customer.
drive.file is Google's recommended non-sensitive scope and covers only files the app created or the user opened with the app. An agent that generates its own decks with presentations.create and edits only those can run on drive.file alone. An agent that must read or edit decks the user built elsewhere needs presentations.readonly or presentations, which are sensitive scopes and apply to every presentation the user can access. drive and drive.readonly are restricted scopes and bring a security assessment; avoid them for a Slides agent.
Sensitive scopes on an External OAuth app require Google's sensitive scope verification: a verified domain, a privacy policy, a written justification per scope, and a demo video. Apps left in Testing status get refresh tokens that expire after 7 days, which silently breaks any weekly reporting agent built during a pilot. Internal apps are exempt from verification; a multi-tenant B2B agent is not internal.
Service accounts see only the decks shared with them. Domain-wide delegation lets one key impersonate any user in a customer's domain and edit every deck in it. What the user can't do, the agent can't do. Domain-wide delegation removes that guarantee by design.
In a multi-tenant B2B agent, MCP gives you a token per user and the direct API gives you a credential per user. In neither case does the path itself solve storage, rotation, or revocation; those are infrastructure problems regardless of which path you choose.
Slides adds a practical wrinkle. Edit rights come from Drive sharing, so a user who loses edit access to a board deck leaves your agent with a valid token and a 403 on every batchUpdate. A Workspace admin who blocks your app under Security > API Controls revokes the grant without telling you.
Recommended reading: OAuth vs API keys for AI agents
Google hosts the server, normalizes the tool schemas, and maps each tool to its REST method. You own everything around it: the OAuth client and its verification status, the per-user refresh tokens your MCP client stores, and the Drive calls for anything the Slides server does not do. Google's guide also puts prompt injection on your side of the line. A deck shared by an outsider can carry instructions in its speaker notes, and read_slide_page returns those notes to the model. Google recommends screening prompts and responses with Model Armor or an equivalent, and avoiding untrusted presentations.
Developer Preview also means the tool surface can change. The configuration page itself currently names two tools in its body text while its reference lists four.
You own schemas, retries, object ID generation, and the token lifecycle. Slides API quotas are per minute: 3,000 read requests per project and 600 per user per project; 600 write requests per project and 60 per user per project. getThumbnail is an expensive read, capped at 300 per project and 60 per user per project. There is no daily cap. Requests over quota return 429, and Google recommends truncated exponential backoff with up to 1,000 milliseconds of jitter. Google also states that exceeding request quotas is planned to incur charges to your Cloud billing account later in 2026.
Write quota is the constraint that matters. A deck-generation agent that issues one batchUpdate per slide burns 60 writes per user per minute on a single 60-slide deck. Batch all requests for a deck into one call and the same deck costs one write. Thumbnails have their own trap: the returned URL expires after about 30 minutes, so an agent that stores it for a Slack digest posts a broken image the next morning.
The Slides API is v1, and Google adds request types inside it: comment requests now sit alongside the original shape and text requests. On the direct path, new request types are opt-in and old code keeps working. On the MCP path, update_presentation passes the request vocabulary through, so new types arrive when Google updates the preview server, and so do changes to tool names and response formats.
Both paths hand you a Google OAuth grant per user. Neither hands you a vault. A multi-tenant agent with 80 customers and 6 users each is 480 refresh tokens, each bound to one Google account, one consented scope set, and one Workspace admin policy that can revoke it without notice. Each must be stored encrypted, refreshed before its 1-hour access token expires, kept out of logs and LLM context, and deleted when the user disconnects or the customer churns.
The token type is the same on both paths, because Google's Slides MCP server accepts the same OAuth grant the REST API does. The tempting shortcut is one service account with domain-wide delegation per customer. That turns 480 grants into 80 keys and makes each key a write credential for every deck in that customer's domain, including the board deck. Fewer secrets, larger blast radius per secret.
Scalekit's googleslides connector handles the Google OAuth flow, stores each user's tokens in the token vault, and refreshes them, so the MCP vs API decision doesn't change your auth infrastructure. Your agent passes an identifier; the token never enters the agent runtime or the LLM context.
Recommended reading: why a token vault matters for AI agent workflows
Scalekit's googleslides connector is an API-path connector with 5 tools (3 read, 2 write, 0 destructive), one for each Slides API v1 method: googleslides_create_presentation, googleslides_read_presentation, googleslides_get_page, googleslides_get_page_thumbnail, and googleslides_batch_update_presentation. It authenticates with Google OAuth 2.0: each user signs in to Google once, and Scalekit stores and refreshes their tokens as that user's connected account.
The connector uses your own Google OAuth app. In the Scalekit dashboard, go to AgentKit > Connections, create a Google Slides connection with "Use your own credentials", and copy its redirect URI. In Google Cloud Console, enable the Google Slides API, create a Web application OAuth client, and add that redirect URI. Paste the client ID, client secret, and scopes into the connection. Use presentations.readonly for a review agent, drive.file for an agent that only edits decks it creates, and presentations only if the agent must edit decks users built themselves.
The connection name you choose is the connection_name your code passes, and the string must match the dashboard exactly. This is the most common integration error. Set the OAuth audience to External if your users are outside your Workspace organization, and add test users while the app is in Testing. Copy SCALEKIT_ENVIRONMENT_URL, SCALEKIT_CLIENT_ID, and SCALEKIT_CLIENT_SECRET from Developers > API Credentials into .env.
get_or_create_connected_account returns the user's connected account. If it is not ACTIVE, get_authorization_link returns a Google OAuth consent link. The user approves once; Scalekit exchanges the code and stores the tokens.
This is not a catalog load. The agent asks for the tools this user's connected account is authorized to call, then narrows them to the three a deck-review agent needs. googleslides_batch_update_presentation never reaches the model, so a review agent cannot rewrite or delete slides in a customer's live pitch deck on a misread instruction.
The loop runs until the model stops requesting tools. Every tool call executes with this user's Google credential. The presentation ID comes from your app's config for this customer; it is the long ID in the deck's edit URL.
For pipelines, skip the model. execute_tool runs one tool with a fixed input and returns data plus an execution_id you can log. This job creates a weekly metrics deck, then adds a titled slide in a single batchUpdate, so the whole build costs one write request against the 60-per-user quota.
When the deck is shared with humans, pass required_revision_id from the last read. If someone edited the deck since, the write is rejected instead of overwriting their change, and your pipeline can re-read and retry.
Copying a template deck, exporting to PDF, and sharing are Drive API operations. Use Scalekit's Google Drive connector for those, under the same connected account and vault model.
The googleslides connector has 5 tools, so token bloat is not the risk. Overreach is. googleslides_batch_update_presentation accepts deleteObject, and a summarizer that holds it can remove slides from a customer's board deck. A Scalekit virtual MCP server declares exactly which tools an agent role can see, and session tokens keep each run bound to one user's connected accounts. Docs: set up a virtual MCP server.
One server definition serves every user. Before each run, check that the user's accounts are active and mint a short-lived session token scoped to them. Any MCP client that speaks Streamable HTTP can connect; this example uses langchain-mcp-adapters (pip install langchain-mcp-adapters) and passes the token as a Bearer header.
The agent sees three tools. The endpoint is static; the identity is per-user. Compared with pointing an agent at Google's Slides MCP server directly, the difference is the boundary: Google's server exposes update_presentation to every client that connects, while a virtual MCP server lets a review role see only read tools and adds googleslides_create_presentation, which Google's server does not offer, for a generation role.
Every execute_tool call returns an execution_id, and every execution is attributed to a connected account, which maps to one of your users and one customer. When a customer asks which agent run deleted slide 12 from their investor update or replaced the pricing on their renewal deck, the answer is a lookup, not an investigation. Google's revision history shows the edit came from the user's account; your execution log shows which agent run, on whose behalf, made it.
A shared credential breaks that. If every user's agent runs on one service account with domain-wide delegation, Google's side records the impersonated account and your side can only prove that the shared key did it. Shared credentials are a single-user solution. They do not survive a second user.
Recommended reading: audit trails for agent auth
If your agent is one person's assistant in Claude or Antigravity, editing decks that already exist, Google's Slides MCP server is the obvious start: Google hosts it, its tool surface matches the editing half of the API, and the preview status is an acceptable risk for interactive use. If your agent creates decks, runs on a schedule, needs revision-safe writes, or serves more than one customer, build against the Slides API, with Drive alongside it for copy, export, and share. The MCP server will leave Developer Preview and probably gain tools. The need to store, scope, and revoke one Google OAuth grant per user, per customer, will not change, and that's what needs production-grade infrastructure.
Yes, in Developer Preview through the Google Workspace Developer Preview Program, at https://slidesmcp.googleapis.com/mcp/v1 over Streamable HTTP with OAuth 2.0. It exposes four tools that wrap one REST method each: read_presentation, read_slide_page, read_slide_page_thumbnail, and update_presentation. It cannot create a presentation, and copying, exporting, sharing, and deleting a deck are Drive operations on both paths.
On editing they are at parity, because update_presentation passes the same batchUpdate request vocabulary through. The API adds presentations.create, a fields mask to keep read payloads out of model context, and writeControl with requiredRevisionId so a human edit mid-run fails the write instead of being overwritten. The MCP path adds a second API to enable and an OAuth client marked for AI agent use.
The narrowest that does the job. drive.file is non-sensitive and covers only files the app created or the user opened with it, enough for an agent that generates its own decks. presentations.readonly and presentations are sensitive and apply to every presentation the user can access, which brings Google's sensitive scope verification on an External app. drive and drive.readonly are restricted and should be avoided for a Slides agent.
Per minute: 3,000 read requests per project and 600 per user per project; 600 write requests per project and 60 per user per project; thumbnails capped at 300 per project and 60 per user. Over quota returns 429 with truncated exponential backoff recommended. A deck-generation agent that batches every request for a deck into one batchUpdate spends one write instead of one per slide.
When it creates decks from scratch or from a template copied through Drive, when every request for a deck goes into one batchUpdate with requiredRevisionId, when the flow needs Drive-side copy, export, share, or delete steps, or when it serves more than one customer and must budget writes and thumbnails per user per minute.
The googleslides connector exposes all five Slides API methods as tools and uses your own Google OAuth app with the scopes you choose. Each user signs in once, Scalekit stores and refreshes the tokens in the token vault, a virtual MCP server lets a review role see only read tools while a generation role gets create, and every execution returns an execution_id attributed to that user. Drive steps run through the Google Drive connector under the same account.
Browse the Scalekit Google Slides connector and the Google Slides connector docs with the full tool list. See Scalekit pricing, or talk to us.