
DigitalOcean gives an AI agent two ways into a customer's infrastructure: 25 hosted MCP servers plus an MCP Router that fronts nearly every product it sells, and a REST API with scoped tokens and a real OAuth flow. They overlap heavily on Droplets, databases, Kubernetes, and networking. They diverge on App Platform operations, on how much credential material lands in model context, and on which auth path survives a background agent running for months. This guide compares what each path lets an agent do, the grant each one puts you on, and how to run either across many customer teams in production.
Your agent needs to operate infrastructure in your customers' DigitalOcean accounts: figure out why an App Platform deploy failed, check whether a Droplet is out of memory, snapshot production before a migration, or add a DNS record for a new tenant. DigitalOcean ships official Model Context Protocol (MCP) servers, hosted, covering nearly every product it sells. It also has a mature REST API with scoped tokens and a real OAuth flow. They overlap heavily on Droplets, databases, Kubernetes, and networking. They diverge on App Platform operations, on how much credential material lands in model context, and on which auth path survives a background agent running for months. Here's how to pick.
DigitalOcean released its MCP server on August 26, 2025 as a local package run with npx @digitalocean/mcp, authenticated with an API token in DIGITALOCEAN_API_TOKEN, and narrowed with a --services flag. On December 9, 2025, it added remote MCP for nine services over Streamable HTTP, each at its own hostname such as https://droplets.mcp.digitalocean.com/mcp and https://apps.mcp.digitalocean.com/mcp. The configuration docs now list 25 remote endpoints, from Droplets, App Platform, DBaaS, DOKS, Networking, Spaces, Volumes, Functions, and Container Registry to ten AI platform servers, plus a Documentation server that needs no token. The source is MIT-licensed at digitalocean-labs/mcp-digitalocean.
Two connection models exist. Individual endpoints expose each service's tools directly. The MCP Router at https://mcp.digitalocean.com/mcp exposes three tools instead: find_tools returns a ranked shortlist of up to 25 candidates for a natural-language query, retrieve_schema returns one tool's schema, and invoke_tool runs it by qualified name. Auth is OAuth with a browser sign-in, which DigitalOcean recommends, or an Authorization: Bearer header carrying a DigitalOcean API token. Neither the docs nor the launch posts label the remote servers as preview or GA.
The DigitalOcean API is a REST API at https://api.digitalocean.com/v2. It covers Droplets and their actions, images and snapshots, volumes, App Platform, managed databases, Kubernetes, domains, firewalls, load balancers, reserved IPs, VPCs, projects, tags, monitoring, billing, and the AI platform. Every request carries an Authorization: Bearer header with either a personal access token or an access token from the OAuth API, which supports the Authorization Code flow with PKCE and refresh tokens.
The pattern is the reverse of most providers in this series. DigitalOcean's MCP servers are broad and mostly mirror the API, delete tools included. Where they fall short is App Platform operations, the area an agent touches most when something breaks, and resource organization through projects and tags. The Scalekit connector is narrower in total surface and deeper in the places a triage or operations agent spends its time.
Diagnosing a failed App Platform deploy on the raw API is a chain: list apps to find the ID, list deployments to find the one in ERROR, fetch the deployment to see which step failed, then request a log URL for the right type and download it. Each step needs an ID from the step before.
The MCP path compresses discovery rather than that chain. A developer in Cursor or Claude Code connects one MCP Router URL and gets every service without writing a single schema. find_tools returns five candidates for "resize the staging database" instead of loading hundreds of tool definitions into context, which is DigitalOcean's own answer to tool bloat. invoke_tool also accepts a projection to trim output fields, which matters when a Droplet list response carries every network interface and kernel. Writing the schema is the hard part. Not the API call.
The tradeoff is that DigitalOcean controls the tool set, its names, and its behavior. The local and remote servers already differ: the npm README lists 21 services, the hosted docs list 25. The Insights server marks its v1 alert policy tools deprecated in favor of insights-alert-rule-* tools. An agent prompt that names a tool can break without a release on your side.
On the MCP path, you have two options. OAuth is recommended: the client connects to the server URL with no Authorization header, opens a browser, and "obtains a short-lived access token through a browser-based sign-in." DigitalOcean's MCP docs do not say which scopes that sign-in grants, how long "short-lived" is, or how the user picks a team. The other option is a DigitalOcean API token in an Authorization: Bearer header, or in DIGITALOCEAN_API_TOKEN for the local server. That token sits in the client's config on the developer's machine; DigitalOcean's README notes that the Claude Code setup stores its configuration in ~/.claude.json, so the token value ends up in that file.
On the direct API path, you choose between a personal access token and an OAuth app, and both can be scoped. That is the part DigitalOcean gets right. A custom-scoped token is built from resource:action pairs, roughly 160 in DigitalOcean's table, such as droplet:create, account:read, database:view_credentials, and kubernetes:access_cluster. Scopes cannot be edited after creation, a missing scope returns 403, and a token can never exceed its owner's team role: if a team owner removes a permission from the role, existing tokens lose it too. You set an expiry when you create the token.
The OAuth API is what a multi-user agent should use. Users authorize at https://cloud.digitalocean.com/v1/oauth/authorize, your backend exchanges the code at /v1/oauth/token, and PKCE with S256 is required for public clients. Confidential clients receive access tokens with expires_in of 2,592,000 seconds, 30 days; public clients get one hour. The token response includes team_uuid and team_name, which tells you which team the grant is bound to.
What the user can't do, the agent can't do. On DigitalOcean that principle has teeth, because the token itself can be narrowed below the user's role. A triage agent can run on api:read and never hold droplet:delete, whatever the user's role allows.
In a multi-tenant B2B agent, MCP gives you a credential 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.
DigitalOcean adds a team dimension. A consultant who belongs to two of your customers' DigitalOcean teams can grant your agent access to either, and the team_uuid on the grant is what tells you which one. Tenant isolation on your side has to bind each connected account to one of your users and one customer, and refuse a grant whose team does not match the customer the user is acting for.
Recommended reading: OAuth vs API keys for AI agents
On the MCP path, DigitalOcean hosts the servers, owns the schemas, and decides what is exposed, including what credential material reaches the model. doks-get-kubeconfig and doks-get-credentials return cluster access data, and db-cluster-start-online-migration takes a source database password as tool input. On an MCP server, both land in the model's context and your conversation logs. You also own the credential for every user, either an OAuth session inside a client you may not control or a token in a config file, and you own the gap on events: there is no subscription mechanism, so an agent that must react to a failed deploy polls.
The MCP servers also have no read-only mode. DigitalOcean's README warns that using MCP against your account "can come with risks," and the only reduction mechanisms are which services you connect and which token scopes you grant. A token with api:write behind the Droplets server means the model can see droplet-delete and power-off-droplets-tag on every call.
On the API path, you own schemas, pagination, retries, and the token lifecycle. Rate limits are 5,000 requests per hour and 250 per minute per OAuth token, on a rolling window: each request counts for one hour from when it was made. Responses carry ratelimit-limit, ratelimit-remaining, and ratelimit-reset, and burst-limit 429 responses include retry-after. Some endpoints are stricter: GET /v2/account/keys allows 10 requests per 60 seconds, and CDN endpoints allow 5 per 10 seconds. Lists default to 20 items and accept per_page up to 200.
Most writes are asynchronous. A resize, snapshot, or power-off returns an action with status of in-progress, and the agent must poll GET /v2/actions/{id} until it reads completed or errored. An agent that reports "done" on the first response is reporting a request, not a result.
Eventing is the honest gap on both paths. The v2 API has no general webhook subscription. Monitoring alert policies notify an email list or a slack array of channel and webhook URL pairs, which reaches humans, not your agent. Everything else is polling, budgeted against 250 requests per minute.
Use DigitalOcean MCP when:
Use the DigitalOcean API when:
Both paths hand you a DigitalOcean credential per user. Neither hands you a vault. A multi-tenant agent with 60 customers and 3 engineers each is 180 DigitalOcean grants. Each must be stored encrypted, kept out of logs and LLM context, refreshed, and revoked through /v1/oauth/revoke when a user disconnects or a customer churns.
DigitalOcean's refresh semantics make this harder than average. Each refresh token can be used exactly once; using it issues a new access token and a new refresh token and invalidates the old access token. Two agent workers that notice the same 30-day token is close to expiry and refresh at once produce one winner and one dead grant. The loser's refresh fails, and the user must authorize again. Refresh has to be serialized per connected account, and the new pair must be persisted before any worker uses it.
The tempting shortcut is one admin's personal access token per customer. That collapses 180 grants into 60 that act with the admin's full role, attribute every agent action to the admin, and stop working when the token's chosen expiry passes or the admin leaves. Fewer secrets, larger blast radius per secret.
Scalekit's digitalocean connector runs the OAuth flow, stores each user's tokens in the token vault, and refreshes them for both paths, so the MCP vs API decision doesn't change your auth infrastructure. Your agent passes an identifier; credentials never touch the agent runtime or the LLM context.
Recommended reading: how to handle token refresh for AI agents
Scalekit's digitalocean connector is an API-path connector built by Scalekit with 120 tools: 63 read, 36 write, and 21 destructive. It covers the account, actions, billing and invoices, Droplets and their actions and metrics, images and snapshots, volumes, App Platform apps and deployments, managed databases, Kubernetes clusters and node pools, domains and records, firewalls, load balancers, reserved IPs, VPCs, projects, tags, SSH keys, regions, sizes, and monitoring alert policies. It authenticates with OAuth 2.0: each user signs in to DigitalOcean once, and Scalekit stores and refreshes their tokens. The connector docs list every tool and its inputs.
DigitalOcean connections use your own OAuth app. In the Scalekit dashboard, go to AgentKit > Connections, create a DigitalOcean connection, and copy its redirect URI. Register an OAuth application with DigitalOcean, add that redirect URI as the callback URL, and enter the app's Client ID and Client Secret on the Scalekit connection. Because the app is yours, the DigitalOcean consent screen shows your app's name to your users, and you control its lifecycle.
The name you give the connection is the connection_name your code passes, and the string must match the dashboard exactly. This is the most common integration error. 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 link that sends the user through DigitalOcean's OAuth consent screen for your app. DigitalOcean redirects back to Scalekit, which exchanges the code and stores the tokens. The agent never sees them.
The last call is worth keeping in production. digitalocean_account_get returns the account's email, status, team, and limits such as droplet_limit, so you can confirm the grant belongs to the team you expected before the agent does anything else.
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 seven an App Platform triage agent needs. Loading all 120 DigitalOcean tools would put digitalocean_app_delete, digitalocean_droplet_delete, and digitalocean_database_cluster_delete in front of a model whose job is to read deployments and explain a failure. None of the seven below can change a running app.
The loop runs until the model stops requesting tools. Every call executes with this user's DigitalOcean grant, so the agent sees only the apps that grant can read.
For pipelines, skip the model. execute_tool runs one tool with a fixed input and returns data plus an execution_id you can log. DigitalOcean has no webhook for a failed deployment, so this job runs on a schedule. It sweeps every app the user can read, finds apps whose newest deployment is in ERROR, downloads the tail of the build log, and redeploys with a forced rebuild only when the failure step looks transient.
Watch the budget. One sweep costs one call for the app list plus one per app, before logs, against a 250 per minute burst limit that is per token. A user with 80 apps on a one-minute schedule spends a third of it on polling alone. Run the sweep every five to ten minutes, or only for apps tagged as production.
Droplet writes need the same discipline. digitalocean_droplet_action_run takes a droplet_id and a type such as snapshot, resize, or power_off, and returns an action that is usually still in-progress. Poll digitalocean_action_get with the returned ID until its status reads completed or errored before the pipeline moves on. A resize with disk set to true is permanent, because disks cannot shrink, and belongs behind a human approval step.
The digitalocean connector has 120 tools. At roughly 200 tokens each, that is about 24,000 tokens of tool definitions before the agent does any work, and 21 of them are destructive. A triage agent that also holds digitalocean_droplet_delete is one bad inference away from deleting a customer's server. DigitalOcean's own MCP Router addresses the token cost with find_tools, but it searches everything the token can reach; it does not take tools away. The fix is not better prompting. It is surface reduction. 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 five tools instead of 120. The endpoint is static; the identity is per-user. Unlike DigitalOcean's own MCP servers, this endpoint can include tools they don't have, such as digitalocean_app_deployment_logs_get and digitalocean_app_deployment_cancel, for the one agent role that should hold them, and leave every delete tool out of every role that shouldn't.
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 team. When a customer asks which agent run powered off db-replica-2 at 03:40 or forced a rebuild of storefront six times in an hour, the answer is a lookup, not an investigation. DigitalOcean's own action history, readable with digitalocean_actions_list, records each power event, resize, and attach with its resource_id and timestamps, and your execution log shows which agent run and which prompt led there.
A shared credential breaks that. If every user's agent runs on one admin's personal access token, DigitalOcean records every action under that admin, every agent reaches every resource the admin's role allows, and the token's expiry becomes an outage for every customer at once. 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 a developer's assistant in Claude Code, Cursor, or VS Code, provisioning Droplets and databases, editing firewall rules, or touching Spaces, Functions, and the AI platform with a human watching, DigitalOcean's remote MCP servers are a good fit: they are hosted, they cover more products than any connector, and the MCP Router keeps context small. If your agent runs unattended, sweeps App Platform for failed deploys, waits on Droplet actions to complete, organizes resources into projects, or serves many customer teams, build against the DigitalOcean API with per-user OAuth grants and a deliberately small tool set. Either way, you hold one DigitalOcean grant per user, bound to a team, refreshed with a token that works exactly once, and that's what needs production-grade infrastructure.
Yes, 25 of them. DigitalOcean hosts one remote MCP server per service, such as https://droplets.mcp.digitalocean.com/mcp and https://apps.mcp.digitalocean.com/mcp, plus an MCP Router at https://mcp.digitalocean.com/mcp that fronts every first-party service except Knowledge Bases through three meta-tools: find_tools, retrieve_schema, and invoke_tool. The source is MIT-licensed, and DigitalOcean recommends OAuth with a browser sign-in for the remote servers.
App Platform operations beyond create and update: there is no tool to cancel a deployment, restart a service, validate a spec and its cost, or fetch build and runtime log URLs. There is no Projects server and no tag create or assign. There are no event triggers, no read-only mode, and tools such as doks-get-kubeconfig and db-cluster-start-online-migration put cluster credentials and database passwords into model context.
Yes, and that is unusual among cloud providers. Personal access tokens come as Full Access, Read Only, or Custom Scopes built from roughly 160 resource:action pairs such as droplet:create and database:view_credentials, with an expiry you choose. A token can never exceed its owner's team role, and a missing scope returns 403. A triage agent can run on api:read and never hold droplet:delete.
Each OAuth refresh token can be used exactly once; using it issues a new access token and refresh token and invalidates the old access token. Two agent workers that refresh the same 30-day token at once produce one winner and one dead grant, and the user must authorize again. Refresh has to be serialized per connected account, and the new pair persisted before any worker uses it.
When it runs headless on a schedule sweeping App Platform for deployments in ERROR, when it must confirm results by polling actions until they read completed, when it cancels stuck deployments, restarts services, or checks a spec's cost before applying it, or when it serves many customer teams with per-user OAuth grants bound to a known team_uuid and credentials kept out of model context.
The digitalocean connector exposes 120 tools over the DigitalOcean API, runs the OAuth flow through your own DigitalOcean OAuth app, and stores and refreshes each user's tokens in the token vault, serializing the single-use refresh. A virtual MCP server narrows the tools per agent role so a triage agent never holds a delete tool, and every execution returns an execution_id attributed to that user and customer team.
Browse the Scalekit DigitalOcean connector and the DigitalOcean connector docs with the full tool list. See Scalekit pricing, or talk to us.