The shift-scheduling engine behind Shiftyasan
(mathematical optimization by a constraint-optimization engine), exposed as a public HTTP API and an
MCP server.
AI agents such as Claude and ChatGPT can build and optimize shift schedules conversationally.
The key is read from the environment, because putting it straight on the command line
leaves it in your shell history and in ps output. The export lands
in history too, so keep it in your shell profile or your usual secret manager.
Claude Desktop
Claude Desktop cannot connect to a remote MCP server directly yet, so bridge it with
mcp-remote. This route is the one that does need Node.js 20+
on your machine (claude_desktop_config.json):
Not supported yet. We will announce it here and in the
changelog when it lands.
Using the npm package (still supported)
You can still run the server locally from npm. It needs Node.js 20+ and you update it
yourself.
claude mcp add shiftyasan -e SHIFTYASAN_API_KEY=sk_live_... -- npx -y @shiftyasan/mcp-server
Then just ask something like: "Schedule 4 people across early, late and night shifts for the
first week of September. Give a day off after each night shift, and share night shifts fairly."
The agent calls validate_shift_input (free) and then solve_shift
and returns the schedule.
ChatGPT cannot spawn local MCP servers, so use the HTTP API directly through a
Custom GPT with Actions (our OpenAPI spec is designed to be Actions-compatible):
My GPTs → Create a GPT → Configure → Actions → Import from URL
with https://api.shiftyasan.com/v1/public/openapi.json
Authentication → API Key → Bearer → paste your sk_live_... token
You get four actions: validate_shift_input, solve_shift,
get_solve_job and get_usage. Add to Instructions:
"Always call validate_shift_input before solve_shift. If solve_shift returns 202 with a
job_id, poll get_solve_job every ~15 seconds until it completes."
Creating custom GPTs requires a paid ChatGPT plan. Your API key is stored inside the GPT —
do not share that GPT publicly.
Large problems (roughly 25+ employees) do not return synchronously: you get
202 with a job_id. Poll
GET https://api.shiftyasan.com/v1/public/solve/jobs/{job_id} every ~15 seconds
(typically done in 2–7 minutes).
The full request/response schema is served at
GET https://api.shiftyasan.com/v1/public/openapi.json (OpenAPI 3.1).
Errors follow RFC 7807 (problem+json) with field-level details, so AI agents can self-correct.
Supported constraints (public API, today)
Constraint
Where
Kind
Staffing demand per shift per day (min/max)
shifts[].staffing_demand
min hard / max soft
Staffing demand per duty (shift × day)
duties[].staffing_demand_by_shift
min hard / max soft
Assignable shifts per employee
employees[].assignable_shift_ids
hard
Skill levels (0 = cannot do the duty)
employees[].skill_levels
hard
Day-off / shift preferences
employees[].preferences
soft (strongly rewarded)
Fixed assignments
employees[].fixed_assignments
hard
Working days per month (min/max)
employees[].working_days_per_month
soft+hard
Working days per week
employees[].working_days_per_week
soft
Max consecutive working days Note: omitting this is not "unlimited" — the default is a hard cap of 6 (soft 5)
constraints.max_consecutive_working_days
soft+hard
Forbid/require shift transitions (e.g. rest after night shift)
constraints.shift_transitions
hard or soft
Keep employee pairs apart
constraints.employee_pairings (exclude)
hard
Fair distribution of burdensome shifts (up to 4 independent groups, count-balanced, weight tunable)
constraints.fairness_groups
soft (penalty_weight)
Manager headcount per shift per day
shifts[].manager_demand
min hard / max soft
Weekly working-hours cap (derived from shift times)
employees[].weekly_working_hours_limit
soft or hard
Skill support (pair beginners with seniors)
constraints.skill_support
soft or hard
Cross-shift headcount (time-band style demand, e.g. overnight coverage)
Per-shift assignment count bounds (e.g. at most 4 night shifts)
employees[].shift_count_limits
hard
Business holidays
schedule_period.holidays
hard
When no solution exists, the API diagnoses the cause automatically: it
re-solves quick probe variants with one hard constraint removed at a time and returns
diagnosis.causes[] (cause type, offending field, suggested relaxation), so your
agent can tell the user exactly which constraint to relax. Understaffing is not an error:
the solver returns a schedule with shortage markers, so you still get a usable roster in a
short-staffed week.
Recently added constraints
Multiple independent fairness groups (constraints.fairness_groups, up to 4 — e.g. balance nights and weekends separately) / per-employee shift-type count bounds (e.g. max 4 night shifts) / weekday availability (employees[].available_weekdays)
Pricing
The open beta is free. Each key comes with a free usage quota (units) consumed
per solve call. Email us when you run out. Post-beta pricing is in preparation and
beta users will be notified in advance.
Links
API key dashboard (log in / sign up / issue & disable keys / remaining quota)