get_roles

Read-only

Calls GET /api/roles as the signed-in person · REST reference

List the roles the caller may view

BOUNDED BY THE CALLER'S ORG TREE: the roles of the organizations in which the caller holds admin.roles.view and of every organization beneath them, platform staff included. A role that belongs to no organization is listed to platform staff only. Another organization's roles are read by impersonating one of its people. A caller holding admin.roles.view nowhere is refused 403. Unpaginated, with no filter parameters. The model asks the DAL for limit: 1000 per call (one per organization in the tree, plus one for the roles of no organization), drops any role whose status is ARCHIVED, and sorts system roles first then alphabetically. ENVELOPE SHAPE — { success, data } from BaseController.success, not the bare array that GET /api/users returns. Rows are Role MODEL objects, not DAL entities: createdAt/updatedAt are ISO-8601 STRINGS (the DAL fragment's are epoch milliseconds), and the DAL's type, capabilities, orgId, userCount and soft-delete fields are dropped by the mapping.

Arguments

This tool takes no arguments.

Example call

A client sends this over the MCP session; Claude and other agents build it for you. The values are placeholders — the shape is real.

json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "get_roles",
    "arguments": {}
  }
}

Result

On success (HTTP 200) the tool returns one text item holding the API's JSON, pretty-printed.

Every non-archived role the caller may read, in the success envelope.

json
{
  "data": [
    {
      "createdAt": "2026-01-15T12:00:00Z",
      "groupCount": 1,
      "id": "11111111-1111-4111-8111-111111111111",
      "isSystem": true,
      "metadata": {},
      "name": "string",
      "permissions": [],
      "status": "ACTIVE",
      "createdBy": "11111111-1111-4111-8111-111111111111",
      "description": "string",
      "updatedAt": "2026-01-15T12:00:00Z"
    }
  ],
  "success": true
}

Fields

FieldTypeDescription
dataarray of object
data[].createdAtstring (date-time)ISO-8601 — converted from the DAL's epoch milliseconds.
data[].createdBystring (uuid) | null
data[].descriptionstring | null
data[].groupCountintegerGroups holding this role, projected by the DAL.
data[].idstring (uuid)
data[].isSystembooleanSystem roles are protected from rename and deletion.
data[].metadataobject
data[].namestring
data[].permissionsarray of string
data[].status"ACTIVE" | "INACTIVE" | "ARCHIVED"ARCHIVED never appears here — those rows are filtered out.
data[].updatedAtstring (date-time) | null
successtrue

When it fails

A failed call returns isError: true with the API's message as text.

403

Authenticated, but the caller holds none of the required permissions.

What the model is shown

This is the tool exactly as the server lists it in tools/list. The description starts with the REST call it makes.

json
{
  "name": "get_roles",
  "description": "GET /api/roles — BOUNDED BY THE CALLER'S ORG TREE: the roles of the organizations in which the caller holds `admin.roles.view` and of every organization beneath them, platform staff included. A role that belongs to no organization is listed to platform staff only. Another organization's roles are read by impersonating one of its people. A caller holding `admin.roles.view` nowhere is refused 403. Unpaginated, with no filter parameters. The model asks the DAL for `limit: 1000` per call (one per organization in the tree, plus one for the roles of no organization), drops any role whose status is ARCHIVED, and sorts system roles first then alphabetically. ENVELOPE SHAPE — `{ success, data }` from `BaseController.success`, not the bare array that `GET /api/users` returns. Rows are `Role` MODEL objects, not DAL entities: `createdAt`/`updatedAt` are ISO-8601 STRINGS (the DAL fragment's are epoch milliseconds), and the DAL's `type`, `capabilities`, `orgId`, `userCount` and soft-delete fields are dropped by the mapping.",
  "inputSchema": {
    "type": "object",
    "properties": {}
  },
  "annotations": {
    "readOnlyHint": true,
    "openWorldHint": false
  }
}