Endpoints: 28,729MCP servers: 18,413Payout addresses: 2,071Paid calls: 1,537Letters: 14Defects: 1,323counted 4 min ago
teppi

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 yourselfcurl -s https://api.teppi.xyz/v1/evidence/sha256:69b2a92f2fd98e211eae0546b22b704d653d88020fe414354418e62995aec938 | sha256sum