Server definition
- Hash
- sha256:69b2a92f2fd98e211eae0546b22b704d653d88020fe414354418e62995aec938
- What it is
- What a remote MCP server returned when asked what it offers: 4 tools
The blob, as servednamed by its sha256
{
"instructions": "Builds optimized 24/7 staff rosters (nurses, guards, firefighters, plant crews, help desks...) with a real mixed-integer solver, not a heuristic. Hard rules (availability, skills, minimum rest between shifts, max consecutive days/nights, no day shift right after a night, max hours) are never broken; unfilled posts are allowed but penalised and reported. Typical flow: list_shift_examples -> get_shift_example to see the input shape -> edit it to the user's situation -> build_shift_roster -> if it returns status 'running', call get_shift_roster_result with the job_id. Limits: 60 people, 42 days, 12 shifts, 12 demand types. Free, no sign-up; web version at https://staff-scheduling.kindoflost.com/shift-schedule",
"tools": [
{
"description": "Solve a staff rostering problem to optimality with a MILP solver and return who works which shift each day, coverage, unfilled posts, hours per person and warnings. Solves take 5-60 s. Pass either `example` (to solve a built-in example as-is) or the roster input fields. If the result has status 'running', call get_shift_roster_result with its job_id. If it has status 'too_large', shorten the horizon or reduce people/shift types and retry. Roster input. Minimal example: {\"days\": [\"2026-10-05\", \"2026-10-06\"], \"shifts\": [{\"shift\": \"Day\", \"start\": \"07:00\", \"end\": \"19:00\"}, {\"shift\": \"Night\", \"start\": \"19:00\", \"end\": \"07:00\", \"night\": \"yes\"}], \"demands\": [{\"name\": \"RN\", \"penalty\": 500}], \"people\": [{\"name\": \"Ana\", \"cost\": 40, \"max_hw\": 48}, ...], \"grids\": {\"RN\": {\"2026-10-05|Day\": 2, \"2026-10-05|Night\": 1}}, \"parameters\": {\"MinRestHours\": 11}}. Call get_shift_example for complete, realistic inputs.",
"inputSchema": {
"properties": {
"days": {
"description": "Day labels in order: ISO dates ('2026-10-05') or weekday names ('Mon'). Dates or weekdays enable weekend rules.",
"items": {
"type": "string"
},
"maxItems": 42,
"minItems": 1,
"type": "array"
},
"demands": {
"description": "Posts to fill (roles). Headcount per day/shift goes in grids.",
"items": {
"properties": {
"concurrent": {
"description": "true = the same person may cover this and another demand at once.",
"type": "boolean"
},
"name": {
"type": "string"
},
"penalty": {
"description": "Cost of leaving ONE post unfilled for one shift. Must be well above one person's pay for a shift or the solver will prefer gaps. Omitted = 10 x the highest hourly cost x the longest shift.",
"type": "number"
}
},
"required": [
"name"
],
"type": "object"
},
"maxItems": 12,
"type": "array"
},
"example": {
"description": "Solve this built-in example instead of passing the fields below.",
"enum": [
"hospital-ward",
"three-shift-plant",
"security-site",
"fire-station",
"support-desk"
],
"type": "string"
},
"grids": {
"additionalProperties": {
"type": "object"
},
"description": "Optional per-day/shift cells, keyed by a demand name or a person name, each an object keyed 'DAY|SHIFT'. Demand grid value = headcount required (demand with no grid = 1 on every shift). Person grid value: 'a' or 1 = available, 'f' = must work, 0 or missing = UNAVAILABLE (person with no grid = available everywhere).",
"type": "object"
},
"parameters": {
"description": "Optional rules. MinRestHours (11), MaxConsecutiveDays (6), MaxConsecutiveNights (4), ForbidDayAfterNight ('yes'), NightStartsAfter ('18:00'), MinBlockDays (1), WeekendFairnessPenalty (0), EquityPenalty (0) = even out total hours, NightEquityPenalty (0) = even out total nights (try 20), NightDifferential (1.0), WeekendDifferential (1.0), TimeLimitSeconds (max 60 here), GapPercent (2).",
"type": "object"
},
"people": {
"items": {
"properties": {
"cost": {
"description": "Cost per hour (default 1).",
"type": "number"
},
"max_dw": {
"description": "Max days worked over the WHOLE roster.",
"type": "number"
},
"max_hd": {
"description": "Max hours per day (default 24).",
"type": "number"
},
"max_hw": {
"description": "Max hours over the WHOLE roster (hard). Not per week: for a 28-day roster at 40h/week use 160.",
"type": "number"
},
"min_dw": {
"description": "Min days worked over the WHOLE roster.",
"type": "number"
},
"min_hd": {
"description": "Min hours per worked day.",
"type": "number"
},
"min_hw": {
"description": "Min hours over the WHOLE roster (soft).",
"type": "number"
},
"name": {
"type": "string"
}
},
"required": [
"name"
],
"type": "object"
},
"maxItems": 60,
"minItems": 1,
"type": "array"
},
"shifts": {
"description": "Shift types. A shift may cross midnight (end < start).",
"items": {
"properties": {
"end": {
"description": "HH:MM",
"type": "string"
},
"night": {
"description": "'yes' = counts as a night shift. Omitted = decided from NightStartsAfter.",
"type": [
"string",
"boolean"
]
},
"shift": {
"description": "Shift name, e.g. 'Day'.",
"type": "string"
},
"start": {
"description": "HH:MM",
"type": "string"
}
},
"required": [
"shift",
"start",
"end"
],
"type": "object"
},
"maxItems": 12,
"minItems": 1,
"type": "array"
},
"skills": {
"description": "Who can cover which demand. Omitted = everyone can cover every demand.",
"items": {
"properties": {
"demand": {
"type": "string"
},
"person": {
"type": "string"
},
"rate": {
"description": "Posts covered per person (default 1).",
"type": "number"
}
},
"required": [
"person",
"demand"
],
"type": "object"
},
"type": "array"
},
"wait_seconds": {
"description": "How long to wait for the solve inside this call (default 25).",
"maximum": 45,
"minimum": 0,
"type": "integer"
}
},
"type": "object"
},
"name": "build_shift_roster",
"outputSchema": null
},
{
"description": "Return the full input JSON of one example, in exactly the shape build_shift_roster accepts. Edit it (names, days, headcounts, rules) to match the user's situation.",
"inputSchema": {
"additionalProperties": false,
"properties": {
"lang": {
"description": "es = Spanish shift and post names.",
"enum": [
"en",
"es"
],
"type": "string"
},
"name": {
"enum": [
"hospital-ward",
"three-shift-plant",
"security-site",
"fire-station",
"support-desk"
],
"type": "string"
}
},
"required": [
"name"
],
"type": "object"
},
"name": "get_shift_example",
"outputSchema": null
},
{
"description": "Fetch the result of a build_shift_roster job that returned status 'running'. Waits up to wait_seconds; call again while status is 'running'. Jobs expire 15 minutes after they finish.",
"inputSchema": {
"additionalProperties": false,
"properties": {
"job_id": {
"type": "string"
},
"wait_seconds": {
"maximum": 45,
"minimum": 0,
"type": "integer"
}
},
"required": [
"job_id"
],
"type": "object"
},
"name": "get_shift_roster_result",
"outputSchema": null
},
{
"description": "List the built-in example rostering problems (hospital ward, 3-shift plant, security post, fire station, 24/7 help desk). Use one as a starting point for the user's own roster.",
"inputSchema": {
"additionalProperties": false,
"properties": {},
"type": "object"
},
"name": "list_shift_examples",
"outputSchema": null
}
]
}Verify it yourself
curl -s https://api.teppi.xyz/v1/evidence/sha256:69b2a92f2fd98e211eae0546b22b704d653d88020fe414354418e62995aec938 | sha256sum