Skip to content

fix: MCP update_agent_schedule may accidentally re-enable disabled schedules #741

Description

@vybe

Summary

Two bugs in MCP schedule management that can silently corrupt schedule state when AI agents call `update_agent_schedule`:

  1. Accidental re-enable: The `enabled` field description in `update_agent_schedule` was too terse. An AI model updating other fields (e.g. cron expression) might include `enabled: true` to be "thorough" or copy it from a `list_agent_schedules` response — immediately re-enabling a schedule the user had intentionally disabled.

  2. Silent no-op on retry config: `ScheduleUpdateRequest` (Pydantic model in `routers/schedules.py`) was missing `max_retries` and `retry_delay_seconds`. When an MCP call included these fields, Pydantic's `exclude_unset=True` silently dropped them — the DB layer's `allowed_fields` list included them, but they could never reach it.

Context

Discovered during investigation of schedule CRUD path: MCP tool → Pydantic model → `model_dump(exclude_unset=True)` → `db.update_schedule()` → SQL UPDATE.

Acceptance Criteria

  • `update_agent_schedule` `enabled` field description explicitly warns AI models to omit the field unless intentionally changing enabled state
  • `ScheduleUpdateRequest` includes `max_retries: Optional[int] = None` and `retry_delay_seconds: Optional[int] = None` so retry config changes are no longer silently dropped
  • No regression: toggling via `toggle_agent_schedule` and explicit enable/disable still work correctly
  • Existing tests pass

Technical Notes

Files changed:

  • `src/mcp-server/src/tools/schedules.ts` — expand `enabled` description in `updateAgentSchedule` Zod schema
  • `src/backend/routers/schedules.py` — add `max_retries` and `retry_delay_seconds` to `ScheduleUpdateRequest`

The bug path for (1): disabled schedule → MCP update call with `enabled: true` in payload → backend applies it → schedule re-enabled without user intent.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions