Roster Shifts
roster_shiftsAssign staff to shifts under availability, skills, hour caps and rest gaps. PREMIUM (license).
Typical input {"staff": [{"id": "ana", "skills": ["till"], "max_hours": 40, "unavailable": ["sat-am"]}, ...], "shifts": [{"id": "sat-am", "start": "2026-09-12T08:00", "end": "2026-09-12T14:00", "required": 2, "skill": "till"}, ...], "rules": {"min_rest_hours": 11, "max_consecutive_days": 6}} returns {"assignments": [{"shift": "sat-am", "staff": ["ana", "ben"]}], "unfilled": [{"shift": "sun-pm", "short": 1}], "hours": {"ana": 30.0}, "solver_status": "OPTIMAL"}. The objective fills as many required slots as possible, then spreads hours evenly, then honours preferences (staff.prefer / staff.avoid shift ids). Use for weekly rotas of up to 60 staff and 150 shifts. Not a determination of labour-law compliance: the rules are the ones you pass. Errors: on invalid, missing, or malformed input this tool never raises a protocol error — it returns {"error": ""} (for example {"error": "staff and shifts must be non-empty lists"}). Every call is read-only and idempotent, so after correcting the input it is always safe to retry.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| rules | No | {min_rest_hours (default 0), max_consecutive_days (default 7), max_shifts_per_day (default 1)}. | |
| staff | Yes | {id, skills[], max_hours, min_hours, unavailable[], prefer[], avoid[], max_shifts}. | |
| shifts | Yes | {id, start, end (ISO 8601 local), required, skill, weight}. | |
| time_limit_s | No | solver time budget in seconds (default 10, max 60). |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||