MCP tools

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:

TypeKey fields
Siteid, name, slug, projectId, framework (auto-detected), repositoryUrl
Deploymentid, siteId, environment, status, previewUrl?, createdAt
planthe create_change_plan proposal: a list of intended file edits plus a human-readable summary; not applied until apply_site_patch
checksper-check results from the workspace check matrix (lints, types, custom CI hooks)
summarya 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.