Skip to content

feat(mcp): add set_deployment_schedule_active tool - #9

Merged
rdahis merged 2 commits into
mainfrom
feat/set-deployment-schedule-active
Aug 25, 2026
Merged

feat(mcp): add set_deployment_schedule_active tool#9
rdahis merged 2 commits into
mainfrom
feat/set-deployment-schedule-active

Conversation

@rdahis

@rdahis rdahis commented Aug 19, 2026

Copy link
Copy Markdown
Member

What

Adds set_deployment_schedule_active(flow_name, active, env="prod") — arm or disarm a pipeline's schedule from the MCP.

Merging a pipeline PR deploys the flow paused, and the backend registers it with is_schedule_active=False. Arming was a manual tick in Django admin with no programmatic path, so the MCP could trigger a run (run_deployment) but never arm or disarm a schedule.

Why it wraps a backend endpoint instead of calling Prefect

Arming is three writes together — the stored flag, reactivated_at, and the Prefect unpause. sync-deployments re-enforces the stored is_schedule_active state and CI runs it on every merge to main, so a Prefect-only unpause would report success, look armed, and then silently re-pause at the next unrelated merge.

Reaching for the Prefect API here is the obvious wrong move, so the docstring says so explicitly.

This wraps POST /admin-tools/set-schedule-active/, added in basedosdados/backend#1060.

Notes

  • Setting the state a flow is already in returns action="no_change" without touching Prefect, so the tool doubles as a safe way to read current state.
  • env selects the backend (prod default, plus staging/dev/local) via the existing URLS map.
  • Network and unknown-env errors are returned as {"error": ...} dicts rather than raised, matching run_deployment.
  • Depends on feat(admin_data_tools): add set-schedule-active endpoint backend#1060. Against a backend without the endpoint the call returns an HTTP 404 error dict, so merge that one first.

Verified: module imports, tool registers (43 tools), signature and the pure unknown-env branch behave. The network path needs the backend endpoint deployed.

🤖 Generated with Claude Code

Merging a pipeline PR deploys the flow paused, and the backend registers it with
`is_schedule_active=False`. Arming it was a manual tick in Django admin with no
programmatic path, so the MCP could trigger a run (`run_deployment`) but never
arm or disarm a schedule.

Wraps the new `POST /admin-tools/set-schedule-active/` backend endpoint, which
updates the stored flag, stamps `reactivated_at`, and unpauses the deployment in
Prefect 3 — the same three writes the admin form performs.

Deliberately not implemented against the Prefect API directly. `sync-deployments`
re-enforces the stored `is_schedule_active` state and CI runs it on every merge
to main, so a Prefect-only unpause would report success, look armed, and then
silently re-pause at the next unrelated merge. The docstring says so, because
reaching for the Prefect API here is the obvious wrong move.

Setting the state a flow is already in returns `action="no_change"` without
touching Prefect, so the tool doubles as a safe way to read current state.

Requires the backend endpoint to be deployed; against a backend without it the
call returns an HTTP 404 error dict.
@rdahis rdahis self-assigned this Aug 19, 2026
`set_deployment_schedule_active` mapped every HTTP 404 to "unknown flow". Two
very different things return 404:

- Django's HTML 404, when `/admin-tools/set-schedule-active/` is not deployed —
  which is every backend until basedosdados/backend#1060 merges.
- The view's own JSON 404, when there is genuinely no DisabledFlowSchedule row.

Conflating them is actively misleading. A missing *route* reported as a missing
*row* reads as "this armed pipeline has no stored state and the next backend
sync will re-pause it" — an alarming conclusion drawn from a backend that simply
has not shipped the endpoint yet. I made exactly that misdiagnosis against a
live pipeline.

Now parses the body first and reports the undeployed case explicitly, noting
that it says nothing about whether the flow is armed — `paused` on the Prefect
deployment is the answer to that.

Also corrects the `flow_name` docstring. It is Prefect's bare deployment name
(`au_rba_statistical_tables_flow`); `SyncDeploymentsView` stores `dep["name"]`
straight from `/deployments/filter`, not the '<flow>/<deployment>' display form
the deploy logs show. The old wording would have sent callers to a 404.
@rdahis
rdahis merged commit 258dee9 into main Aug 25, 2026
Winzen added a commit that referenced this pull request Aug 25, 2026
Essa tool (#9) foi adicionada só no server.py monolítico da raiz — o
pacote novo em src/databasis_mcp/ ficou com 43 tools em vez de 44.
Portada 1:1 pra tools/prefect.py, importando URLS de _app (já existia
lá, idêntico ao da raiz).
Winzen added a commit that referenced this pull request Aug 25, 2026
#10)

* chore: finaliza a migração pra uv

pyproject.toml e uv.lock commitados (antes existiam só localmente,
não versionados). requirements.txt removido — ficava redundante e
desatualizado (google-cloud-bigquery>=3.0 vs >=3.41.0 no pyproject).

README.md: seção de instalação trocada de pip pra uv sync.

Limpeza de lixo acumulado de comandos anteriores: =2.0 (redirect mal
interpretado de um uv add sem aspas), main.py (scaffold padrão do uv
init, nunca usado), .venv-pip/ (venv antigo criado com python -m venv,
substituído pelo .venv do uv).

Validado: uv sync roda limpo, src/databasis_mcp importa e registra as
43 tools, server.py da raiz continua com sintaxe válida.

* fix: porta set_deployment_schedule_active pro pacote src/databasis_mcp

Essa tool (#9) foi adicionada só no server.py monolítico da raiz — o
pacote novo em src/databasis_mcp/ ficou com 43 tools em vez de 44.
Portada 1:1 pra tools/prefect.py, importando URLS de _app (já existia
lá, idêntico ao da raiz).

* feat: porta run_deployment e o helper _prefect_get pro pacote novo

A tool run_deployment (server.py, commit 22ef7a4) foi adicionada direto
em main antes da branch do refactor ser cortada, então nunca chegou no
pacote novo — o merge do PR #8 uniu as duas histórias sem conflito
textual, mas deixou essa lacuna. Copiada 1:1 pro
src/databasis_mcp/tools/prefect.py, junto com _prefect_get (helper que
ela usa e que também faltava no pacote).
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