hr_server
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@hr_serverMaya Rodriguez wants to work from Portugal for six weeks, 5 October to 15 November. Can she?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Helios HR Assistant
An agentic AI system that answers HR policy and operations questions for a fictional company, Helios Dynamics. It combines retrieval over a policy corpus with live tool calls against mock HR records, exposed through a Model Context Protocol (MCP) server, and it cites every claim it makes.
The system is built to give a defensible answer to questions that a naive RAG chatbot gets wrong, because answering them correctly requires both the written policy and a specific employee's data:
"Maya Rodriguez wants to work from Portugal for six weeks, 5 October to 15 November. Can she?"
The policy allows 30 days abroad per rolling 12 months. Maya has 12 days already used inside the window — not the 24 a careless reading of her travel history suggests, because her Spain trip closed before the window opened. The agent must retrieve the rule, look up the history, apply the rolling-window arithmetic, and cite the section. The answer is no, by 24 days — and the useful part is the alternatives it offers, which are only reachable by combining retrieval with structured data.
Deployed application: see deployed.md
Design rationale and evaluation results: see design-and-evaluation.md
How AI coding tools were used: see ai-tooling.md
What it does
Capability | Where |
Hybrid RAG (dense + BM25 + reciprocal rank fusion) over 16 policy documents in 4 file formats |
|
12 MCP tools over policy search, employee records, PTO, benefits, travel history, and ticketing |
|
Hand-written agent loop with full step-by-step tracing and provider fallback |
|
FastAPI chat app that renders every tool call, argument, and result |
|
Two-store abstention gate that refuses questions the system genuinely cannot answer |
|
28-case evaluation suite with a deterministic scorer, plus a 6-way retrieval ablation |
|
Related MCP server: HR Assist MCP Server
Architecture at a glance
┌──────────────────────────────────────────┐
browser ───────► │ FastAPI web app (app/main.py) │
│ chat UI + /chat + /health + /healthz │
└───────────────┬──────────────────────────┘
│
┌───────────────▼──────────────────────────┐
│ Agent orchestrator (agent/orchestrator) │
│ plan → call tools → observe → answer │
└──────┬──────────────────────┬────────────┘
│ │
┌────────▼────────┐ ┌─────────▼──────────────┐
│ LLM provider │ │ MCP client │
│ Groq → Gemini │ │ (agent/mcp_client.py) │
│ automatic fallback│ └─────────┬─────────────┘
└──────────────────┘ │ stdio (JSON-RPC)
│
┌──────────────▼─────────────┐
│ MCP server (mcp_server/) │
│ 12 tools, annotated │
└───┬────────────────┬───────┘
│ │
┌─────────▼──────┐ ┌──────▼────────────┐
│ RAG index │ │ Mock HR data │
│ numpy + BM25 │ │ 6 JSON datasets │
│ 184 chunks │ │ + rule engine │
└────────────────┘ └───────────────────┘Everything runs inside one process tree, so it fits a single free-tier web service. The MCP server is a genuine child process speaking JSON-RPC over stdio — not an in-process function call dressed up as a protocol.
Full detail, including transport rationale and tool schemas, is in
design-and-evaluation.md.
Setup
Requires Python 3.11+ (developed on 3.12).
git clone https://github.com/mariumatu-cmd/helios-hr-agent.git
cd helios-hr-agent
python -m venv .venv
# Windows
.\.venv\Scripts\Activate.ps1
# macOS / Linux
source .venv/bin/activate
pip install -e ".[dev]"Configure a model provider
Copy the template and add at least one key. Both providers have free tiers.
cp .env.example .envVariable | Where to get it | Notes |
| Primary. Fast, free tier. | |
| Last-resort fallback. |
Set either one, or both. With neither, the app still starts and every non-LLM
endpoint works — /health reports degraded and the chat endpoint says plainly
that no model is configured.
Degradation is a chain of models, not just of providers. Groq meters its free tier per model — measured directly, two back-to-back calls to different Groq models each saw a full 8,000-token bucket rather than a shared, draining one. That matters more than it sounds: at roughly 6,000 tokens per request against an 8,000 tokens-per-minute bucket, a single model allows about one agent step per minute, which is not enough to finish a multi-step task. Rotating across four Groq models multiplies the usable budget before Gemini is touched at all.
Rotation is strictly reactive: it happens because a call failed, never because a quota header looked close. Predictive switching would make the agent non-deterministic and would invalidate any groundedness or latency claim measured across a run. Every hop is recorded in the trace.
Two other variables matter on a free tier:
Variable | Default | Why it exists |
|
| Comma-separated, tried in order after |
|
| Completion cap. Groq reserves it against the per-minute budget whether the model uses it or not, so it is a prompt-budget decision as much as an output one. |
|
| Max estimated prompt tokens per agent step. Groq's free tier allows 8,000 tokens/minute and that bucket covers the prompt and the completion, so a request over it can never succeed — not on a retry, and not on another model. Every step resends the tool manifest plus all prior tool results, so without this cap a multi-step run grows past the limit and stalls. The orchestrator compacts the oldest tool results to stay under it, always preserving citations. |
.env.example documents every variable; .env is git-ignored and no key is
ever committed.
Build the retrieval index
The index is committed, so this is only needed if you change the corpus:
python -m rag.ingest.build_indexIt parses all 16 documents (Markdown, HTML, plain text, and PDF), chunks them on
heading boundaries, embeds them with BAAI/bge-small-en-v1.5 running locally via
ONNX, and writes rag/index/. Takes about 30 seconds. Deterministic — the same
corpus always produces the same 184 chunks, verified by a fingerprint in
rag/index/index_info.json.
Reproducibility
Every entry point — the web app, the index builder, and both evaluation
harnesses — calls config.apply_seeds() before doing any work, which fixes
random, numpy and PYTHONHASHSEED from the single SEED variable
(default 42). The seed used is written into rag/index/index_info.json
alongside the corpus fingerprint, so an index can always be traced back to the
corpus and seed that produced it.
Determinism is enforced, not just intended:
Chunking is deterministic; CI rebuilds the index and fails the build if the committed one does not match the corpus. The fingerprint normalises line endings, so a Windows checkout and a Linux container agree — that was a real bug, and the regression test for it is in
tests/test_ingestion.py.Retrieval is exact (no ANN approximation) over a committed index.
The agent runs at
AGENT_TEMPERATURE=0.0, and model rotation is reactive only, so a run cannot silently drift onto a different model mid-suite.Scoring is rule-based rather than LLM-judged, so the same trace always receives the same score.
The remaining source of variance is the provider itself, which is not
bit-reproducible even at temperature 0. design-and-evaluation.md reports that
honestly rather than claiming determinism the system does not have.
Run locally
uvicorn app.main:app --reload --port 8000Open http://127.0.0.1:8000. The app starts its own MCP server subprocess, so there is nothing else to launch.
Four demo questions are seeded in the UI, including one the system is expected to refuse. Every response shows the full trace: which tools ran, with which arguments, what came back, and which policy sections were cited.
Useful endpoints
Endpoint | Purpose |
| Liveness. Always 200 while the process is up. Used by the host. |
| Readiness. 503 when the index or a model provider is missing. |
| The live MCP tool manifest, as discovered from the server. |
| The indexed corpus. |
|
|
Running the MCP server on its own
The server is a standard MCP server and works with any MCP client, including Claude Desktop and MCP Inspector:
python mcp_server/hr_server.py # stdio
python scripts/mcp_smoketest.py # connect, list tools, call a fewTo run it as a separate HTTP service instead of a subprocess, set
MCP_TRANSPORT=http and MCP_SERVER_URL. The client supports both; stdio is the
default because it keeps the free-tier deployment to a single service.
Tests and checks
pytest -q # 143 tests, ~50 s
ruff check . # lint
python scripts/validate_mock_data.py # referential integrity of the mock data
python scripts/check_rules.py # hand-verified rule-engine edge cases
python scripts/healthcheck.py # end-to-end smoke test, no API key neededThe test suite covers ingestion determinism, retrieval and abstention, all 12 MCP tools over a real client session, the rule engine's date arithmetic, the agent loop against a scripted model, and the HTTP layer.
Evaluation
# No API key required -- retrieval quality and a 6-way ablation
python -m evaluation.run_retrieval_eval
# Requires an API key -- full agent evaluation over 28 cases
python -m evaluation.run_eval
python -m evaluation.run_eval --category refusal # one slice
python -m evaluation.run_eval --min-pass-rate 0.85 # gate for CIResults, methodology, and an honest reading of what the numbers do and do not
show are in design-and-evaluation.md. Raw output
lands in evaluation/results/.
Deployment
The repository deploys as a single Docker service on Render's free tier
(render.yaml + Dockerfile). The image bakes in the embedding model weights so
that startup does no network I/O.
docker build -t helios-hr .
docker run -p 8000:8000 -e GROQ_API_KEY=... helios-hrMeasured memory is 343 MB against the 512 MB free-tier cap
(evaluation/results/memory_footprint.txt).
Free-tier instances spin down after ~15 minutes idle; the first request
afterwards takes roughly 50 seconds. See deployed.md for the
live URL and the cold-start details.
Repository layout
agent/ orchestrator, MCP client, LLM providers with fallback, prompts
app/ FastAPI application, chat UI, static assets
corpus/ 16 HR policy documents in md / html / txt / pdf
mcp_server/ MCP server, 12 tool definitions, and the HR rule engine
mock_data/ 6 JSON datasets: employees, PTO, benefits, travel, offices, tickets
rag/ chunking, indexing, hybrid retrieval, abstention vocabulary
evaluation/ 28 scored cases, deterministic scorer, harnesses, results
scripts/ calibration, diagnostics, validation, smoke tests
tests/ 154 testsA note on the mcp_server/ directory name
It is not called mcp/. The official MCP Python SDK installs a top-level package
with that exact name, and a local mcp/ directory shadows it on sys.path, so
from mcp.server import ... would import this project instead of the SDK. The
assignment suggests mcp/ or equivalent; this is the equivalent.
This server cannot be deployed
Maintenance
Related MCP Connectors
Hosted MCP endpoint with realistic fake data for prototyping agents. 12 tools, no setup.
# **RChilli MCP Hub** RChilli MCP Hub is a production-grade MCP server that exposes RChilli's full HR data intelligence platform as 17 AI-callable tools across 4 categories. Built on 15+ years of HR data intelligence, it is trusted by ATS vendors, HR technology platforms, staffing agencies, and enterprise recruiting teams worldwide. Every tool is read-only and returns a consistent, structured JSON response — no raw exceptions, no inconsistent formats. <br> --- <br> # **Tools — 17 Total** userkey and subuserid are injected automatically from your Bearer token — you never need to pass them manually. <br> --- <br> # **🔍 Resume & Job Description Parsing — 3 tools** <br> > ### **`extract_resume_data`** > > Extracts and converts resumes, CVs, and candidate documents into structured, searchable profiles with contact details, skills, experience, education, certifications, and taxonomy-enriched data for ATS, HCM, and AI recruiting workflows. When used on a careers page or application form, the same extraction call auto-fills every application field in under 10 seconds — documented to increase candidate conversion by up to 194%. Supports 40+ languages with English-normalized output for global intake, and runs in batch mode to process legacy databases or migration backlogs overnight at scale. Also supports resume reprocessing — re-running previously extracted resumes through the latest extraction logic and taxonomy version to bring older records up to current data quality, without requiring a new document from the candidate. Distinct from bulk import (first-time extraction of a new batch) and from talent data refresh (re-enrichment from a newer submitted resume). <br> > ### **`extract_resume_data_from_url`** > > Accepts a direct URL to a PDF, DOCX, or RTF file and returns the same normalized JSON profile as the Resume Data Extraction tool. Ideal for pipeline automation where resumes are stored in cloud storage, S3, or email attachments. Also supports the same auto-fill, multilingual, and batch-processing capabilities as the core extraction tool for URL-based intake sources. <br> > ### **`extract_job_data`** > > Extracts and converts job descriptions into structured hiring data including job title, required skills, preferred skills, responsibilities, experience, education, and taxonomy-normalized role requirements for recruitment automation and candidate matching. <br> --- <br> # **🧠 Skills & Job Taxonomy — 4 tools** <br> > ### **`lookup_skill`** > > Returns authoritative detail for a known skill including description, all aliases, related skills, proficiency levels, and O*NET/ESCO mappings. Use when you need the complete record rather than a ranked search. <br> > ### **`lookup_job_profile`** > > Returns authoritative detail for a known job profile including canonical title, SOC/O*NET code, job family, typical required and preferred skills, salary bands, and work context. <br> > ### **`autocomplete_skill`** > > Accepts a partial skill string (min 2 chars) and returns up to 10 ranked autocomplete suggestions with canonical names and categories. Prevents free-text entry errors and keeps skill data clean at point of entry. <br> > ### **`autocomplete_job_profile`** > > Accepts a partial job title string and returns ranked autocomplete suggestions with canonical titles and job families. Ensures job titles map to taxonomy profiles from the moment a recruiter starts typing. <br> --- <br> # **🛡️ Redaction, Documents & Utilities — 7 tools** <br> > ### **`redact_resume`** > > Redacts personally identifiable information from candidate profiles to support anonymized review, bias-aware screening, compliance workflows, and audit logs. Configurable redaction scope. Idempotent. <br> > ### **`reformat_resume_with_template`** > > RChilli's Resume Reformatting tool accepts any structured candidate profile and applies one of six branded templates (TM001–TM006) to produce a consistently formatted output document in PDF, DOCX, RTF, or HTML — ensuring every candidate is presented in a standardized, professional layout regardless of how their original resume was structured. Designed for staffing firms, recruitment agencies, and enterprise HR teams who need to control candidate presentation at scale, it eliminates manual reformatting effort and enforces brand consistency across all submissions. <br> > ### **`convert_document_format`** > > Accepts a document as base64 or URL and converts between PDF, DOCX, RTF, HTML, and plain text. Preserves formatting fidelity. Useful as a pre-processing step before data extraction on non-standard file types. <br> > ### **`tag_entities`** > > RChilli's Named Entity Recognition tool takes already-extracted HR text and annotates it by wrapping each recognized entity in a structured XML-style label inline — returning output such as `<job_title>Senior Data Engineer</job_title>`, `<skill>Python</skill>`, `<city>Austin</city>`, `<degree>Bachelor of Science</degree>`, and `<organization>Google</organization>` — covering 10+ HR-specific entity types including person name, state, country, date, and year. Unlike data extraction tools that produce separate field lists, tag_entities preserves the full original text structure with entities labeled in place, making the output immediately consumable by ATS field-mapping pipelines, candidate profile builders, and content annotation workflows without any offset calculation or post-processing. <br> > ### **`extract_contacts`** > > Identifies and structures names, emails, phone numbers, LinkedIn URLs, and addresses with field-level confidence scores from candidate records, emails, or documents. Safe for GDPR/CCPA workflows. <br> > ### **`geolocate`** > > Converts partial or informal location text into structured city, state, country, ISO codes, latitude, and longitude. Enables radius-based candidate and job search and supports workforce planning analytics. <br> > ### **`classify_job_zone`** > > RChilli's Job Zone Classification tool reads the job profile from a resume or job description and returns its O/*NET Job Zone — one of five standardized levels ranging from Zone 1 (little or no preparation required) through Zone 2 (some preparation), Zone 3 (medium preparation), Zone 4 (considerable preparation), to Zone 5 (extensive preparation required) — based on the education, experience, and training criteria defined by O/*NET. The returned Job Zone level enables downstream workflows such as candidate-to-role fit filtering, compensation benchmarking, over/under-qualification flagging, and job architecture standardization without any manual O/*NET lookup. <br> --- <br> # **🎯 Search & Matching — 3 tools** <br> > ### **`score_resume_against_jd`** > > Accepts one resume and one Job Description (no index required) and returns an overall match score, dimension scores, skill gap list, and natural-language explanation. Bias-controlled and audit-ready. <br> > ### **`find_matches_in_index`** > > Accepts a resume or Job Description as input and returns the top-N most similar documents from the indexed corpus ranked by semantic similarity. No index setup required for the input document. <br> > ### **`search_indexed_documents`** > > Accepts a query string and returns ranked document references from the tenant's pre-populated index. Supports Boolean and semantic search modes. Requires documents to be indexed before use.
CareerProof MCP gives AI agents direct access to a professional-grade career and workforce intelligence platform. Two namespaces: atlas_* for HR/TA teams (candidate evaluation, batch shortlisting, competency scoring, interview generation, JD analysis, custom eval frameworks, research reports) and ceevee_* for professionals (CV optimization, career positioning, salary intelligence, market reports). Backed by RAG knowledge from 50+ premium research sources (McKinsey, BCG, HBR, Gartner, WEF)
Gateway between LLM agents and world data through eight tools and a bundled endpoint catalog.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceAn MCP server exposing employee info retrieval and web search tools, designed to be consumed by a LangChain agent for decoupled tool execution.-
- FlicenseCqualityCmaintenanceAgentic HR assistant providing employee, leave, meeting, ticket, and email tools over the Model Context Protocol, designed to automate onboarding workflows via an MCP client such as Claude Desktop.14-
- FlicenseNot gradedqualityCmaintenanceExposes travel planning data and constraint checking as MCP tools over stdio, enabling AI agents to query reference information and evaluate plan validity.-
- FlicenseNot gradedqualityCmaintenanceAn MCP server exposing internal business operations as tools — task management (create, list, update status) and RAG-style semantic search over an internal knowledge base (leave, expense, and onboarding policies) that any MCP-compatible AI agent can call directly for grounded, non-hallucinated answers.-