get_person
Retrieve a person by their Humaans id; custom field values are merged as top-level keys, with native attributes prevailing on name conflicts.
Instructions
Retrieve a single person by their Humaans id. Employee-scoped custom field values are merged onto the person object as top-level keys named after the field (e.g. "Level": "IC5", "Cost Center": ["R&D"]). Native attributes win on name collisions.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| person_id | Yes |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||
Implementation Reference
- humaans_mcp/server.py:59-67 (handler)The main handler for the 'get_person' tool. Fetches a person by ID from /people/{person_id}, retrieves custom field names and values for that person, and merges employee-scoped custom field values onto the person object as top-level keys.
@mcp.tool() async def get_person(person_id: str) -> dict[str, Any]: """Retrieve a single person by their Humaans id. Employee-scoped custom field values are merged onto the person object as top-level keys named after the field (e.g. "Level": "IC5", "Cost Center": ["R&D"]). Native attributes win on name collisions.""" person = await client().get(f"/people/{person_id}") names = await _custom_field_names() values = await client().list_all("/custom-values", filters={"personId": person_id}) for k, v in _resolve_custom(values, names).items(): person.setdefault(k, v) return person - humaans_mcp/server.py:59-59 (registration)The tool is registered using the @mcp.tool() decorator on line 59, which registers 'get_person' with the FastMCP server.
@mcp.tool() - humaans_mcp/server.py:59-67 (schema)The input schema is defined by the function signature: takes a single 'person_id' parameter of type str. The output type is dict[str, Any]. The decorator @mcp.tool() auto-generates the JSON schema from this type annotation.
@mcp.tool() async def get_person(person_id: str) -> dict[str, Any]: """Retrieve a single person by their Humaans id. Employee-scoped custom field values are merged onto the person object as top-level keys named after the field (e.g. "Level": "IC5", "Cost Center": ["R&D"]). Native attributes win on name collisions.""" person = await client().get(f"/people/{person_id}") names = await _custom_field_names() values = await client().list_all("/custom-values", filters={"personId": person_id}) for k, v in _resolve_custom(values, names).items(): person.setdefault(k, v) return person - humaans_mcp/server.py:104-107 (helper)Helper function _custom_field_names() fetches all custom field definitions and returns a mapping of customFieldId -> field name. Called by get_person to resolve custom field IDs to human-readable names.
async def _custom_field_names() -> dict[str, str]: """Map customFieldId → field name for every custom field configured.""" fields = await client().list_all("/custom-fields") return {f["id"]: f.get("name") for f in fields if f.get("id")} - humaans_mcp/server.py:110-124 (helper)Helper function _resolve_custom() processes custom field values for a person, filtering to employee-scoped values (resourceId is null) and mapping them to field names. Called by get_person to merge custom data onto the person object.
def _resolve_custom(values: list[dict[str, Any]], names: dict[str, str]) -> dict[str, Any]: """Project employee-scoped custom values (resourceId is null) into {fieldName: value}. Job-role/salary-bound values are skipped — query /custom-values directly for those.""" by_name: dict[str, list[dict[str, Any]]] = {} for v in values: if v.get("resourceId") is not None: continue name = names.get(v.get("customFieldId") or "") if not name: continue by_name.setdefault(name, []).append(v) return { name: max(vs, key=lambda v: v.get("updatedAt") or "")["value"] for name, vs in by_name.items() }