@attendance-engine/mcp 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +272 -0
- package/dist/chunk-UACYGW4C.js +489 -0
- package/dist/chunk-UACYGW4C.js.map +1 -0
- package/dist/cli.cjs +501 -0
- package/dist/cli.cjs.map +1 -0
- package/dist/cli.d.cts +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +15 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.cjs +491 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +19 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/package.json +82 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Md. Arifur Rahman
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
# ๐ attendance-engine MCP
|
|
4
|
+
|
|
5
|
+
### Wage-and-hour answers your AI agent can actually trust.
|
|
6
|
+
|
|
7
|
+
**Ask Claude *"Did anyone miss a meal break last Tuesday?"* โ and have it actually be right.**
|
|
8
|
+
|
|
9
|
+
[](https://www.npmjs.com/package/@attendance-engine/mcp)
|
|
10
|
+
[](https://github.com/arifur9993/attendance-engine-mcp/actions)
|
|
11
|
+
[](LICENSE)
|
|
12
|
+
[](https://modelcontextprotocol.io/)
|
|
13
|
+
|
|
14
|
+
</div>
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## ๐ค The problem
|
|
19
|
+
|
|
20
|
+
Every HR / payroll / time-tracking team eventually asks Claude (or Cursor, or Windsurf) something like:
|
|
21
|
+
|
|
22
|
+
> *"Rahim's punches yesterday were 09:00, 13:00, 14:00, and 18:00. Did he get his meal break under California rules?"*
|
|
23
|
+
|
|
24
|
+
And the LLM does what LLMs do: it eyeballs the timestamps, mumbles something about "yes probably, his lunch looks fine," and moves on. Sometimes it's right. Sometimes it forgets that California requires the meal to *start before the end of the 5th hour*. Sometimes it counts a 25-minute break as compliant. Sometimes, for an overnight shift that crosses midnight, it just gives up.
|
|
25
|
+
|
|
26
|
+
**You can't put that in front of an auditor.** You can't ship it inside a payroll product. You can't trust it with overtime calculations that turn into back-pay liability if they're wrong.
|
|
27
|
+
|
|
28
|
+
## ๐ก What this is
|
|
29
|
+
|
|
30
|
+
A small **Model Context Protocol** server that gives your AI agent **deterministic, tested, fixture-backed tools** for:
|
|
31
|
+
|
|
32
|
+
- Resolving a duty day from raw clock punches (overnight, breaks, OT, all of it).
|
|
33
|
+
- Auditing meal/rest compliance under the **California** rule pack (Labor Code ยงยง 226.7, 512; IWC wage orders), including *Donohue v. AMN* rebuttable-presumption signals.
|
|
34
|
+
- Rounding worked time without losing the exact-minute baseline (so you can prove your rounding is neutral).
|
|
35
|
+
- Building rotating rosters: 2-2-3, 4-on-4-off, DuPont, Pitman.
|
|
36
|
+
- Triaging suspicious punch streams *before* you trust them.
|
|
37
|
+
- Running a multi-day **wage-and-hour audit** across a whole pay period and rolling up premium hours owed, days at risk, and the flag heatmap.
|
|
38
|
+
|
|
39
|
+
The math lives in [`@attendance-engine/core`](https://www.npmjs.com/package/@attendance-engine/core) โ a pure-function, zero-deps TypeScript library with 100% test coverage. This MCP server is the thin agent surface on top.
|
|
40
|
+
|
|
41
|
+
## ๐ง How it actually works
|
|
42
|
+
|
|
43
|
+
```mermaid
|
|
44
|
+
flowchart LR
|
|
45
|
+
A[You: "Did Rahim miss his meal break last Tuesday?"]
|
|
46
|
+
B[Claude / Cursor / Windsurf]
|
|
47
|
+
C[attendance-engine MCP]
|
|
48
|
+
D[("@attendance-engine/core
|
|
49
|
+
pure-function engine
|
|
50
|
+
100% coverage")]
|
|
51
|
+
|
|
52
|
+
A -->|prompt| B
|
|
53
|
+
B -->|tool call| C
|
|
54
|
+
C -->|function call| D
|
|
55
|
+
D -->|"DayResult + ComplianceResult"| C
|
|
56
|
+
C -->|"JSON content block"| B
|
|
57
|
+
B -->|"plain-English answer with citations"| A
|
|
58
|
+
|
|
59
|
+
classDef user fill:#0b3d91,stroke:#fff,color:#fff
|
|
60
|
+
classDef host fill:#5b1ea3,stroke:#fff,color:#fff
|
|
61
|
+
classDef mcp fill:#1f6f43,stroke:#fff,color:#fff
|
|
62
|
+
classDef core fill:#7c4a03,stroke:#fff,color:#fff
|
|
63
|
+
class A user
|
|
64
|
+
class B host
|
|
65
|
+
class C mcp
|
|
66
|
+
class D core
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Two important properties:
|
|
70
|
+
|
|
71
|
+
1. **Claude doesn't do the math.** It picks a tool, fills the arguments, and forwards the answer. If the engine says "this was a late meal," the agent says "this was a late meal." If you re-ask the same question, you get the same answer โ every time.
|
|
72
|
+
2. **Time zones are explicit, not guessed.** Every timestamp carries its own offset. The engine never reads the host clock, never assumes UTC, never silently converts. DST days work because *you* told it the offset, not because it inferred it.
|
|
73
|
+
|
|
74
|
+
## ๐ Install โ pick your host
|
|
75
|
+
|
|
76
|
+
Pick the MCP host you're already using. Same one-liner everywhere:
|
|
77
|
+
|
|
78
|
+
<details>
|
|
79
|
+
<summary><b>Claude Desktop (macOS / Windows)</b></summary>
|
|
80
|
+
|
|
81
|
+
Edit `~/Library/Application Support/Claude/claude_desktop_config.json` on macOS or `%APPDATA%\Claude\claude_desktop_config.json` on Windows:
|
|
82
|
+
|
|
83
|
+
```json
|
|
84
|
+
{
|
|
85
|
+
"mcpServers": {
|
|
86
|
+
"attendance-engine": {
|
|
87
|
+
"command": "npx",
|
|
88
|
+
"args": ["-y", "@attendance-engine/mcp"]
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Fully quit and relaunch Claude Desktop (Cmd-Q on macOS โ closing the window isn't enough).
|
|
95
|
+
</details>
|
|
96
|
+
|
|
97
|
+
<details>
|
|
98
|
+
<summary><b>Cursor</b></summary>
|
|
99
|
+
|
|
100
|
+
`~/.cursor/mcp.json`:
|
|
101
|
+
|
|
102
|
+
```json
|
|
103
|
+
{
|
|
104
|
+
"mcpServers": {
|
|
105
|
+
"attendance-engine": {
|
|
106
|
+
"command": "npx",
|
|
107
|
+
"args": ["-y", "@attendance-engine/mcp"]
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
</details>
|
|
113
|
+
|
|
114
|
+
<details>
|
|
115
|
+
<summary><b>Windsurf</b></summary>
|
|
116
|
+
|
|
117
|
+
`~/.codeium/windsurf/mcp_config.json`:
|
|
118
|
+
|
|
119
|
+
```json
|
|
120
|
+
{
|
|
121
|
+
"mcpServers": {
|
|
122
|
+
"attendance-engine": {
|
|
123
|
+
"command": "npx",
|
|
124
|
+
"args": ["-y", "@attendance-engine/mcp"]
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
```
|
|
129
|
+
</details>
|
|
130
|
+
|
|
131
|
+
<details>
|
|
132
|
+
<summary><b>Any other MCP host</b></summary>
|
|
133
|
+
|
|
134
|
+
Launch the stdio binary directly:
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
npx -y @attendance-engine/mcp
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
The server speaks JSON-RPC over stdin/stdout โ that's the whole contract.
|
|
141
|
+
</details>
|
|
142
|
+
|
|
143
|
+
## ๐ฌ See it in action
|
|
144
|
+
|
|
145
|
+
> **๐ผ๏ธ Scenario cards below are publish-ready SVG mockups** (render inline on GitHub, npm, LinkedIn). Real-product screenshots can replace them when you capture them โ see [`docs/screenshots/README.md`](docs/screenshots/README.md).
|
|
146
|
+
|
|
147
|
+
### Scenario 1 โ Did the night-shift nurse get her meal break?
|
|
148
|
+
|
|
149
|
+

|
|
150
|
+
|
|
151
|
+
> **You:** *"Sara was on the 22:00โ06:00 shift on June 1st. Punches: 21:54, 02:00, 02:30, 06:18. Apply California rules."*
|
|
152
|
+
>
|
|
153
|
+
> **Claude (calls `evaluate_break_compliance`):** *"Sara worked 7h54m on her duty date of June 1st (her clock-out fell on June 2nd but belongs to this shift). She took a 30-minute meal beginning at her 4-hour mark, which is compliant under California's mandate to start the first meal before the end of the 5th hour. Worked time spans midnight; flagged accordingly. She left 18 minutes past schedule โ that 18m counts as overtime."*
|
|
154
|
+
|
|
155
|
+
### Scenario 2 โ Find every late-meal day this month
|
|
156
|
+
|
|
157
|
+

|
|
158
|
+
|
|
159
|
+
> **You:** *"Run an `audit_period_compliance` for employee EMP-007 across June 2026. Here are 30 days of punches and shifts. Use California."*
|
|
160
|
+
>
|
|
161
|
+
> **Claude:** *"3 days at high presumption risk โ June 4, June 12, June 22. All three are late meals (started past the 5th hour). Total meal-period premium hours owed: 3. June 22 also drops below the 12-hour second-meal threshold. No rest-period violations detected."*
|
|
162
|
+
|
|
163
|
+
### Scenario 3 โ Are these punches even usable?
|
|
164
|
+
|
|
165
|
+

|
|
166
|
+
|
|
167
|
+
> **You:** *"I have punches 09:00, 13:00, 14:00 for June 1st. Can I trust these?"*
|
|
168
|
+
>
|
|
169
|
+
> **Claude (calls `diagnose_punches`):** *"Recommendation: **reject**. The punch count is odd โ one in or out is missing. Without that, worked-time and overtime would be guesses. Also: every punch falls on a 5-minute boundary, which often indicates manual entry rather than a device read. Worth verifying with the source system before resolving."*
|
|
170
|
+
|
|
171
|
+
### Scenario 4 โ Plan a 4-on-4-off roster for next month
|
|
172
|
+
|
|
173
|
+

|
|
174
|
+
|
|
175
|
+
> **You:** *"Build me a 4-on-4-off roster for July 2026."*
|
|
176
|
+
>
|
|
177
|
+
> **Claude (calls `generate_roster`):** *"31 days โ work days on July 1โ4, 9โ12, 17โ20, 25โ28 (12h day shifts, 07:00โ19:00). Rest days fill the gaps. Want me to assign team rotations across this pattern?"*
|
|
178
|
+
|
|
179
|
+
## ๐ ๏ธ Tools at a glance
|
|
180
|
+
|
|
181
|
+
| Tool | When you'd use it |
|
|
182
|
+
|---|---|
|
|
183
|
+
| **`resolve_day`** | "What happened on this single day? Lateness, OT, segments, flags." |
|
|
184
|
+
| **`resolve_period`** | "Roll up a week or a month: per-day results plus an aggregated summary." |
|
|
185
|
+
| **`evaluate_break_compliance`** | "Did this person get their meal/rest breaks under California law? Is any premium owed?" |
|
|
186
|
+
| **`audit_period_compliance`** | "Audit a whole pay period. Show me total premium hours, high-risk days, and the flag heatmap." |
|
|
187
|
+
| **`apply_rounding`** | "Round worked/OT minutes to a unit โ and keep the exact view alongside it so I can prove neutrality." |
|
|
188
|
+
| **`diagnose_punches`** | "Triage this raw punch stream. Should I trust it?" |
|
|
189
|
+
| **`generate_roster`** | "Build a 2-2-3 / 4-on-4-off / DuPont / Pitman / custom rotation." |
|
|
190
|
+
| **`list_rule_packs`** | "What jurisdictions are supported?" *(currently CA; more arrive in minor releases)* |
|
|
191
|
+
|
|
192
|
+
## ๐ Resources & prompts
|
|
193
|
+
|
|
194
|
+
Resources you can paste into a chat:
|
|
195
|
+
|
|
196
|
+
| URI | What it is |
|
|
197
|
+
|---|---|
|
|
198
|
+
| `attendance://docs/overview` | One-pager about the engine, time-zone rules, and how the tools compose. |
|
|
199
|
+
| `attendance://docs/api` | Compact field-by-field API reference. |
|
|
200
|
+
| `attendance://rules/CA` | The California rule pack as JSON โ meal/rest thresholds, waiver limits, premium caps, the citation source. |
|
|
201
|
+
|
|
202
|
+
Guided prompts (the host's `/` menu, or `prompts/get`):
|
|
203
|
+
|
|
204
|
+
- **`analyse_timecard`** โ walks the model through the right tool calls to analyse a single duty day.
|
|
205
|
+
- **`roster_planner`** โ generates a roster and renders it as a Markdown table.
|
|
206
|
+
|
|
207
|
+
## ๐ฐ๏ธ The time-zone rule (read this once and you're fine)
|
|
208
|
+
|
|
209
|
+
Every ISO timestamp must carry its own offset:
|
|
210
|
+
|
|
211
|
+
- โ
`2026-06-01T08:57:00+06:00`
|
|
212
|
+
- โ
`2026-06-01T08:57:00Z`
|
|
213
|
+
- โ `2026-06-01T08:57:00` *(rejected โ the engine won't guess)*
|
|
214
|
+
|
|
215
|
+
The engine reduces everything to absolute instants on a single timeline. DST works because the offsets are explicit. The duty date and shift `HH:MM` are worksite local wall-clock โ match them to your business calendar, not to UTC.
|
|
216
|
+
|
|
217
|
+
For days with no punches (an absence, a holiday), pass `policy.tzOffsetMinutes` explicitly so the engine has something to anchor the shift window to.
|
|
218
|
+
|
|
219
|
+
## ๐ค Embedding (advanced)
|
|
220
|
+
|
|
221
|
+
Building your own host? Skip the CLI:
|
|
222
|
+
|
|
223
|
+
```ts
|
|
224
|
+
import { createServer } from '@attendance-engine/mcp';
|
|
225
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
226
|
+
|
|
227
|
+
const server = createServer({ name: 'my-hr-server', version: '1.0.0' });
|
|
228
|
+
await server.connect(new StdioServerTransport());
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
Use it for: custom HTTP/SSE adapters, Claude Agent SDK setups, test harnesses, in-house deployments where the binary needs to live inside a bigger Node process.
|
|
232
|
+
|
|
233
|
+
## ๐ช What it's good for
|
|
234
|
+
|
|
235
|
+
- Internal HR / payroll / workforce-analytics chat assistants
|
|
236
|
+
- Audit-prep workflows for California employers
|
|
237
|
+
- Customer-support tools at HR-tech vendors who need their AI to actually be right
|
|
238
|
+
- Pre-payroll compliance triage ("which days need a human to review?")
|
|
239
|
+
- Schedule planners that need a real roster engine, not vibes
|
|
240
|
+
|
|
241
|
+
## ๐งฑ What it's not
|
|
242
|
+
|
|
243
|
+
- A leave-balance / accrual system (the engine deals in minutes, not entitlements).
|
|
244
|
+
- A payroll-money calculator (it gives you the hour buckets โ *you* multiply by the rate).
|
|
245
|
+
- A biometric device protocol (pair it with whatever ingest layer you've got).
|
|
246
|
+
- A UI. There's no dashboard in here; that's a separate concern.
|
|
247
|
+
|
|
248
|
+
## ๐ Compatibility
|
|
249
|
+
|
|
250
|
+
| | |
|
|
251
|
+
|---|---|
|
|
252
|
+
| **Node** | 18+ (CI runs 20 LTS) |
|
|
253
|
+
| **MCP SDK** | 1.x |
|
|
254
|
+
| **Engine** | `@attendance-engine/core` โฅ 0.4 (peer dep) |
|
|
255
|
+
| **Hosts tested** | Claude Desktop 1.x ยท Cursor ยท Windsurf ยท any stdio MCP client |
|
|
256
|
+
|
|
257
|
+
## ๐ More reading
|
|
258
|
+
|
|
259
|
+
- ๐ [Detailed scenarios with full tool transcripts](docs/scenarios.md)
|
|
260
|
+
- ๐ผ๏ธ [How to capture your own demo screenshots](docs/screenshots/README.md)
|
|
261
|
+
- ๐ [Engine API reference](https://github.com/arifur9993/attendance-engine/blob/main/packages/core/docs/api.md)
|
|
262
|
+
- ๐ [Time-zone semantics](https://github.com/arifur9993/attendance-engine/blob/main/packages/core/docs/timezones.md)
|
|
263
|
+
- ๐๏ธ [California Labor Code ยงยง 226.7, 512](https://www.dir.ca.gov/dlse/faq_mealperiods.htm)
|
|
264
|
+
- ๐๏ธ [Donohue v. AMN Services (Cal. 2021)](https://law.justia.com/cases/california/supreme-court/2021/s253677.html)
|
|
265
|
+
|
|
266
|
+
## โค๏ธ Credits
|
|
267
|
+
|
|
268
|
+
Built by [Md. Arifur Rahman](https://www.linkedin.com/in/md-arifur-rahman-mar/). Companion to [`@attendance-engine/core`](https://github.com/arifur9993/attendance-engine) (TypeScript) and [`arifur9993/attendance-engine`](https://github.com/arifur9993/attendance-engine-php) (PHP). Same author, same fixtures, same answers โ in three places your stack can reach for.
|
|
269
|
+
|
|
270
|
+
## License
|
|
271
|
+
|
|
272
|
+
MIT โ see [LICENSE](LICENSE).
|