Skip to main content
Glama
mcp-mayo

mcp-mayo

MCP Mayo

PyPI version Python License: MIT MCP GitHub stars GitHub issues GitHub last commit

MCP Server for MAYO Apollo — exposes the HRM platform's Foundation (人事), Attendance (差勤), and Payroll (薪資勞健保) APIs as AI-callable tools via the Model Context Protocol.

繁體中文 · Part of the Asgard AI Platform open-source ecosystem.

What This Does

  • 33 tools — 28 thin wrappers around every MAYO Apollo endpoint plus 5 semantic compositions

  • Three backend domains — Foundation, Attendance, Payroll — served from one MCP server with a single hrmlicense API key

  • Date-format normalization — callers use ISO YYYY-MM-DD / YYYY-MM; the server converts to each endpoint's expected format internally

  • Semantic aggregations — one-call helpers like get_employee_profile, get_organization_snapshot_as_of, get_attendance_summary

  • Typed with Pydantic — every parameter has a description the AI can see

  • E2E test runner — exercises every registered tool against the live PRE environment

Related MCP server: MCP Employee Identity Server

Quick Start

Install

Requires Python 3.10+, uv (recommended) or pip, and a MAYO-issued hrmlicense API key with read access to the FD / PT / PY backends you plan to call.

From PyPI (once published):

uv add mcp-mayo
# or
pip install mcp-mayo

From source (current state):

git clone https://github.com/asgard-ai-platform/mcp-mayo.git
cd mcp-mayo
uv sync
cp .env.example .env
# Edit .env and set MAYO_API_KEY

Set your API key:

export MAYO_API_KEY=your_hrmlicense_token

Env var

Required

Purpose

MAYO_API_KEY

Yes

The token value placed on the hrmlicense header; authenticates Foundation, Attendance, and Payroll in a single credential

Run the server directly to verify it starts:

uv run --env-file .env python mcp_server.py

Use with Claude Code

Add the server via the Claude CLI:

claude mcp add --transport stdio mayo -e MAYO_API_KEY=your_hrmlicense_token -- uvx mcp-mayo

Or, when working from a local clone, .mcp.json:

{
  "mcpServers": {
    "mayo": {
      "command": "uv",
      "args": ["run", "mcp-mayo"],
      "cwd": "${PWD}",
      "env": {
        "PYTHONPATH": "${PWD}",
        "MAYO_API_KEY": "${MAYO_API_KEY}"
      }
    }
  }
}

Use with Claude Desktop

Add to your claude_desktop_config.json:

{
  "mcpServers": {
    "mayo": {
      "command": "uvx",
      "args": ["mcp-mayo"],
      "env": {
        "MAYO_API_KEY": "your_hrmlicense_token"
      }
    }
  }
}

Use with other MCP clients

Cursor and any other MCP-compatible client: point it at uvx mcp-mayo with MAYO_API_KEY in its environment.

Tools (33)

Tool

What it does

get_employee_profile

One employee's PA + work history + education in a single call

get_organization_snapshot_as_of

Org tree + active headcount for a date

get_attendance_summary

History + abnormal + overtime + leave fan-out over a range

search_active_employees

list_active_employees with today as default

get_monthly_payroll_report

Single-month salary/bonus roster using ISO YYYY-MM

Foundation (FD) — 15

list_active_employees ¹, list_resigned_employees ¹, get_organization_tree ¹, export_organization_with_employees, export_employees, export_departments, export_organization_full, export_employees_full, export_expatriations, export_working_history, export_education_history, export_employee_changes, export_organization_changes, export_pa_options, export_company_custom_fields

Attendance (PT) — 8

get_attendance_rules, get_attendance_history, get_attendance_abnormal, get_forgot_checkin_records, get_leave_history, get_employee_calendar, get_overtime_records, get_trip_history ²

Payroll (PY) — 5

get_monthly_labor_insurance ², get_monthly_nhi ², get_monthly_labor_pension ², get_salary_insurance_detail, get_salary_bonus_list

¹ The three /ClientOut/ReportCenter/* routes (plus the two semantic wrappers search_active_employees and get_organization_snapshot_as_of that depend on them) currently return 404 on the PRE Foundation backend. The tools stay exposed so they work the moment MAYO redeploys these endpoints.

² Flagged as failing upstream in MAYO's own Postman collection. Same story — tool stays, docstring carries a KNOWN ISSUE note.

Usage Examples

"Who was active in department C030010 yesterday?"

You: 昨天 C030010 部門還在職的人列一下

AI calls:

search_active_employees(
  dept_code = "C030010",
)

Result: SUCCESS — returns the active-employee list from the Foundation backend with today as the effective date.

"Give me A00384's full profile"

You: 給我員編 A00384 的完整資料

AI calls:

get_employee_profile(
  employee_number = "A00384",
)

Result: SUCCESS — aggregates /PA, /Working, and /Education, locally filtered to A00384.

"Attendance picture for the first week of September"

You: 9/1 到 9/7 的出勤統計,含異常跟加班

AI calls:

get_attendance_summary(
  start_date = "2025-09-01",
  end_date   = "2025-09-07",
)

Result: SUCCESS — returns history, abnormal, overtime, and leave sections for the range.

"January salary roster"

You: 2025-01 的薪資發放清冊

AI calls:

get_monthly_payroll_report(
  year_month = "2025-01",
)

Result: SUCCESS — converts to 2025/01 under the hood and calls SalaryBonusList.

Architecture

stdio (JSON-RPC 2.0)
  → mcp_server.py                 entry point; imports tool modules
    → app.py                      FastMCP("mcp-mayo") singleton
      → tools/                    @mcp.tool() decorated functions
          foundation_tools.py       15 FD wrappers
          attendance_tools.py       8 PT wrappers
          payroll_tools.py          5 PY wrappers
          semantic_tools.py         5 high-level compositions
        → connectors/rest_client.py  retry + multi-domain URL resolution
          → auth/api_key.py          builds {"hrmlicense": <MAYO_API_KEY>}
            → config/settings.py     BASE_URLS + ENDPOINTS (keyed by domain)

Testing

uv run --env-file .env python scripts/auth/test_connection.py   # probes FD / PT / PY
uv run --env-file .env python tests/test_all_tools.py           # runs every tool

Contributing

See CONTRIBUTING.md.

License

MIT — see LICENSE.

Available Tools

33 tools
export_company_custom_fieldsB

Export the custom field definitions configured by the tenant.

Inputs: language.

export_departmentsA

Export effective department master data (core fields only).

Inputs: language.

export_education_historyA

Export all employees' education records.

Inputs: no named parameters.

export_employee_changesA

Export employee change orders within a date range (paginated).

Inputs: end_date (required), start_date (required), language, page_size, +1 more.

export_employeesA

Export effective employee master data (core fields only).

Inputs: language.

export_employees_fullC

Export effective employee data with every PA field. Supports many optional filters.

Inputs: end_date, language, start_date, bank_details, +4 more.

export_expatriationsB

Export effective employee expatriation (外派/派駐) assignments.

Inputs: language.

export_organization_changesB

Export organization change orders within a date range (paginated).

Inputs: end_date (required), start_date (required), language, page_size, +1 more.

export_organization_fullC

Export effective organization master data with all fields (OM endpoint).

Inputs: language.

export_organization_with_employeesC

Export effective organization units together with their employees (OM + PA).

Inputs: language.

export_pa_optionsC

Export reference code tables used by the People+ (PA) module.

Inputs: language.

export_working_historyA

Export all employees' work-experience records.

Inputs: no named parameters.

get_attendance_abnormalA

Get attendance exceptions (late, early leave, missed punch, etc.) within a date range.

Inputs: end_date (required), start_date (required).

get_attendance_historyA

Get raw clock-in / clock-out records across all employees within a date range.

Inputs: end_date (required), start_date (required).

get_attendance_rulesA

Get each employee's base attendance configuration as of a given date.

Returns the shift, rest-day rule, and attendance-group information that applies to every active employee on search_date.

Inputs: search_date (required).

get_attendance_summaryA

Build a consolidated attendance picture for a date range.

Fans out to attendance_history plus optional attendance_abnormal, overtime_records, and leave_history, returning each section under a dedicated key.

Inputs: end_date (required), start_date (required), include_leave, include_abnormal, +1 more.

get_employee_calendarA

Get each employee's assigned shift calendar (work day / rest day / holiday) for a range.

Inputs: end_date (required), start_date (required).

get_employee_profileA

Aggregate one employee's master, work history, and education into a single profile.

Calls PA (filtered by employee_number) plus the company-wide Working and Education exports, then filters the latter two down to the target employee. Useful when an assistant needs a complete picture without having to call three raw tools and join the results.

Inputs: employee_number (required), language.

get_forgot_checkin_recordsA

Get manually-added or corrected clock-in records within a date range.

Inputs: end_date (required), start_date (required).

get_leave_historyA

Get approved and pending leave applications within a date range (leave_historyV2).

Inputs: end_date (required), start_date (required).

get_monthly_labor_insuranceB

Get the monthly labor insurance (勞保) detail list for an insurance unit.

KNOWN ISSUE: This endpoint is marked as failing upstream in MAYO's own Postman collection. Expect a server-side error response until MAYO fixes it.

Inputs: search_date (required), insurance_no (required), language.

get_monthly_labor_pensionA

Get the monthly labor pension (勞退) detail list for a unit.

KNOWN ISSUE: This endpoint is marked as failing upstream in MAYO's own Postman collection. Expect a server-side error response until MAYO fixes it.

Inputs: search_date (required), insurance_no (required), language.

get_monthly_nhiA

Get the monthly National Health Insurance (健保) detail list for a unit.

KNOWN ISSUE: This endpoint is marked as failing upstream in MAYO's own Postman collection. Expect a server-side error response until MAYO fixes it.

Inputs: search_date (required), insurance_no (required), language.

get_monthly_payroll_reportA

Get the salary and bonus distribution roster for a single month.

Accepts ISO YYYY-MM (or YYYY-MM-DD, truncated) and converts to MAYO's required YYYY/MM format. Use the raw get_salary_bonus_list tool when you need a multi-month range.

Inputs: year_month (required).

get_organization_snapshot_as_ofA

Capture the organization tree and active headcount as of a specific date.

Combines organization_tree (OrgData) with active_employees (ActiveEmployeeData) so one call returns both the org hierarchy and the people staffed against it on that day.

KNOWN ISSUE: Both underlying Report Center routes currently 404 on the PRE Foundation backend. This composite tool will light up once MAYO redeploys those endpoints.

Inputs: dept_code, as_of_date.

get_organization_treeA

Get the organization hierarchy as of a specific date.

KNOWN ISSUE: The /ClientOut/ReportCenter/OrgData route returns 404 on the PRE Foundation backend. The tool is kept for when MAYO deploys the Report Center endpoints to this environment.

Inputs: query_date (required), dept_code, include_ineffective.

get_overtime_recordsB

Get approved overtime records within a date range.

Inputs: end_date (required), start_date (required).

get_salary_bonus_listA

Get the salary and bonus distribution roster across a month range.

Accepts ISO-style YYYY-MM input (or a full YYYY-MM-DD, which is truncated to its month) and sends MAYO's expected YYYY/MM format internally.

Inputs: end_month (required), start_month (required).

get_salary_insurance_detailA

Get per-employee salary insurance contribution detail for a given date.

Inputs: search_date (required), language, dept_code, employee_number, +1 more.

get_trip_historyA

Get business trip / field-work records within a date range.

KNOWN ISSUE: This endpoint is marked as failing upstream in MAYO's own Postman collection. Expect a server-side error response until MAYO fixes it.

Inputs: end_date (required), start_date (required).

list_active_employeesA

List active employees as of a given date, optionally scoped to a department.

KNOWN ISSUE: The /ClientOut/ReportCenter/ActiveEmployeeData route returns 404 on the PRE Foundation backend. The tool is kept for when MAYO deploys the Report Center endpoints to this environment.

Inputs: effective_date (required), dept_code.

list_resigned_employeesA

List employees who resigned or took leave within a date range.

KNOWN ISSUE: The /ClientOut/ReportCenter/ResignAndLeaveData route returns 404 on the PRE Foundation backend. The tool is kept for when MAYO deploys the Report Center endpoints to this environment.

Inputs: end_date (required), start_date (required), dept_code.

search_active_employeesB

List active employees as of a date, defaulting to today when as_of_date is omitted.

KNOWN ISSUE: Wraps /ClientOut/ReportCenter/ActiveEmployeeData, which currently returns 404 on the PRE Foundation backend.

Inputs: dept_code, as_of_date.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    B3.2/5.0

    Scored across 33 tools

    Disambiguation2/5

    Several tool pairs have unclear boundaries, such as list_active_employees vs search_active_employees, get_salary_bonus_list vs get_monthly_payroll_report, and export_employees vs export_employees_full. While descriptions attempt to differentiate them, the overlap makes it easy for an agent to select the wrong tool.

    Naming Consistency3/5

    Most tools follow a snake_case verb_noun pattern, but the verbs are inconsistent: list, get, search, and export are used interchangeably without a clear rule. For example, list_active_employees and search_active_employees both exist, and get_ vs export_ prefixes are used for similar data.

    Tool Count2/5

    With 33 tools, the server is well beyond the typical 3-15 range. Although the HR domain is broad, many tools are redundant or could be consolidated, such as the multiple export variants and monthly insurance getters, making the count feel excessive.

    Completeness4/5

    The server covers a wide range of HR data including employees, organization, attendance, leave, salary, insurance, and expatriation. Composite tools like get_employee_profile and get_attendance_summary fill gaps, though write operations are absent, which is acceptable for a reporting-focused server.

    Maintenance

    ActivityInactive
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers