Skip to main content
Glama
PrasenjitSaha

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
```