Skip to main content
Glama
JigeeshaJain

gh-review-queue-mcp

by JigeeshaJain

gh-review-queue-mcp

1つの質問に答えるMCPサーバー:次に何をレビューすべきか?

公開するツールは1つだけ、get_review_queue。これはあなたのGitHubプルリクエストレビュー待ちキューを、重複を除いてランク付けしたビューを返します——あなたに依頼されたレビュー、あなたのチームに依頼されたレビュー、そして誰かのレビューを待っているあなた自身のプルリクエスト。

ツールが1つだけというのは意図的な制約です。list_prssearch_prsget_statusの間で選ばなければならないアシスタントは、最初のターンを選択に費やします。一方、すでに優先順位付けされたリストを返すツールが1つだけあれば、アシスタントはただ答えるだけです。


実際にやっていること

ツールが呼び出されると、4つのことが順番に行われます。

1. あなたとあなたのチームを特定する

サーバーはviewer { login }に加えて、あなたが所属するチーム(organizations.teams(role: MEMBER))を取得するGraphQLクエリを発行します。チームのスラッグが重要なのは、GitHubの検索APIには「自分のチームのいずれかに依頼された」という修飾子がないためです——各チームを明示的に指定する必要があります。これが、トークンがread:orgスコープを必要とする唯一の理由です。

2. 1つのバッチ検索にファンアウトする

GitHubには「私の注意を必要とするすべて」を1つのクエリで取得する方法がないため、サーバーは複数の検索を実行してそれらを結合します。それらはすべて1つのGraphQLドキュメントにエイリアスを使ってまとめられるため、チームがいくつあってもHTTPラウンドトリップは1回です:

エイリアス

検索

理由となる値

requested_of_me

is:pr is:open archived:review-requested:@me

requested_of_me

my_pr_awaiting_review

is:pr is:open archived:author:@me

my_pr_awaiting_review

team_0team_1、…

is:pr is:open archived:team-review-requested:<org>/<team>

requested_of_my_teams

検索文字列はGraphQL変数として渡され、クエリドキュメントにインターpolateされることは決してないため、チームのスラッグがクエリを変形させることはできません。

同じクエリはrateLimit { remaining resetAt }も要求するため、毎回のレスポンスで残りの利用枠を、追加の呼び出しなしで報告できます。

レスポンスの形状に関する2つの注意点。GitHubのsearch(type: ISSUE)はプルリクエストだけでなくイシューも返します。PullRequest上のインラインフラグメントによる選択セットのため、イシューは空のノードとして返ってきて、パース時に破棄されます。またstatusCheckRollupcommits(last: 1)から読み取られます——つまりHEADコミットのCI状態であり、ブランチ全体の履歴ではありません。

3. マージ、重複排除、フィルタ、ランク付け

同じプルリクエストが複数の検索から返ってくるのは日常茶飯事です——あなたが直接レビューアに指定されかつあなたのチームにも依頼されているPRは、2つのバケットに現れます。それらはGraphQLのノードIDで重複排除され、理由は1つのエントリに累積されるため、レスポンスは「ここに2つの理由で存在する」と伝えます。「2回リストされている」のではありません。

その後、あなたのフィルタが適用され、生き残ったものがスコアリングされ並べ替えられます。

4. シリアライズ

ランク付けされたリストは構造化された出力として返されます——ツールは完全なJSON出力スキーマを宣言するため、クライアントはパースしなければならない散文ではなく、型付けされたフィールドを受け取ります。


Related MCP server: github-ops-mcp

ランキングの仕組み

ランキングは重み調整ではなく階層型です。各プルリクエストは正確に1つの階層に分類され、その階層の値は、内部に累積されるものよりもはるかに大きくなります:

階層

条件

基準値

3

CIが失敗している自分のPR

300

2

変更を依頼された自分のPR

200

1

あなたに直接依頼されたレビュー

100

0

チームへの依頼、または単に待機中の自分のPR

0

階層内では、2つの小さなシグナルが適用されます:

  • 経過日数 — PRが開かれてからの日数1日につき2ポイント、上限20。古いレビュー依頼も浮上しますが、6ヶ月前のPRが永遠に支配することはありません。

  • 小さな差分 — 差分が100行以下の場合の一律8ポイントボーナス。すぐに終えられる小さなレビューは、後回しにしたくなる大きなレビューに勝ります。

上限がポイントです。階層内で累積できる最大値は20 + 8 = 28であり、階層のステップ幅100を大きく下回ります。したがって階層の優位性は構造的に保証されます:新しい直接依頼は常に古いチーム依頼より上位になります。将来スコアリングのシグナルを追加する場合も、階層内合計を100未満に保てば、その保証は壊れません。

同点は最新のアクティビティ(updatedAt)で決着します。同じスコアなら、停滞した議論より活発な議論が上位になります。

すべての項目はpriority_reasonsを持ちます——["my PR, CI failing", "3 days old"]のような人間が読める文字列——これにより、ランキングの理由が「説明のつかない数値」ではなく、そのまま伝わります。


インストール

Python 3.11以上とuvが必要です。

git clone <this repo>
cd ReviewQueueMcp
uv sync

トークン

サーバーはGITHUB_TOKENからGitHubの個人アクセストークンを読み取ります:

cp .env.example .env      # then edit it
export GITHUB_TOKEN=ghp_...

必要なスコープ:

  • repo — プライベートリポジトリのプルリクエストを読むため

  • read:org — チームレビュー依頼の検索のため、あなたのチームメンバーシップを読むため

クラシックなPATが最も簡単です。ファイングレインのトークンでも、「Pull requests: read」プラス「organization member read」が付与されていれば機能します。作成はhttps://github.com/settings/tokensで。

GITHUB_GRAPHQL_URLはオプションで、GitHub Enterprise Serverのエンドポイントを上書きします。

トークンはツール呼び出しのたびに読み取られ、起動時ではありません——サーバーはトークンなしでもクリーンに起動し、呼び出された時点で実行可能なエラーを返します。MCPハンドシェイク中に死んで、クライアントには壊れたパイプしか見えない、という事態は避けられます。


実行方法

uv run gh-review-queue-mcp

MCP over stdioで通信し、クライアントが反対側にいることを期待します。直接実行すれば、ただ待機します。

MCP Inspectorを使う場合

npx @modelcontextprotocol/inspector uv --directory /absolute/path/to/ReviewQueueMcp run gh-review-queue-mcp

表示されたURLを開いて接続すると、ツールがToolsの下に、生成された入力スキーマとともに表示されます。

Claude Desktopを使う場合

claude_desktop_config.jsonに追加します——macOSでは~/Library/Application Support/Claude/claude_desktop_config.json

{
  "mcpServers": {
    "gh-review-queue": {
      "command": "uv",
      "args": [
        "--directory",
        "/absolute/path/to/ReviewQueueMcp",
        "run",
        "gh-review-queue-mcp"
      ],
      "env": {
        "GITHUB_TOKEN": "ghp_..."
      }
    }
  }
}

パスは絶対パスでなければなりません——Claude Desktopはあなたのシェルからサーバーを起動するわけではないため、作業ディレクトリやエクスポートされた環境を引き継ぎません。編集後はClaude Desktopを再起動してください。その後、「what should I review today?」と尋ねてみてください。


ツールリファレンス

get_review_queue

すべての引数はオプションです。

引数

デフォルト

意味

include

requested_of_me | requested_of_my_teams | my_pr_awaiting_review の配列

すべて

含める理由。項目はいずれかの理由が含まれていれば残ります。

exclude_drafts

boolean

true

ドラフトを除外。ドラフトは降格ではなく除外です——ドラフトはまだレビュー可能ではありません。

max_age_days

integer

なし

この日数より前に開かれたPRを除外。境界値は含みます。

repos

owner/name の配列

なし

これらのリポジトリに限定。完全一致。

limit

integer 1–100

25

返される最大項目数。total_matchingは依然として総数を報告します。

レスポンス:

{
  "viewer": "octocat",
  "generated_at": "2026-08-20T12:00:00Z",
  "returned": 5,
  "total_matching": 5,
  "rate_limit_remaining": 4712,
  "warnings": [],
  "items": [
    {
      "repository": "acme/payments-api",
      "number": 4830,
      "title": "Add idempotency keys",
      "url": "https://github.com/acme/payments-api/pull/4830",
      "author": "octocat",
      "reasons": ["my_pr_awaiting_review"],
      "priority_score": 306.0,
      "priority_reasons": ["my PR, CI failing", "3 days old"],
      "age_days": 3.0,
      "diff_size": 374,
      "changed_files": 12,
      "is_draft": false,
      "review_decision": "REVIEW_REQUIRED",
      "ci_status": "FAILURE"
    }
  ]
}

returnedtotal_matchingの区別は、「ここに25件あります」と「多数あります」を区別するためのものです——これがないと、制限されたレスポンスは完全なレスポンスと区別がつきません。

warningsはGraphQLの部分的な失敗を伝えます。GitHubはエラーとともに使用可能なデータを返すことがあります(1つの組織が読めない、1つの検索が失敗するなど)。キュー全体を捨てるのではなく、それらは警告に格下げされ、残りの結果は引き続き返ってきます。


アーキテクチャ

src/gh_review_queue/の下に4つのモジュールがあり、その境界は構造上重要です:

server.py    MCP wiring. Parse arguments -> call client -> domain layer -> serialize.
   |         Deliberately thin; its docstring sets a ~120-line budget.
   v
github.py    The only module that touches the network. Builds GraphQL, handles HTTP
   |         and GraphQL errors, returns domain objects. Never ranks or filters.
   v
queue.py     Pure functions: merge -> apply_filters -> rank/score, via build_queue.
   |         Input is a snapshot and a clock. Nothing else.
   v
models.py    Frozen pydantic value objects. The only place GitHub's nested GraphQL
             shape is flattened. No network types.

その見返りはqueue.pyにあります:QueueSnapshotdatetimeだけを受け取り、それ以外は受け取らないため、すべてのランキングルールがプレーンなデータだけでテストでき、モックもネットワークもクロックのパッチも不要です。それが分割の理由であり、httpxのインポートが決してそこに到達してはならない理由でもあります。

失敗するのではなく劣化する

GitHubからの未知のenum値——新しいreviewDecision、新しいCIロールアップ状態——は、例外を発生させるのではなくNoneにマッピングされます。GitHub側で追加された状態が、あなたのキュー全体を壊すべきではありません。同じ考え方がパース層全体に通底しています:著者がいない場合はghostになります(削除されたアカウントに対するGitHub自身の慣例)、PRではない検索結果は破棄され、タイムスタンプが存在しない場合だけが、唯一本当に回復不能であり例外を発生させるケースです。


開発

uv run pytest                       # all tests
uv run pytest tests/test_queue.py   # one file
uv run pytest -k "rank or score"    # by name
uv run ruff check .                 # lint
uv run ruff format .                # format
uv run mypy                         # typecheck (strict)

mypyは裸で実行してください——ターゲットをpyproject.toml[tool.mypy] filesから取得するため、パスを渡すと意図したよりもチェック範囲が狭くなります。

テストのアプローチ

テストはtests/fixtures/queue_response.jsonを使って実行されます。これは、厄介なケースを含むように構築された、キャプチャされた1つのGraphQLレスポンスです:2つのバケットに現れるPR、ドラフト、非常に古いPR、ビューア自身のCI失敗PR、そしてnullのステータスロールアップ。

test_rank_orders_the_fixture_the_way_a_reviewer_would_read_itは、固定されたクロックに対して正確なスコアを検証します。これはスコアリング変更のカナリアです——失敗した場合は、数値を更新する前に、新しい順序が本当に優れているかどうかを判断してください。


ステータス

フェーズ

範囲

状態

1

スキャフォールド、パッケージング、ツーリング

完了

2

models.pyqueue.py、ドメインテスト

完了

3

github.py GraphQLクライアント、実物のserver.py

完了

4

クライアントとサーバーのテスト

未着手

5

ドキュメント

このファイル

フェーズ3はエンドツーエンドで検証済みです——実際のMCP stdioハンドシェイク、ツール発見、ツール呼び出し——ただしtests/test_server.pyはまだプレースホルダーです。クライアントのエラーパス(401、403、部分的なGraphQL失敗、到達不能なホスト)は記述されていますが、まだ自動テストでカバーされていません。

F
license - not found
Not graded
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

View all related MCP servers

Related MCP Connectors

  • A Model Context Protocol (MCP) application for automated GitHub PR analysis and issue management.…

  • An MCP server that gives your AI access to the source code and docs of all public github repos

  • A MCP server built for developers enabling Git based project management with project and personal…

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/JigeeshaJain/ReviewQueueMcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server