Microsoft Entra Identity Tool
Read Microsoft Entra (Azure AD) users, groups and group membership. This is the tool for who is in the directory, who is in a group, who reports to whom, and which accounts are disabled. It reads no mail, no files and no Teams messages, so it asks for only the two directory scopes it needs.
Tool ID
msgraph-identity
Credential Required
Yes — the shared msgraph credential, owned by the msgraph connector. Configure the tenant
once and all nine tools use it; rotating the client secret is one edit rather than nine.
It is a server-managed OAuth credential: InTouch mints and refreshes the access token itself and
the connector never sees the secret. For unattended work set grant_type to client_credentials
(the app-only grant) — an app-only token belongs to the application, so a 06:00 schedule does not
run as a person, see only what that person can see, and stop working the day they leave.
Credential Properties
| Property | Type | Default | Description |
|---|---|---|---|
client_id |
string | — | Required. The Entra app registration's Application (client) ID. |
client_secret |
string | — | Required for app-only. The secret's Value, not its Secret ID. |
token_url |
string | — | Required. https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/token |
grant_type |
string | (blank) | client_credentials for unattended app-only use. Blank means the user-delegated refresh-token flow. |
scope |
string | — | https://graph.microsoft.com/.default — resolves to whatever application permissions an admin has consented to. |
access_token |
string | — | Machine-managed. Leave empty; the server mints and persists it. |
refresh_token |
string | — | Delegated credentials only. Not used by the app-only grant. |
expires_at |
string | 0 |
Machine-managed expiry, epoch seconds. |
Entra setup
- https://entra.microsoft.com → App registrations → your app → API permissions.
- Add a permission → Microsoft Graph → Application permissions — not Delegated. Picking Delegated is the most common failure: it consents cleanly and then 403s at runtime.
- Tick the permissions listed under Permissions below, then Grant admin consent. The Status column must read Granted.
- Permissions live in the token, not the portal. A token minted before the grant carries the old
claims for about an hour — blank
access_tokento force a fresh mint.
Permissions
User.Read.All and GroupMember.Read.All, or the single Directory.Read.All that covers both.
Operations
1. list_users — List users
Every user in the tenant. Calls GET /users.
Properties:
| Property | Type | Default | Description |
|---|---|---|---|
operation |
string | — | Required. list_users |
query |
string | — | Optional. OData query params as a JSON object string. Ask for only the fields you need — e.g. {"$select": "displayName,userPrincipalName,accountEnabled"} — and filter server-side where you can, e.g. {"$filter": "accountEnabled eq false"}. |
Published Outputs:
- result — the JSON response body
- status — HTTP status code
2. get_user — Get one user
One user by id or userPrincipalName (e.g. [email protected]). Calls GET /users/{id}.
Properties:
| Property | Type | Default | Description |
|---|---|---|---|
operation |
string | — | Required. get_user |
id |
string | — | Required. User or group id, or a user principal name (e.g. [email protected]). Required by get_user, get_user_manager, get_group and list_group_members. |
query |
string | — | Optional. OData query params as a JSON object string. Ask for only the fields you need — e.g. {"$select": "displayName,userPrincipalName,accountEnabled"} — and filter server-side where you can, e.g. {"$filter": "accountEnabled eq false"}. |
Published Outputs:
- result — the JSON response body
- status — HTTP status code
3. get_user_manager — Get a user's manager
That user's manager — the building block of a reporting-line report. Calls GET /users/{id}/manager.
Properties:
| Property | Type | Default | Description |
|---|---|---|---|
operation |
string | — | Required. get_user_manager |
id |
string | — | Required. User or group id, or a user principal name (e.g. [email protected]). Required by get_user, get_user_manager, get_group and list_group_members. |
query |
string | — | Optional. OData query params as a JSON object string. Ask for only the fields you need — e.g. {"$select": "displayName,userPrincipalName,accountEnabled"} — and filter server-side where you can, e.g. {"$filter": "accountEnabled eq false"}. |
Published Outputs:
- result — the JSON response body
- status — HTTP status code
4. list_groups — List groups
Every group in the tenant. Calls GET /groups.
Properties:
| Property | Type | Default | Description |
|---|---|---|---|
operation |
string | — | Required. list_groups |
query |
string | — | Optional. OData query params as a JSON object string. Ask for only the fields you need — e.g. {"$select": "displayName,userPrincipalName,accountEnabled"} — and filter server-side where you can, e.g. {"$filter": "accountEnabled eq false"}. |
Published Outputs:
- result — the JSON response body
- status — HTTP status code
5. get_group — Get one group
One group by id. Calls GET /groups/{id}.
Properties:
| Property | Type | Default | Description |
|---|---|---|---|
operation |
string | — | Required. get_group |
id |
string | — | Required. User or group id, or a user principal name (e.g. [email protected]). Required by get_user, get_user_manager, get_group and list_group_members. |
query |
string | — | Optional. OData query params as a JSON object string. Ask for only the fields you need — e.g. {"$select": "displayName,userPrincipalName,accountEnabled"} — and filter server-side where you can, e.g. {"$filter": "accountEnabled eq false"}. |
Published Outputs:
- result — the JSON response body
- status — HTTP status code
6. list_group_members — List group members
Who is in a group. Paged — a large group is not one response. Calls GET /groups/{id}/members.
Properties:
| Property | Type | Default | Description |
|---|---|---|---|
operation |
string | — | Required. list_group_members |
id |
string | — | Required. User or group id, or a user principal name (e.g. [email protected]). Required by get_user, get_user_manager, get_group and list_group_members. |
query |
string | — | Optional. OData query params as a JSON object string. Ask for only the fields you need — e.g. {"$select": "displayName,userPrincipalName,accountEnabled"} — and filter server-side where you can, e.g. {"$filter": "accountEnabled eq false"}. |
Published Outputs:
- result — the JSON response body
- status — HTTP status code
Paging
Graph answers a collection with 100 rows and an @odata.nextLink, so a naive listing returns a
fraction of a large tenant with HTTP 200 and no sign anything is missing. This connector follows
the continuation link until the collection is exhausted. If it stops at the page cap it says so —
the result carries complete: false with a warning, and the step returns WARNING rather than
SUCCESS. A page cap must never look like the end of the data.
Notes
Ask for only the fields you need and filter server-side. {"$select": "displayName,userPrincipalName,accountEnabled"}
turns a heavy listing into a light one, and {"$filter": "accountEnabled eq false"} is a
disabled-account report in one call rather than a full directory pull plus post-processing.
Self-Contained JAR
The jar bundles all runtime dependencies; only intouch-tool-api is provided by the server.
Publishes
The keys a later task may reference as {{taskName.key}}. Referencing anything not listed here resolves to nothing at run time.
completeoperationresultstatuswarning
Fields not listed above
Generated from this tool's own schema on 2026-09-02, because a README that defers ("same as the OpenAI tool") or omits a field leaves a caller — human or model — with no way to learn it exists.
| Field | Type | Description |
|---|---|---|
query |
string | Optional OData query params as a JSON object string. Ask for only the fields you need — e.g. {"$select": "displayName,userPrincipalName,accountEnabled"} — and filter server-side where you can, e.g. {"$filter": "accountEnabled eq false"}. |
Fields not documented above
Generated from this tool's own schema and published outputs on 2026-09-03. A field the README omits is discoverable only by reading the source, and a published key nothing documents is a capability nobody can reference.
Also published: status, warning