woffu-manager
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@woffu-managerHow many holidays do I have left, and when do they expire?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
woffu-adapter-mcp
An MCP server for Woffu: clock in the days you have left, see what time off you have and when it expires, and tell how much of your team is actually around next sprint.
Ask your agent, in whatever words you use:
"Which days haven't I clocked in this month?" — then confirm, and it fills them.
"How many holidays do I have left, and when do they expire?"
"Book me the 14th of August off" — then confirm, and it files the request.
"Who is off in August?" / "How much of the team is around next sprint?"
"Is Maria away the week of the 20th?"
"When is the next public holiday?"
Nothing is written to your timesheet or filed on your behalf without you seeing it first.
Tools
Read-only unless it says otherwise.
Tool | What it answers |
| Workdays with no hours logged, each with the exact time ranges that would be sent. Plus |
| Writes. Clocks in the days you name. Every one is re-checked against Woffu first, and refused with a reason rather than a blanket "not pending". |
| What is left in each bucket and when it expires — soonest first, because whatever is left in a bucket is lost on that date. |
| Your requests: |
| Writes. Files a request for a leave type, validated against Woffu first. Whole-day types take a date range; hourly types take a day and a time span. |
| Writes. Changes a request's dates, times or comment. The leave type cannot change — cancel and file anew for that. |
| Writes. Withdraws a request; a pending one is deleted and its balance returned. |
| The public holidays ahead. One costs no days from any bucket, and one next to a weekend makes a long weekend. |
| How many days each teammate is around over a range, and how many they are off. For sizing a sprint before committing to it. |
Clocking in
clock_in_days needs an explicit list of dates — there is no "clock in everything",
so you always see what is about to be logged. ranges overrides the schedule when you
want specific hours ([{"in": "09:00", "out": "13:30"}, ...]); omit it and each day
uses the theoretical schedule Woffu itself proposes, which is nearly always what you
meant. A weekend, a public holiday, an absence, a day already logged or one Woffu has
locked is refused by name, so you can tell which of those it was.
Working a public holiday is possible in Woffu, but only by filing a "work on a holiday" request. That is not implemented, so holidays are simply refused.
Requesting time off
request_time_off files a request for a leave type by name — the same names
get_time_off_balance lists ("Vacaciones", "Horas Ajuste Calendario"...). Whole-day
types take from and an optional to; the day count is whatever Woffu charges after its
own weekends and holidays, so a Friday-to-Monday range costs two days, not four. Hourly
types take a single from with startTime and endTime instead.
Every request is checked against Woffu before anything is written: an overdrawn balance, a weekend or a public holiday is refused with a reason rather than filed. Types that need a supporting document, and half-day requests, are out of scope — file those in Woffu directly.
edit_time_off_request and cancel_time_off_request both take a requestId from
list_time_off_requests. Editing changes dates, times or the comment; the leave type is
fixed, so to change that you cancel and file a new one. Cancelling a pending request
deletes it and returns the balance it held.
Team availability
Per person: workingDays in the range (weekends and public holidays already out),
daysOff already approved, pendingDaysOff still awaiting approval, and
availableDays — working days minus approved time off. totals carries the whole
team's capacity in person-days. Least-available first, since those are the people who
constrain the sprint.
Pending absences are not subtracted from availableDays: they are the risk, not the
plan, so they are reported next to it. Woffu does not count them as absent either.
It reads your own team by default — no id, no name, nothing to configure. Name
another team to look at it instead, or a person to narrow the answer to one of them.
Related MCP server: afkbot-mcp
Install
Nothing to download. The server is published to npm, so npx fetches and runs it — the
package name is the whole prerequisite:
claude mcp add woffu \
-e WOFFU_HOST=yourcompany.woffu.com \
-e WOFFU_USERNAME=you@company.com \
-e WOFFU_PASSWORD='...' \
-- npx -y woffu-adapter-mcpnpx -y woffu-adapter-mcp always pulls the latest published version. Pin it if you would
rather it did not move under you: woffu-adapter-mcp@1.0.0 takes any published version.
Configuration
Variable | Required | Example | What it is |
| Yes |
| Your Woffu domain. Paste the whole URL if it is easier; only the host is kept. |
| Yes |
| Your Woffu login. |
| Yes |
| Used once, to request a token. Never stored. |
| No |
| Only to make |
| No |
| The office time zone, any IANA name. It decides which instant a 09:00 clock-in lands on. Defaults to |
The password is only used to request a token and is never stored. The token is cached,
in ~/.woffu-manager/token.json (mode 600), and Woffu issues it with a one-year lifetime
— so logging in happens once. Delete that file to force a new login.
GitHub Copilot, in VS Code
Put this in .vscode/mcp.json (or the user-level one, via MCP: Open User Configuration), then hit the Start action the file shows above the entry. Copilot
says servers, not mcpServers, and a local server has to declare "type": "stdio".
The password goes in as an input, so VS Code asks once, masks it and keeps it in the OS keychain — which means the file can be committed with the rest of the project without a password in it:
{
"inputs": [
{
"type": "promptString",
"id": "woffu-password",
"description": "Woffu password",
"password": true
}
],
"servers": {
"woffu": {
"type": "stdio",
"command": "npx",
"args": ["-y", "woffu-adapter-mcp"],
"env": {
"WOFFU_HOST": "yourcompany.woffu.com",
"WOFFU_USERNAME": "you@company.com",
"WOFFU_PASSWORD": "${input:woffu-password}"
}
}
}
}The tools show up under the 🛠️ icon in Copilot Chat, in Agent mode.
Any other MCP client
{
"mcpServers": {
"woffu": {
"command": "npx",
"args": ["-y", "woffu-adapter-mcp"],
"env": {
"WOFFU_HOST": "yourcompany.woffu.com",
"WOFFU_USERNAME": "you@company.com",
"WOFFU_PASSWORD": "..."
}
}
}
}Clone it only to work on it:
git clone git@github.com:alechagonzalo/woffu-adapter-mcp.git
cd woffu-adapter-mcp
npm install && npm testWhat counts as "pending"
Two layers, because neither is enough on its own:
From the month summary: weekends, holidays, events, absences (
absenceEvents/pendingAbsenceEvents: leave, adjustment days, sick leave), future days and days with hours already worked are all excluded.isUserEditableis the hard gate — Woffu refuses writes wherever it isfalse.From the day's slots: a day that was clocked in but not yet confirmed still shows zero hours in the summary. What gives it away is a real
signIdon its slots. Without this second check the same day would be clocked in twice.
Today is included, even mid-workday: its full theoretical schedule gets logged.
The Woffu API, in case it needs revisiting
POST /api/svc/accounts/authorization/token— OAuth2 login (grant_type=password). ReturnsaccessToken(a JWT carrying theUserId, which is where we read it from) andexpiresIn.GET /api/svc/core/diariesquery/users/{id}/diaries/summary/presence— days in a month.GET /api/svc/core/diariesquery/diarysummaries/{diarySummaryId}/workday/slots/self— a day's exact time ranges. The summary only gives first entry, last exit and total break; it never says where the break falls. Only this endpoint knows a workday is 09:00–13:30 plus 14:00–17:53. The slots come back withsignId: 0: they are the proposal the UI preloads, not actual clocked time.PUT /api/svc/core/users/{id}/diarysummaries/workday/slots/self— saves. Times travel in UTC,signTypegoes from 1 (proposal) to 3 (manual clock-in, which is how Woffu displays them), andsignStatusto 1. It answers 200 with an empty body.GET /api/users/calendar-events/next— upcoming holidays.Typeis 2 on every one seen so far; other values are surfaced rather than assumed to be holidays.GET /api/user-agreement-events/availability— time-off balance per bucket. Carries no dates.POST /api/users/allocations/row— the allocations behind one bucket, and the only place the expiry date lives. Body:{agreementEventId, pageIndex, pageSize, createdOnFilter: {filterType: "CurrentCycle"}, affectedCycleFilter: "CurrentCycle"}. The cycle filter matters:/allocations/tablereports across cycles and disagrees with the availability endpoint (12 days vs 9), while the current cycle agrees.GET /api/users/{id}— the profile.DepartmentIdis the user's team, and it is the same number the calendar wants as anEntityId, so nobody has to configure their own team.DepartmentNamecomes back empty; only the calendar spells the name out.GET /api/scope/search?query=&types=999678— resolves a team name to the{EntityId, EntityType}pair the calendar wants; a team answers withEntityType32.typesis a bitmask over the scopes the calendar's own search box asks for.POST /api/svc/core/calendar— the shared calendar: one entry per person, one per day, already clipped to the range.visibilitiesis not optional: with an empty list Woffu answers with the whole company rather than the team.keywordmatches a person's name.requestStates: 3brings back approved and pending absences. No total comes back, so paging runs until a short page.eventDuration/absenceEventsDurationare an enum, not a count of days:1is a full day and2is an hours-only absence (isTimeOnly: true,startDate"09:00" rather than a date). Summing them books a half-day as two days off —isTimeOnlyis what tells them apart. Absences do land on weekends and holidays, and cost nobody a day.presenceEventsis telework: the person is still available.POST /api/svc/core/calendar/totals-simple— presents/absents per day. Unused: it counts every weekend as "everyone absent". The per-person calendar above agrees with it exactly on working days, once the same absences are counted.GET /api/users/requests/list?statusType=— time-off requests.statusTypeis 10 pending, 20 approved, 30 denied; it is required, so all three are fetched to list everything. Amounts arrive as{Resource, Values}, where the resource name is the only hint at the unit, and hours come split as["8", "30"]meaning 8h30m.
scripts/inspect.mjs /api/some/endpoint dumps any endpoint using the cached token —
useful when reverse-engineering a new surface.
npm test covers the filters, the day-counting rules, and that the payload matches,
field for field, the one the web app sends.
Available Tools
9 toolscancel_time_off_requestCancel a time-off requestA
Withdraws a time-off request. WRITES to Woffu: a pending request is deleted outright and the balance it held is returned. requestId comes from list_time_off_requests. This cannot be undone, so confirm with the user which request it is — by type and dates — before calling.
| Name | Required | Description | Default |
|---|---|---|---|
| requestId | Yes | The request to cancel, from list_time_off_requests. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Without annotations, the description fully bears the burden. It discloses that it WRITES to Woffu, deletes outright, returns balance, and is irreversible ('cannot be undone'). It does not specify permissions or state restrictions beyond 'pending', but covers major behavioral traits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three concise sentences, each serving a distinct purpose: purpose, effect, and usage warning. No unnecessary words; well-structured and front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple tool with one parameter and no output schema, the description covers all necessary aspects: what it does, how it works, irreversible nature, and guidance on using requestId from a sibling tool. Complete for effective selection and invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with description for requestId. The tool description adds that requestId comes from list_time_off_requests, providing helpful source context beyond the schema. Baseline 3 plus extra value.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'Withdraws' and the resource 'time-off request'. It distinguishes from sibling tools like edit_time_off_request and request_time_off by being a cancellation action.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly warns that cancellation cannot be undone and instructs to confirm with the user which request by type and dates. It also references list_time_off_requests for obtaining the requestId, providing clear when-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
clock_in_daysClock in daysA
Clocks the given days in Woffu. WRITES to the user's official timesheet. Requires an explicit list of dates: there is no "clock in everything". Before calling this, show the user the dates and their time ranges (from list_pending_days) and get their confirmation. By default each day uses the theoretical schedule Woffu itself proposes, which is almost always what the user wants. Only pass ranges when the user explicitly asks for different hours; it then overrides the schedule on every date in the call, so group dates that share a schedule. Each day is re-validated against Woffu before writing, so an already-clocked day is rejected rather than duplicated.
| Name | Required | Description | Default |
|---|---|---|---|
| dates | Yes | Dates to clock in (YYYY-MM-DD). They should come from list_pending_days. | |
| ranges | No | Optional override, e.g. [{"in":"09:00","out":"13:30"},{"in":"14:00","out":"17:53"}]. Omit to use the schedule Woffu proposes for each day. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description carries full burden. It discloses that the tool performs a write operation, each day is re-validated before writing, and already-clocked days are rejected. However, it does not mention potential side effects like whether the action is reversible or any rate limits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single paragraph but well-structured and informative. Each sentence adds value, though it could be slightly more concise by grouping related information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema, the description adequately explains input and behavior. It mentions rejection of already-clocked days, which implies some response handling. However, it does not describe the success response or potential error messages.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with both parameters described. The description adds significant value: explains that dates should come from list_pending_days, that ranges override the schedule for all dates in the call, and that the default uses the theoretical schedule from Woffu.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses specific verb 'Clocks' and identifies the resource 'days in Woffu'. It clearly states it writes to the user's official timesheet, and the tool is distinct from siblings which deal with time-off and availability.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly instructs to show the user dates and time ranges from list_pending_days and get confirmation before calling. Provides clear guidance on when to use the optional ranges parameter and cautions that it overrides all dates, so group dates that share a schedule.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
edit_time_off_requestEdit a time-off requestA
Changes the dates, times or comment of an existing request. WRITES to Woffu. requestId comes from list_time_off_requests. The leave type cannot change here — cancel and file a new one for that. Pass only what changes; anything omitted keeps its current value. A whole-day request takes from/to; an hourly one takes startTime/endTime. Re-validated against Woffu before saving, so a weekend, a holiday or an overdraw is refused. Confirm the change with the user before calling.
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | New last day, inclusive (YYYY-MM-DD). Whole-day requests. | |
| from | No | New first day (YYYY-MM-DD). Whole-day requests. | |
| comment | No | Replacement note. | |
| endTime | No | New end (HH:MM). Hourly requests. | |
| requestId | Yes | The request to change, from list_time_off_requests. | |
| startTime | No | New start (HH:MM). Hourly requests. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, but description fully discloses: writes to Woffu, re-validates against Woffu, can refuse weekends/holidays/overdraw, and only pass changed fields (others keep current value).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Concise, front-loaded with main action, then details. Every sentence adds value with no redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 6 parameters, no output schema, and no annotations, description covers all necessary context: two request modes, re-validation, and constraint on leave type. Sufficient for an edit operation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, but description adds value: explains whole-day vs hourly request modes, that from/to are for whole-day, startTime/endTime for hourly, and requestId comes from list_time_off_requests. Only minor improvement needed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states it edits an existing time-off request, changing dates/times/comment. Distinguishes from siblings like cancel_time_off_request and request_time_off.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly tells when to use (modify existing request) and when not (can't change leave type; cancel and file new). Mentions prerequisite (requestId from list_time_off_requests) and instructs to confirm with user before calling.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_team_availabilityGet team availabilityA
How many days each person on the team is available over a date range, and how many they are off. Built for capacity planning: a PO sizing a sprint needs to know who is away before committing to a load. Per person: workingDays in the range (weekends and public holidays already excluded), daysOff already approved, pendingDaysOff still awaiting approval, and availableDays — working days minus approved time off. Pending days are NOT subtracted from availableDays; they are the risk, so report them separately. availability is the fraction of the range the person is around (1 = fully available). A half-day absence counts as 0.5. People come back least-available first, each with their absences as date ranges. totals carries the team-wide capacity in person-days. Read-only.
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | End of the range, inclusive (YYYY-MM-DD). Defaults to 30 days after `from`. | |
| from | No | Start of the range (YYYY-MM-DD). Defaults to today. | |
| team | No | Another team, by name. Omit for the user's own team, which is the usual question. | |
| person | No | Narrow the answer to the people on the team whose name matches. Omit for the whole team. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description fully covers behavior. Discloses that weekends and holidays are excluded from working days, half-day counts as 0.5, people are returned least-available first, pending days are reported separately and not subtracted, and the read-only nature.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Description is well-structured and uses bullet-like formatting. Every sentence adds value, but could be slightly more concise by removing redundant phrases like 'the usual question'.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema, the description fully explains all output fields (workingDays, daysOff, pendingDaysOff, availableDays, availability, totals, absences). With 4 optional parameters and no required ones, the coverage is complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, but description adds significant value: explains defaults for 'from' (today) and 'to' (30 days after from), clarifies that omitting 'team' returns the user's own team, and 'person' narrows to matching names. This goes beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it is for capacity planning, listing per-person availability metrics (available days, working days, days off, pending days, availability fraction). It distinguishes from sibling tools like list_time_off_requests or get_time_off_balance by aggregating over a date range with different output fields.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says 'Built for capacity planning: a PO sizing a sprint needs to know who is away before committing to a load.' It explains that pending days are not subtracted from available days. However, it does not explicitly state when to avoid this tool or mention sibling alternatives by name.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_time_off_balanceGet remaining time offA
How much time off the user has left, per bucket: holidays, paid leave, calendar adjustment hours, and so on. Each entry carries its own unit — some buckets count days and others hours, so never add them together. Every bucket also carries expiresOn and daysUntilExpiry: time left in a bucket is LOST on that date, so when advising the user, always suggest spending the soonest-expiring bucket first. The list comes back in that order. Read-only.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries full burden and excels: it discloses read-only nature, explains the per-bucket structure (units, expiresOn, daysUntilExpiry), warns about losing time, and confirms the list order. This is comprehensive behavioral disclosure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise (~80 words), front-loaded with purpose, and every sentence serves a purpose: identifying buckets, warning about unit mixing, explaining expiration, and noting read-only nature.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema and no parameters, the description fully covers what the tool returns, how to use the data (spend soonest-expiring), and important caveats (different units). It leaves no obvious gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There are no parameters (schema coverage 100%, 0 params), so baseline is 4. The description adds value by explaining what each bucket contains and how to interpret the results, enhancing the schema's implicit emptiness.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states that the tool returns remaining time off per bucket (holidays, paid leave, etc.), with specific verb 'get' and resource 'time off balance'. It is distinct from sibling tools like request_time_off or cancel_time_off_request.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit guidance: never add buckets together due to different units, and suggests spending the soonest-expiring bucket first. It implies usage for checking leave balances, but does not explicitly state when not to use it or list alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_holidaysList upcoming public holidaysA
The public holidays ahead on the user's work calendar, roughly a year out. Useful for planning time off: a holiday costs no days from any bucket, and one next to a weekend makes a long weekend. weekend: true means it lands on a Saturday or Sunday and buys no day off. Read-only.
| Name | Required | Description | Default |
|---|---|---|---|
| from | No | Only holidays on or after this date (YYYY-MM-DD). Defaults to today. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and discloses read-only behavior, date range, and the meaning of the 'weekend: true' field. However, it does not detail error handling or pagination.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences, front-loaded with purpose, followed by usage guidance and field explanation. Every sentence adds value without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite no output schema, the description covers return semantics (holidays, weekend field) and usage context. For a simple tool with one optional parameter, it provides sufficient completeness.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% for the single optional 'from' parameter, including pattern and description. The description adds context about default (today) but does not significantly extend semantic meaning beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool lists upcoming public holidays on the user's work calendar, specifying a time range of roughly a year out. It distinguishes from sibling tools like request_time_off by focusing on read-only holiday viewing.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains when to use: for planning time off, noting that holidays cost no days off and adjacent weekends create long weekends. It provides context but does not explicitly state when not to use or alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_pending_daysList days pending clock-inA
Workdays with no hours logged in Woffu, each with the exact time ranges that would be clocked in. Excludes weekends, holidays, absences (leave, adjustment days, sick leave), days already clocked in, and days Woffu will not let the user edit. Read-only. lockedDays are unfilled days Woffu no longer allows editing — report them, they cannot be fixed through this tool. Show the ranges to the user before clocking anything in.
| Name | Required | Description | Default |
|---|---|---|---|
| month | No | Month as YYYY-MM. Defaults to the current month. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Declares read-only, lists exclusions, and explains lockedDays behavior. Without annotations, this provides sufficient transparency about what the tool does and does not modify. Lacks detail on output structure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four sentences, each with distinct value: purpose, exclusions, read-only, lockedDays explanation, and usage guidance. No fluff or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple tool with one optional parameter and no output schema, the description covers purpose, output content, exclusions, edge cases, and usage instruction. No gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema fully documents the month parameter (format, default). The description adds no additional meaning beyond the schema, so baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it lists workdays with no hours logged, provides exact time ranges, and lists exclusions (weekends, holidays, absences, etc.), effectively distinguishing it from sibling tools like clock_in_days.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly advises showing ranges to user before clocking in, and states lockedDays cannot be fixed via this tool, implying reporting. However, it does not name the alternative sibling tool (e.g., clock_in_days).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_time_off_requestsList time-off requestsA
The user's time-off requests (holidays, leave...) with their status: pending, approved or denied. Omit status to get all of them. Read-only: this never files a request.
| Name | Required | Description | Default |
|---|---|---|---|
| status | No | Filter by status. Omit for all. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description correctly calls out that this tool is read-only ('never files a request'). It does not mention pagination, ordering, or date range behavior, but the core behavioral trait (non-destructive) is well communicated.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two concise sentences that front-load the purpose and quickly cover the key details (status options and read-only nature). Every word earns its place with no redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
While the tool is simple, there is no output schema and the description does not mention what fields are returned besides status. It also lacks mention of pagination or limits, which would be helpful for a list operation. With only one parameter, the gaps are moderate.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema covers the single parameter with an enum and description. The description adds the practical tip 'Omit `status` to get all of them,' which provides semantic value beyond the schema by clarifying default behavior.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb ('list') and the resource ('time-off requests') along with the specific fields returned (statuses like pending, approved, denied). It distinguishes from sibling tools like request_time_off and cancel_time_off_request by emphasizing it is a read-only listing.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains how to filter by status and that omitting status returns all requests. This gives clear context for usage, though it does not explicitly mention when to avoid this tool or suggest alternatives for specific scenarios.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
request_time_offRequest time offA
Files a time-off request in Woffu. WRITES to the user's record and their manager sees it. type is the leave type by name, exactly as get_time_off_balance lists it (e.g. "Vacaciones"). Whole-day types take from and optionally to for a range; the day count is whatever Woffu charges after its own weekends and holidays, so a Fri–Mon range may cost two days. Hourly types instead take a single from with startTime and endTime. The balance is checked before anything is filed, and whole-day requests are also validated against Woffu's calendar, so an overdraw, a weekend or a holiday is refused with a reason rather than filed. Half-day requests and types that require a document are not supported here. Before calling, show the user the type, dates and any times, and get their confirmation.
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | Last day of a range, inclusive (YYYY-MM-DD). Whole-day types only. Defaults to `from`. | |
| from | Yes | First day (YYYY-MM-DD). | |
| type | Yes | Leave type by name, as get_time_off_balance lists it. | |
| comment | No | Optional note. Do not include unnecessary personal data. | |
| endTime | No | End of an hourly request (HH:MM). Hourly types only. | |
| startTime | No | Start of an hourly request (HH:MM). Hourly types only. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, but description fully discloses write nature, balance/calendar validation, refusal reasons, day count logic, and unsupported types. No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single dense paragraph, front-loaded with core action. Every sentence is informative and non-redundant. No wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With 6 params, 100% coverage, no output schema, description explains behavior, constraints, validation, unsupported types, and pre-call user confirmation. Very thorough for a write tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, baseline 3. Description adds meaning: differentiation between whole-day and hourly types, type must match get_time_off_balance, to defaults to from, comment personal data caution. Adds clear usage rules beyond schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states it files a time-off request, WRITES to the user's record, and is seen by manager. Distinguishes from siblings by listing unsupported types (half-day, document requiring).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear context for when to use (filing time-off) and what types are supported. Lacks explicit 'when-not-to-use' or direct alternatives like 'use edit_time_off_request to modify', but context is sufficient for an agent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
9 tool updates
v0.1.0- First observed
cancel_time_off_request - First observed
clock_in_days - First observed
edit_time_off_request - First observed
get_team_availability - First observed
get_time_off_balance - First observed
list_holidays - First observed
list_pending_days - First observed
list_time_off_requests - First observed
request_time_off
TDQS
Scored across 9 tools
Each tool targets a distinct action (cancel, clock in, edit, get availability, get balance, list holidays, list pending, list requests, request) with no overlap. An agent can easily differentiate them.
All tool names follow a consistent verb_noun pattern in snake_case (e.g., cancel_time_off_request, list_holidays), making them predictable and easy to remember.
Nine tools is a well-scoped set for a time-off and attendance manager, covering essential operations without unnecessary bloat.
The toolset covers core CRUD for time-off requests, clock-in for pending days, and support data (holidays, balances). Minor gaps exist: no ability to view past clocked days or edit clock-in entries, but the main workflows are supported.
Maintenance
Related MCP Connectors
MCP server providing attendance data queries via the CloudTime API.
- mcp-serverOAuthio.klokin
MCP server exposing klokin time-tracking operations (employees, time entries, stores) to AI clients.
MCP server for public_holidays_mcp
MCP server for Cronofy — read calendars, events and free/busy, and create, update or delete events.
Related MCP Servers
- AlicenseAqualityBmaintenanceEnables clocking in/out, viewing work status, and managing time entries on Woffu via MCP tools.93MIT

afkbot-mcpofficial
AlicenseNot gradedqualityAmaintenanceMCP server for AFKBot PTO management that allows users to file and manage time-off requests from any MCP-compatible client.MIT- FlicenseNot gradedqualityBmaintenanceA modular MCP server integrating Clockify, WakaTime, and Azure DevOps for time tracking, work item management, and time logging via a unified API.2-
- AlicenseAqualityBmaintenanceAn unofficial MCP server that exposes the Timetastic API to enable querying and managing absence & leave data.39MIT