hr-agent-mcp
Provides tools for querying and managing employee time records stored in a SQLite database, including viewing punch histories, listing and approving adjustments, and maintaining an audit log.
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-agent-mcpShow my time logs for last week"
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.
🕐 HR Agent MCP
Conversational HR agent that replaces static time-tracking screens with a chat interface — built with MCP, LangGraph, RAG and BigQuery.
🔗 Live demo: hr-agent-mcp-cyd.streamlit.app (password: on request) ·
What it does
The agent handles four kinds of natural-language requests, all through chat:
Time-punch queries — "how were Ana's punches over the last two weeks?" returns the history, with late arrivals and incomplete punches highlighted.
Policy questions, with sources — "what is the lateness tolerance?" is answered with RAG over the company's HR policies, citing the source document rather than a generic summary.
Adjustment approval with human confirmation — write requests (for example, approving a time-punch adjustment) go through an explicit confirmation card before anything changes in the database, and are recorded in an audit trail.
Analytics on BigQuery — analytical questions ("which team accumulated the most overtime per month?") generate SQL via LLM, which passes through a governance layer before touching the warehouse.
▶️ Try it live: hr-agent-mcp-cyd.streamlit.app — or follow the 3-minute walkthrough.
Related MCP server: HRizzle-HR-Assist
Architecture
flowchart TD
UI[Streamlit — chat + MCP panel] --> AG[LangGraph — ReAct agent\nmemory + human-in-the-loop]
AG -->|MCP stdio| SRV[MCP server — FastMCP]
SRV --> T1[consultar_batidas] --> DB[(SQLite\noperational)]
SRV --> T2[list/approve adjustments] --> DB
T2 --> AUD[(audit_log)]
SRV --> T3[consultar_politica] --> RAG[FAISS — HR policies]
SRV --> T4[analytics_rh] --> BQ[(BigQuery\nrh_analytics)]
ETL[Python ETL\nextract→transform→load] --> DB
ETL --> BQThe system deliberately separates two worlds: the operational side (SQLite, read-write, low latency, day-to-day data such as punches and adjustments) and the analytical side (BigQuery, read-only, aggregated data for management questions). This separation keeps heavy analytical queries from competing with the transactional path, and keeps the warehouse as a derived, auditable copy — never a source of truth for writes.
Technical decisions
Tools behind an MCP server (stdio) rather than in-process functions: the agent and the tool layer evolve independently, and any MCP-compatible client can reuse the same server.
Every write goes through
interrupt— the graph pauses and hands control back to the UI, which requires explicit human confirmation — and is recorded inaudit_logbefore it counts as done. The agent never writes silently.LLM-generated SQL passes a governance layer before touching BigQuery, instead of trusting the model with raw warehouse access.
Two-layer eval scoring — deterministic checks (tool choice, regex, gate state) plus LLM-as-judge only for what string matching cannot cover.
Capabilities demonstrated
Capability | Where in the code |
MCP (server + client) |
|
Agent orchestration (LangGraph) |
|
Human-in-the-loop (interrupt) |
|
RAG (FAISS + embeddings) |
|
ETL (extract→transform→load) |
|
BigQuery + SQL governance |
|
Agent evaluation (evals) |
|
Python APIs / tests / CI |
|
Evaluation (evals)
The agent is evaluated end-to-end by a 28-case suite across 8 categories
(routing, operational, policies, analytics, write gate, governance,
disambiguation and cross-source questions), with two-layer scoring —
deterministic (tool chosen, regex, gate state) plus LLM-as-judge for what string
matching cannot cover. Write cases run against an isolated copy of the database.
Run with uv run python -m evals.run; results live in EVALS.md.
Running locally
git clone https://github.com/cydgxbriel/hr-agent-mcp.git && cd hr-agent-mcp
cp .env.example .env && uv sync # fill in OPENAI_API_KEY
uv run python -m etl.pipeline && uv run streamlit run app/main.pyAPP_PASSWORD is optional in development (it protects the app when publicly
exposed). BigQuery is optional too: without configured credentials the agent
keeps working and the analytics tool degrades gracefully, reporting the feature
as unavailable instead of failing.
BigQuery (optional)
Create a project in the GCP Sandbox (free, no credit card).
Create a service account with BigQuery Data Editor + BigQuery Job User roles in that project (Data Editor creates datasets; Job User runs load jobs and queries — least privilege).
Download the service account's JSON key.
Set
GCP_PROJECT_IDin.envto the new project id — without this variable the BigQuery client stays disabled even with credentials configured.Point
GOOGLE_APPLICATION_CREDENTIALSat the key file path (local use) or paste the file contents intoGCP_SERVICE_ACCOUNT_JSON(Streamlit Cloud, which has no persistent filesystem).Run
uv run python -m etl.pipelineto load therh_analyticsdataset (tableagregados_mensais) into BigQuery.
Data
All data is 100% synthetic, generated with Faker (seed 42): employees, time punches, adjustments and HR policies are fictional personas and documents created exclusively for this demonstration. No real data from any company is used or referenced anywhere in the project.
Stack
Python 3.11+
uv (environment and dependency management)
mcp ≥1.2 / FastMCP (stdio MCP server)
LangGraph ≥0.2.60 (ReAct agent orchestration)
langchain-mcp-adapters ≥0.1 (the agent's MCP client)
langchain-openai ≥0.2.10 (gpt-4o-mini)
langchain-community ≥0.3.10 / FAISS ≥1.8 (RAG)
pandas ≥2.2 (ETL)
Faker ≥30 (synthetic data generation)
google-cloud-bigquery ≥3.25
Streamlit ≥1.40 (chat interface)
pytest ≥8 (35 tests)
ruff (lint)
Available Tools
5 toolsanalytics_rhA
Executa uma consulta analítica SELECT no data warehouse (BigQuery).
Use para perguntas agregadas sobre a equipe: total de horas extras por mês, evolução de atrasos, batidas incompletas por equipe. Escreva SQL padrão BigQuery usando exclusivamente esta tabela: rh_analytics.agregados_mensais — colunas: equipe STRING (Produto, Engenharia, Comercial), mes STRING 'YYYY-MM', total_atraso_minutos INT64, total_hora_extra_minutos INT64, batidas_incompletas INT64, colaboradores INT64. Somente SELECT é aceito; a consulta passa por validação de governança. Não use WITH/CTE, ponto e vírgula nem comentários — apenas um SELECT direto.
| Name | Required | Description | Default |
|---|---|---|---|
| consulta_sql | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description carries full burden. Discloses constraints: SELECT only, no CTEs/semicolons/comments, and governance validation. Does not mention rate limits or authentication, but adds valuable behavioral context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Every sentence serves a purpose: action, usage, schema, constraints. No wasted words; front-loaded with the core function.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers purpose, usage, SQL details, and constraints. Output schema exists, so return values need not be described. Could explicitly state no side effects, but overall complete for a SQL query tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, but description fully compensates by detailing the required SQL content, exact table and columns, and formatting constraints. Adds critical meaning beyond the generic schema title.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Specific verb 'Executa' and resource 'consulta analítica SELECT no data warehouse (BigQuery)'. Clearly distinguishes from sibling tools like 'aprovar_ajuste' (approvals) and 'consultar_batidas' (time tracking).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit use cases for aggregate queries (horas extras, atrasos, batidas incompletas) and specifies the table and columns. Lacks explicit when-not-to-use or alternative pointers, but sibling context helps.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
aprovar_ajusteA
Aprova um ajuste de ponto pendente. AÇÃO DE ESCRITA com auditoria.
Use somente quando a gestora pedir explicitamente para aprovar um ajuste. Exige o id do ajuste (veja listar_ajustes_pendentes) e uma justificativa. A aprovação corrige a batida e registra na trilha de auditoria.
| Name | Required | Description | Default |
|---|---|---|---|
| ajuste_id | Yes | ||
| justificativa | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description discloses that it is a WRITE ACTION with audit, and explains that approval corrects the clock-in/out and records in the audit trail, sufficient behavioral context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences long, front-loaded with the core purpose, and every sentence earns its place (purpose, usage condition, behavioral note).
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity (2 parameters, no annotations, output schema exists), the description adequately covers purpose, usage, inputs, and behavior, though output details are left to the schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, but the description adds meaning by stating that ajuste_id comes from listar_ajustes_pendentes and that justificativa is required. However, it does not elaborate on formats or constraints.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Approve a pending time adjustment' with a specific verb and resource, distinguishing it from sibling tools like listar_ajustes_pendentes which lists adjustments.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states 'Use only when the manager explicitly asks to approve an adjustment' and directs the user to listar_ajustes_pendentes to obtain the adjustment ID, providing clear when-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
consultar_batidasA
Consulta as batidas de ponto de um colaborador da equipe num período.
Use para perguntas sobre horários, atrasos, horas extras ou batidas faltantes de uma pessoa específica. Aceita nome parcial (ex.: 'Bruno'). Datas no formato YYYY-MM-DD. O período dos dados vai de maio a julho de 2026.
| Name | Required | Description | Default |
|---|---|---|---|
| data_fim | Yes | ||
| data_inicio | Yes | ||
| nome_colaborador | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description properly discloses important behaviors: accepts partial names ('Aceita nome parcial'), expects date format YYYY-MM-DD, and notes the data range (maio a julho de 2026). This adds value beyond the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, each purposeful: purpose, usage scenarios, and technical details. No redundant or unnecessary information. Efficiently structured.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given three required parameters, no annotations, and an output schema present, the description adequately covers purpose, usage, parameter details, and data constraints. Lacks explanation of absence handling, but output schema likely covers return structure.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so description must compensate. It explains that 'nome_colaborador' accepts partial names, and date parameters use format YYYY-MM-DD within a specific period. This gives meaning to the three parameters beyond their schema titles.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it consults time punches ('batidas de ponto') for a team member in a period, using specific verb 'Consulta'. This distinctly separates it from sibling tools like analytics_rh (HR analytics) or aprovar_ajuste (approve adjustments).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says 'Use para perguntas sobre horários, atrasos, horas extras ou batidas faltantes de uma pessoa específica', providing clear when-to-use context. It doesn't explicitly state when not to use, but the sibling tool names imply alternatives for other tasks.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
consultar_politicaA
Busca trechos relevantes das políticas internas de RH (RAG).
Use para dúvidas sobre regras: tolerância de atraso, banco de horas, ajuste de batida, home office, advertências. Retorna trechos literais com a fonte; responda com base neles, citando a política.
| Name | Required | Description | Default |
|---|---|---|---|
| pergunta | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries full behavioral disclosure. It states the tool returns literal excerpts with sources and instructs the agent to respond based on them citing the policy. It does not mention read-only behavior or authentication, but for a RAG search tool, the transparency is adequate.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is very concise: two sentences that cover purpose, usage, and return value. It is front-loaded with the main action and every sentence adds value. No redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has only one parameter and the output schema exists (though not shown), the description covers what the tool does, when to use it, and what the output contains. It is complete for a simple RAG query tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has one parameter 'pergunta' with no description (schema coverage 0%). The description compensates by indicating the parameter should be a question about HR rules and gives examples. While it doesn't detail syntax, it provides enough context for the parameter's purpose.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool searches for relevant excerpts from internal HR policies using RAG. It lists specific examples like tolerância de atraso and banco de horas, making the purpose concrete. The sibling tools (analytics_rh, aprovar_ajuste, etc.) are distinct, so there is no confusion.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says 'Use para dúvidas sobre regras' and provides a list of example use cases. However, it does not explicitly state when not to use this tool or compare it directly to siblings, though the sibling names imply different functions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
listar_ajustes_pendentesA
Lista os ajustes de ponto aguardando aprovação da gestora.
Use quando a gestora perguntar o que está pendente, o que precisa aprovar, ou pedir a fila de ajustes. Retorna id, colaborador, data, campo a corrigir, valor proposto e motivo.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Sem anotações, mas a descrição informa que retorna uma lista de ajustes pendentes (id, colaborador, data, etc.). Não menciona efeitos colaterais, mas é claramente uma leitura. Poderia ser mais explícito sobre não ser destrutivo.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Duas frases, sem redundância. A primeira frase define o propósito, a segunda fornece contexto de uso e conteúdo do retorno. Front-loading perfeito.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Para uma ferramenta simples e sem parâmetros, a descrição cobre o suficiente: o que faz, quando usar e o que retorna. A existência de output schema complementa.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Nenhum parâmetro. A descrição não precisa adicionar informações sobre parâmetros, pois o schema já cobre 100%. Baseline para 0 parâmetros é 4.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Descrição específica: 'Lista os ajustes de ponto aguardando aprovação da gestora'. Verbo claro ('Lista') e recurso definido. Distingue-se dos irmãos como 'aprovar_ajuste' e 'consultar_batidas'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitamente diz quando usar: 'Use quando a gestora perguntar o que está pendente, o que precisa aprovar, ou pedir a fila de ajustes'. Falta contraste direto com alternativas, mas fica implícito.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
5 tool updates
v0.1.0- First observed
analytics_rh - First observed
aprovar_ajuste - First observed
consultar_batidas - First observed
consultar_politica - First observed
listar_ajustes_pendentes
TDQS
Scored across 5 tools
Each tool targets a distinct aspect: aggregate analytics, individual punch queries, policy lookup, listing adjustments, and approving adjustments. There is no functional overlap.
All names follow snake_case and imperative verb_noun pattern, but 'analytics_rh' mixes English verb with Portuguese noun, while others are fully Portuguese.
Five tools cover the core HR agent tasks concisely without being too sparse or overwhelming. The count fits the scope well.
Covers analytics, individual queries, policy lookup, and adjustment workflow (list and approve). Missing a reject action for adjustments but otherwise complete for manager tasks.
Maintenance
Related MCP Connectors
MCP-Native LLM Orchestration Agent
Human-in-the-loop review and approval for AI agents. Audit trail, approval policies, native MCP.
Human-in-the-loop for AI agents over MCP: durable approvals with a hosted review page & audit trail
Let AI agents query data and act across all your business apps via MCP.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceAn MCP-powered HR management system that automates employee onboarding, leave tracking, meeting scheduling, and IT ticketing. It allows users to manage organizational workflows and administrative tasks through natural language interactions with Claude.2-
- AlicenseNot gradedqualityDmaintenanceMCP-based HR automation tool that streamlines employee onboarding, leave management, and equipment requests via natural language conversations.1MIT
- FlicenseNot gradedqualityCmaintenanceAn MCP server for interacting with an HR database, enabling querying employee data and HR operations via natural language.-
- FlicenseNot gradedqualityBmaintenanceEnables querying HR data like recent hires, employee details, departments, and PTO balances through natural language in an MCP client.-