Appearance
date: 2026-06-06 tags: [github, projects, status, graphql, triage, web-env] status: active graduated_to:
Projects v2 Status is writable from the web env — via GraphQL + $GH_TOKEN, not the MCP server
Symptom — triage assumed the readiness Status couldn't be set in the Claude Code web/remote env: the GitHub MCP server exposes no Projects-v2 tool, there's no gh CLI, and an unauthenticated api.github.com hit 403s — so Status was only ever reported, never applied.
Root cause — Status is a Projects v2 board field; the native Issues REST API (and the MCP issue_write / list_issue_fields) only reach issue fields like Area, never a project's per-board Status. Projects v2 is GraphQL-only. The 403 was just missing auth — the env's $GH_TOKEN authenticates fine and carries project-write scope.
Fix — set Status with the GraphQL updateProjectV2ItemFieldValue mutation against https://api.github.com/graphql, header Authorization: Bearer $GH_TOKEN. The issue must be a board item (it is, once added to the project); read its item id via repository.issue(number:){ projectItems(first:10){ nodes { id project { id } } } }. Reusable IDs for org Project v2 #3 "Tempo":
- project:
PVT_kwDOEVOzGc4BZyyo - Status field:
PVTSSF_lADOEVOzGc4BZyyozhUvAaU - options: Needs Triage
209ea7d2· Needs Infoeddb06eb· Ready for Agent03206af8· Ready for Human7d192ed2· In Progress47fc9ee4· Done98236657· Wontfix7575332d
Re-discover with node(id:"<project>"){ ... on ProjectV2 { fields(first:50){ nodes { ... on ProjectV2SingleSelectField { id name options { id name } } } } } } if the board changes.
Guard — .claude/skills/triage/SKILL.md and docs/agents/triage-labels.md now say apply Status via this mutation, not just recommend it. Complements [[2026-06-05-github-native-typed-backlog-api]] (REST issue-type / sub-issue / dependency primitives) and [[2026-06-05-agent-identity-two-layers]] (the token side).