Skip to main content

MCP-Rollback Tools

Rollback Tool Suite for Dev MCP

lamatic-dev-mcp-rollback-enhancement-request.md

9 KB

1 comment

Log in to comment and vote

Comments1

  • Pat Carney

    •

    Jul 22

    Enhancement: Add safe project deployment rollback tools

    Summary

    Add first-class project deployment rollback support to @lamatic/dev-mcp so an MCP client can safely inspect and restore a previously successful Lamatic deployment without editing Flow graphs or reconstructing an older release manually.

    This capability belongs in Dev MCP because rollback is a project/deployment lifecycle mutation. Graph MCP should remain focused on discovering and executing deployed Flows.

    Current design baseline: Lamatic/Dev-MCP-Lamatic at commit f3d60db657ec089dd1f603fb5609a5bbe8ff50e0 (2026-06-02). Dev MCP currently exposes dev_deploy_project, dev_list_all_deployments, and dev_get_deployment, but no rollback operation.

    Problem

    When a deployment introduces a regression, an MCP operator can inspect deployment history but cannot restore a known-good deployment. The only available MCP path is to modify project configuration and deploy again, which is slower and can fail to reproduce the exact prior runtime artifact.

    Rollback is a high-impact operation. A single unguarded mutation tool would be easy for an agent to call against the wrong project or from stale deployment state. The MCP interface should therefore separate inspection from execution and make the mutation conditional and auditable.

    Proposed Dev MCP tools

    1. dev_preview_project_rollback

    Read-only. Validates the target and reports exactly what a rollback would restore.

    server.tool('dev_preview_project_rollback', 'Preview rollback of a Lamatic project to a previous successful deployment', {
      projectId: z.string().describe('The project ID'),
      targetDeploymentId: z.string().describe('The successful deployment to restore'),
    }, async ({ projectId, targetDeploymentId }) => {
      // Thin handler following the existing server.js pattern.
    });
    

    The response should include:

    • Project ID and name.

    • Current deployment ID, name, status, and creation time.

    • Target deployment ID, name, status, and creation time.

    • Whether the target belongs to the same project and is eligible for rollback.

    • A deterministic summary of deployed Flows/resources that would change.

    • Resources explicitly excluded from rollback.

    • Warnings and blocking conditions.

    • A short-lived confirmationToken bound to the project, current deployment, target deployment, authenticated user, and preview digest.

    Preview must fail when the target deployment:

    • Does not belong to the project.

    • Is not in a terminal successful state.

    • Is already the current deployment.

    • Does not have an immutable restorable artifact.

    • Is incompatible with the project's current runtime or region.

    2. dev_rollback_project

    Mutating. Creates a new deployment whose source artifact is the selected prior deployment.

    server.tool('dev_rollback_project', 'Rollback a Lamatic project to a previously successful deployment', {
      projectId: z.string().describe('The project ID'),
      targetDeploymentId: z.string().describe('The successful deployment to restore'),
      expectedCurrentDeploymentId: z.string().describe('Current deployment ID observed during preview'),
      confirmationToken: z.string().describe('Short-lived token returned by dev_preview_project_rollback'),
      name: z.string().optional().describe('Rollback deployment name'),
      description: z.string().optional().describe('Reason for the rollback'),
      idempotencyKey: z.string().optional().describe('Caller-generated key preventing duplicate rollback requests'),
    }, async ({
      projectId,
      targetDeploymentId,
      expectedCurrentDeploymentId,
      confirmationToken,
      name,
      description,
      idempotencyKey,
    }) => {
      // Thin handler following the existing server.js pattern.
    });
    

    The tool should return:

    • Newly created rollback deployment ID.

    • Source/target deployment ID.

    • Previous current deployment ID.

    • Initial rollback status.

    • Triggered-by identity and timestamp.

    • A message directing the client to monitor the new deployment with the existing dev_get_deployment tool.

    Rollback behavior

    1. A rollback creates a new deployment; it never rewrites or deletes deployment history.

    2. The backend atomically verifies that expectedCurrentDeploymentId is still current before starting the rollback.

    3. The confirmationToken must match the project, authenticated user, target deployment, expected current deployment, and preview digest.

    4. A repeated request with the same idempotencyKey returns the original rollback deployment rather than starting another rollback.

    5. Only one deploy or rollback operation may mutate a project at a time.

    6. The rollback restores the immutable deployed runtime artifact represented by targetDeploymentId.

    7. Project-scoped credentials, secret values, OAuth state, API keys, Context contents, and external integration state are not changed implicitly.

    8. The preview and deployment details must state which resource classes are restored and which remain current.

    9. The rollback record must retain rollback_of, rollback_from, reason/description, authenticated user ID, and timestamps for auditability.

    10. Failure must leave the currently served deployment unchanged.

    Proposed API helper style

    Add thin helpers to utils/api.js, consistent with triggerDeployment, listAllDeployments, and getDeployment:

    async function previewProjectRollback({ orgId, projectId, targetDeploymentId, userId }) {
      const response = await axios.post(
        `${BASE_URL}/organizations/${orgId}/project/${projectId}/deployments/rollback/preview`,
        { targetDeploymentId, userId },
        { headers: getHeaders() }
      );
      return response.data;
    }
    
    async function rollbackProject({
      orgId,
      projectId,
      targetDeploymentId,
      expectedCurrentDeploymentId,
      confirmationToken,
      name,
      description,
      idempotencyKey,
      userId,
    }) {
      const response = await axios.post(
        `${BASE_URL}/organizations/${orgId}/project/${projectId}/deployments/rollback`,
        {
          targetDeploymentId,
          expectedCurrentDeploymentId,
          confirmationToken,
          name,
          description,
          idempotencyKey,
          userId,
        },
        { headers: getHeaders() }
      );
      return response.data;
    }
    

    Endpoint names are proposed and should be aligned to the enterprise API's final rollback contract. If the enterprise API does not yet expose immutable deployment restoration, that backend capability is a prerequisite.

    Error contract

    Return stable, actionable error codes in addition to a human-readable message:

    • ROLLBACK_TARGET_NOT_FOUND

    • ROLLBACK_TARGET_NOT_ELIGIBLE

    • ROLLBACK_TARGET_WRONG_PROJECT

    • ROLLBACK_ALREADY_CURRENT

    • ROLLBACK_PREVIEW_EXPIRED

    • ROLLBACK_PREVIEW_MISMATCH

    • CURRENT_DEPLOYMENT_CHANGED

    • DEPLOYMENT_OPERATION_IN_PROGRESS

    • ROLLBACK_ARTIFACT_UNAVAILABLE

    • ROLLBACK_FAILED

    Do not include credentials, secret values, signed artifact URLs, or sensitive deployment payloads in MCP responses or errors.

    Acceptance criteria

    • [ ] Dev MCP exposes dev_preview_project_rollback and dev_rollback_project using the existing dev_* naming convention and Zod schemas.

    • [ ] Preview is read-only and returns a deterministic change summary plus a short-lived confirmation token.

    • [ ] Apply requires the target deployment, expected current deployment, and confirmation token.

    • [ ] Rollback produces a new deployment and preserves the complete deployment history.

    • [ ] The operation is atomic with respect to concurrent deploy/rollback requests.

    • [ ] The target must be a successful, restorable deployment from the same project.

    • [ ] Credentials, secrets, OAuth state, API keys, Context data, and external system state are never rolled back implicitly.

    • [ ] Failure leaves the current deployment serving traffic.

    • [ ] Existing dev_list_all_deployments and dev_get_deployment expose rollback metadata and terminal status.

    • [ ] README tool tables and examples document the preview/apply workflow and its mutation risk.

    • [ ] The package version and MCP server version are updated consistently.

    Test cases

    1. Preview and roll back from deployment B to prior successful deployment A.

    2. Reject a deployment ID belonging to another project.

    3. Reject failed, cancelled, pending, or artifact-less target deployments.

    4. Reject apply when the current deployment changed after preview.

    5. Reject an expired, altered, or wrong-user confirmation token.

    6. Confirm duplicate idempotency keys do not create duplicate deployments.

    7. Confirm concurrent deploy/rollback attempts are serialized or rejected deterministically.

    8. Confirm rollback failure preserves the previously current deployment.

    9. Confirm credentials, Context data, and integration state remain unchanged.

    10. Confirm list/get deployment responses identify rollback source and previous deployment.

    11. Confirm all responses and errors redact secret values and signed artifact locations.

    Non-goals

    • Rolling back individual Flow drafts or overwriting Flow editor graphs.

    • Rolling back credentials, secret values, OAuth authorizations, or API keys.

    • Reverting vector/Memory Context contents or external system data.

    • Executing Graph MCP Flows as part of rollback.

    • Automatically selecting a rollback target without an explicit deployment ID.