Caio Lins Home

My Timesheet Is Now a Conversation

Oct 2026 4 min read

Month-End

Every month-end, I generated a CSV with my usual hours, 10:00 to 19:00, then opened my calendar to remember which days I had taken off. I deleted those days from the CSV, manually requested the leave in Jobcan, and ran calendar2jobcan on the tidied-up file.

I used my fork of calendar2jobcan.

I also started a Jobcan extension for Raycast, which I never finished and have since archived. It had recordings of Jobcan’s login flow and endpoints.

One evening, I sat down with Claude and those two old projects. The result was jobcan-agent, an unofficial, open-source tool for working with Jobcan 勤怠管理 from an AI agent. I used it for real the next day.

One Evening With Claude

We started by reading the old code. It took an evening of back-and-forth with Claude.

Plain HTTP was enough to talk to Jobcan. We did not need browser automation. We wrote the pure logic and tests against a fake of Jobcan’s pages first, then touched the real service in read-only mode. Writes came last.

The tool is an MCP server, so Claude—or another agent that speaks MCP—can use it to work with Jobcan. Skills combine it with Slack and Google Calendar to announce leave and add out-of-office events.

The Next Day

Between other work, I used it from a chat window to:

  • Backfill a month of attendance: 15 days, 30 clock records.
  • Find three days off I had announced but never filed, by comparing my chat posts and calendar with Jobcan.
  • Replace a half day, recorded as four hours of hourly leave, with a full day.
  • File a new day off, post it to the team’s time-off channel following its rules, and create an out-of-office block on my calendar.

I previewed and confirmed every write first.

What Broke

Jobcan’s hour dropdown starts at 03:00. Its value 7 is displayed as 10. My first hourly leave request landed three hours late because we treated the value like the hour. The fix was to encode hours through the dropdown’s own labels.

Withdrawing a leave request is a plain link, using GET. “Only send GET requests” does not mean “read-only.” The client now has a fixed list of pages it may touch, in any mode.

After one withdrawal, Jobcan redirected to a page the client did not know. The client treated that as a failure and never filed the replacement request. For about a minute, that day had no leave at all. Now it leaves an unknown redirect after a write alone and checks the result from the list.

Manual clock records wait for approval, and Jobcan hides their times on the timesheet until then. A second run would have recorded the whole month twice. Days marked as pending are now skipped.

Google Calendar refuses descriptions on out-of-office events. The Jobcan request ID goes in the event title instead.

Each of these bugs became a test before we fixed it. By the end, there were 427 unit tests against the fake pages, plus a read-only verify command to check the real service.

Local Settings

Every company configures Jobcan differently. My usual hours, how leave is announced, and who gets mentioned live in a preset file on my machine. Nothing about my company is in the repository.

Every write stays a dry run until I confirm the plan it shows. Credentials stay in the OS keychain and never pass through the chat or the model.

If the leave form requires a reason and I do not give one, the tool reuses the reason from my last request and tells me in the preview.

Still Early

So far, I have tested it on one company’s Jobcan, in the session that built it.

The README lists what was tested and what was not, in English, Japanese, and Portuguese. Still untested: setup by someone who is not an engineer, a fresh session invoking the skills by name, other companies’ configurations, and single sign-on.

The next thing I want to build is a setup flow that asks about your workflow and writes the preset for you.

jobcan-agent is unofficial and is not affiliated with DONUTS, Jobcan’s vendor. The README also tells people to ask their Jobcan administrator before using it: the terms are between Jobcan and the subscribing company, and while they do not mention automation, they prohibit “analysing” the service.

The repository is open. Issues and pull requests are welcome, especially ones that explain how they were tested.