Most “AI staff scheduling” tools I tried do one of two things: they let a chatbot write a schedule that looks right and quietly breaks your rules, or they put a little AI button on top of a calendar you still fill in by hand. I wanted the opposite: you describe your team to an AI assistant in plain words, and a real optimization solver builds the roster, with the rules treated as rules. So I built a free connector for Claude that does exactly that. It’s called Shift Scheduler, there’s no signup, and it has been in the Claude directory since late September.
This post covers how to use it, how I built it (and what I broke along the way), what the first month of use looks like, and what I’m changing next.
Why a chatbot alone can’t do staff scheduling
Ask any AI chat for “a 4-week nurse schedule, 12 nurses, 12-hour shifts, nobody works a day shift right after a night” and you’ll get a nice table. Then count. Somebody works six nights in a row, Tuesday has two nurses when you needed three, and the rest rule is broken twice. The model isn’t lying; it’s writing text that looks like a schedule. It never actually checks the rules, it just makes something that reads well.
A solver works the other way around. It turns every rule into a constraint (minimum rest between shifts, max days in a row, max nights in a row, who has which skill, who’s off when) and searches for the roster that covers the most posts at the lowest cost without breaking any of them. My engine is a mixed-integer program solved with HiGHS, an open-source solver. When it says a roster is optimal, it checked. When there aren’t enough people to cover everything, it still gives you a roster and names the posts it couldn’t fill, instead of pretending.
The connector is the bridge: Claude reads your description and turns it into the input; my server does the math; Claude explains the result back to you.
How to use AI staff scheduling in Claude
You need a Claude account. Open the Shift Scheduler page in the Claude directory and connect it. Nothing to log into on my side. Then ask in your own words:
“Build a 4-week schedule for 14 nurses on a ward that needs 3 on days and 2 on nights, 12-hour shifts, at least 11 hours rest, no more than 3 nights in a row. Maria and Jo can’t work weekends.”
“I run a security company. One post, staffed 24/7 with 8-hour shifts. I have 6 guards. Make me a fair rotation for next month.”
“Armá un cronograma de turnos rotativos 24/7 para 10 operarios, tres turnos de 8 horas.”
If you’re not sure how to describe it, say “show me the shift scheduler examples first”. There are ready examples for a hospital ward, a 3-shift plant, a security post, a fire station and a service desk, and Claude can start from the closest one and change it.
Limits per run: 60 people, 42 days, 12 shift types, 12 kinds of posts. What it doesn’t do (on purpose): shift swaps, time clocks, payroll. It builds the roster; you run your team.
No AI? The same solver runs on the 24/7 shift schedule maker page, with templates for nurse scheduling, guards, firefighters and more.
How I built it, and the three things I broke
This was my first MCP server, and I built it with Claude: I made the calls, Claude wrote most of the code, I tested it against the real thing. The engine underneath already existed (the general scheduler post tells that story), so the work was the plumbing. The main decisions:
No login, rate-limited instead. Same idea as everything else I make: if you have to sign up, I’ve already lost you. The server runs one solve at a time, holds a short queue, and caps how many solves one address can start in ten minutes.
Friendly defaults. If you don’t list skills, everybody can cover everything. If you name a post but don’t say how many people per shift, it assumes one. Small things, but an assistant fills in what it’s given, and my web tool’s defaults were written for people with a spreadsheet in front of them.
Jobs for long solves. A 28-day ward takes 15 to 30 seconds. The tool waits about 25 seconds inside the call; if the roster isn’t ready, Claude gets a job number and asks again.
And now the humbling part (there’s always one). Three things went wrong in the first two days:
First, a burst of 12 solves in a row pushed my little 512 MB server over its memory limit and Render restarted it, taking the website down with it for a moment. Now every solve runs in its own separate process with a memory watchdog, so a big roster can only kill itself, not the whole server.
Second, the solver happily put more people on a shift than needed, because extra coverage wasn’t costing it anything. Technically “optimal”, practically silly. I capped coverage at demand and added an option that spreads the night shifts more evenly between people. (I wrote about a cousin of this bug in my solver said optimal and two shifts were empty.)
Third, my own robots.txt was blocking Google from the connector’s help page, because “Disallow: /mcp” also matches “/mcp-server”. One line fixed it. It took me a while to notice.
The connector went into the official MCP Registry and the Claude directory on September 26, and Claude approved it as a Community connector the next day.
How it’s going: one month of the log
Every call writes one row to my usage sheet: size, time, result. No names. From September 26 to October 24:

41 rosters, from 5 people up to about 30, the biggest with 220 shift assignments. Every one came back usable. But I have to be straight about who ran them: when Claude calls my server, the request comes from Anthropic’s computers, so the log can’t tell me who anyone is. Most of the launch-week runs were me testing. After that I left it alone, so the 11 rosters on October 11, 18 and 24 were real people: a batch of five rosters of about 30 people, then four smaller ones, then two more. Small numbers, but real ones. What I can’t see is what those people were trying to do, and that’s what I’m fixing below.
The other 42 calls were not people. 35 were automated checkers that call the tool with no data at all, every day, just to see if it answers; they were being counted as “bad input”, which made the tool look broken in my own sheet. Seven were real inputs the server rejected, all in the first week, mostly while I was still testing what an assistant sends.
Honest summary: the connector works, nobody has complained, and the audience is small. Nobody publishes how many people use a Claude connector, so this log is all I’ve got.
What’s next
From the log, straight to the to-do list:
The empty checker calls now get a friendly answer and are logged as test calls, so the real mistakes stand out. If an assistant sends the team and the shifts but forgets the dates, the server assumes the next 7 days and says so, instead of refusing. And I’m adding an optional one-sentence “goal” field (“a 4-week rota for 12 nurses”) and a “check request” tool that tells the assistant up front whether something fits, like shift swaps or more than 60 people. Every “no” gets logged. That’s how I’ll find out what people actually wanted, instead of guessing.
I also turned the same solver into a Google Sheets add-on, for teams that live in a spreadsheet instead of a chat. That one gets its own post.
If you schedule a team, try the connector and tell me where it got your rules wrong. That’s the most useful thing anyone can send me right now.
Things that I use, like, and am affiliated with:
Mint Mobile offers great cell phone service for $15 flat, get $15 off using the link. Get discounted phones with service activation and no contract.
I never spend money before I check Mr Rebates or Rakuten to get cashbacks, rebates, discounts, coupons or cheaper gift cards.
