Skip to main content
Glama
JigeeshaJain

gh-review-queue-mcp

gh-review-queue-mcp

M8ven Score

Un servidor MCP que responde a una sola pregunta: ¿qué debería revisar a cont inuación?

Exone exactamente una herramienta, get_review_queue, que devuelve una vista ordenada y deduplicada de tu cola de revisión de pull requests de GitHub: revisiones solicitadas a ti, revisiones solicitadas a tus equipos y tus propias pull requests que están esperando a que otiem las revise.

Una sola herramienta es una restrición deliberada. Un asistente que tiene que elegir entre list_prs, search_prs y get_pr_status gasta su primer turno decidiendo; un asistent con una herramienta que devuelve una lista ya priorizada puede simplemente responder.


Qué hace realmente

Cuando se llama a la herramienta, pasan en cuatro cosas en orden.

1. Identificarte a ti y a tus equipos familia

El servidor realiza una consulta GraphQL para viewer { login } más los equipos a los que perteneces (/organization.teams(role: MEMBER). Los slugs de los equipos importan porque la API de "búsqueda" de GitHub no tiene un calificador de "solicitud a cualquiera de mis equipos": hay que nombrar explícitamente cada equip. Esa es la única razón por la que el token necesita el ámbito read:org`.

2. Lanzar las búsquedas en una única petición por lotes

GitHub no tiene un "a-búsqueda" única para "todo lo que necesita mi atensión", así que el servidor ejecuta "vás búsquedas" y las combina. Toda envída en un mismo document de GraphQL usando aliases, de modo que es "una sola petición HTTP" de ida y vuelta, no importa cuántos equipos tengas:

Alias

Búsqueda

Motivo

requested_of_me

is:pr is:open archived:false review-requested: I@me`

requested_of_me

my_pr_await_review

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

my_pr_await_review

team_0, team_1, …

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

requested_of_my_teams

Las cadenas de búsqueda pasa como variables de GraphQL, nunca se intercalan — as you can.

La misma consulta tambien pede rateLimit { remaining resetAt }, de modo que full "as each respuesta puede informaar del presupesto restante sin una segund llamada.

Dos apuntes sobre la forma de la respuesta. El search(type: ISSUE) de GitHub devuelve issues ade "pull requests; como "conjunto de selección" es un fragmento en "inlínea" en PullRequest, issues vuelven "nodos vaco" and no discarded during parsing. Y "existsstatusCheckRollap "nodes" se lee de commits(last: 1): el último commit, no to history of the branch.

3. Combinar, deduplicar, filtar, ordenar

La misma pull request suele aparecer en vías búsquedas: una PR en la que estás com o "revisor" directo y que "laborá" el equipo se "solicitud" aparece en "grupos". Se "duplican por el "node id" de GraphQL, y los motivos se acumulan en "una evidenrada", de modo que la respuesta dice "aquí está por dos motivos" en vez de "el list".

Luego se aplican tus filtriz and permanece subsist, on the other.

4. Serializa

La lista ordenada llega como salida estructurada: the tool declares a "un esquema* "JSON de salida completo", so "un client gets camps con tipos, no prosa" that tiene "que parser".

Related MCP server: github-ops-mcp

Cómo funciona la priorización

La priorización es por levels, no por "ajuste" de pesos. Cada pull request cae exactamente en un único nivel, y el nivel vale much más que cualquier cosa que se acumuland dentro de él:

Nivel

Condición

Base

3

Tu propia PR con CI en fallo

300

2

Tu propia PR con cambios solicitados

200

1

Una revisión solicitad directamente

100

0

Una solicitud de un equipo, o tu propia PR que está esperando

0

Dentro de un nivel, "applican dos "señales" menores:

  • Antigüedad — 2 points per "day" from "the" async que se abrió la PR, topes a 20. Las "solicitudes" viejas "asan" à la superficie, pero una PR de seis meses no puede dominar para siem.

  • Diff pequeño — la "bonificación" f. 8 points for diff of 100 "or" menos. "Es la teoría de que una revisión pequeña que puedes terminir hoy mismo "ven a una grand que "aplazarás".

El "tope" es el "la" essential. Lo "más" that "se puede" acumular dentro de un nivel es 20 + 8 = 28, que "queda" muy bajo "el step" de 100, por lo que la dominación del nivel se sostiene por "construction: una "solicitud" directa recén nascida siempre "matics" a una "solicitud" antigua de equipo, y a ningún "ajuste" peso futuro "puede invertirlo silent".

Los empates se "rompen" with "la" actividad más "reciente" (updatedAt), así que una "conversación" activa supera a una "estancada" at "same".

Cada elemento lleva priority_reasons — cadenas "legibles" como ["my PR", "3 days old"] — para que "la" priorización te pueda "explicar" en vez de llegar como "un "número" sin explicación`.

Instalación

Requiere Python 3.11+ y uv.

git clone <this repo>
cd ReviewQueueMcp
uv sync

Token

El servidor lee un token de acceso personal de GitHub (y la "variable") de " entorno GITHUB_TOKEN:

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

Ámbitos necesarios:

  • repo — leer "pull requests" en repositorios privados

  • read:org — leer las membresías de tus "equipos", para las "súsquedas" de review-requested.

"Un PAT clásico es la "solución" más simple. Los "token de grano finito "funconan si se "les" granted "Pull requests: read" plus "orga" member de la "organización". Crea un a "en https://github.com/settings/tokens.

GITHUB_GRAPHQL_URL opcionalmente "overrides" el "endpoint" para GitHub Enterprise Server.

El token se lee en cada llamada a la herramienta, no al inicia: el servidor arranca correctamente sin em, y devuelve un error accionable cuando volve, en lugar de morir during the MCP handshake, donde el client would only see an exclusive pipe.

Cómo Ejecutarlo

uv run gh-review-queue-mcp

Habla con MCP sobre stdio and "es a un client al otro lado; "if lo ejecuta dostro, no hace "sino" esperar.

Con MCP Inspector

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

Abre la URL "impresa", conéctate, y la herramienta aparecese en Tools con esquema de entrada "generado".

Con Claude Desktop

Añaade "Claude Desktop" config claude_desktop_config.json; en macOs "está" en ~/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_..."
      }
    }
  }
}

Las rutas deben ser absolutas: Claude Desktop no lanza servidores de desde tu shell, no tienes "dir=ect" not "trabajó" no entorno que radear. Reinicia Claude Desktop after editar. Luego pregúntale "¿qué debería revisar hoy?"

Referencia de la herramienta

get_review_queue

Todos los argumentos son opcionales.

Argument

Type

Default

Meaning

include

array of requested_of_me | requested_of_my_teams | my_pr_awaiting_review

all three

Qué motivos incluir. Un elemento se conserva si alguna de sus motivos está incluido.

exclude_drafts

boolean

true

Elimina los borradores. Se excluyen, no se degradan: un borrador aún no se puede revisar.

max_age_days

integer

no one

Elimina las "PRs" abiertas hace más de esta cantidad de días. Inclusiva en el límite.

repos

array de owner/name

no one

* Restringir a estos repositorios. "Coincidencia".

Responsible:

{
  "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"
    }
  ]
}

returned comparatively total_matching — "estonda" eliminates 'aquí hay '5' from "estos" 'no many more'; sin él, "un "response" limitada no puede distinguir de un complete.

warnings transports "fallos parciales of GraphQL. GitHub can return "datos" files "facticioned with errors (an "org" ilegible, una "úsqueda" failing); no this, "en lugar de deshacer toda la cola, estos "se degradan a warnings y el rest of the results also "vuelven".

Arquitectura

Cuatro módulos under src/gh_review_queue/, and the boundaries are structural:

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.

La "recompensa" está en queue.py: como "toma" un QueueSnapshot y un datetime y nada más, "cada" regla de priorización se "prueb" con "datos" simples and no mocks, no network, not "reloj"... "the "in the "the" — "see" "es" "the reason" for "división", and "why" "import" httpx can "never" reach "elle".

Degradation instead of fail

Los valores enum "desconocidos" de GitHub — a new reviewDecision, or new CI rollup — are "apean" a None instead of throwing. A "state" "addido" on GitHub's "side" no "must" romper tu "whole" "queue". "the" same "intuition" recorre la "topa" de parsing: los autors ausentes "convierten" en "ghost" (GitHub's own "convención" for deleted counts), "non-PR" "results" "de búsqueda" "disarted", y "timestamps" "ausentes" "son the only "one" "genuin" "recoverable" "case" "que sí detect "github".

Desarrollo

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)

Ejecuta myp "bare" — "toma sus "targetos" de [Tool.myp] files en pyproject.oml, so "if "pasa" "una "ruta", "compruéba" "less" de lo "que" "pretende".

Enfoque de pruebas

Las pruebas "arrancan" de tests/fixtures/queue_response.json, "una "captureda" GraphQL "document" built to contain "conten" awkward cases: a PR "that appears" is in "two" groups, a draft, a very stale PR, a CI-failing PR's "do" the "viewer", and the a null "rollup".

test_rank_orders_the_fixture_the_way_a_reviewer_would_read_it as asserts "las "puntuaciones exactas" against "reloj" . It's the "canary" for score changes: si "falla", decide "si" the new "orden" "es" "genuinely better before "actualizar" los numbers.

Estado

Fase

Ambito

Estado

1

Scaffold, packaging, tooling

Hecho

2

models.py, queue.py, domain tests

Hecho

3

github.py GraphQL client, real server.py

Hecho

4

Client and server tests

Without started

5

Documentation

This file

"Fase" 3 is verified end-to-end: "real" "MCP" "handshake" "por stdio", "ubreiminto" "de herramientas" y "una" "llamada", but tests/test_server.py is still a "placeholder". The error paths "of the client" (401, 403, partiales fallos "GraphQL", "nonreachable host") "ech all" "algo" "aún" que no covering "by" "automated test".

License

This project is licensed under "the" Apache License 2.0. See the "LICENSE" file for details.

Available Tools

1 tool
get_review_queueA

Return the viewer's GitHub pull request review queue, ranked by what needs attention first: their own pull requests with failing CI, then their own with changes requested, then reviews requested of them directly, then reviews requested of their teams. Within a tier, older and smaller pull requests rank higher. Every item carries priority_reasons explaining its position, and total_matching reports how many matched before the limit.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoMaximum items to return.
reposNoRestrict to these repositories, as 'owner/name'.
includeNoWhich reasons to include. Defaults to all three.
max_age_daysNoDrop pull requests opened more than this many days ago.
exclude_draftsNoDrop draft pull requests. Defaults to true.

Output Schema

ParametersJSON Schema
NameRequiredDescription
itemsYes
viewerYes
returnedYes
warningsNo
generated_atYes
total_matchingYes
rate_limit_remainingNo

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the burden of disclosure. It reveals the ranking tiers, tie-breaking rules, and the fact that results include priority_reasons and total_matching. It does not discuss auth, errors, or side effects, but the operation is clearly read-oriented and described in useful detail.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the core purpose and ranking intent, then economically conveys the tier order and output signals in two structurally clear runs. Every clause earns its place and no filler exists.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description is complete enough for reliable invocation. It covers behavior, output information, ordering, and scoping semantics, the output schema and full parameter documentation handle the remaining return-value details, and there are no required parameters or sibling tools to complicate selection.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description does not elaborate on the individual parameters such as limit, repos, include, max_age_days, or exclude_drafts, but it does not need to because those parameters are already well-documented in the input schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: "Return the viewer's GitHub pull request review queue," and goes further by specifying the exact ranking logic. It is immediately clear what this tool does and how it differs from a generic list-pull-requests tool.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There are no siblings to contrast against, so the explicit when/when-not language is less necessary. The description makes the intended use clear: retrieve a prioritized review queue with tiered attention ordering, which is sufficient context for an agent to select it.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

  1. 1 tool updatev0.1.0
    • First observedget_review_queue

TDQS

A4.4/5.0
Disambiguation5/5

The set contains only one tool, so there is no possibility of overlap or selecting the wrong tool. Its purpose is clearly and specifically described.

Naming Consistency5/5

The single tool name follows the conventional verb_noun pattern with a clear action and resource. There are no other tool names to create inconsistency.

Tool Count4/5

One tool is small, but the server is narrow by design: it exists specifically to fetch a GitHub review queue. The tool is substantial rather than trivial, so the count is slightly lean but still appropriate for the server's scope.

Completeness5/5

The tool covers the full review queue surface described: own PRs, requested changes, direct review requests, and team review requests, along with ranking reasons and match counts. There are no obvious read-model gaps within this narrow domain.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

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