Schedule icon
Parallel icon
List icon
Export icon
Get icon
Script icon
If icon
Log icon
SlackIncomingWebhook icon
Set icon
Fail icon

Monitor MCP tool contract drift

Detect breaking MCP tool contract changes in Kestra flows and preserve an explicitly accepted baseline.

Categories
AICoreInfrastructure

Changes to an MCP tool's inputs, outputs, server assignment, or safety annotations can break the agents that call it even when the underlying flow remains valid. This blueprint compares the contracts of flows exposed through McpToolTrigger with an accepted Kestra KV snapshot, writes Markdown and JSON drift reports, and optionally sends a Slack digest or fails on breaking changes.

How it works

  1. collect_state reads the accepted KV baseline and inventories and exports flows in monitored_namespace in parallel. The YAML export preserves plugin-specific trigger fields omitted by the typed flows.List output.
  2. analyze_contracts cross-checks the inventories, selects enabled MCP tool triggers from enabled flows, and normalizes tool metadata, inputs, outputs, and safety annotations before comparing them with the accepted snapshot.
  3. The analyzer writes mcp-contract-report.json and mcp-contract-report.md, including severity counts, affected tool paths, and before/after values. report_drift logs a summary and the report locations.
  4. When notify_on_drift=true, alert_on_drift sends a Slack digest for unaccepted drift with counts, the first five changed tool paths, and the execution ID. Initial baselines, unchanged contracts, and accepted changes do not send alerts.
  5. persist_baseline stores the initial snapshot or replaces it when accept_current_contracts=true. Other runs preserve the accepted baseline. fail_breaking_gate then fails the execution if fail_on_breaking=true and breaking changes have not been accepted.
  6. periodic_contract_check provides a six-hour schedule, disabled by default. A concurrency limit of one queues overlapping runs of the monitor.

What you get

  • A persistent, explicitly accepted contract baseline for each monitored namespace.
  • Markdown and JSON reports that distinguish breaking changes from other drift.
  • Typed status, change counts, tool count, and report URIs for downstream flows.
  • Optional Slack alerts and a breaking-change gate for deployment pipelines.

Breaking drift includes removed or renamed tools, MCP server moves, incompatible input or output changes, and safety annotations becoming less restrictive. Description and title changes are reported without failing the gate. Schema changes are treated as breaking; the analyzer does not establish semantic compatibility for arbitrary JSON schemas.

Who it's for

  • Platform teams exposing Kestra flows as MCP tools to AI agents.
  • Flow owners reviewing interface changes before accepting a new contract.
  • Teams adding contract monitoring and deployment gates to their MCP workflows.

Why orchestrate this with Kestra

Kestra connects flow inventory, Python analysis, KV persistence, conditional alerts, and scheduling in one execution history. Reviewers can open the full reports from the same execution as a Slack alert, while downstream flows can consume typed outputs or use the breaking-change gate in a deployment pipeline. Baseline creation and reporting use the existing Kestra instance without an external API, LLM, database, or SaaS service.

Prerequisites

  • Kestra 2.0+ with plugin-kestra, the Python Scripts plugin, and the Slack Notifications plugin installed.
  • A worker able to run python:3.13-slim and install the kestra and PyYAML packages.
  • Same-instance SDK authentication configured when the Kestra API requires it. Flow inventory uses the instance's configured SDK defaults.
  • Read access to the monitored namespace and access to the monitor flow's KV namespace.

Secrets

  • SLACK_WEBHOOK_URL: Slack incoming webhook used when notify_on_drift=true. Store it as a Kestra secret and reference it with {{ secret('SLACK_WEBHOOK_URL') }}. No Blueprint secret or webhook is needed when alerts are disabled.

Quick start

  1. Add this flow to Kestra and set monitored_namespace to the namespace containing your McpToolTrigger flows. The monitor may reside elsewhere.
  2. Execute once to create the baseline. A namespace with no MCP tools creates an empty baseline.
  3. Change an MCP tool contract and execute again. Open the Markdown and JSON reports in the execution outputs to review the drift.
  4. If the change is intentional, rerun with accept_current_contracts=true. The execution reports the diff and then replaces the accepted baseline.
  5. For Slack alerts, configure SLACK_WEBHOOK_URL and run with notify_on_drift=true. For a deployment gate, set fail_on_breaking=true.
  6. Set the input defaults or add inputs overrides on periodic_contract_check for the namespace and options you want scheduled runs to use, then enable the trigger. Manual execution inputs do not configure future scheduled runs.

How to extend

  • Send the JSON report to object storage or a warehouse for historical analysis.
  • Use changed, breakingChanges, and status in a parent flow to open a review ticket or gate deployment of MCP-enabled flows.
  • Add another notification plugin after report_drift, using the same unaccepted-drift condition as the Slack branch.
  • Monitor additional namespaces with separate monitor flows so their KV baselines and execution queues can be managed independently.

Inputs

  • monitored_namespace: STRING, default company.team; namespace to inventory.
  • accept_current_contracts: BOOL, default false; explicitly replace the baseline.
  • fail_on_breaking: BOOL, default false; fail on unaccepted breaking changes.
  • notify_on_drift: BOOL, default false; send Slack alerts for unaccepted drift.

Outputs

  • status: BASELINE_INITIALIZED, NO_DRIFT, DRIFT_DETECTED, or DRIFT_ACCEPTED.
  • changed: whether the current contracts differ from the accepted baseline.
  • breakingChanges, totalChanges, and toolCount: counts for downstream logic.
  • jsonReport and markdownReport: internal-storage URIs of the full reports, also available as {{ outputs.analyze_contracts.outputFiles['mcp-contract-report.json'] }} and {{ outputs.analyze_contracts.outputFiles['mcp-contract-report.md'] }}.

Links

See How

New to Kestra?

Use blueprints to kickstart your first workflows.