MCP server for managing employee vacation days with support for querying vacation days left, charging vacation days, and retrieving employee lists. Available in both TypeScript (HTTP and Stdio transports) and C# (HTTP and Stdio transports).
This MCP server exhibits severe structural and naming problems that make it unsuitable for production use. The tool registry contains 12 entries, but only 3 unique tools are actually defined (significant duplication). Naming is inconsistent across implementations (TypeScript uses camelCase with 'Async' suffix; C# uses PascalCase). Descriptions are minimal and generic. No input validation, no error handling guidance, and no output schema documentation. The server duplicates tool definitions across transport implementations without consolidation, indicating organizational debt. Parameter descriptions are present but extremely terse (8-20 chars). No evidence of idempotency markers, rate limiting, or security considerations. The codebase shows basic MCP SDK usage but lacks production-grade tooling patterns.
Charge vacation days for a given employee.
Charge vacation days for a given employee.
Get the list of employees with their number of vacation days left
Get the list of employees with their number of vacation days left
Get the vacation days left for a given employee.
Get the vacation days left for a given employee.
Charge vacation days for a given employee.
Charge vacation days for a given employee.
Duplicate tool definitions across implementations: The same 3 logical tools (getVacationDaysLeft, chargeVacationDays, getAllEmployees) are registered 4 times (TS/SSE, C#/SSE, C#/STDIO, and C# agent client), creating confusion, maintenance burden, and tool registry bloat. LLMs will see duplicate or conflicting tool offerings and waste reasoning cycles.
Inconsistent tool naming conventions: TypeScript tools use camelCase with 'Async' suffix (getVacationDaysLeftAsync), while C# tools use PascalCase (GetVacationDaysLeftAsync). Parameter names also differ inconsistently (TS uses 'name' and 'daysToCharge', C# uses 'employeeName' and 'daysToCharge'). This forces LLMs to reason about multiple naming styles and increases hallucination risk when invoking the 'right' tool variant.
Inferred effective spec: 2026-07-28+.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | F | 44 | 2026-07-28+ | v2 |
| 2026-03-09 | F | 47 | - | v1 |
Get the list of employees with their number of vacation days left
Get the list of employees with their number of vacation days left
Get the vacation days left for a given employee
Get the vacation days left for a given employee
Parameter naming lacks consistency and clarity: TS version uses bare 'name' (ambiguous, is it first name, full name, or employee ID?), while C# version uses 'employeeName' (explicit). The inconsistency means different tool invocations require different field names, and LLMs must track which version expects which parameter. This violates the 'Natural Identifiers' pattern (mxe:natural-identifiers), the tool should accept both email and name, not force LLMs to guess the format.
Descriptions are minimal and lack context for LLM tool selection: All descriptions are under 50 characters and generic ('Get the vacation days left for a given employee'). Per the rubric baseline, effective tool descriptions average 194 chars (p10=34, p90=392). These descriptions do not explain WHEN to use each tool, what edge cases exist, or how to interpret the response.
No error handling or recovery guidance: None of the tools include error descriptions or recovery paths. For example, chargeVacationDaysAsync might fail if the employee has insufficient days, but there is no message telling the LLM 'Insufficient vacation days remaining; call getVacationDaysLeft to check the balance first.' Without recovery guidance, agents get stuck on failures.
No output schema documentation: The code shows that tools return values (e.g., 'String(await employeeVacationService.getVacationDaysLeft(name))' for a numeric result), but the MCP server registration does not document the shape of the response. LLMs do not know whether the response is a number, a structured object with fields, or a list. Per the rubric, 100% of A+ tools document return types; this server has 0% documentation.
Naming uses suffix 'Async' which is an implementation detail, not a semantic distinction. Tool names like 'getVacationDaysLeftAsync' embed async/await semantics that are irrelevant to the LLM and the user. The 'Async' suffix adds 5 chars and zero signal, it's technical debt exposed to the agent.
Destructive tool (chargeVacationDaysAsync / ChargeVacationDaysAsync) lacks confirmation or dry-run support. Charging vacation days is an irreversible state change. There is no mention of a confirmation step, audit trail, or ability to preview the outcome before committing. Per the pattern:confirmation-request, irreversible operations should support a dry-run or confirmation flow. An agent might accidentally charge 365 days because it misread the parameter.
No tool annotations (readOnlyHint, destructiveHint, idempotentHint): Per the current MCP spec (2026-07-28), tools should include annotations to tell the LLM which operations are safe to retry, which modify state, and which are read-only. The C# tools return boolean for success (e.g., ChargeVacationDaysAsync returns 'Task<bool>'), suggesting they may fail, but there is no idempotent marker or guidance on retry safety. The TS tools also lack these hints.
Parameter descriptions are too terse to guide LLM input: 'The name of the employee' (30 chars) and 'The number of vacation days to charge' (36 chars) lack context about valid formats, ranges, and edge cases. Per the rubric, descriptions should explain expected format, range, and allowed values. There is no mention of whether 'name' accepts first name, last name, full name, email, or employee ID. There is no min/max for 'daysToCharge', can the LLM pass 0.5? 365? Negative numbers?