A Spring Boot-based MCP server providing tools for human resources operations including employee management, benefits administration, address management, email services, weather information, and web search capabilities.
This HR MCP server exposes 26 tools across employee, benefits, address, and external services. While tool schemas are present with typed parameters, most tools suffer from generic or absent descriptions, lack of enumerated constraints on parameters, missing output documentation, and critical security gaps. The server mixes core HR operations (searchEmployeesInState) with unrelated external services (braveSearch, getWeather, generateImage), violating single-responsibility design. Only 8 of 26 tools have descriptions exceeding 20 characters; parameter descriptions are minimal (e.g., 'Field to sort by' without explaining valid values or behavior); and no tools document return schemas. Security is severely compromised: sendEmail, uploadFile, and generateImage expose dangerous write operations without confirmation patterns, permission gates, or rate limits. The server does not follow composition patterns, tools like countEmployeesInState and searchEmployeesInState should be unified into a single discovery tool with optional filters.
Perform web searches using Brave Search API
Count the number of employees located in a specific city
Count the number of employees located in a specific state
Count the number of employees in a specific zipcode
Count the number of enrollments for a specific plan
Count the number of enrollments for a specific plan type
Delete an address by ID
Enroll an employee in a benefit plan
Multiple count/search tool pairs (countEmployeesInState + searchEmployeesInState, etc.) violate single-responsibility design. LLMs waste reasoning cycles choosing between them. Should be unified into single discovery tools with optional filters.
Unrelated external services (braveSearch, getWeather, generateImage, uploadFile) mixed with core HR operations. These belong in separate, domain-focused MCP servers. Current design violates cohesion and makes the server harder to reason about and maintain.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | F | 48 | <=2025-11-25 | v2 |
| 2026-03-09 | F | 45 | - | v1 |
Generate an image using AI
Retrieve an address by ID
Retrieve all benefit plans
Retrieve benefit enrollments for a specific employee
Retrieve all enrollments for a specific benefit plan
Retrieve all enrollments for a specific plan type
Retrieve a specific benefit plan by ID
Retrieve benefit plans by type
Retrieve weather information for a location
Perform a keep-alive health check
Save a new address record
Search for addresses with optional filters
Search for employees in a specific city with pagination and sorting
Search for employees in a specific state with pagination and sorting
Search for employees in a specific zipcode with pagination and sorting
Send an email message
Unenroll an employee from a benefit plan
Upload a file to cloud storage
Critical security gap: sendEmail, uploadFile, and generateImage are destructive/write operations with no confirmation pattern, permission gates, or rate limits. Agents can trigger unintended side effects (send unsolicited emails, upload arbitrary data, generate content). Missing dry-run or confirmation_before_execute pattern.
deleteAddressById is a destructive operation with no recovery mechanism, confirmation step, or audit trail. Agents can permanently delete address records without safeguards.
Parameter 'sortBy' and 'sortOrder' in searchEmployeesInState/City/Zipcode lack enumerated constraints. Descriptions say 'Field to sort by' and 'Sort order (asc or desc)' but do not enumerate valid sort fields or warn against invalid values. LLMs will hallucinate invalid field names.
No output schemas documented for any tool. LLMs cannot infer what fields to expect from responses. E.g., does searchEmployeesInState return {id, name, email, phone} or something else? Unknown return structure forces LLMs to guess or parse responses blindly.
Pagination not explicitly addressed. Tools like getAllPlans and getEnrollmentsByPlanType do not document page/limit parameters or total counts. If results exceed thousands of items, LLMs will receive bloated responses that exhaust context.
Parameter 'address' in saveAddress is described as 'Address object with city, state, postalCode, and isRemote fields' but no schema defines the nested object structure. Is it a JSON string? An object with required vs optional fields? Ambiguous parameter structure forces LLMs to guess serialization.
sendEmail, uploadFile parameters do not specify constraints on size, format, or content. An LLM could attempt to send a 500MB file or an email to thousands of recipients. No validation guidance.
No error recovery guidance documented. Tools lack actionable error messages. E.g., if getPlanById fails with 'Plan not found', does the LLM retry with a different ID, or call a discovery tool first? Missing recovery-guide patterns across all error cases.