# Microsoft Graph — People & Directory  · replaces agent365 `user` / `m365copilot`

Paging: add `max_items=N` to any GET (≤ 1000). Coverage + limits: see the SKILL.md guide.

## Me / profile

| Task | Call |
|------|------|
| My profile | `GET /me` |
| Specific fields | `GET /me?$select=displayName,mail,jobTitle,department,officeLocation` |
| My manager | `GET /me/manager` |
| My direct reports | `GET /me/directReports` |
| Groups I'm in | `GET /me/memberOf` |
| My photo (metadata) | `GET /me/photo` |

## Contacts

| Task | Call |
|------|------|
| List | `GET /me/contacts?$top=50` |
| One contact | `GET /me/contacts/{id}` |
| Create | `POST /me/contacts` → `{"givenName":"Sam","emailAddresses":[{"address":"sam@x.com","name":"Sam"}]}` |
| Contact folders | `GET /me/contactFolders` |

Incremental sync (changes only): `GET /me/contactFolders/{id}/contacts/delta` →
save the `@odata.deltaLink`, pass it back next run (delta pattern: SKILL.md).

## People & search

| Task | Call |
|------|------|
| People I work with | `GET /me/people?$search="jane"` |
| Search M365 content | `POST /search/query` |

`/search/query` searches across `entityTypes`: `message` · `event` · `driveItem` ·
`drive` · `site` · `listItem` · `person` · `chatMessage` (Teams messages, WAM
host). Paginate with `from`/`size` (not `$top`); `site`/`listItem` may 403 on a
harvest-only host. Body:

```json
{ "requests": [{ "entityTypes": ["message", "driveItem", "chatMessage"], "query": { "queryString": "quarterly budget" }, "from": 0, "size": 25 }] }
```

## Directory **reads** (users / groups) — read-only

| Task | Call |
|------|------|
| A user | `GET /users/{id-or-userPrincipalName}` |
| Find users (simple) | `GET /users?$filter=startsWith(displayName,'Jane')&$select=id,displayName,mail,jobTitle` |
| A group | `GET /groups/{id}` |
| Group members | `GET /groups/{id}/members` |
| Find groups (simple) | `GET /groups?$filter=startsWith(displayName,'Eng')` |

Only simple `eq`/`startsWith` filters work. `$search`, `$count`, `endsWith`, and
`$filter ... not` need `ConsistencyLevel: eventual`, which the tool can't send —
fall back to agent365 for those. **Writes** to `/users` / `/groups` are rejected
(risk 10).
