Skip to content

Add MCP blueprint management tools#6

Draft
hookdump wants to merge 12 commits into
mainfrom
xdev-2316-crud-for-blueprints
Draft

Add MCP blueprint management tools#6
hookdump wants to merge 12 commits into
mainfrom
xdev-2316-crud-for-blueprints

Conversation

@hookdump
Copy link
Copy Markdown

@hookdump hookdump commented May 20, 2026

Summary

Adds a full read + granular-write tool surface to the @churnkey/mcp server so agents can inspect and edit cancel-flow blueprints and segments through a Data API key, with contracts that mirror the dashboard. Every write is granular (the agent never resends the whole nested steps array), draft edits are kept separate from live-impacting actions, and the API audit-logs every configuration change.

Backed by companion API PR churnkey/churnkey-api#836.

Tools

Read

  • list_blueprints — current flow inventory: the default org flow plus every non-deleted segment flow, each with status (active / setup_pending / inactive), published, hasUnpublishedChanges, editableBlueprintId / publishedBlueprintId, and compact draft / publishedBlueprint metadata.
  • get_blueprint — the full blueprint incl. the steps array (each step/offer/survey-choice carries its guid for targeted edits).
  • list_segments — segment metadata in priority order: priority index, enabled, and the audience filter rules.

Blueprint draft edits — granular, draft-only

  • update_blueprint_draft — top-level fields (name, brandImage, primaryColor, translatedLanguages).
  • update_blueprint_step — one step's copy + behavioral config (header/description/enabled, offer copy, survey randomize/followupRequired/minLength, freeform/confirm config, survey-choice value/followupQuestion) by stepGuid or stepIndex.
  • update_blueprint_offer — an offer's type + functional config (discount / pause / trial / redirect / plan-change), addressable on an offer step, a survey choice, or a structured follow-up option.
  • edit_survey_structure — add/remove/reorder survey choices and configure a choice's follow-up (freeform / structured / freeform-structured / none).
  • add_blueprint_step / remove_blueprint_step — add a step at a canonical place (the server builds the base step) or remove one by stepGuid.

Publish & segments — live config, confirm-gated

  • publish_blueprint (confirm: "publish")
  • reorder_segments (confirm: "reorder_segments")
  • set_segment_enabled (confirm: "set_segment_enabled")
  • update_segment_filter (confirm: "update_segment_filter", whole-array replace)

Design principles

  • Granular, not full-payload. Each edit sends only the targeted fields, so the agent never reconstructs the full steps array (with translations). Offer config, survey structure, and step add/remove each have their own validated path.
  • Draft vs. live. Blueprint edits mutate the unlocked working copy only; publish_blueprint is the single live gate and the only blueprint action that requires a confirm. Segment edits act on live config directly, so each requires its own confirm literal. Destructive draft ops carry destructiveHint.
  • Contracts mirror the dashboard. Response shapes and field names match what the web app uses (see below).

Contract alignment with the web app

Beyond the tools, this branch tightened the contracts against the dashboard and surfaced real errors:

  • Server error messages now reach the agent. The Data API returns error bodies as plain text; the client previously read only a JSON message field and discarded them, so every validation/authorization failure showed as a generic Churnkey API error <status>. The client now relays the server message verbatim, with clearer 403/404 fallbacks.
  • list_blueprints always includes the default org flow and every non-deleted segment (segments without a resolvable blueprint were previously dropped), and gained hasUnpublishedChanges. status is documented as a coarse subset of the dashboard badges — the "Unpublished Changes" badge is status: "active" + hasUnpublishedChanges: true.
  • list_segments now returns audience filter rules and a 0-based priority (replacing a vestigial, never-written order field), includes disabled segments, and drops a duplicate _id in favor of id.
  • brandImage validation now mirrors the server (path ends in .png/.jpg/.jpeg/.gif/.webp, or hosted on images.churnkey.co).
  • Docs: scoped the live/test mode note (mode applies to session analytics + DSR; blueprint config is shared and recoveries aren't mode-partitioned) and documented dsr_delete's deleted / reasonForRejection outcome.

API dependency

Depends on companion API PR: https://github.com/churnkey/churnkey-api/pull/836

Linear

Related PRs

Tests

  • 27 Vitest unit tests: tool routing + body shape for every tool; draft/step/offer/survey/segment schema validation (exactly-one selectors, confirm literals, brandImage rules, BETWEEN value length, unknown-key rejection); client error-message mapping (plain-text bodies, 401/403/404, JSON fallback); query-builder regressions.
  • Scriptable end-to-end smoke harness (scripts/smoke.mjs) that drives the built server against a local churnkey-api: asserts every tool registers, the new contract shapes, error surfacing, and an opt-in reversible write round-trip (--mutate) that writes a field, re-reads to confirm it persisted, then restores the original.
  • pnpm local-run for running the server against a local API.

Validation

  • pnpm --filter @churnkey/mcp test — 4 files / 27 tests passed.
  • pnpm --filter @churnkey/mcp typecheck / build / biome check — clean.
  • Live smoke against a local API (scripts/smoke.mjs --mutate): 17 checks passed, including the observed reversible write round-trip (survey.randomize true→false→true, with translationsInvalidated: false).
  • Pre-push hook ran full SDK turbo typecheck + turbo test.

hookdump and others added 12 commits May 20, 2026 17:24
The Data API returns error bodies as plain text, but the client only read
a JSON `message` field, so every validation/authorization failure showed as
a generic "Churnkey API error <status>". Relay the server message verbatim
and add clearer 403/404 fallbacks.

Contract/doc alignment with the dashboard:
- list_blueprints: document the new hasUnpublishedChanges flag and that
  status is a coarse subset of the dashboard badges (not a 1:1 mirror)
- get_blueprint: document the step/offer/survey-choice guid response shape
- list_segments: document audience filter rules, priority, enabled, and
  that A/B variant segments appear as separate entries
- update_blueprint_draft: brandImage validation now mirrors the server
  (path ends in png/jpg/jpeg/gif/webp, or images.churnkey.co); reject
  empty-string step/choice guids instead of silently treating as absent
- dsr_delete: document the deleted/reasonForRejection outcome
- README: scope the live/test mode note (sessions + DSR only; config is
  shared and recoveries are not mode-partitioned); drop the phantom
  invoiceMonth breakdown from the changelog

Tests: add client error-handling cases and brandImage validation cases;
add scripts/smoke.mjs for end-to-end checks against a local churnkey-api.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
New tools so an agent can edit a flow without resending the whole steps array:

- update_blueprint_offer: change an offer's type + functional config
  (discount/pause/trial/redirect/plan-change), addressable on an offer step,
  a survey choice, or a structured follow-up option via guids.
- edit_survey_structure: add/remove/reorder survey choices and configure a
  choice's follow-up (freeform / structured / freeform-structured / none).
- add_blueprint_step / remove_blueprint_step: add a step at a canonical place
  (server builds the base step) or remove one by stepGuid.
- update_blueprint_step gained survey behavior (randomize, followupRequired,
  minLength) and freeform/confirm config.
- set_segment_enabled and update_segment_filter for segment config.

Draft blueprint edits are draft-only and not confirm-gated (publish is the
live gate; destructive ones carry destructiveHint). Segment edits act on live
config so they require a confirm literal. Adds routing/validation tests and an
observed reversible write round-trip to scripts/smoke.mjs.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant