dply runs a Model Context Protocol (MCP) server. MCP lets an AI assistant such as Claude Code, Claude Desktop, or Cursor call tools on your behalf. With the dply server connected, the assistant can look up the apps in your organization and their status without you copying details from the dashboard.
What the assistant may do is what its token allows: with read abilities only, it looks and diagnoses; give the token Edge → Deploy or Edge → Environment write and it can deploy, roll back and change environment variables too. It never reads environment variable values. Domains, resources and other settings stay in the CLI and the HTTP API.
Endpoint and authentication
| URL | https://edge.dply.io/mcp |
| Transport | Streamable HTTP |
| Authentication | Authorization: Bearer dply_… |
| Rate limit | 60 requests per minute per token, shared with the HTTP API |
The server authenticates with a regular dply API token, the same kind the HTTP API uses. The token belongs to one organization, so the assistant sees only that organization's apps. The server also checks your membership on every request: if you leave the organization, the token stops working.
Create a token
Organization owners and admins create API tokens in the dashboard:
- Open Profile → API keys.
- Enter a name, for example
Claude. - Select the abilities the assistant needs (see Tools): List and read sites (
sites.read) and Edge → Read (edge.read) to look and diagnose; add Edge → Deploy (edge.deploy) and Edge → Environment read/write (edge.env.read,edge.env.write) for it to act. - Create the token and copy it. dply shows the token only once.
Members and deployers can't open API keys. Sign in with the CLI instead (dply-edge login grants sites.read to every role) and use the token it saves in ~/.dply/config.json, or ask an admin to create one for you.
A dedicated token with only the abilities you want the assistant to use limits the damage if it leaks. Your role still applies: a viewer's token can't deploy whatever abilities it lists.
Warning
Treat the token like a password. MCP clients store it in plain-text config files. Don't commit those files. Revoke the token under Profile → API keys if it's exposed.
Connect a client
In each example, replace dply_YOUR_TOKEN with your token.
Claude Code
claude mcp add --transport http dply-edge https://edge.dply.io/mcp \
--header "Authorization: Bearer dply_YOUR_TOKEN"
Run claude mcp list to confirm that the server connects. Add --scope user to make it available in every project.
Cursor
Add the server to ~/.cursor/mcp.json, or to .cursor/mcp.json in a project:
{
"mcpServers": {
"dply": {
"url": "https://edge.dply.io/mcp",
"headers": {
"Authorization": "Bearer dply_YOUR_TOKEN"
}
}
}
}
Claude Desktop
Claude Desktop's config file doesn't set request headers on remote servers, so use the mcp-remote bridge. It requires Node.js. Edit claude_desktop_config.json (Settings → Developer → Edit Config):
{
"mcpServers": {
"dply": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"https://edge.dply.io/mcp",
"--header",
"Authorization:${DPLY_AUTH}"
],
"env": {
"DPLY_AUTH": "Bearer dply_YOUR_TOKEN"
}
}
}
}
Restart Claude Desktop after you save the file.
Other clients
Any client that supports streamable HTTP and custom headers can connect. Point it at https://edge.dply.io/mcp and send the Authorization header.
Tools
Tools return JSON with a top-level data key. A tool whose ability the token lacks returns This API token lacks the required "…" ability.
| Tool | Ability | What it does |
|---|---|---|
list_sites, get_site |
sites.read |
The organization's apps; one app's repository, branch and domains. |
get_site_health |
edge.read |
Live and latest deploy, billing pause, container instances. |
list_deployments, get_deployment_log |
edge.read |
Recent deploys with timings and failure reasons; a deploy's log. |
get_app_logs, get_app_errors |
edge.read |
A container app's own output, and its errors grouped with stack traces. |
get_recent_requests, probe_url |
edge.read |
What visitors got (filter by status); request a path on the app's own hostnames. |
deploy_app |
edge.deploy |
Deploy the branch's latest commit, or a given commit (rebuild to build a live one again). |
rollback_deployment |
edge.deploy |
Put an earlier deploy (deployment_id) back live. |
cancel_deployment |
edge.deploy |
Stop a building deploy; restart queues a fresh one. |
list_env_vars |
edge.env.read |
Production variable names, and which a resource sets. Never values. |
set_env_var, delete_env_var |
edge.env.write |
Change one production variable. Takes effect on the next deploy. |
Deploy and environment tools also need a role that may do it on that app (owner, admin or member; a deployer can deploy but not change variables). Variables a resource sets (an attached database's DB_* …) change on Resources.
The two site tools in detail:
list_sites
Lists the apps in the organization. Preview deployments aren't included. It takes no input.
{
"data": [
{
"id": "01j9z4k7m2q8r5t6v3w0x1y2z3",
"slug": "marketing",
"name": "marketing",
"runtime_mode": "static",
"status": "edge_active",
"live_url": "https://marketing-a1b2c3.on-dply.live",
"last_deploy_at": "2026-09-24T09:15:02+00:00",
"created_at": "2026-09-20T14:02:11+00:00"
}
]
}
runtime_mode is static, hybrid, ssr or container. live_url is null until the first deploy goes live.
get_site
Returns one app.
| Input | Type | Required | Description |
|---|---|---|---|
site_id |
string | Yes | The app's id or slug. |
It returns the list_sites fields plus:
| Field | Description |
|---|---|
repository |
The connected repository, for example acme/marketing. |
branch |
The production branch. |
custom_domains |
Each attached domain: hostname, dns_status (pending, ready, failed) and ssl_status. |
If the app doesn't exist, belongs to another organization, or you can't view it, the tool returns Site "<id>" was not found in this organization.
Resources
Resources let a client load context without calling a tool. They need sites.read, like the tools.
| URI | Description |
|---|---|
dply://sites |
The organization's apps, with the same fields as list_sites. |
dply://sites/{site_id} |
One app, with the same fields as get_site. site_id accepts an id or slug. |
Troubleshooting
| Symptom | Cause |
|---|---|
401 Unauthorized or Token expired or invalid |
The header is missing or malformed, or the token was revoked or has expired. |
403 Forbidden |
You're no longer a member of the token's organization, or the request came from an IP address outside the token's allow list. |
lacks the required "…" ability |
Create a token that includes that ability (see Tools). |
Your role does not allow this on this app. |
Your role in the organization can't do that on this app, whatever the token lists. |
429 Too Many Requests |
The token went over 60 requests per minute, counting HTTP API calls. Wait a minute. |
| An app is missing | The token belongs to a different organization. Create a token in the organization that owns the app. |