gh CLI, so there is no token to configure.
Requirements
ghinstalled and signed in (gh auth statusshould succeed)- A project whose git remote points at the GitHub repository you want to write to, or an explicit
--repo owner/name
taskgraph github status to check both.
CLI
push works on the active tag unless you pass --tag <name> or --all-tags. Without --yes it prints the plan and asks before writing, and it refuses to write at all when it cannot ask (piped output or --json). Other options:
Pulling status
taskgraph github pull reads the issues once and updates task statuses. It never writes to GitHub. It takes the same --tag, --all-tags, --id, --repo, --dry-run, --yes and --json options as push, and it asks before changing a status unless you pass --yes.
For each linked task, pull compares three statuses: the one at the last push or pull, the task’s status now, and the issue’s status.
- Only the issue changed: the task takes the issue’s status.
- Only the task changed: nothing happens. A push sends it to GitHub.
- Both changed to the same status: pull records them as in sync.
- Both changed to different statuses: this is a conflict. The task keeps its local status and is listed in the plan. Run
taskgraph github pushto overwrite GitHub with it.
MCP tools
There is no MCP tool for pull, because it changes your local tasks. Use the CLI. Both tools below are in theall tier. Set TASKGRAPH_TOOLS to all (see MCP Tools) to load them.
github_status
Read-only. Reports whether gh is usable, the repository that would be used, and the counts of linked and unlinked tasks.
github_push
Creates, updates and closes issues. It is a preview unless you pass dryRun: false, so an agent that calls it without thinking cannot write to your repository. The intended flow is to call it once, read the plan, then call it again with dryRun: false.
The result has the plan (one step per task:
create, update, skip or close, with a reason), the counts, and any orphan issues.
What an issue looks like
- Title:
[<id>] <task title> - Body: a hidden marker, the description,
Blocked by #Nlines for dependencies that already have issues, and a### Subtaskschecklist. Subtasks are part of the parent’s issue, not separate issues. - Labels:
taskgraph,taskgraph:priority/<priority>,taskgraph:status/<status>while the task is open, andtaskgraph:tag/<tag>. TaskGraph creates missing labels. - State:
donecloses the issue as completed,cancelledcloses it as not planned, anything else is open.
push again is cheap and safe.
How tasks stay linked
After the first push, each task stores its issue in itsmetadata.github field. If that is lost, the next push finds the issue again through the hidden marker in its body and relinks it, so a task is not duplicated.
unlink removes the stored link and leaves the issue alone. The marker is still in the issue body, so the next push relinks it. Remove the marker from the issue if you want the task to get a new one.
Limits
- Content is one way. Only status is read back, by
pull. Edits to an issue’s title, body or subtask checkboxes are not, and the next push of a changed task overwrites them along with the labels and state. - Orphans are reported, not closed, unless you pass
--close-orphansorcloseOrphans: true. --idandidmatch top-level tasks. Subtasks follow their parent.

