MCP tool reference
Every Showly MCP tool — scope, parameters, return shape, audit behavior.
Every tool the Showly MCP server exposes. Each entry lists the required scope, the input schema in short form, the return shape, and what gets written to the audit log.
All tools require an authenticated MCP client. Tokens are issued from Workspace settings → MCP clients. The canonical tool + scope list is [packages/shared/src/mcp-catalog.ts](https://github.com/flot/showly-platform/blob/main/packages/shared/src/mcp-catalog.ts). A catalog-parity test fails the build if this page drifts from the catalog. When you add a tool, update both files together.
list_projects
Scope: project:read
Lists projects (workspaces) the token can see.
Input: {}
Output: { ok, data: Array<{ id, name, slug, createdAt }> }
Audit: mcp.list_projects
list_sites
Scope: site:read
Lists sites in the current workspace. Pass projectId to scope the listing; a project-scoped MCP token forces this filter regardless of the parameter.
Input: { projectId?: string }
Output: { ok, data: Array<Site> }
Audit: mcp.list_sites
get_site_context
Scope: site:read
Returns the site, its latest preview, and the latest production deployment id for a given siteId. See the Site shape in [Common types](#common-types).
Input: { siteId }
Output: { ok, data: { site, latestPreview, latestProductionDeploymentId } }
Audit: mcp.get_site_context (records siteId)
create_change_plan
Scope: site:read
Produces a change plan proposal. Does _not_ modify any files. The agent typically reads the returned plan, asks the user for confirmation, then calls apply_site_patch.
Input: { siteId, request: string }
Output: { ok, data: { siteId, request, plan, nextStep } }
Audit: mcp.create_change_plan
apply_site_patch
Scope: site:write
Stages file edits for a site. The staged changeset is temporary and must be materialized by create_preview.
Input: { siteId, files: Array<{ path, content }>, message: string }
Output: { ok, data: { changesetId, siteId, fileCount, ttlSeconds, nextStep } }
Audit: mcp.apply_site_patch (records siteId + changesetId + file count)
create_preview
Scope: preview:create
Builds the patched workspace and produces a preview URL.
Input: { changesetId?, siteId?, files? }
Output: { deploymentId, previewUrl, framework?, fileCount? }
Audit: mcp.create_preview
retry_deployment
Scope: preview:create
Rebuilds a failed or canceled preview deployment. Showly retains the source bundle from the original build, so a retry is one call — files is optional: omit it and the saved source is reused (true one-click rebuild). If the original source was never retained (older deployments) you'll get a clear error asking you to re-supply files; pass the same files you gave create_preview to recover. Mints a new deploymentId (the failed one stays as history) in status: "building" and returns it for polling. Each retry counts against your monthly deploy quota — it is a fresh build. Returns 409 not_retryable if the deployment is still building or already ready, 404 if it isn't visible to your token, 402 if you're over quota.
Input: { deploymentId, files?: [{ path, content }] } // files optional when the source bundle was retained
Output: { ok, data: { deploymentId, status: "building", pollUrl, retriedFrom } }
Audit: mcp.retry_deployment
run_checks
Scope: checks:run
Runs the workspace's check matrix (lints, types, custom CI hooks) against a preview.
Input: { deploymentId }
Output: { ok, data: { deploymentId, checks, summary } }
Audit: mcp.run_checks
request_publish
Scope: publish:request
Opens an approval request for a ready preview deployment. The response includes a webApprovalUrl deep link; surface that link to the user so they can complete approval and step-up MFA in the Showly web UI.
Input: { deploymentId, message: string }
Output: { approvalId, deploymentId, state: "pending", expiresAt, reused, webApprovalUrl }
Audit: mcp.request_publish
get_preview_status
Scope: preview:read
Returns the current status of a preview deployment. Optionally long-polls (up to 60s) until the status transitions away from a known value — useful after request_publish while waiting on a reviewer. When status is failed or canceled, the result also carries errorCode, errorMessage, stage, and a short logTail explaining why the build failed; pair with retry_deployment to rebuild.
Input: { deploymentId, waitForChange?: boolean, currentStatus?: string, timeoutMs?: number }
Output: { ok, data: Deployment & { errorCode?, errorMessage?, stage?, logTail? }, changed?, timedOut? }
Audit: mcp.get_preview_status
get_deployment_logs
Scope: logs:read
Returns the build log tail for a deployment (the last lineCount lines, default 200, of the captured build output). source discriminates db (real log lines), pending (deployment exists but no log captured yet — still building or no tail), or not-found (no such deployment for this token).
Input: { deploymentId, lineCount?: number }
Output: { ok, data: { deploymentId, lineCount, source, lines } }
Audit: mcp.get_deployment_logs
diagnose_deployment
Scope: logs:read
Self-diagnose one of your own deployments. Returns a single structured, AI-consumable diagnostic bundle so the agent can reason about why a build failed in one call — then fix the source and retry_deployment — rather than stitching together separate get_preview_status / get_deployment_logs reads. The bundle aggregates: the build failure (stage, errorCode, errorMessage, a logTail), related runtime errors from Sentry (correlated by commit SHA + environment + a window around the deploy, fail-soft), the deploy's ops-job status, the org's quota status, any agent-pushed clientLogs (redacted + capped), and deterministic hypotheses — likely root causes with a confidence (e.g. quota_exceeded / build_install_failed), derived by rules (not AI) as a high-quality starting point.
Tenant-isolated: you can only diagnose deployments in your own org. A deployment id that isn't visible to your token returns 404 (indistinguishable from a non-existent id — no cross-org existence leak). This is the agent-facing twin of the staff Diagnostics Center bundle; both share one backend aggregator. Calls GET /deployments/:deploymentId/diagnostics.
Input: { deploymentId }
Output: { ok, data: { deployment, failure, jobRun, quota, sentry, clientLogs, hypotheses } }
Audit: mcp.diagnose_deployment
list_templates
Scope: template:read
Lists Showly site templates available to the current token. Pair with create_site_from_template to onboard a new site without a Git repo.
Input: { framework?: string }
Output: { ok, data: Array<{ slug, displayName, description, framework, screenshots }> }
Audit: mcp.list_templates
create_site_from_template
Scopes: template:create, site:write
Materialises a new Showly-managed site from a template. Creates the sites row and the initial site_versions row in one transaction. The returned siteId can be polled with get_preview_status to watch the first build.
Input: { projectId, templateSlug, name, siteSlug, variables?: Record<string, unknown> }
Output: { ok, data: { siteId, projectId, initialVersionId, templateSlug, createdAt } }
Audit: mcp.create_site_from_template
Production tools (not MCP-exposed)
Not MCP-exposed — requires Web/API approval flow.
publish_site and rollback_deployment are intentionally not registered with the MCP server — they do not appear in tools/list and cannot be called from an MCP token. Both actions live on the web UI behind step-up MFA + approval. From an MCP session, use request_publish to open an approval and hand the user the webApprovalUrl it returns; for rollback, surface the Rollback button in the editor.
The shared catalog (packages/shared/src/mcp-catalog.ts) marks these entries with productionWriteable: false and kind: "production" so audit copy and docs can resolve the names without the MCP server registering them.
Common types
The reference uses a few named shapes above. The concrete field set is shown in the end-to-end flow, which walks a full session with real JSON. Quick summaries:
| Type | Key fields |
|---|---|
Site | id, name, slug, projectId, framework (auto-detected), repositoryUrl |
Deployment | id, siteId, environment, status, previewUrl?, createdAt |
plan | the create_change_plan proposal: a list of intended file edits plus a human-readable summary; not applied until apply_site_patch |
checks | per-check results from the workspace check matrix (lints, types, custom CI hooks) |
summary | a roll-up of checks (counts of passed/failed) returned by run_checks |
status is one of queued, building, ready, failed, canceled. ready is the terminal success state for both preview and production deployments. framework is auto-detected at build time and is one of astro, vite, next-export, static-html, custom, or unknown — it is not something you set on the manifest.
Versioning
Tool schemas follow semver via the MCP version field. Breaking changes ship a new tool name (apply_site_patch_v2); the old name continues to work for at least one release cycle with a deprecation note in notes.