get_reporting_chain_up
Trace an employee's reporting chain upward from themselves to the top of the organization. Returns an ordered list ending with the highest manager.
Instructions
Walk the management chain upward from the given person. Returns an ordered list starting with the person and ending at the top of the chain (someone with no manager).
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| person_id | Yes | ||
| max_depth | No |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| result | Yes |
Implementation Reference
- humaans_mcp/server.py:178-192 (handler)The actual handler function for the get_reporting_chain_up tool. It walks the management chain upward from a given person by building a child→parent index from the full people list, then iterates from the person up to the top (someone with no manager).
@mcp.tool() async def get_reporting_chain_up(person_id: str, max_depth: int = 20) -> list[dict[str, Any]]: """Walk the management chain upward from the given person. Returns an ordered list starting with the person and ending at the top of the chain (someone with no manager).""" by_id, parent_of, custom_by_person = await _people_index() chain: list[dict[str, Any]] = [] seen: set[str] = set() current: str | None = person_id while current and current not in seen and len(chain) < max_depth: seen.add(current) person = by_id.get(current) if person is None: break chain.append(_person_summary(person, custom_by_person.get(current))) current = parent_of.get(current) return chain - humaans_mcp/server.py:178-178 (registration)The tool is registered via the @mcp.tool() decorator on the async function. 'mcp' is a FastMCP instance defined at line 7.
@mcp.tool() - humaans_mcp/server.py:127-148 (helper)The _people_index() helper builds the data structures used by get_reporting_chain_up: by_id (person id → person dict), parent_of (report id → manager id from the directReports array), and custom_by_person (person id → custom field values).
async def _people_index() -> tuple[dict[str, dict[str, Any]], dict[str, str], dict[str, dict[str, Any]]]: """Return (by_id, parent_of, custom_by_person). parent_of maps a report's id to their manager's id; custom_by_person maps personId to {fieldName: value}.""" all_people = await client().list_all("/people") by_id = {p["id"]: p for p in all_people if "id" in p} parent_of: dict[str, str] = {} for p in all_people: mgr_id = p.get("id") for child_id in p.get("directReports") or []: parent_of[child_id] = mgr_id names = await _custom_field_names() all_values = await client().list_all("/custom-values") values_by_person: dict[str, list[dict[str, Any]]] = {} for v in all_values: pid = v.get("personId") if pid: values_by_person.setdefault(pid, []).append(v) custom_by_person = { pid: _resolve_custom(vs, names) for pid, vs in values_by_person.items() } return by_id, parent_of, custom_by_person - humaans_mcp/server.py:151-160 (helper)The _person_summary() helper creates a summary dict for each person in the chain, merging custom field values with core identity fields.
def _person_summary(p: dict[str, Any], custom: dict[str, Any] | None = None) -> dict[str, Any]: return { **(custom or {}), "id": p.get("id"), "firstName": p.get("firstName"), "lastName": p.get("lastName"), "jobTitle": p.get("jobTitle"), "email": p.get("email"), "contractType": p.get("contractType"), } - humaans_mcp/server.py:179-179 (schema)The input schema is defined by the function signature: person_id (str, required) and max_depth (int, optional, default 20). The return type is list[dict[str, Any]].
async def get_reporting_chain_up(person_id: str, max_depth: int = 20) -> list[dict[str, Any]]: