# Tools Reference

## Read Server (gh-tooling)

Tools available via the `gh-tooling` MCP server. Requires `gh` CLI installed and authenticated.

### Shared Tool Parameters

All gh-tooling MCP tools accept these parameters:

| Parameter         | Type    | Default | Description                                                             |
|-------------------|---------|---------|-------------------------------------------------------------------------|
| `suppress_errors` | boolean | `false` | Silence stderr; errors produce empty output instead of an error message |
| `fallback`        | string  | --      | Return this text (successfully) when the gh command fails               |

Tools that produce structured JSON output also accept `jq_filter` (string) for filtering and transforming results with full jq expression syntax. A syntax check runs before execution to give early feedback on invalid expressions.

`pr_view`, `pr_list`, `run_view`, `run_list`, `issue_view`, `issue_list`, and `search` only emit JSON when `fields` is set; without it the underlying `gh` command prints a human-readable summary. On those seven, a `jq_filter` passed without `fields` is rejected before the call, with an error naming both. `issue_view` also emits JSON under `with_field_values: true`, which satisfies the requirement on its own.

Tools with large text output (`run_logs`, `job_logs`, `pr_diff`) additionally accept:

| Parameter             | Type    | Description                                                 |
|-----------------------|---------|-------------------------------------------------------------|
| `max_lines`           | integer | Return only the first N lines (`head -n N`)                 |
| `tail_lines`          | integer | Return only the last N lines (`tail -n N`)                  |
| `grep_pattern`        | string  | Extended regex filter (grep -E); non-matching lines removed |
| `grep_context_before` | integer | Lines of context before each match (-B)                     |
| `grep_context_after`  | integer | Lines of context after each match (-A)                      |
| `grep_ignore_case`    | boolean | Case-insensitive matching (-i)                              |
| `grep_invert`         | boolean | Return non-matching lines (-v)                              |

A `grep_pattern` that `grep -E` rejects, such as an unbalanced `(`, fails the call with `Error: Invalid grep_pattern` before `gh` runs, the same as an invalid `jq_filter`. A pattern that matches nothing is not an error. The result is empty.

`max_lines` and `tail_lines` are also available on `pr_view`, `pr_checks`, `pr_comments`, `pr_reviews`, `issue_view`, `api_read`, `label_list`, `project_list`, and `project_view` for output size control.

`job_logs`, `repo_file`, and `api_read` remove terminal escape sequences from the text they return, so `grep_pattern`, `max_lines`, and `tail_lines` work on the words rather than on the colour codes wrapped around them. `repo_file` with `download_to` is the exception: it writes the file's bytes unchanged.

#### Repository selection

PR, issue, search, commit, and repo browsing tools accept the repository in any of these shapes — pass whichever matches the data you have:

| Shape                    | Example                                                | Notes                                              |
|--------------------------|--------------------------------------------------------|----------------------------------------------------|
| `repo`                   | `repo: "shopware/shopware"`                            | Owner/repo string. Legacy short form.              |
| `repository`             | `repository: "shopware/shopware"`                      | Owner/repo string. Alias of `repo`.                |
| `owner` + `repo`         | `owner: "shopware"`, `repo: "shopware"`                | Split form. `repo` must be the bare name (no `/`). |
| `url` (repo tools only)  | `url: "https://github.com/shopware/shopware/blob/..."` | Parsed for owner/repo/ref/path.                    |

If none of the above is supplied, the default repo from `.mcp-gh-tooling.json` is used. PR and issue tools also fall back to the local git remote when invoked inside a clone; outside a git repository they fail with a prescriptive error rather than letting `gh`'s native git-detection error surface.

Unknown parameters are rejected at the MCP layer (`additionalProperties: false`), so a misspelled or fabricated field returns an explicit error instead of being silently dropped.

### `pr_view`

View pull request details.

```
Use gh-tooling pr_view with number 14642
Use gh-tooling pr_view with number 14642 and fields "title,body,state,reviews"
Use gh-tooling pr_view with number 14642 and comments true
```

**Parameters:**
- `number` (integer, required): PR number.
- Repository selection: see [Repository selection](#repository-selection).
- `fields` (string, optional): Comma-separated JSON fields (e.g. `title,body,state,reviews,files`)
- `comments` (boolean, optional): Append the PR's comments and reviews to the text output, after a `--- comments and reviews ---` line. Ignored when `fields` is set. `max_lines` counts the PR and its comments together. The limits listed under [`issue_view`](#issue_view) apply here too.

### `pr_diff`

Get the unified diff for a pull request.

```
Use gh-tooling pr_diff with number 14642
Use gh-tooling pr_diff with number 14642 and file "src/Core/Migration/V6_6/Migration1720094362.php"
Use gh-tooling pr_diff with number 14642 and name_only true
```

**Parameters:**
- `number` (integer, required): PR number.
- `file` (string, optional): Limit diff to a specific file path.
- `name_only` (boolean, optional): List only changed file names.
- `max_lines` (integer, optional): Return only the first N lines.
- `tail_lines` (integer, optional): Return only the last N lines.
- `grep_pattern` (string, optional): Filter lines by extended regex.
- `grep_context_before` / `grep_context_after` (integer, optional): Context lines around matches.
- `grep_ignore_case` (boolean, optional): Case-insensitive grep.
- `grep_invert` (boolean, optional): Return non-matching lines.

### `pr_list`

List pull requests with filters.

```
Use gh-tooling pr_list with author "mitelg" and state "merged" and limit 5
Use gh-tooling pr_list with search "NEXT-3412" and state "all"
Use gh-tooling pr_list with head "feature/my-branch"
```

### `pr_checks`

View CI status checks for a pull request.

```
Use gh-tooling pr_checks with number 14642
```

### `pr_comments`

Get inline review comments (code-level) for a PR.

```
Use gh-tooling pr_comments with number 14642
Use gh-tooling pr_comments with number 14642 and jq_filter ".[] | {path, body, line, user: .user.login}"
```

### `pr_reviews`

Get review decisions for a pull request.

```
Use gh-tooling pr_reviews with number 14642
Use gh-tooling pr_reviews with number 14642 and jq_filter ".[] | select(.state == \"CHANGES_REQUESTED\") | {user: .user.login, body}"
```

### `pr_files`

Get changed files with patch content.

```
Use gh-tooling pr_files with number 13911
Use gh-tooling pr_files with number 13911 and jq_filter ".[] | select(.filename | contains(\"Migration\")) | {filename, patch}"
```

### `pr_commits`

Get the commit history for a pull request.

```
Use gh-tooling pr_commits with number 14642
```

### `issue_view`

View a GitHub issue.

```
Use gh-tooling issue_view with number 8498
Use gh-tooling issue_view with number 8498 and with_comments true
Use gh-tooling issue_view with number 8498 and fields "title,body,state,labels,comments"
Use gh-tooling issue_view with number 8498 and with_field_values true
```

`with_comments: true` appends the issue's comments to the text output, after a
`--- comments ---` line. It is ignored when `fields` is set, and rejected together
with `with_field_values`. `max_lines` counts the issue and its comments together,
so a long body can leave the comments out.

The issue and its comments come from two `gh` calls. If the comments call fails,
the whole call fails, or returns `fallback`; the tool never returns the issue
without its comments. Known limits, which apply to `pr_view` with `comments` too:

- A comment posted or deleted between the two calls makes the issue's
  `comments:` count disagree with the list that follows.
- `gh` leaves hidden (minimized) comments out of the list, so an issue whose only
  comments are hidden shows a count but no separator.
- The separator is plain text: a body that contains the same line reads as the
  start of the comments.

`with_field_values` returns the issue's type and its field values keyed by field
name, which `gh issue view` exposes for neither:

```json
{"type": "Bug", "field_values": {"Priority": "Low", "Effort": "Low"}}
```

The `field_values` object is the shape `issue_field_set` takes, so it can be read,
edited, and passed straight back. Output is always JSON; combine it with `fields`
to add gh's own fields to the same document, and request comments separately.

### `issue_list`

List issues with filters.

```
Use gh-tooling issue_list with search "TODO label:component/core" and limit 20
```

### `issue_schema`

List an organization's issue types and issue fields, including each single-select field's options.
The organization comes from `org`, `owner`, a repository parameter, the configured default repo, or the
current clone's remote. When none of them supplies one, the error says `org` is required and, when
reading the clone's remote failed, includes gh's message unless `suppress_errors` is set.

Types and fields are independent. GitHub lets an organization pin fields to a type, but that pinning
only drives the web UI: any organization field can be set on an issue of any type, so this tool
reports the two lists side by side instead of nesting fields under types.

`type` and `field` match one name exactly, case-insensitively, and each narrows only its own list. A
name that matches nothing is an error rather than an empty list.

```
Use gh-tooling issue_schema with repo "shopware/shopware"
Use gh-tooling issue_schema with org "shopware" and type "Bug"
Use gh-tooling issue_schema with field "Priority" and jq_filter "[.fields[0].options[].name]"
```

### `run_view`

View the status of a GitHub Actions workflow run.

```
Use gh-tooling run_view with run_id 21534190745
Use gh-tooling run_view with run_id 21534190745 and fields "status,conclusion"
```

### `run_list`

List recent GitHub Actions runs with optional filters.

```
Use gh-tooling run_list with branch "tests/content-system-unit-tests" and limit 5
Use gh-tooling run_list with workflow "CI" and status "failure" and limit 10
Use gh-tooling run_list with workflow "CI" and branch "main" and event "push"
Use gh-tooling run_list with user "mitelg" and created ">2024-01-01"
Use gh-tooling run_list with commit "abc1234" and fields "databaseId,status,conclusion"
```

**Parameters:**
- `repo` (string, optional): Repository in `owner/repo` format.
- `branch` (string, optional): Filter by branch name.
- `workflow` (string, optional): Filter by workflow name or filename (e.g. `CI`, `build.yml`).
- `status` (string, optional): Filter by status (e.g. `completed`, `failure`, `success`).
- `event` (string, optional): Filter by trigger event (e.g. `push`, `pull_request`, `schedule`).
- `user` (string, optional): Filter by GitHub username who triggered the workflow.
- `created` (string, optional): Filter by creation date range (e.g. `>2024-01-01`).
- `commit` (string, optional): Filter by commit SHA.
- `limit` (integer, optional): Max results. Default: 20.
- `fields` (string, optional): Comma-separated JSON fields.

### `run_logs`

Get CI workflow run logs (failed steps by default).

```
Use gh-tooling run_logs with run_id 22245862281
Use gh-tooling run_logs with run_id 22245862281 and failed_only false and max_lines 500
Use gh-tooling run_logs with run_id 22245862281 and grep_pattern "FAILED|Error" and grep_context_after 3
Use gh-tooling run_logs with run_id 22245862281 and tail_lines 100
```

**Parameters:**
- `run_id` (integer, required): Workflow run ID.
- `failed_only` (boolean): Return only failed step logs. Default: `true`.
- `max_lines` (integer, optional): Return only the first N lines.
- `tail_lines` (integer, optional): Return only the last N lines.
- `grep_pattern` (string, optional): Filter lines by extended regex.
- `grep_context_before` / `grep_context_after` (integer, optional): Context lines around matches.
- `grep_ignore_case` (boolean, optional): Case-insensitive grep.
- `grep_invert` (boolean, optional): Return non-matching lines.

### `workflow_jobs`

Aggregate jobs across workflow runs in a single call. Reduces N+1 tool calls (run_list + N x job_view) to one invocation. Fetches runs for a workflow, then retrieves jobs for each run. If the jobs of any run cannot be fetched, the call fails, or returns `fallback` when set, rather than returning the jobs of the other runs.

```
Use gh-tooling workflow_jobs with workflow "CI" and repo "shopware/shopware" and job "PHPStan" and limit 3
Use gh-tooling workflow_jobs with workflow "CI" and repo "shopware/shopware" and conclusion "failure"
Use gh-tooling workflow_jobs with workflow "CI" and repo "shopware/shopware" and job "unit" and step "Run tests" and limit 5
Use gh-tooling workflow_jobs with workflow "CI" and repo "shopware/shopware" and run_status "failure" and branch "main"
```

**Parameters:**
- `workflow` (string, required): Workflow name or filename (e.g. `CI`, `build.yml`).
- `repo` (string, required): Repository in `owner/repo` format (pass explicitly or configure default).
- `job` (string, optional): Filter jobs by name (case-insensitive substring).
- `conclusion` (string, optional): Filter by job conclusion (e.g. `failure`, `success`).
- `step` (string, optional): Filter and include steps by name. Steps are excluded unless this is set.
- `limit` (integer, optional): Max workflow runs to fetch (each = 1 API call). Default: 5.
- `run_status` (string, optional): Filter runs by status.
- `branch` (string, optional): Filter runs by branch.
- `event` (string, optional): Filter runs by trigger event.
- `jq_filter` (string, optional): jq expression to filter the final output.
- `max_lines` (integer, optional): Return only the first N lines.

### `job_view`

Get details for a specific CI job including step statuses.

```
Use gh-tooling job_view with job_id 62056364818
Use gh-tooling job_view with job_id 62056364818 and jq_filter ".steps[] | select(.conclusion == \"failure\") | {name, number}"
```

### `job_logs`

Get log output for a specific CI job, with terminal escape sequences removed.

```
Use gh-tooling job_logs with job_id 62056364818
Use gh-tooling job_logs with job_id 62056364818 and max_lines 200
Use gh-tooling job_logs with job_id 62056364818 and grep_pattern "Fatal|Exception" and grep_context_after 5
Use gh-tooling job_logs with job_id 62056364818 and tail_lines 50
```

**Parameters:**
- `job_id` (integer, required): GitHub Actions job ID.
- `max_lines` (integer, optional): Return only the first N lines.
- `tail_lines` (integer, optional): Return only the last N lines.
- `grep_pattern` (string, optional): Filter lines by extended regex.
- `grep_context_before` / `grep_context_after` (integer, optional): Context lines around matches.
- `grep_ignore_case` (boolean, optional): Case-insensitive grep.
- `grep_invert` (boolean, optional): Return non-matching lines.

### `job_annotations`

Get inline error annotations from a CI check run.

```
Use gh-tooling job_annotations with check_run_id 62056364818
```

### `commit_pulls`

List GitHub pull requests associated with a pushed commit SHA. GitHub-only -- for local commit metadata (files changed, commit message) use `git show <sha>` via Bash.

```
Use gh-tooling commit_pulls with sha "15a7c2bb86"
Use gh-tooling commit_pulls with sha "15a7c2bb86" and jq_filter ".[].number"
```

**Parameters:**
- `sha` (string, required): Commit SHA (7-40 hex characters). Must be pushed to GitHub.
- `repo` (string, optional): Repository in `owner/repo` format.
- `jq_filter` (string, optional): jq expression to filter/transform the PR list.

### `search`

Search for issues or pull requests.

```
Use gh-tooling search with search "NEXT-3412" and type "prs"
Use gh-tooling search with search "custom field translation" and type "issues" and limit 20
Use gh-tooling search with search "attribute entity" and state "closed"
Use gh-tooling search with search "\"custom field\" label:\"good first issue\"" and type "issues"
```

**Search expressions** (`search`, `search_repos`, `search_commits`): each word is its own keyword, so a result has to match all of them, in any order. Double quotes keep a phrase together (`"custom field"`), also as a qualifier value (`label:"good first issue"`). A `search` with an unmatched `"` fails before `gh` runs. `gh` cannot pass three forms through: a negated phrase (`-"exact phrase"` becomes a phrase that starts with `-`; use `NOT "exact phrase"`), a quoted single word (`"OR"` becomes the operator), and a phrase containing `:`.

### `search_code`

Search for code across GitHub repositories. Uses the legacy code search engine (no regex, no symbol search, no path globs). Rate limit: 10 requests/minute.

```
Use gh-tooling search_code with search "addClass" and repo "shopware/shopware"
Use gh-tooling search_code with search "extends AbstractController" and language "php" and limit 10
Use gh-tooling search_code with search "composer.json" and match "path" and owner "shopware"
Use gh-tooling search_code with search "addClass" and repo "shopware/shopware" and download_to "/tmp/results"
```

**Parameters:**
- `search` (string, required): Code search expression, matched as exact text (no regex). Unlike the other search tools, the whole value is one phrase.
- `owner` (string, optional): Limit to repositories owned by this user/org, instead of the configured default repo. With a bare repo name in `repo`, the two form `owner/repo`.
- `repo` (string, optional): Limit to this repository, as `owner/repo` or as a bare name together with `owner`. An `owner` passed with an `owner/repo` value must name the same owner.
- `language` (string, optional): Filter by language (e.g. `php`, `typescript`).
- `extension` (string, optional): Filter by file extension (e.g. `php`, `ts`).
- `filename` (string, optional): Filter by filename (e.g. `composer.json`).
- `match` (string, optional): Restrict matches to `file` contents or `path`.
- `limit` (integer, optional): Max results. Default: 30.
- `download_to` (string, optional): Local directory. Downloads matching files instead of returning results.
- Supports all grep parameters and `max_lines`/`tail_lines`.

### `search_repos`

Search for repositories by search expression, owner, topic, language, license, or star count. `search` is optional -- filters alone suffice.

```
Use gh-tooling search_repos with owner "shopware" and language "php"
Use gh-tooling search_repos with search "ecommerce" and stars ">100" and sort "stars"
Use gh-tooling search_repos with topic "shopware" and limit 10
```

**Parameters:**
- `search` (string, optional): Search expression; see [Search expressions](#search). A value with no words searches by the filters alone.
- `owner` (string, optional): Filter by owner.
- `topic` (string, optional): Filter by topic tag.
- `language` (string, optional): Filter by language.
- `license` (string, optional): Filter by SPDX license (e.g. `mit`).
- `stars` (string, optional): Star count range (e.g. `>100`, `50..200`).
- `sort` (string, optional): `stars`, `forks`, `help-wanted-issues`, or `updated`.
- `limit` (integer, optional): Max results. Default: 20.

### `search_commits`

Search for commits by message text, author, date range, or hash.

```
Use gh-tooling search_commits with search "NEXT-1234" and repo "shopware/shopware"
Use gh-tooling search_commits with search "fix cart" and author "mitelg" and author_date ">2024-01-01"
```

**Parameters:**
- `search` (string, required): Commit message search expression; see [Search expressions](#search).
- `repo` (string, optional): Limit to this repository, as `owner/repo` or as a bare name together with `owner`. An `owner` passed with an `owner/repo` value must name the same owner.
- `owner` (string, optional): Limit to repositories owned by this user/org, instead of the configured default repo. With a bare repo name in `repo`, the two form `owner/repo`.
- `author` (string, optional): Filter by commit author username.
- `committer` (string, optional): Filter by committer username.
- `author_date` (string, optional): Date range (e.g. `>2024-01-01`, `2024-01-01..2024-06-30`).
- `committer_date` (string, optional): Committer date range.
- `hash` (string, optional): Filter by SHA prefix.
- `merge` (boolean, optional): Filter merge commits.
- `sort` (string, optional): `author-date` or `committer-date`.
- `limit` (integer, optional): Max results. Default: 20.

### `search_discussions`

Search for GitHub discussions via GraphQL. Discussions are only available via GraphQL.

```
Use gh-tooling search_discussions with search "RFC" and repo "shopware/shopware"
Use gh-tooling search_discussions with search "authentication" and category "Q&A" and with_comments true
```

**Parameters:**
- `search` (string, required): Discussion search text.
- `repo` (string, optional): Limit to this repository in `owner/repo` format.
- `category` (string, optional): Filter by category name (e.g. `RFC`, `Q&A`).
- `author` (string, optional): Filter by author username.
- `state` (string, optional): State qualifier (e.g. `is:answered`, `is:open`).
- `with_comments` (boolean, optional): Include comment bodies and replies. Default: `false`.
- `limit` (integer, optional): Max results. Default: 20.
- `jq_filter` (string, optional): Applied to full GraphQL response. Default: `.data.search.nodes`.

### `repo_tree`

Browse repository directory contents or get the full recursive file tree. Accepts GitHub URLs. Use instead of `WebFetch` on GitHub tree URLs.

```
Use gh-tooling repo_tree with url "https://github.com/shopware/shopware/tree/main/src/Core"
Use gh-tooling repo_tree with repository "shopware/shopware" and path "src/Core"
Use gh-tooling repo_tree with repository "shopware/shopware" and recursive true
```

**Parameters:**
- `owner` (string, optional): Repository owner. Used with `repo`.
- `repo` (string, optional): Repository name. Used with `owner`.
- `repository` (string, optional): `owner/repo` format.
- `path` (string, optional): Directory path. Default: root.
- `ref` (string, optional): Branch, tag, or SHA.
- `recursive` (boolean, optional): Get full recursive tree. Default: `false`.
- `url` (string, optional): GitHub URL to parse. Explicit params override URL values. Note: URLs with slashed refs (e.g. `feature/my-branch`) are not parsed correctly -- use explicit `ref` param instead.

### `repo_file`

Fetch a single file from a GitHub repository as raw text. Accepts GitHub URLs. Use instead of `WebFetch` on GitHub blob URLs.

```
Use gh-tooling repo_file with url "https://github.com/shopware/shopware/blob/main/composer.json"
Use gh-tooling repo_file with repository "shopware/shopware" and path "composer.json"
Use gh-tooling repo_file with repository "shopware/shopware" and path "src/Core/Kernel.php" and line_start 1 and line_end 20
Use gh-tooling repo_file with repository "shopware/shopware" and path "composer.json" and download_to "/tmp/composer.json"
```

**Parameters:**
- `owner` (string, optional): Repository owner. Used with `repo`.
- `repo` (string, optional): Repository name. Used with `owner`.
- `repository` (string, optional): `owner/repo` format.
- `path` (string, required unless from URL): File path within the repository.
- `ref` (string, optional): Branch, tag, or SHA.
- `url` (string, optional): GitHub URL to parse. Explicit params override URL values. Note: URLs with slashed refs (e.g. `feature/my-branch`) are not parsed correctly -- use explicit `ref` param instead.
- `line_start` (integer, optional): First line to return (1-indexed).
- `line_end` (integer, optional): Last line to return (inclusive).
- `download_to` (string, optional): Local path. Saves file content instead of returning it.
- Supports all grep parameters and `max_lines`/`tail_lines`.

### `release_list`

Look up release versions for one or more repositories. Built for dependency-update tasks: pass a `repos` array to get the latest version of each in a single call instead of one `api_read` per repo. Releases are sorted by semantic version descending (not by publish date), so the highest version is treated as latest.

```
Use gh-tooling release_list with repos ["actions/checkout", "actions/setup-node", "docker/build-push-action"] and fields ["repo", "tag_name"]
Use gh-tooling release_list with repo "docker/setup-buildx-action" and jq_filter ".[].tag_name"
Use gh-tooling release_list with repo "docker/build-push-action" and constraint "4" and latest false
Use gh-tooling release_list with repo "actions/setup-python" and resolve_sha true and fields ["tag_name", "commit_sha"]
Use gh-tooling release_list with repo "nodejs/node" and include_prereleases true and limit 50 and latest false
```

**Parameters:**
- `repos` (array of strings, optional): Batch mode -- repositories in `owner/repo` format. When set, the single-repo parameters are ignored and one entry is returned per repo.
- `repo` (string, optional): Single repository in `owner/repo` format. Also accepts `owner`+`repo`, `repository`, or `url`. Falls back to the configured default repo.
- `latest` (boolean, optional): Return only the highest-version release per repo. Default `true`. Set `false` for the full filtered list.
- `constraint` (string, optional): Restrict to a version line by prefix -- a major (`4`/`v4`) or major.minor (`4.2`/`v4.2`). Range operators (`^`, `~`, `>=`, `<`) are not supported. Filtering applies within the fetched window, so increase `limit` to reach older major lines.
- `include_prereleases` (boolean, optional): Consider prereleases. Default `false` (matches GitHub's `releases/latest` behavior).
- `include_drafts` (boolean, optional): Consider draft releases. Default `false`.
- `limit` (integer, optional): Releases fetched per repo before filtering. Default 30, capped at 100.
- `resolve_sha` (boolean, optional): Add a `commit_sha` field by resolving each tag to its commit (lightweight and annotated tags both resolve correctly). One extra API call per result. Useful for pinning GitHub Actions to an immutable SHA.
- `fields` (array of strings, optional): Restrict each result object to these keys. Allowed: `repo`, `tag_name`, `name`, `published_at`, `html_url`, `prerelease`, `draft`, `commit_sha`. Example: `["tag_name"]` for just version numbers.
- `jq_filter` (string, optional): jq expression applied to the final result array. Output is JSON; `.[].tag_name` reduces it to the (JSON-quoted) version strings.
- `suppress_errors` (boolean, optional): In batch mode, skip a repo whose lookup fails instead of failing the whole call.
- `fallback` (string, optional): Text to return if a lookup fails.

### `label_list`

List labels for a repository. Returns label names, descriptions, and colors.

```
Use gh-tooling label_list
Use gh-tooling label_list with repo "shopware/shopware"
Use gh-tooling label_list with filter "bug"
Use gh-tooling label_list with jq_filter ".[] | {name, description}"
```

**Parameters:**
- `repo` (string, optional): Repository in `owner/repo` format.
- `filter` (string, optional): Filter labels by name substring (case-insensitive).
- `jq_filter` (string, optional): jq expression to filter/transform the JSON output.
- `max_lines` (integer, optional): Return only the first N lines.

### `project_list`

List GitHub Projects (v2) for a user or organization. Returns project numbers, titles, and URLs.

```
Use gh-tooling project_list
Use gh-tooling project_list with owner "shopware"
Use gh-tooling project_list with jq_filter ".[] | {number, title}"
```

**Parameters:**
- `owner` (string, optional): Owner (user or org) to list projects for. Defaults to the owner from the configured default repo.
- `jq_filter` (string, optional): jq expression to filter/transform the JSON output.
- `max_lines` (integer, optional): Return only the first N lines.

### `project_view`

View details of a GitHub Project (v2), including field definitions and status options. Use to discover available status values before setting them.

```
Use gh-tooling project_view with number 5
Use gh-tooling project_view with number 5 and owner "shopware"
Use gh-tooling project_view with number 5 and jq_filter ".fields[] | select(.name == \"Status\")"
```

**Parameters:**
- `number` (integer, required): Project number.
- `owner` (string, optional): Owner (user or org). Defaults to the owner from the configured default repo.
- `jq_filter` (string, optional): jq expression to filter/transform the JSON output.
- `max_lines` (integer, optional): Return only the first N lines.

### `api_read`

Read-only GitHub REST API call (GET only). Use the gh-tooling-write server's `api` tool for POST, PATCH, PUT, or DELETE requests.

```
Use gh-tooling api_read with endpoint "repos/shopware/shopware/issues/8498/timeline"
Use gh-tooling api_read with endpoint "repos/shopware/shopware/pulls/14642/comments" and paginate true
Use gh-tooling api_read with endpoint "search/issues" and jq_filter ".items[] | {number, title, state}"
```

**Parameters:**
- `endpoint` (string, required): GitHub API endpoint, relative to `https://api.github.com/`.
- `method` (string, optional): HTTP method. Enum: `GET`, `POST`, `PATCH`, `PUT`, `DELETE`. Default: `GET`.
- `jq_filter` (string, optional): jq expression to filter/transform the JSON response.
- `paginate` (boolean, optional): Fetch all pages of paginated results. Default: `false`.
- `fields` (string, optional): Comma-separated fields for `--jq` selection.
- `max_lines` (integer, optional): Return only the first N lines of output.
- `tail_lines` (integer, optional): Return only the last N lines of output.

---

## Write Server (gh-tooling-write)

Tools available via the `gh-tooling-write` MCP server. Requires `enable_write_server: true` in `.mcp-gh-tooling.json`.

### Shared Tool Parameters

All gh-tooling-write MCP tools accept these parameters:

| Parameter         | Type    | Default | Description                                                             |
|-------------------|---------|---------|-------------------------------------------------------------------------|
| `suppress_errors` | boolean | `false` | Silence stderr; errors produce empty output instead of an error message |
| `fallback`        | string  | --      | Return this text (successfully) when the gh command fails               |

Unknown parameters are rejected at the MCP layer (`additionalProperties: false`), the same as on the read server. A misspelled or unsupported field (e.g. `body_file` on `pr_edit`) returns an error naming the allowed parameters instead of being silently dropped from the write.

### PR Write Tools

#### `pr_create`

Create a new pull request. Opens a PR from the current or specified branch. Use `draft` to create a draft PR that is not ready for review.

```
Use gh-tooling-write pr_create with title "Fix cart calculation" and body "Resolves NEXT-1234"
Use gh-tooling-write pr_create with title "Add feature" and base "main" and head "feature/my-feature" and draft true
Use gh-tooling-write pr_create with title "Bug fix" and labels ["bug", "priority/high"] and assignees ["mitelg"]
```

**Parameters:**
- `title` (string, required): Title of the pull request.
- `body` (string, optional): Body text (description) of the pull request.
- `base` (string, optional): Base branch to merge into (e.g. `main`). Defaults to the repository's default branch.
- `head` (string, optional): Head branch containing the changes. Defaults to the current branch.
- `draft` (boolean, optional): Create as a draft pull request. Default: `false`.
- `labels` (array of strings, optional): Labels to apply to the pull request.
- `assignees` (array of strings, optional): GitHub usernames to assign.
- `reviewers` (array of strings, optional): GitHub usernames to request reviews from.
- `milestone` (string, optional): Milestone name or number.
- `repo` (string, optional): Repository in `owner/repo` format.

#### `pr_edit`

Edit an existing pull request's metadata: title, body, base branch, labels, assignees, or milestone. Labels and assignees are added (not replaced). Use the GitHub API tool to remove labels or assignees.

```
Use gh-tooling-write pr_edit with number 14642 and title "Updated title"
Use gh-tooling-write pr_edit with number 14642 and labels ["needs-review"] and assignees ["reviewer1"]
Use gh-tooling-write pr_edit with number 14642 and body "Updated description with more context"
```

**Parameters:**
- `number` (integer, required): Pull request number.
- `title` (string, optional): New title.
- `body` (string, optional): New body text.
- `base` (string, optional): New base branch.
- `labels` (array of strings, optional): Labels to add.
- `assignees` (array of strings, optional): Usernames to add as assignees.
- `milestone` (string, optional): Milestone name or number.
- `repo` (string, optional): Repository in `owner/repo` format.

#### `pr_ready`

Mark a draft pull request as ready for review. Transitions the PR from draft state to open/reviewable state.

```
Use gh-tooling-write pr_ready with number 14642
```

**Parameters:**
- `number` (integer, required): Pull request number.
- `repo` (string, optional): Repository in `owner/repo` format.

#### `pr_merge`

Merge a pull request immediately. Supports merge commit, squash, and rebase strategies. Optionally deletes the head branch after merging.

```
Use gh-tooling-write pr_merge with number 14642
Use gh-tooling-write pr_merge with number 14642 and method "squash" and delete_branch true
Use gh-tooling-write pr_merge with number 14642 and method "squash" and subject "fix: resolve cart calculation"
```

**Parameters:**
- `number` (integer, required): Pull request number.
- `method` (string, optional): Merge strategy. Enum: `merge`, `squash`, `rebase`. Default: `merge`.
- `delete_branch` (boolean, optional): Delete the head branch after merging. Default: `false`.
- `subject` (string, optional): Subject line for the merge commit (used with merge and squash methods).
- `body` (string, optional): Body text for the merge commit message.
- `repo` (string, optional): Repository in `owner/repo` format.

#### `pr_close`

Close a pull request without merging. Optionally posts a comment explaining why the PR is being closed.

```
Use gh-tooling-write pr_close with number 14642
Use gh-tooling-write pr_close with number 14642 and comment "Superseded by #14650"
```

**Parameters:**
- `number` (integer, required): Pull request number.
- `comment` (string, optional): Comment to post when closing.
- `repo` (string, optional): Repository in `owner/repo` format.

#### `pr_reopen`

Reopen a previously closed pull request.

```
Use gh-tooling-write pr_reopen with number 14642
```

**Parameters:**
- `number` (integer, required): Pull request number.
- `repo` (string, optional): Repository in `owner/repo` format.

### Review Write Tools

#### `pr_review_submit`

Submit a review on a pull request, optionally batching inline code comments in a single call. Mirrors the web UI flow: start a review, attach line comments, submit with an event.

When `comments` is omitted, acts as a plain event-only review submission (uses `gh pr review`). When `comments` is provided, posts the full review via the REST reviews endpoint; `commit_id` is auto-fetched from the PR head if not given. Use ```suggestion blocks inside a comment body for one-click suggested changes.

```
Use gh-tooling-write pr_review_submit with number 14642 and event "approve"
Use gh-tooling-write pr_review_submit with number 14642 and event "request_changes" and body "A few blockers inline."
Use gh-tooling-write pr_review_submit with number 14642, event "comment", body "Overall LGTM, notes inline.", and comments [{"path": "src/Core/Cart/Calculator.php", "line": 42, "body": "Use strict comparison here."}, {"path": "src/Core/Cart/Calculator.php", "line": 50, "body": "```suggestion\n    return $this->resolve($foo);\n```"}]
```

**Parameters:**
- `number` (integer, required): Pull request number.
- `event` (string, optional): Review event type. Enum: `approve`, `request_changes`, `comment`. Default: `comment`.
- `body` (string, optional): Overall review body text (the top-level summary). Required for `request_changes`.
- `comments` (array, optional): Inline review comments. Each item: `path` (string), `line` (integer), `body` (string), `side` (`LEFT`|`RIGHT`, default `RIGHT`), `start_line` (integer, for multi-line ranges), `start_side` (`LEFT`|`RIGHT`).
- `commit_id` (string, optional): Commit SHA the review is anchored to. Only used when `comments` is non-empty. Defaults to the PR's current head SHA (auto-fetched).
- `repo` (string, optional): Repository in `owner/repo` format.

#### `pr_comment`

Add a general (conversation-tab) comment to a pull request. Not tied to any line or review.

```
Use gh-tooling-write pr_comment with number 14642 and body "CI is green, ready to merge"
```

**Parameters:**
- `number` (integer, required): Pull request number.
- `body` (string, required): Comment body text.
- `repo` (string, optional): Repository in `owner/repo` format.

#### `pr_review_reply`

Reply to an existing review comment thread. Posts a threaded reply to a prior review comment (by `comment_id`), continuing the same conversation thread. Use `pr_review_submit` to start a new review with inline comments; use this to respond to someone else's existing thread.

```
Use gh-tooling-write pr_review_reply with number 14642 and comment_id 1234567 and body "Fixed in b8f9a8c, thanks for catching this."
```

**Parameters:**
- `number` (integer, required): Pull request number.
- `comment_id` (integer, required): ID of the parent review comment to reply to. Obtain from `pr_comments` or `pr_reviews`.
- `body` (string, required): Reply body text.
- `repo` (string, optional): Repository in `owner/repo` format.

### Issue Write Tools

#### `issue_create`

Create a new GitHub issue. Supports labels, assignees, milestone, and project.

```
Use gh-tooling-write issue_create with title "Cart calculation bug" and body "Steps to reproduce..."
Use gh-tooling-write issue_create with title "Feature request" and labels ["enhancement"] and assignees ["mitelg"]
Use gh-tooling-write issue_create with title "Task" and project "Sprint Board"
```

**Parameters:**
- `title` (string, required): Title of the issue.
- `body` (string, optional): Body text (description).
- `labels` (array of strings, optional): Labels to apply.
- `assignees` (array of strings, optional): GitHub usernames to assign.
- `milestone` (string, optional): Milestone name or number.
- `project` (string, optional): Project name or URL to add the issue to.
- `repo` (string, optional): Repository in `owner/repo` format.

#### `issue_edit`

Edit an existing issue's metadata: title, body, labels, assignees, or milestone. Labels and assignees are added (not replaced). Use the GitHub API tool to remove labels or assignees.

```
Use gh-tooling-write issue_edit with number 8498 and title "Updated issue title"
Use gh-tooling-write issue_edit with number 8498 and labels ["priority/high"] and assignees ["reviewer1"]
```

**Parameters:**
- `number` (integer, required): Issue number.
- `title` (string, optional): New title.
- `body` (string, optional): New body text.
- `labels` (array of strings, optional): Labels to add.
- `assignees` (array of strings, optional): Usernames to add as assignees.
- `milestone` (string, optional): Milestone name or number.
- `repo` (string, optional): Repository in `owner/repo` format.

#### `issue_close`

Close an issue. Optionally specify a reason (completed or not_planned) and post a comment when closing.

```
Use gh-tooling-write issue_close with number 8498
Use gh-tooling-write issue_close with number 8498 and reason "completed" and comment "Fixed in #14642"
Use gh-tooling-write issue_close with number 8498 and reason "not_planned" and comment "Won't fix: out of scope"
```

**Parameters:**
- `number` (integer, required): Issue number.
- `reason` (string, optional): Reason for closing. Enum: `completed`, `not_planned`.
- `comment` (string, optional): Comment to post when closing.
- `repo` (string, optional): Repository in `owner/repo` format.

#### `issue_reopen`

Reopen a previously closed issue.

```
Use gh-tooling-write issue_reopen with number 8498
```

**Parameters:**
- `number` (integer, required): Issue number.
- `repo` (string, optional): Repository in `owner/repo` format.

#### `issue_comment`

Post a comment on an issue.

```
Use gh-tooling-write issue_comment with number 8498 and body "This has been fixed in the latest release"
```

**Parameters:**
- `number` (integer, required): Issue number.
- `body` (string, required): Comment text to post.
- `repo` (string, optional): Repository in `owner/repo` format.

### Issue Type and Field Write Tools

Both tools take names, not IDs, and resolve them against the organization's schema before calling the
API, so an unknown name fails with the valid ones listed. Use `issue_schema` to see what is available.
Issue types and issue fields apply to issues only, not pull requests.

#### `issue_type_set`

Set or clear an issue's type. The name replaces whatever the issue carried before, and `null` clears
it, so repeating the same call leaves the issue in the same state.

```
Use gh-tooling-write issue_type_set with number 19952 and type "Bug"
Use gh-tooling-write issue_type_set with number 19952 and type null
```

**Parameters:**
- `number` (integer, required): Issue number.
- `type` (string or null, required): Issue type name, matched case-insensitively, or `null` to clear.
- `repo` (string, optional): Repository in `owner/repo` format.

#### `issue_field_set`

Replace an issue's field values. The `values` object becomes the issue's **complete** set: a field
left out is cleared, and `{}` clears them all. To change one field without dropping the others, read
the current values with `issue_view` and `with_field_values true`, edit the entry you want, and pass
the whole object back — its `field_values` object and this `values` object are the same shape, and so
is this tool's own response.

Values are typed by the field: a single-select takes an option name, a multi-select takes an array of
option names, a date takes `YYYY-MM-DD`, a number takes a number, and a text field takes a string.

```
Use gh-tooling-write issue_field_set with number 19952 and values {"Priority": "High", "Effort": "Low"}
Use gh-tooling-write issue_field_set with number 19952 and values {}
```

**Parameters:**
- `number` (integer, required): Issue number.
- `values` (object, required): Complete set of field values keyed by field name. `{}` clears every value.
- `repo` (string, optional): Repository in `owner/repo` format.

### Label Write Tools

#### `label_add`

Add labels to a pull request or issue by name.

```
Use gh-tooling-write label_add with number 14642 and type "pr" and labels ["bug", "priority/high"]
Use gh-tooling-write label_add with number 8498 and type "issue" and labels ["needs-triage"]
```

**Parameters:**
- `number` (integer, required): PR or issue number.
- `type` (string, required): Whether this is a PR or issue. Enum: `pr`, `issue`.
- `labels` (array of strings, required): Label names to add.
- `repo` (string, optional): Repository in `owner/repo` format.

#### `label_remove`

Remove labels from a pull request or issue by name.

```
Use gh-tooling-write label_remove with number 14642 and type "pr" and labels ["needs-triage"]
Use gh-tooling-write label_remove with number 8498 and type "issue" and labels ["bug"]
```

**Parameters:**
- `number` (integer, required): PR or issue number.
- `type` (string, required): Whether this is a PR or issue. Enum: `pr`, `issue`.
- `labels` (array of strings, required): Label names to remove.
- `repo` (string, optional): Repository in `owner/repo` format.

### Assignee Write Tools

#### `assignee_add`

Assign users to a pull request or issue.

```
Use gh-tooling-write assignee_add with number 14642 and type "pr" and assignees ["mitelg", "reviewer1"]
Use gh-tooling-write assignee_add with number 8498 and type "issue" and assignees ["developer1"]
```

**Parameters:**
- `number` (integer, required): PR or issue number.
- `type` (string, required): Whether this is a PR or issue. Enum: `pr`, `issue`.
- `assignees` (array of strings, required): GitHub usernames to assign.
- `repo` (string, optional): Repository in `owner/repo` format.

#### `assignee_remove`

Remove assigned users from a pull request or issue.

```
Use gh-tooling-write assignee_remove with number 14642 and type "pr" and assignees ["reviewer1"]
Use gh-tooling-write assignee_remove with number 8498 and type "issue" and assignees ["developer1"]
```

**Parameters:**
- `number` (integer, required): PR or issue number.
- `type` (string, required): Whether this is a PR or issue. Enum: `pr`, `issue`.
- `assignees` (array of strings, required): GitHub usernames to remove.
- `repo` (string, optional): Repository in `owner/repo` format.

### Sub-Issue Write Tools

#### `sub_issue_add`

Add a sub-issue to a parent issue. Both must exist in the same repository. Uses GitHub's GraphQL sub-issues API.

```
Use gh-tooling-write sub_issue_add with issue_number 100 and sub_issue_number 101
Use gh-tooling-write sub_issue_add with issue_number 100 and sub_issue_number 101 and repo "shopware/shopware"
```

**Parameters:**
- `issue_number` (integer, required): Parent issue number.
- `sub_issue_number` (integer, required): Issue number to add as sub-issue.
- `repo` (string, optional): Repository in `owner/repo` format.

#### `sub_issue_remove`

Remove a sub-issue from a parent issue. Uses GitHub's GraphQL sub-issues API.

```
Use gh-tooling-write sub_issue_remove with issue_number 100 and sub_issue_number 101
```

**Parameters:**
- `issue_number` (integer, required): Parent issue number.
- `sub_issue_number` (integer, required): Sub-issue number to remove.
- `repo` (string, optional): Repository in `owner/repo` format.

### Project Write Tools

#### `project_item_add`

Add an issue or PR to a GitHub Project by project name. The server resolves the project name to its ID.

```
Use gh-tooling-write project_item_add with number 14642 and type "pr" and project "Sprint Board"
Use gh-tooling-write project_item_add with number 8498 and type "issue" and project "Backlog"
```

**Parameters:**
- `number` (integer, required): PR or issue number.
- `type` (string, required): Whether this is a PR or issue. Enum: `pr`, `issue`.
- `project` (string, required): Project name (human-readable). Server resolves to project number.
- `repo` (string, optional): Repository in `owner/repo` format.

#### `project_status_set`

Set the Status field of an issue or PR in a GitHub Project. Both project and status are specified by name -- the server resolves to IDs. The item must already be in the project (use `project_item_add` first).

```
Use gh-tooling-write project_status_set with number 14642 and type "pr" and project "Sprint Board" and status "In Progress"
Use gh-tooling-write project_status_set with number 8498 and type "issue" and project "Sprint Board" and status "Done"
```

**Parameters:**
- `number` (integer, required): PR or issue number.
- `type` (string, required): Whether this is a PR or issue. Enum: `pr`, `issue`.
- `project` (string, required): Project name. Server resolves to project number.
- `status` (string, required): Status value name (e.g. `In Progress`, `Done`). Server resolves to option ID.
- `repo` (string, optional): Repository in `owner/repo` format.

### Write API

#### `api`

Execute a GitHub API call using gh api. Supports all HTTP methods (GET, POST, PATCH, PUT, DELETE). Use this as an escape hatch when specific write tools don't cover your use case.

```
Use gh-tooling-write api with endpoint "repos/shopware/shopware/pulls/14642/requested_reviewers" and method "POST"
Use gh-tooling-write api with endpoint "repos/shopware/shopware/issues/8498/labels" and method "DELETE"
Use gh-tooling-write api with endpoint "repos/shopware/shopware/issues/8498/timeline" and jq_filter ".[] | {event, actor: .actor.login}"
```

**Parameters:**
- `endpoint` (string, required): GitHub API endpoint, relative to `https://api.github.com/`.
- `method` (string, optional): HTTP method. Enum: `GET`, `POST`, `PATCH`, `PUT`, `DELETE`. Default: `GET`.
- `jq_filter` (string, optional): jq expression to filter/transform the output.
- `paginate` (boolean, optional): Enable pagination. Default: `false`.
- `fields` (string, optional): jq expression for `--jq` flag on the gh api call.
- `max_lines` (integer, optional): Return only the first N lines of output.
- `tail_lines` (integer, optional): Return only the last N lines of output.

Shares the implementation of `api_read`, including its escape-sequence handling — see Read Server §Shared Tool Parameters.
