<!-- Generated by `just docs` from catalog/toolkits/github.yaml, catalog/expansions/github.yaml, catalog/evals/scorecard.json. Edit the source, not this file. -->

# GitHub

Code hosting. Manage repositories, issues, pull requests, files, and releases, and search across everything you can see.

| Property | Value |
| --- | --- |
| Slug | `github` |
| Definition version | `0.1.0` |
| Base URL | `https://api.github.com` |
| Auth schemes | `oauth2`, `api_key` |
| Action tools | 36 |
| By class | 19 read, 14 write, 3 destructive |
| Triggers | 3 |
| Provider rate limit | 5000 requests per 1h, per account |

## Measured routing accuracy

30 golden cases replayed through the router over the whole index: measured over corpus `ea4f12ad2948` (65 toolkits, 2283 tools indexed and 13 declared uncallable), 15 cases written by hand and 15 cases from the paraphrase pass. A case counts as top-1 when its gold tool ranked first and top-8 when it reached the slate at all.

| Measure | Cases | Share |
| --- | --- | --- |
| top-1 | 14/30 | 46.7% |
| top-8 | 24/30 | 80.0% |

The sweep is offline: the reranker is a deterministic identity fake that returns candidates in the order retrieval produced them, so top-1 measures retrieval order rather than a reranked slate. `just eval-live` measures the same cases through the live reranker.

## Authentication

Connect an entity with `ConnectionsService.InitiateConnection`, naming this toolkit's slug. Credentials stay in the connections vault; callers hold connected-account ids only.

### `oauth2`

| Property | Value |
| --- | --- |
| Authorization URL | `https://github.com/login/oauth/authorize` |
| Token URL | `https://github.com/login/oauth/access_token` |
| Default scopes | `repo` |
| Refresh tokens | no, so the end user reauthorizes when the token expires |

### `api_key`

| Property | Value |
| --- | --- |
| Placement | `header` |
| Name | `Authorization` |
| Rendered as | `Bearer {key}` |

Submit the key with `ConnectionsService` rather than putting it in a request; it is sealed at rest and never returned.

## Tools

36 action tools. The catalog-wide slug is `github.<tool>`, which is what `search_tools` returns and `call_tool` takes.

### `github.get_repo`

Get one repository's details by owner and name: description, default branch, visibility, stars, forks, open issue count, primary language. Use for a specific known repo. To find repos by keyword or topic, use search_repositories instead.

Class `read` (reads only). No scopes beyond the connection's defaults. Calls `GET /repos/{{params.owner}}/{{params.repo}}`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `owner` | string | **yes** | Repository owner, a user or org login, e.g. "facebook". |
| `repo` | string | **yes** | Repository name without the owner, e.g. "react". |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `default_branch` | string |  |
| `description` | string |  |
| `forks_count` | integer |  |
| `full_name` | string |  |
| `html_url` | string |  |
| `language` | string |  |
| `open_issues_count` | integer |  |
| `private` | boolean |  |
| `stargazers_count` | integer |  |

Also retrieved by: "what's this project about", "how many people starred it", "is it public or private", "check out this codebase", "pull up info on this repo".

### `github.list_my_repos`

List repositories the signed-in user owns or collaborates on. Use when the user says my repos, our projects, or what repositories do I have. For someone else's repos or keyword discovery, use search_repositories.

Class `read` (reads only). No scopes beyond the connection's defaults. Calls `GET /user/repos`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `per_page` | integer | no | Results per page, max 100. |
| `sort` | string, one of created, updated, pushed, full_name | no | Sort order, e.g. "updated" for recently active first. |
| `visibility` | string, one of all, public, private | no | Filter by visibility. Defaults to all. |

Also retrieved by: "what am I working on", "show my github projects", "everything I've built so far", "stuff under my account".

### `github.create_repo`

Create a new repository for the signed-in user. Use when the user wants to start, set up, or make a new repo or project. Optionally private and initialized with a README.

Class `write` (writes, no confirmation needed). No scopes beyond the connection's defaults. Calls `POST /user/repos`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `auto_init` | boolean | no | True to create an initial commit with an empty README. |
| `description` | string | no | Short repository description. |
| `name` | string | **yes** | New repository name, e.g. "billing-service". |
| `private` | boolean | no | True for a private repo. Defaults to false (public). |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `default_branch` | string |  |
| `full_name` | string |  |
| `html_url` | string |  |
| `private` | boolean |  |

Also retrieved by: "spin up a new codebase", "I need a fresh repository", "kick off a new project on github", "scaffold something brand new".

### `github.delete_repo`

Permanently delete a whole repository, including its issues, pull requests, and history. Irreversible. Use only when the user explicitly asks to delete or remove a repo they own. Not for single files.

Class `destructive` (held by the mutation gate until the call's own arguments carry `"confirm": true`). Scopes `delete_repo`. Calls `DELETE /repos/{{params.owner}}/{{params.repo}}`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `owner` | string | **yes** | Repository owner login. |
| `repo` | string | **yes** | Repository name to delete. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `deleted` | boolean |  |

Also retrieved by: "nuke this repository", "get rid of this project for good", "wipe this off github", "I don't want this codebase anymore".

### `github.fork_repo`

Fork a repository into the signed-in user's account or an organization. Use when the user wants their own copy of someone else's repo to work on or contribute from.

Class `write` (writes, no confirmation needed). No scopes beyond the connection's defaults. Calls `POST /repos/{{params.owner}}/{{params.repo}}/forks`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `organization` | string | no | Optional org login to fork into instead of the user account. |
| `owner` | string | **yes** | Owner of the repository to fork. |
| `repo` | string | **yes** | Name of the repository to fork. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `fork` | boolean |  |
| `full_name` | string |  |
| `html_url` | string |  |

Also retrieved by: "I want to contribute to this project", "copy this repo to my account", "make my own version of their code", "grab a copy so I can hack on it".

### `github.list_branches`

List the branches of a repository with the head commit of each. Use when the user asks what branches exist or wants to pick a branch for another call.

Class `read` (reads only). No scopes beyond the connection's defaults. Calls `GET /repos/{{params.owner}}/{{params.repo}}/branches`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `owner` | string | **yes** | Repository owner login. |
| `per_page` | integer | no | Results per page, max 100. |
| `repo` | string | **yes** | Repository name. |

Also retrieved by: "what versions of the code are there", "show me the different lines of work", "which branch should I use", "see the feature branches".

### `github.get_file_contents`

Read a file from a repository, or list a directory's entries. Use when the user wants to see, open, or fetch a file such as a README or config. File content returns base64-encoded with the blob sha needed for edits.

Class `read` (reads only). No scopes beyond the connection's defaults. Calls `GET /repos/{{params.owner}}/{{params.repo}}/contents/{{params.path}}`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `owner` | string | **yes** | Repository owner login. |
| `path` | string | **yes** | File or directory path inside the repo, e.g. "README.md" or "src/lib". |
| `ref` | string | no | Branch, tag, or commit sha to read from. Defaults to the default branch. |
| `repo` | string | **yes** | Repository name. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `content` | string |  |
| `encoding` | string |  |
| `html_url` | string |  |
| `name` | string |  |
| `path` | string |  |
| `sha` | string |  |
| `size` | integer |  |

Also retrieved by: "show me what's inside this file", "open up the config", "peek at the source", "read this document from the repo".

### `github.create_or_update_file`

Create a file or replace an existing file's contents with a commit. Use when the user wants to add, write, edit, or save a file in a repo. Updating an existing file requires its current blob sha from get_file_contents.

Class `write` (writes, no confirmation needed). No scopes beyond the connection's defaults. Calls `PUT /repos/{{params.owner}}/{{params.repo}}/contents/{{params.path}}`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `branch` | string | no | Branch to commit to. Defaults to the default branch. |
| `content` | string | **yes** | New file content, base64-encoded. |
| `message` | string | **yes** | Commit message for this change. |
| `owner` | string | **yes** | Repository owner login. |
| `path` | string | **yes** | File path to create or update, e.g. "docs/setup.md". |
| `repo` | string | **yes** | Repository name. |
| `sha` | string | no | Current blob sha of the file. Required when updating, omit when creating. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `commit` | object |  |
| `commit.message` | string |  |
| `commit.sha` | string |  |
| `content` | object |  |
| `content.html_url` | string |  |
| `content.path` | string |  |
| `content.sha` | string |  |

Also retrieved by: "save my changes to this file", "put a new file in the repo", "jot this down in the codebase", "commit a quick edit".

### `github.delete_file`

Delete a single file from a repository with a commit. Use when the user asks to remove or delete a file, not the whole repository. Requires the file's current blob sha from get_file_contents. The file stays recoverable in git history, but the branch head changes.

Class `destructive` (held by the mutation gate until the call's own arguments carry `"confirm": true`). No scopes beyond the connection's defaults. Calls `DELETE /repos/{{params.owner}}/{{params.repo}}/contents/{{params.path}}`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `branch` | string | no | Branch to commit to. Defaults to the default branch. |
| `message` | string | **yes** | Commit message for the deletion. |
| `owner` | string | **yes** | Repository owner login. |
| `path` | string | **yes** | Path of the file to delete. |
| `repo` | string | **yes** | Repository name. |
| `sha` | string | **yes** | Current blob sha of the file being deleted. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `commit` | object |  |
| `commit.message` | string |  |
| `commit.sha` | string |  |

Also retrieved by: "take this file out of the project", "trash this old file", "get rid of that config".

### `github.list_commits`

List commits on a repository, newest first. Use when the user asks for recent changes, commit history, or who changed what. Filterable by branch, author, file path, and date range. For one commit's diff, use get_commit.

Class `read` (reads only). No scopes beyond the connection's defaults. Calls `GET /repos/{{params.owner}}/{{params.repo}}/commits`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `author` | string | no | Filter by author login or email. |
| `owner` | string | **yes** | Repository owner login. |
| `path` | string | no | Only commits touching this file or directory. |
| `per_page` | integer | no | Results per page, max 100. |
| `repo` | string | **yes** | Repository name. |
| `sha` | string | no | Branch, tag, or commit sha to start from. Defaults to the default branch. |
| `since` | string (date-time) | no | Only commits after this ISO 8601 timestamp. |
| `until` | string (date-time) | no | Only commits before this ISO 8601 timestamp. |

Also retrieved by: "what's been happening in this repo lately", "who touched this last", "show me the timeline of changes", "recent work on this project".

### `github.get_commit`

Get one commit by sha, branch, or tag, including its message, author, per-file diff stats, and changed file list. Use when the user asks what a specific commit changed. For history, use list_commits.

Class `read` (reads only). No scopes beyond the connection's defaults. Calls `GET /repos/{{params.owner}}/{{params.repo}}/commits/{{params.ref}}`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `owner` | string | **yes** | Repository owner login. |
| `ref` | string | **yes** | Commit sha, branch, or tag, e.g. "a1b2c3d" or "main". |
| `repo` | string | **yes** | Repository name. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `commit` | object |  |
| `commit.message` | string |  |
| `files` | array of object |  |
| `files[].additions` | integer |  |
| `files[].deletions` | integer |  |
| `files[].filename` | string |  |
| `files[].status` | string |  |
| `html_url` | string |  |
| `sha` | string |  |
| `stats` | object |  |
| `stats.additions` | integer |  |
| `stats.deletions` | integer |  |

Also retrieved by: "what did that change actually do", "show me the diff for that one", "details on a single change".

### `github.list_releases`

List a repository's releases, newest first, with tag, name, notes, and publish date. Use when the user asks about versions, releases, or what shipped recently.

Class `read` (reads only). No scopes beyond the connection's defaults. Calls `GET /repos/{{params.owner}}/{{params.repo}}/releases`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `owner` | string | **yes** | Repository owner login. |
| `per_page` | integer | no | Results per page, max 100. |
| `repo` | string | **yes** | Repository name. |

Also retrieved by: "what versions have gone out", "show me the shipping history", "what's been shipped so far".

### `github.create_release`

Create a release from a tag, with a title and changelog notes. Use when the user wants to publish, cut, or ship a release or version. Creates the tag if it does not exist yet.

Class `write` (writes, no confirmation needed). No scopes beyond the connection's defaults. Calls `POST /repos/{{params.owner}}/{{params.repo}}/releases`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `body` | string | no | Release notes, markdown allowed. |
| `draft` | boolean | no | True to save as an unpublished draft. |
| `name` | string | no | Release title. Defaults to the tag name. |
| `owner` | string | **yes** | Repository owner login. |
| `prerelease` | boolean | no | True to mark as a prerelease. |
| `repo` | string | **yes** | Repository name. |
| `tag_name` | string | **yes** | Tag for the release, e.g. "v2.0.0". |
| `target_commitish` | string | no | Branch or sha to tag if the tag is new. Defaults to the default branch. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `draft` | boolean |  |
| `html_url` | string |  |
| `name` | string |  |
| `tag_name` | string |  |

Also retrieved by: "put out a new version", "ship this update to users", "tag and publish a new build".

### `github.list_issues`

List issues in one repository: tickets, bugs, tasks, feature requests. Filterable by state, labels, assignee, and creator. Pull requests appear here too. For queries across repositories or complex filters, use search_issues.

Class `read` (reads only). No scopes beyond the connection's defaults. Calls `GET /repos/{{params.owner}}/{{params.repo}}/issues`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `assignee` | string | no | Login of the assignee, or "*" for any, or "none". |
| `creator` | string | no | Only issues opened by this login. |
| `direction` | string, one of asc, desc | no | Sort direction. Defaults to desc. |
| `labels` | string | no | Comma-separated label names, e.g. "bug,help wanted". |
| `owner` | string | **yes** | Repository owner login. |
| `per_page` | integer | no | Results per page, max 100. |
| `repo` | string | **yes** | Repository name. |
| `sort` | string, one of created, updated, comments | no | Sort field. Defaults to created. |
| `state` | string, one of open, closed, all | no | Which issues to list. Defaults to open. |

Also retrieved by: "what's on our plate for this repo", "show me the open github issues in this repository", "which bugs are still outstanding on this repo", "the issue backlog for one github project".

### `github.get_issue`

Get a single issue or ticket by its number: title, full body, state, labels, assignees, comment count. Use when the user names a specific issue like "issue 42". For lists, use list_issues.

Class `read` (reads only). No scopes beyond the connection's defaults. Calls `GET /repos/{{params.owner}}/{{params.repo}}/issues/{{params.issue_number}}`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `issue_number` | integer | **yes** | Issue number, e.g. 42. |
| `owner` | string | **yes** | Repository owner login. |
| `repo` | string | **yes** | Repository name. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `assignees` | array of object |  |
| `assignees[].login` | string |  |
| `body` | string |  |
| `comments` | integer |  |
| `html_url` | string |  |
| `labels` | array of object |  |
| `labels[].name` | string |  |
| `number` | integer |  |
| `state` | string |  |
| `title` | string |  |
| `user` | object |  |
| `user.login` | string |  |

Also retrieved by: "pull up that one ticket", "look at bug number forty two", "details on this specific report".

### `github.create_issue`

Open a new issue on a repository. Use when the user wants to file a bug report, log a ticket, create a task, or request a feature. Optionally set labels, assignees, and a milestone at creation.

Class `write` (writes, no confirmation needed). No scopes beyond the connection's defaults. Calls `POST /repos/{{params.owner}}/{{params.repo}}/issues`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `assignees` | array of string | no | Logins to assign. |
| `body` | string | no | Issue description, markdown allowed. |
| `labels` | array of string | no | Label names to apply, e.g. ["bug"]. |
| `milestone` | integer | no | Milestone number to attach. |
| `owner` | string | **yes** | Repository owner login. |
| `repo` | string | **yes** | Repository name. |
| `title` | string | **yes** | Issue title, e.g. "Login fails with SSO accounts". |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `html_url` | string |  |
| `number` | integer |  |
| `state` | string |  |
| `title` | string |  |

Also retrieved by: "flag this problem for the team", "log a task for someone to pick up", "write up a feature idea", "report something broken".

### `github.update_issue`

Edit an existing issue: retitle, rewrite the body, close or reopen it, or replace labels and assignees. Use when the user wants to close a ticket, mark it done, reopen it, or change its details.

Class `write` (writes, no confirmation needed). No scopes beyond the connection's defaults. Calls `PATCH /repos/{{params.owner}}/{{params.repo}}/issues/{{params.issue_number}}`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `assignees` | array of string | no | Replacement assignee logins. Omit to leave unchanged. |
| `body` | string | no | New body, markdown allowed. |
| `issue_number` | integer | **yes** | Issue number to update. |
| `labels` | array of string | no | Replacement label set. Omit to leave labels unchanged. |
| `owner` | string | **yes** | Repository owner login. |
| `repo` | string | **yes** | Repository name. |
| `state` | string, one of open, closed | no | Set "closed" to close, "open" to reopen. |
| `state_reason` | string, one of completed, not_planned, reopened | no | Why the state changed, e.g. "completed" when fixed. |
| `title` | string | no | New title. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `html_url` | string |  |
| `number` | integer |  |
| `state` | string |  |
| `title` | string |  |

Also retrieved by: "mark this ticket as done", "reopen that old bug", "change the title on this one", "this is fixed now".

### `github.add_issue_comment`

Post a comment on an issue or pull request. Use when the user wants to reply, respond, leave a note, or give an update on a ticket or PR discussion thread.

Class `write` (writes, no confirmation needed). No scopes beyond the connection's defaults. Calls `POST /repos/{{params.owner}}/{{params.repo}}/issues/{{params.issue_number}}/comments`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `body` | string | **yes** | Comment text, markdown allowed. |
| `issue_number` | integer | **yes** | Issue or pull request number to comment on. |
| `owner` | string | **yes** | Repository owner login. |
| `repo` | string | **yes** | Repository name. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `body` | string |  |
| `html_url` | string |  |
| `id` | integer |  |

Also retrieved by: "tell them the status on this ticket", "drop a note on that one", "let people know what's going on with this bug".

### `github.list_issue_comments`

Read the comments on an issue or pull request, oldest first. Use when the user wants the discussion, replies, or feedback people left on a ticket or PR.

Class `read` (reads only). No scopes beyond the connection's defaults. Calls `GET /repos/{{params.owner}}/{{params.repo}}/issues/{{params.issue_number}}/comments`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `issue_number` | integer | **yes** | Issue or pull request number. |
| `owner` | string | **yes** | Repository owner login. |
| `per_page` | integer | no | Results per page, max 100. |
| `repo` | string | **yes** | Repository name. |

Also retrieved by: "what did people say on this ticket", "read the back and forth on that one", "catch up on the conversation there".

### `github.add_labels`

Add labels to a GitHub issue or pull request, keeping the labels already on it. Use when the user wants to tag or label an issue in a repository, for example as a bug. To replace the whole set, use update_issue.

Class `write` (writes, no confirmation needed). No scopes beyond the connection's defaults. Calls `POST /repos/{{params.owner}}/{{params.repo}}/issues/{{params.issue_number}}/labels`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `issue_number` | integer | **yes** | Issue or pull request number. |
| `labels` | array of string | **yes** | Label names to add, e.g. ["bug", "priority-high"]. |
| `owner` | string | **yes** | Repository owner login. |
| `repo` | string | **yes** | Repository name. |

Also retrieved by: "flag this github issue as high priority", "put another label on a pull request", "mark an issue in this repository".

### `github.remove_label`

Remove one label from a GitHub issue or pull request. Use when the user wants to untag an issue in a repository, for example to take off "needs-triage". The label itself still exists in the repository.

Class `write` (writes, no confirmation needed). No scopes beyond the connection's defaults. Calls `DELETE /repos/{{params.owner}}/{{params.repo}}/issues/{{params.issue_number}}/labels/{{params.name}}`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `issue_number` | integer | **yes** | Issue or pull request number. |
| `name` | string | **yes** | Label name to remove. |
| `owner` | string | **yes** | Repository owner login. |
| `repo` | string | **yes** | Repository name. |

Also retrieved by: "take a label off this github issue", "that marker no longer applies to the pull request", "unlabel an issue in this repository".

### `github.add_assignees`

Assign people to an issue or pull request, keeping existing assignees. Use when the user wants to assign a ticket to someone or give a task an owner. To replace all assignees, use update_issue.

Class `write` (writes, no confirmation needed). No scopes beyond the connection's defaults. Calls `POST /repos/{{params.owner}}/{{params.repo}}/issues/{{params.issue_number}}/assignees`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `assignees` | array of string | **yes** | Logins to assign, e.g. ["octocat"]. |
| `issue_number` | integer | **yes** | Issue or pull request number. |
| `owner` | string | **yes** | Repository owner login. |
| `repo` | string | **yes** | Repository name. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `assignees` | array of object |  |
| `assignees[].login` | string |  |
| `number` | integer |  |

Also retrieved by: "put someone on this ticket", "hand this off to a teammate", "who's responsible for this now".

### `github.list_labels`

List the labels defined in a repository with their colors and descriptions. Use when the user asks what labels or tags exist, or before labeling an issue with add_labels.

Class `read` (reads only). No scopes beyond the connection's defaults. Calls `GET /repos/{{params.owner}}/{{params.repo}}/labels`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `owner` | string | **yes** | Repository owner login. |
| `per_page` | integer | no | Results per page, max 100. |
| `repo` | string | **yes** | Repository name. |

Also retrieved by: "what labels does this github repository define", "which markers can I put on an issue here", "the label palette configured on this repo".

### `github.list_pull_requests`

List pull requests in a repository: pending merges, proposed changes, code submissions waiting for review. Filterable by state and branch. For one PR's details, use get_pull_request.

Class `read` (reads only). No scopes beyond the connection's defaults. Calls `GET /repos/{{params.owner}}/{{params.repo}}/pulls`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `base` | string | no | Filter by base branch name, e.g. "main". |
| `direction` | string, one of asc, desc | no | Sort direction. Defaults to desc. |
| `head` | string | no | Filter by head branch as "user:branch", e.g. "octocat:fix-login". |
| `owner` | string | **yes** | Repository owner login. |
| `per_page` | integer | no | Results per page, max 100. |
| `repo` | string | **yes** | Repository name. |
| `sort` | string, one of created, updated, popularity, long-running | no | Sort field. Defaults to created. |
| `state` | string, one of open, closed, all | no | Which pull requests to list. Defaults to open. |

Also retrieved by: "what code is waiting on review", "show me open PRs", "what's queued up to merge".

### `github.get_pull_request`

Get one pull request by number: title, description, branches, merge status, mergeability, and diff size. Use when the user names a specific PR. For its changed files, use list_pull_request_files.

Class `read` (reads only). No scopes beyond the connection's defaults. Calls `GET /repos/{{params.owner}}/{{params.repo}}/pulls/{{params.pull_number}}`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `owner` | string | **yes** | Repository owner login. |
| `pull_number` | integer | **yes** | Pull request number, e.g. 512. |
| `repo` | string | **yes** | Repository name. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `additions` | integer |  |
| `base` | object |  |
| `base.ref` | string |  |
| `body` | string |  |
| `changed_files` | integer |  |
| `deletions` | integer |  |
| `draft` | boolean |  |
| `head` | object |  |
| `head.ref` | string |  |
| `head.sha` | string |  |
| `html_url` | string |  |
| `mergeable` | boolean |  |
| `merged` | boolean |  |
| `number` | integer |  |
| `state` | string |  |
| `title` | string |  |

Also retrieved by: "pull up that one PR", "details on this code submission", "what's in this specific one".

### `github.create_pull_request`

Open a pull request proposing changes from one branch into another. Use when the user wants to open a PR, submit their branch for review, or merge a feature branch via review. Supports draft PRs.

Class `write` (writes, no confirmation needed). No scopes beyond the connection's defaults. Calls `POST /repos/{{params.owner}}/{{params.repo}}/pulls`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `base` | string | **yes** | Branch to merge into, e.g. "main". |
| `body` | string | no | Pull request description, markdown allowed. |
| `draft` | boolean | no | True to open as a draft not yet ready for review. |
| `head` | string | **yes** | Branch with the changes, e.g. "fix-login". Cross-fork uses "user:branch". |
| `owner` | string | **yes** | Repository owner login. |
| `repo` | string | **yes** | Repository name. |
| `title` | string | **yes** | Pull request title. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `draft` | boolean |  |
| `html_url` | string |  |
| `number` | integer |  |
| `state` | string |  |
| `title` | string |  |

Also retrieved by: "put my branch up for review", "send this code for review", "propose these changes to the team".

### `github.update_pull_request`

Edit an open pull request: retitle it, rewrite the description, close or reopen it, or retarget the base branch. Use when the user wants to change or close a PR without merging. Merging is merge_pull_request.

Class `write` (writes, no confirmation needed). No scopes beyond the connection's defaults. Calls `PATCH /repos/{{params.owner}}/{{params.repo}}/pulls/{{params.pull_number}}`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `base` | string | no | New base branch name. |
| `body` | string | no | New description, markdown allowed. |
| `owner` | string | **yes** | Repository owner login. |
| `pull_number` | integer | **yes** | Pull request number to update. |
| `repo` | string | **yes** | Repository name. |
| `state` | string, one of open, closed | no | Set "closed" to close without merging, "open" to reopen. |
| `title` | string | no | New title. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `html_url` | string |  |
| `number` | integer |  |
| `state` | string |  |
| `title` | string |  |

Also retrieved by: "change the description on that one", "close this without merging it", "update the target branch for this one".

### `github.merge_pull_request`

Merge an open pull request into its base branch. Use when the user says merge the PR, land it, or ship it. Changes the base branch permanently; choose merge, squash, or rebase.

Class `destructive` (held by the mutation gate until the call's own arguments carry `"confirm": true`). No scopes beyond the connection's defaults. Calls `PUT /repos/{{params.owner}}/{{params.repo}}/pulls/{{params.pull_number}}/merge`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `commit_message` | string | no | Extra detail appended to the merge commit message. |
| `commit_title` | string | no | Title for the merge commit. Defaults to GitHub's standard title. |
| `merge_method` | string, one of merge, squash, rebase | no | How to merge. Defaults to merge. |
| `owner` | string | **yes** | Repository owner login. |
| `pull_number` | integer | **yes** | Pull request number to merge. |
| `repo` | string | **yes** | Repository name. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `merged` | boolean |  |
| `message` | string |  |
| `sha` | string |  |

Also retrieved by: "land this change already", "ship this branch into main", "this is good to go, merge it".

### `github.list_pull_request_files`

List the files changed in a pull request with per-file additions, deletions, and patch hunks. Use when the user asks what a PR touches or wants to review its diff.

Class `read` (reads only). No scopes beyond the connection's defaults. Calls `GET /repos/{{params.owner}}/{{params.repo}}/pulls/{{params.pull_number}}/files`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `owner` | string | **yes** | Repository owner login. |
| `per_page` | integer | no | Results per page, max 100. |
| `pull_number` | integer | **yes** | Pull request number. |
| `repo` | string | **yes** | Repository name. |

Also retrieved by: "what files does this touch", "show me everything modified here", "review the diff on this submission".

### `github.list_pull_request_reviews`

List the reviews on a pull request: who approved, who requested changes, and their summary comments. Use when the user asks whether a PR is approved or what reviewers said.

Class `read` (reads only). No scopes beyond the connection's defaults. Calls `GET /repos/{{params.owner}}/{{params.repo}}/pulls/{{params.pull_number}}/reviews`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `owner` | string | **yes** | Repository owner login. |
| `pull_number` | integer | **yes** | Pull request number. |
| `repo` | string | **yes** | Repository name. |

Also retrieved by: "did anyone sign off on this", "what feedback came back on this", "is this approved yet".

### `github.create_pull_request_review`

Submit a review on a pull request: approve it, request changes, or leave a review comment. Use when the user wants to approve a PR, sign off, or send back feedback. Merging is merge_pull_request.

Class `write` (writes, no confirmation needed). No scopes beyond the connection's defaults. Calls `POST /repos/{{params.owner}}/{{params.repo}}/pulls/{{params.pull_number}}/reviews`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `body` | string | no | Review summary text. Required for REQUEST_CHANGES and COMMENT. |
| `event` | string, one of APPROVE, REQUEST_CHANGES, COMMENT | **yes** | Review verdict. |
| `owner` | string | **yes** | Repository owner login. |
| `pull_number` | integer | **yes** | Pull request number to review. |
| `repo` | string | **yes** | Repository name. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `html_url` | string |  |
| `id` | integer |  |
| `state` | string |  |

Also retrieved by: "give this code the thumbs up", "send back some feedback on this one", "I want to weigh in on this change".

### `github.request_reviewers`

Ask specific people or teams to review a pull request. Use when the user wants to add reviewers, request a review from someone, or route a PR to a team for sign-off. It only assigns reviewers on the pull request itself.

Class `write` (writes, no confirmation needed). No scopes beyond the connection's defaults. Calls `POST /repos/{{params.owner}}/{{params.repo}}/pulls/{{params.pull_number}}/requested_reviewers`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `owner` | string | **yes** | Repository owner login. |
| `pull_number` | integer | **yes** | Pull request number. |
| `repo` | string | **yes** | Repository name. |
| `reviewers` | array of string | no | User logins to request, e.g. ["octocat"]. |
| `team_reviewers` | array of string | no | Team slugs to request, e.g. ["platform-team"]. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `number` | integer |  |
| `requested_reviewers` | array of object |  |
| `requested_reviewers[].login` | string |  |

Also retrieved by: "get someone to look over this code", "loop in a reviewer", "who should check this".

### `github.search_repositories`

Search all of GitHub for repositories by keyword, topic, language, or stars. Use when the user wants to find, discover, or look up projects they do not already know by exact owner and name.

Class `read` (reads only). No scopes beyond the connection's defaults. Calls `GET /search/repositories`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `order` | string, one of asc, desc | no | Sort direction. Defaults to desc. |
| `per_page` | integer | no | Results per page, max 100. |
| `q` | string | **yes** | Search query with qualifiers, e.g. "http server language:rust stars:>500". |
| `sort` | string, one of stars, forks, help-wanted-issues, updated | no | Sort field. Defaults to best match. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `items` | array of object |  |
| `items[].description` | string |  |
| `items[].full_name` | string |  |
| `items[].html_url` | string |  |
| `items[].language` | string |  |
| `items[].stargazers_count` | integer |  |
| `total_count` | integer |  |

Also retrieved by: "what's out there for building a web app", "any good open source options for this", "browse projects on the platform".

### `github.search_issues`

Search issues and pull requests across repositories with qualifiers like repo, author, assignee, label, and state. Use for cross-repo queries such as everything assigned to me. For one repo's list, use list_issues.

Class `read` (reads only). No scopes beyond the connection's defaults. Calls `GET /search/issues`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `order` | string, one of asc, desc | no | Sort direction. Defaults to desc. |
| `per_page` | integer | no | Results per page, max 100. |
| `q` | string | **yes** | Search query, e.g. "is:issue is:open assignee:octocat label:bug". |
| `sort` | string, one of created, updated, comments, reactions | no | Sort field. Defaults to best match. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `items` | array of object |  |
| `items[].html_url` | string |  |
| `items[].number` | integer |  |
| `items[].repository_url` | string |  |
| `items[].state` | string |  |
| `items[].title` | string |  |
| `total_count` | integer |  |

Also retrieved by: "show me everything I owe across every project", "what's outstanding across all our repos", "find every open item tied to me".

### `github.search_code`

Search file contents across GitHub repositories. Use when the user wants to find where a function, string, or config appears in code, e.g. "search for uses of the old auth header in our org".

Class `read` (reads only). No scopes beyond the connection's defaults. Calls `GET /search/code`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `per_page` | integer | no | Results per page, max 100. |
| `q` | string | **yes** | Code query with qualifiers, e.g. "parseToken repo:acme/api language:go". |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `items` | array of object |  |
| `items[].html_url` | string |  |
| `items[].name` | string |  |
| `items[].path` | string |  |
| `items[].repository` | object |  |
| `items[].repository.full_name` | string |  |
| `total_count` | integer |  |

Also retrieved by: "where in our codebase does this get used", "track down every place this appears", "grep across all our repos".

### `github.search_users`

Search GitHub user and organization accounts by name, login, location, or language. Use when the user wants to find a person's or company's GitHub profile.

Class `read` (reads only). No scopes beyond the connection's defaults. Calls `GET /search/users`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `order` | string, one of asc, desc | no | Sort direction. Defaults to desc. |
| `per_page` | integer | no | Results per page, max 100. |
| `q` | string | **yes** | User query with qualifiers, e.g. "tom location:seattle type:user". |
| `sort` | string, one of followers, repositories, joined | no | Sort field. Defaults to best match. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `items` | array of object |  |
| `items[].html_url` | string |  |
| `items[].login` | string |  |
| `items[].type` | string |  |
| `total_count` | integer |  |

Also retrieved by: "look up someone's handle", "find their profile on the platform", "who is this person on github".

## Triggers

Triggers are app-initiated. They are not retrievable as tools and cannot be called; subscribe with `TriggersService.CreateSubscription` and events arrive as signed deliveries.

### `issue_opened`

Fires when someone opens an issue on a repository the connected account can see. Carries the issue number, title, body, author, and repository.

Payload fields (anything the schema does not declare never reaches a subscriber):

| Field | Type | Notes |
| --- | --- | --- |
| `action` | string |  |
| `issue` | object |  |
| `issue.body` | string |  |
| `issue.created_at` | string |  |
| `issue.html_url` | string |  |
| `issue.number` | integer |  |
| `issue.state` | string |  |
| `issue.title` | string |  |
| `issue.user` | object |  |
| `issue.user.login` | string |  |
| `repository` | object |  |
| `repository.full_name` | string |  |
| `repository.html_url` | string |  |
| `sender` | object |  |
| `sender.login` | string |  |

### `pull_request_opened`

Fires when someone opens a pull request. Carries the PR number, title, body, head and base branches, author, and repository.

Payload fields (anything the schema does not declare never reaches a subscriber):

| Field | Type | Notes |
| --- | --- | --- |
| `action` | string |  |
| `pull_request` | object |  |
| `pull_request.base` | object |  |
| `pull_request.base.ref` | string |  |
| `pull_request.body` | string |  |
| `pull_request.created_at` | string |  |
| `pull_request.draft` | boolean |  |
| `pull_request.head` | object |  |
| `pull_request.head.ref` | string |  |
| `pull_request.head.sha` | string |  |
| `pull_request.html_url` | string |  |
| `pull_request.number` | integer |  |
| `pull_request.state` | string |  |
| `pull_request.title` | string |  |
| `pull_request.user` | object |  |
| `pull_request.user.login` | string |  |
| `repository` | object |  |
| `repository.full_name` | string |  |
| `repository.html_url` | string |  |
| `sender` | object |  |
| `sender.login` | string |  |

### `push`

Fires when commits are pushed to a branch or tag. Carries the ref, the before and after commit shas, the commit list, and the pusher.

Payload fields (anything the schema does not declare never reaches a subscriber):

| Field | Type | Notes |
| --- | --- | --- |
| `after` | string |  |
| `before` | string |  |
| `commits` | array of object |  |
| `commits[].author` | object |  |
| `commits[].author.email` | string |  |
| `commits[].author.name` | string |  |
| `commits[].author.username` | string |  |
| `commits[].id` | string |  |
| `commits[].message` | string |  |
| `commits[].timestamp` | string |  |
| `commits[].url` | string |  |
| `forced` | boolean |  |
| `pusher` | object |  |
| `pusher.email` | string |  |
| `pusher.name` | string |  |
| `ref` | string |  |
| `repository` | object |  |
| `repository.full_name` | string |  |
| `repository.html_url` | string |  |

## Inbound webhooks

Providers post to `/webhooks/github`. Posts that fail verification are rejected before anything is stored, and the ingest path refuses every post while the secret variable is unset.

| Property | Value |
| --- | --- |
| Verification scheme | `hmac_sha256` |
| Shared secret | `AUTOMATON_GITHUB_WEBHOOK_SECRET` (deployment environment) |
| Signature header | `X-Hub-Signature-256` |
| Signature format | `sha256={sig}` |
| Delivery id header | `X-GitHub-Delivery` (repeat posts are answered `duplicate`) |

Mappings are tried in order and the first match wins.

| Trigger | Matches when | Entity resolved from |
| --- | --- | --- |
| `issue_opened` | header `X-GitHub-Event` = `issues`, payload `action` = `opened` | sender.login |
| `pull_request_opened` | header `X-GitHub-Event` = `pull_request`, payload `action` = `opened` | sender.login |
| `push` | header `X-GitHub-Event` = `push` | sender.login |
