Add person resolver: email → LookupId for writing person columns

Person/group columns store a numeric LookupId into each site's hidden User Information List, and SPO's ensureUser needs certificate auth that client secrets can't provide — so resolve by querying the hidden list directly via Graph (item id IS the LookupId). New resolvePersonByEmail() in graph.mjs (server-side EMail/UserName filter with a paged case-insensitive scan fallback), a 'person' CLI command, and a sharepoint_resolve_person MCP tool (9 tools now). Verified live against known ground truth (LookupIds 53 and 136) plus the not-found path.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
ang3l12
2026-07-08 19:02:25 -06:00
parent 7d41c1ca15
commit 65fe53710a
7 changed files with 119 additions and 4 deletions

View File

@@ -100,6 +100,11 @@ async function main() {
case "get":
result = await client.getItem(await needSite(), needList(), needId());
break;
case "person": {
if (!flags.email) throw new Error("Missing --email user@domain.com");
result = await client.resolvePersonByEmail(await needSite(), flags.email);
break;
}
case "create":
result = await client.createItem(await needSite(), needList(), readFields(flags));
break;
@@ -187,6 +192,7 @@ Commands:
columns --site URL --list NAME_OR_ID Show column internal names + types
items --site URL --list NAME_OR_ID [filters] Query list items
get --site URL --list NAME_OR_ID --id ID Get one item
person --site URL --email USER@DOMAIN Resolve a person to the LookupId used by person columns
create --site URL --list NAME_OR_ID --fields J Create an item
update --site URL --list NAME_OR_ID --id ID --fields J Update an item
delete --site URL --list NAME_OR_ID --id ID Delete an item