HR System MCP Server
README.md
# HR System MCP Server
A Model Context Protocol (MCP) server that exposes a mock HR system to LLM clients (Claude Desktop, Claude Code, custom agents). Ships with in-memory seed data so you can start experimenting without wiring up a real HRIS.
## Capabilities
| Group | Module | What it does |
|---|---|---|
| Leave & Attendance | `capabilities/leave.py` | Balances, applications, attendance records, holiday calendar |
| Benefits & Compensation | `capabilities/benefits.py` | Compensation summary, benefits catalog, payslips, tax declarations |
| Employee Lifecycle | `capabilities/lifecycle.py` | Profiles, onboarding, offboarding, internal transfers |
| Learning & Development | `capabilities/learning.py` | Course catalog, enrollment, learning history, recommendations |
| Performance Management | `capabilities/performance.py` | Review cycles, goals, self-assessments |
| Travel & Expense | `capabilities/travel.py` | Travel policy, expense submission and status |
| HR Policy Search | `capabilities/policy.py` | Full-text search over policy corpus + summarization |
| HR FAQ | `capabilities/faq.py` | FAQ catalog + search |
All eight groups share a single `FastMCP` instance and are served together.
## Requirements
- Python 3.10+
- pip / uv
## Install
```bash
pip install -e .
```
## Run
```bash
python run.py
```
You should see:
```
INFO: Uvicorn running on http://127.0.0.1:8765
```
The MCP endpoint is `http://127.0.0.1:8765/mcp` (streamable HTTP transport).
Configure via env vars (see `.env.example`):
- `HR_MCP_HOST` (default `0.0.0.0`)
- `HR_MCP_PORT` (default `8765`; `PORT` is honored first for PaaS hosts)
- `HR_MCP_LOG_LEVEL` (default `INFO`)
- `HR_MCP_AUTH_TOKEN` — when set, every request to `/mcp` must include `Authorization: Bearer <token>`. `/healthz` is always open.
- `HR_MCP_ALLOWED_HOSTS` — comma-separated Host headers FastMCP will accept (DNS-rebinding protection). **Required on any public deployment** (e.g. `hr-mcp.onrender.com`). Symptom if missing: `Error POSTing to endpoint: Invalid Host header` / HTTP 421.
## Try it with the MCP Inspector
```bash
npx @modelcontextprotocol/inspector
```
Choose transport **Streamable HTTP** and URL `http://127.0.0.1:8765/mcp`. You should see ~30 tools grouped by capability.
## Register with Claude Desktop / Claude Code
**Local, no auth:**
```json
{
"mcpServers": {
"hr-system": {
"url": "http://127.0.0.1:8765/mcp"
}
}
}
```
**Remote (Render), with bearer token:**
```json
{
"mcpServers": {
"hr-system": {
"url": "https://hr-mcp.onrender.com/mcp",
"headers": {
"Authorization": "Bearer YOUR_TOKEN_FROM_RENDER"
}
}
}
}
```
Then ask things like:
- "What's the leave balance for employee E001?"
- "Search HR policies for maternity leave and summarize the top match."
- "Show me the payslip for E002 for March 2026."
## Deploy to Render (free tier)
The repo ships with `render.yaml` — a Render Blueprint that provisions everything.
### 1. Push to a new GitHub repo
```bash
git init
git add .
git commit -m "Initial commit: HR MCP server"
# Create the empty repo on GitHub first (via the website or `gh repo create`),
# then push
git remote add origin https://github.com/<your-user>/hr-mcp.git
git branch -M main
git push -u origin main
```
### 2. Provision on Render
1. Sign in at <https://dashboard.render.com>.
2. **New → Blueprint** → connect your GitHub account → pick the `hr-mcp` repo.
3. Render reads `render.yaml`, previews the service, and asks you to confirm. Click **Apply**.
4. First deploy takes ~2–3 minutes. When the service goes green, note its URL: `https://hr-mcp-<hash>.onrender.com`.
5. Open the service → **Environment** tab → copy the auto-generated `HR_MCP_AUTH_TOKEN` value. That's your bearer token.
### 3. Try it
```bash
# Health check (no auth needed)
curl https://hr-mcp-<hash>.onrender.com/healthz
# → ok
# MCP endpoint (401 without token, works with)
curl -H "Authorization: Bearer $HR_MCP_AUTH_TOKEN" \
https://hr-mcp-<hash>.onrender.com/mcp
```
Point the MCP Inspector at `https://hr-mcp-<hash>.onrender.com/mcp` and set a custom header `Authorization: Bearer <token>` in the Inspector's connection settings.
### 4. Notes on the free plan
- Instances spin down after **15 minutes** of idle. First request after a nap has a **~30 s cold start**. For a personal demo this is fine; upgrade to the Starter tier ($7/mo) if you need always-on.
- 750 free instance-hours per month across all your Render services.
- `/healthz` is exempt from auth so Render's health prober keeps working.
## Seed data
The server seeds ~10 employees (`E001`–`E010`), a set of policies, courses, benefits, holidays, and FAQs at startup. All data lives in memory — restarting resets state. Swap `src/hr_mcp/data/store.py` for a real backend when you're ready.
## Structure
```
src/hr_mcp/
├── __main__.py # CLI entrypoint
├── server.py # FastMCP wiring
├── config.py # env-var settings
├── data/
│ ├── models.py # Pydantic models
│ ├── store.py # in-memory store
│ └── seed.py # sample data
└── capabilities/ # one module per capability group
```
This server cannot be deployed
Maintenance
ActivitySlowing
ResponsivenessNo issues