Shift Scheduler

Builds optimal 24/7 staff rosters with a real MILP solver: rest rules, skills, nights, fairness.

사용해야 할까요

품질 및 안전성

A
설명 품질
100%
스키마 완전성
72%
이름 품질
100%
오염 위험
100%
권한 일치
100%
프로토콜 준수
100%

도구 정의와 프로토콜 준수에 대한 자동 분석을 기반으로 합니다.

컨텍스트 비용

~1,568토큰 (도구 정의)
~2.9 KB일반적인 응답 크기
중간 정도의 주의 영향 (128k 컨텍스트의 1.23%)

이는 서버의 도구가 모델의 컨텍스트에 로드될 때마다 소비되는 대략적인 토큰 수입니다. 수치가 높을수록 다른 작업에 사용할 수 있는 주의가 줄어듭니다.

설치

원클릭 설치

`claude_desktop_config.json` 파일에 다음을 추가하세요:

{
  "mcpServers": {
    "shift-scheduler": {
      "url": "https://staff-scheduling.kindoflost.com/mcp"
    }
  }
}

원격 엔드포인트

https://staff-scheduling.kindoflost.com/mcpstreamable-http

할 수 있는 일

도구 목록

도구 (4)

🟢 읽기 전용🟡 쓰기🔴 삭제⚪ 알 수 없음
🟢list_shift_examples

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.

입력 스키마

{
  "type": "object",
  "properties": {},
  "additionalProperties": false
}
🟢get_shift_example(name, lang)

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.

입력 스키마

{
  "type": "object",
  "properties": {
    "name": {
      "type": "string",
      "enum": [
        "hospital-ward",
        "three-shift-plant",
        "security-site",
        "fire-station",
        "support-desk"
      ]
    },
    "lang": {
      "type": "string",
      "enum": [
        "en",
        "es"
      ],
      "description": "es = Spanish shift and post names."
    }
  },
  "required": [
    "name"
  ],
  "additionalProperties": false
}
🟢build_shift_roster(example, days, shifts, demands, people, ...)

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. 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.

입력 스키마

{
  "type": "object",
  "properties": {
    "example": {
      "type": "string",
      "enum": [
        "hospital-ward",
        "three-shift-plant",
        "security-site",
        "fire-station",
        "support-desk"
      ],
      "description": "Solve this built-in example instead of passing the fields below."
    },
    "days": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "minItems": 1,
      "maxItems": 42,
      "description": "Day labels in order: ISO dates ('2026-10-05') or weekday names ('Mon'). Dates or weekdays enable weekend rules."
    },
    "shifts": {
      "type": "array",
      "minItems": 1,
      "maxItems": 12,
      "description": "Shift types. A shift may cross midnight (end < start).",
      "items": {
        "type": "object",
        "required": [
          "shift",
          "start",
          "end"
        ],
        "properties": {
          "shift": {
            "type": "string",
            "description": "Shift name, e.g. 'Day'."
          },
          "start": {
            "type": "string",
            "description": "HH:MM"
          },
          "end": {
            "type": "string",
            "description": "HH:MM"
          },
          "night": {
            "type": [
              "string",
              "boolean"
            ],
            "description": "'yes' = counts as a night shift. Omitted = decided from NightStartsAfter."
          }
        }
      }
    },
    "demands": {
      "type": "array",
      "maxItems": 12,
      "description": "Posts to fill (roles). Headcount per day/shift goes in grids.",
      "items": {
        "type": "object",
        "required": [
          "name"
        ],
        "properties": {
          "name": {
            "type": "string"
          },
          "penalty": {
            "type": "number",
            "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."
          },
          "concurrent": {
            "type": "boolean",
            "description": "true = the same person may cover this and another demand at once."
          }
        }
      }
    },
    "people": {
      "type": "array",
      "minItems": 1,
      "maxItems": 60,
      "items": {
        "type": "object",
        "required": [
          "name"
        ],
        "properties": {
          "name": {
            "type": "string"
          },
          "cost": {
            "type": "number",
            "description": "Cost per hour (default 1)."
          },
          "min_hd": {
            "type": "number",
            "description": "Min hours per worked day."
          },
          "max_hd": {
            "type": "number",
            "description": "Max hours per day (default 24)."
          },
          "min_dw": {
            "type": "number",
            "description": "Min days worked over the WHOLE roster."
          },
          "max_dw": {
            "type": "number",
            "description": "Max days worked over the WHOLE roster."
          },
          "min_hw": {
            "type": "number",
            "description": "Min hours over the WHOLE roster (soft)."
          },
          "max_hw": {
            "type": "number",
            "description": "Max hours over the WHOLE roster (hard). Not per week: for a 28-day roster at 40h/week use 160."
          }
        }
      }
    },
    "skills": {
      "type": "array",
      "description": "Who can cover which demand. Omitted = everyone can cover every demand.",
      "items": {
        "type": "object",
        "required": [
          "person",
          "demand"
        ],
        "properties": {
          "person": {
            "type": "string"
          },
          "demand": {
            "type": "string"
          },
          "rate": {
            "type": "number",
            "description": "Posts covered per person (default 1)."
          }
        }
      }
    },
    "grids": {
      "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).",
      "additionalProperties": {
        "type": "object"
      }
    },
    "parameters": {
      "type": "object",
      "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 120 here), GapPercent (2)."
    },
    "wait_seconds": {
      "type": "integer",
      "minimum": 0,
      "maximum": 45,
      "description": "How long to wait for the solve inside this call (default 25)."
    }
  }
}
🟢get_shift_roster_result(job_id, wait_seconds)

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.

입력 스키마

{
  "type": "object",
  "properties": {
    "job_id": {
      "type": "string"
    },
    "wait_seconds": {
      "type": "integer",
      "minimum": 0,
      "maximum": 45
    }
  },
  "required": [
    "job_id"
  ],
  "additionalProperties": false
}

커뮤니티

이 서버 평가하기

증거

최근 관측

검증됨버전이 기록되지 않음도구 4개