bitbucket-pr-review-mcp
bitbucket-pr-review-mcp
Un servidor MCP que permite a un modelo de lenguaje leer una solicitud de extracción de Bitbucket Cloud y dejar comentarios en ella, anclados a las líneas sobre las que tratan, más un resumen al principio.
El servidor proporciona material y publica palabras. No forma opiniones: el modelo que llama es quien hace la revisión, y aquí no hay ninguna instrucción de revisión ni credencial de modelo.
Cómo funciona y por qué: docs/architecture.md
Las decisiones detrás de ello: docs/adr/
El idioma que utiliza: CONTEXT.md
Lo que no puede hacer
Puede crear y actualizar comentarios. No puede aprobar, rechazar ni fusionar una solicitud de extracción, no puede escribir en ramas ni archivos, y nunca elimina un comentario.
Bitbucket no vende un permiso que separe comentar de fusionar. La credencial que le das a este servidor es capaz de fusionar tus solicitudes de extracción; nada de tokens o ámbitos lo impide. Lo que lo impide es que ninguna herramienta lo pide, que un único punto de estrangulamiento en el cliente HTTP lo rechaza sin importar cómo se construya la solicitud, y —la parte que no depende de que este código sea correcto— las restricciones de rama que configures tú mismo en el repositorio. Consulta ADR-0002 y lee Antes de empezar.
Related MCP server: Bitbucket MCP Server
Antes de empezar
Configura restricciones de rama en cualquier repositorio que permitas. En Bitbucket: Configuración del repositorio → Restricciones de rama. Restringe quién puede fusionar en tu rama predeterminada y exige las aprobaciones que tu equipo espera. Bitbucket las aplica sin importar lo que haga este servidor, lo que las convierte en la única garantía aquí que sobrevive a un error en este repositorio. Toma un minuto y es la diferencia entre "creemos que este código es cuidadoso" y "no importa si no lo es".
Instalación
Requiere uv y Python 3.13. Los mismos tres comandos funcionan en Windows, macOS y Linux:
git clone <this repository>
cd bitbucket-pr-review-mcp
uv syncLuego indícale qué repositorios puede tocar:
cp config/repositories.yaml.example config/repositories.yaml...y edítalo. El archivo lista entradas workspace/repo, no contiene secretos y está pensado para ser confirmado:
repositories:
- streamstech/db-explorer
- streamstech/lent-managerEl servidor se niega a arrancar sin él. Una lista ausente es indistinguible de permiso para tocar todos los repositorios a los que tu credencial puede acceder, y los comodines se rechazan por la misma razón.
Conectando tu cuenta de Bitbucket
Ejecuta la configuración y abre el enlace que imprime:
uv run bb-pr-mcp --setupSirve una página en tu propia máquina —solo loopback, en un puerto aleatorio, enlace de un solo uso, desaparece después de cinco minutos— pidiendo tu correo electrónico de cuenta de Atlassian (no tu nombre de usuario de Bitbucket, ni el nombre que le diste al token) y un token de API. Verifica el par contra Bitbucket y te muestra tu nombre para mostrar antes de almacenar nada, luego coloca la credencial en el llavero de tu sistema operativo y se cierra.
Crea el token en https://id.atlassian.com/manage-profile/security/api-tokens con exactamente estos cuatro ámbitos:
Ámbito | Por qué |
| Para que el servidor sepa de quién son los comentarios — sin él, cada re-revisión apila duplicados |
| Leer archivos y confirmaciones alrededor del cambio |
| Leer la solicitud de extracción en sí — los ámbitos granulares no se anidan, así que el ámbito de escritura abajo no cubre esto |
| Publicar y actualizar comentarios |
Nada más amplio. Un token que también pueda escribir en un repositorio, administrar uno o ejecutar pipelines se rechaza en el formulario y se rechaza de nuevo al inicio.
Introduce la fecha de caducidad del token cuando lo configures y se te avisará una semana antes de que expire en lugar de encontrarte con un 401 a mitad de revisión.
Nunca tienes que ejecutar --setup explícitamente: sin credencial almacenada, cada herramienta responde con la URL de configuración en lugar de un error.
Compruébalo cuando quieras:
uv run bb-pr-mcp --checkEso valida la lista de permitidos, la credencial y sus ámbitos, imprime quién eres al publicar y sale con un estado de shell — 0 bien, 1 sin credencial utilizable, 2 un token cuyos ámbitos son incorrectos.
Eliminándolo
uv run bb-pr-mcp --forgetEso elimina la credencial del llavero de este dispositivo y nada más — el token sigue existiendo en Atlassian hasta que lo revoques allí, y el comando lo dice. La siguiente llamada a una herramienta te dará un enlace de configuración nuevo.
Deliberadamente no hay ninguna herramienta para esto. Una herramienta que elimine la credencial es una herramienta que una descripción de solicitud de extracción puede convencer a un modelo de que llame, y no se gana nada: quien quiera que desaparezca ya está en una terminal.
El modelo nunca ve el token
El token va desde tu navegador al llavero, y de allí a un encabezado Authorization. Nunca es un argumento de una herramienta, nunca está en la respuesta de una herramienta, nunca en un mensaje de error, y no está en la URL de configuración — esa lleva un token diferente de un solo uso, que no concede nada más que el derecho a rellenar un formulario en esta máquina. tests/test_the_token_never_reaches_the_model.py va a buscarlo en todos esos lugares.
Si el llavero no está disponible
La credencial va al llavero del sistema operativo y a ningún otro sitio — nunca a un archivo. En macOS y Windows eso funciona de serie. En Linux necesitas un Secret Service (gnome-keyring o KWallet) ejecutándose y desbloqueado; si no hay ninguno, el servidor se detiene en lugar de recurrir a un archivo (ADR-0003).
Ejecutándolo
El servidor habla MCP sobre stdio. Apunta tu cliente a él:
{
"mcpServers": {
"bitbucket-pr-review": {
"command": "uv",
"args": ["run", "--directory", "/path/to/bitbucket-pr-review-mcp", "bb-pr-mcp"]
}
}
}En Windows usa la misma forma con una ruta de Windows ("C:\\path\\to\\bitbucket-pr-review-mcp"). Nada más difiere entre plataformas.
Para Claude Code:
claude mcp add bitbucket-pr-review -- uv run --directory /path/to/bitbucket-pr-review-mcp bb-pr-mcpEjecutándolo en Docker
La imagen habla MCP sobre stdio como todo lo demás, así que no hay puerto ni nada que up. Constrúyela, luego ejecútala con -i y habla con ella.
docker build -t bitbucket-pr-review-mcp:local .Un contenedor no tiene llavero, y la página de configuración no puede ayudar: enlaza un puerto loopback dentro del contenedor, al que tu navegador no puede llegar. Así que una ejecución en contenedor recibe su credencial en lugar de almacenar una. Eso es una degradación real — una variable de entorno es visible para docker inspect y para cualquier cosa que pueda leer el proceso — y es una decisión más que un recurso: nada degrada a ello, ambas variables deben estar establecidas, y el inicio lo dice cada vez. Consulta ADR-0007.
Pon la credencial en un archivo que no esté en este repositorio:
BB_MCP_EMAIL=you@yourcompany.com
BB_MCP_API_TOKEN=ATATT...
BB_MCP_TOKEN_EXPIRES_ON=2027-08-24Luego compruébalo y conéctalo a un cliente:
docker run --rm \
--env-file /path/to/env.docker \
-v /path/to/repositories.yaml:/config/repositories.yaml:ro \
bitbucket-pr-review-mcp:local --check{
"mcpServers": {
"bitbucket-pr-review": {
"command": "docker",
"args": [
"run", "--rm", "-i",
"--env-file", "/path/to/env.docker",
"-v", "/path/to/repositories.yaml:/config/repositories.yaml:ro",
"bitbucket-pr-review-mcp:local"
]
}
}
}docker-compose.yaml escribe las mismas banderas una vez: docker compose run --rm bitbucket-pr-review, leyendo .env.docker (ignorado por git) desde este directorio.
Algunas cosas que vale la pena saber:
En Windows, usa una ruta de estilo Windows en
-v(d:/path/to/repositories.yaml:/config/...). Bajo Git Bash, prefija el comando conMSYS_NO_PATHCONV=1o la ruta se reescribe.La lista de permitidos se monta, no se hornea. Nombra los repositorios que el servidor puede tocar; esa lista pertenece a quien ejecuta la imagen, no a la imagen.
--setupsale con 2 en un contenedor, diciendo dónde se puede ejecutar la configuración en su lugar. Rotar un token significa reiniciar con uno nuevo.El contenedor se ejecuta como un usuario no root, de solo lectura, con todas las capacidades eliminadas.
Probando el servidor compartido desde Claude Desktop
El despliegue compartido —varias personas, un servidor, cada una con su propia cuenta de Bitbucket— todavía se está construyendo. Lo que funciona hoy es suficiente para conducir de extremo a extremo localmente.
Un conector personalizado de Claude Desktop no puede alcanzar localhost. Claude se conecta a un servidor MCP remoto desde la propia infraestructura de Anthropic, no desde tu máquina, así que un servidor en tu portátil es inalcanzable sin importar cómo esté configurado. El bucle local pasa por mcp-remote: un puente stdio que se ejecuta en tu máquina, realiza el flujo OAuth en tu navegador y habla HTTP con el servidor.
Inicia el servidor de autorización y el servidor de revisión:
docker compose -f docker compose --profile shared up -d
BB_MCP_PUBLIC_URL=http://localhost:8000/mcp BB_MCP_OIDC_ISSUER=http://localhost:8080/realms/streamstech BB_MCP_OIDC_CLIENT_SECRET=development-only-replace-before-deploying-too BB_MCP_VAULT_KEY="$(uv run python -c 'from bitbucket_pr_review_mcp.vault import VaultKey; print(VaultKey.generate().exported())')" uv run bb-pr-mcp --http --port 8000Luego añade esto a claude_desktop_config.json (%APPDATA%\Claude\ en Windows, ~/Library/Application Support/Claude/ en macOS — una instalación de Microsoft Store lo mantiene bajo %LOCALAPPDATA%\Packages\Claude_*\LocalCache\Roaming\Claude\):
{
"mcpServers": {
"bitbucket-pr-review": {
"command": "npx",
"args": [
"-y", "mcp-remote",
"http://localhost:8000/mcp",
"3334",
"--allow-http",
"--static-oauth-client-info", "{\"client_id\":\"bitbucket-pr-review-cli\"}"
]
}
}
}deploy/claude_desktop_config.example.json contiene lo mismo. Reinicia Claude Desktop, y la primera llamada a una herramienta abre un inicio de sesión de Keycloak (dev / dev-only-not-for-production en el reino de desarrollo). Después de iniciar sesión, una llamada a una herramienta responde con un enlace a /connect, donde conectas tu cuenta de Atlassian — esa página hace que el navegador también inicie sesión, por eso el enlace es seguro de ver en una transcripción.
Algunas cosas que vale la pena saber:
El puente es un cliente OAuth público, sin secreto. Un secreto de cliente en un archivo de configuración en un portátil no es un secreto; PKCE es lo que protege un flujo de loopback.
Su callback es
http://127.0.0.1:3334/oauth/callback— el literal IP en lugar delocalhost, y/oauth/callbacken lugar del/callbackde Claude Code. El reino los registra todos, porque equivocarse falla en el último paso del flujo.--allow-httpes obligatorio mientras el servidor esté en http plano. Un despliegue real es https, y este servidor se niega a describirse a sí mismo sobre http en cualquier lugar que no sea loopback.el perfil
sharedes configuración de desarrollo. Su Keycloak tiene una base de datos en memoria y contraseñas escritas en el archivo.
Operándolo
uv run bb-pr-mcp --health
uv run bb-pr-mcp --rotate-key /path/to/new.key--health dice si el despliegue está en condiciones de ejecutarse — TLS, la clave del vault, el almacén, la lista de permitidos, si el servidor de autorización es alcanzable y cuántas personas están conectadas — y sale 0 sano, 1 algo que mirar, 2 esto no arrancará.
--rotate-key vuelve a sellar cada credencial almacenada bajo una nueva clave sin que nadie se vuelva a inscribir, luego te dice el orden para hacer el resto.
Lee docs/deploying-the-shared-server.md antes de ejecutar esto en cualquier lugar real. Declara cuánto cuesta un compromiso del host, que es mayor de lo que parece, y qué hacer al respecto.
Quién está conectado, y sacar a alguien
uv run bb-pr-mcp --who
uv run bb-pr-mcp --revoke alice@streamstech.com--who lista a todos los que han conectado una cuenta de Bitbucket: el id opaco, el correo de Atlassian, cuándo se conectaron y cuándo expira su token. Descifra el vault para responder, y luego imprime todo excepto el único campo que vale la pena descifrar.
--revoke elimina la credencial almacenada de una persona. Toma un correo o suficiente del id opaco para ser inequívoco, y se niega en lugar de adivinar cuando un nombre coincide con dos personas. La revocación tiene efecto en la siguiente llamada a una herramienta, incluso en un servidor que ya está en ejecución — el servidor compartido lee la credencial en lugar de mantenerla, precisamente para que un operador en otra terminal no esté esperando un reinicio.
Lo que no hace es la parte que vale la pena leer. Tres lugares guardan algo después de que alguien se va, y este comando posee uno de ellos:
Aquí. La credencial almacenada ha desaparecido.
Keycloak. Todavía pueden iniciar sesión y conectar un token nuevo. Desactiva su cuenta allí para detener eso.
Atlassian. Su token de API todavía existe y sigue funcionando en cualquier otro lugar. Solo ellos, o un administrador de Atlassian, pueden revocarlo.
El comando dice los tres cada vez, porque una lista de verificación de baja que se marca después del primer paso es peor que ninguna lista.
Ninguna de las dos es una herramienta, y eso es deliberado: una descripción de solicitud de extracción no debe poder convencer a un Caller de que desconecte a un colega.
Las herramientas
Herramienta | Qué hace |
| Título, estado, autor, ramas y la Base de Revisión |
| Cada archivo modificado con recuentos, marcando entradas binarias, generadas y de lockfile |
| El diff completo, o un solo archivo, con un margen de anclas que muestra el número de cada línea |
| La conversación existente, con anclas, marcas de obsoleto y qué comentarios son del propio servidor |
| Publicar un hallazgo o una revisión completa; se valida todo antes de enviar nada |
| Publicar o actualizar el comentario de resumen único |
| Metadatos y la rama por defecto |
| Cualquier archivo en un repositorio permitido, en una ref |
| Un listado de directorio, en una ref |
| Historial de una ref o de una solicitud de extracción |
| Búsqueda de código dentro de un repositorio permitido |
Una solicitud de extracción se nombra con una sola cadena: o una URL de Bitbucket o la forma
abreviada workspace/repo/id.
Configuración
Todo lo siguiente tiene un valor predeterminado funcional. Configúralos en el entorno o en un archivo .env, todos
con el prefijo BB_MCP_:
Configuración | Predeterminado | Qué hace |
|
| Dónde vive la lista de permitidos |
|
| Los registros van a stderr, nunca a stdout |
|
| Un objeto JSON por línea, para enviar a un agregador |
|
| Tiempo de espera por solicitud |
|
| Límite de respuesta del diff |
|
| Límite de respuesta de archivo |
|
| Filas del manifiesto |
|
| Filas del directorio |
|
| Filas de commits |
|
| Coincidencias de búsqueda |
|
| Comentarios leídos por solicitud de extracción |
Existen dos más y están vacíos hasta que se complete el despliegue compartido: la instalación por dispositivo descrita arriba no necesita ninguno, porque stdio tiene exactamente un llamador:
Configuración | Qué hace |
| La dirección a la que se conecta Claude, exactamente como se escribe en el conector. Es lo que los tokens deben nombrar como su audiencia |
| El reino de Keycloak que emite esos tokens. Debe coincidir exactamente con el emisor en el documento de descubrimiento del reino: una barra final es una diferencia |
| Dónde se guardan las credenciales por persona. Cifrado bajo |
| El cliente de Keycloak con el que este servidor inicia sesión a las personas, para que la página que recoge un token de API pueda preguntar quiénes son |
| El secreto de ese cliente. Requerido para la página de conexión; sin él, a un llamador sin credencial se le dice que la configuración no está disponible en lugar de enviarlo a algún lugar inútil |
Cada límite se indica en la respuesta cuando se alcanza. La truncación nunca es silenciosa: un llamador que no pueda distinguir un diff truncado de uno completo revisará la mitad faltante asumiendo que estaba bien.
Desarrollo
uv run pytest # the suite
uv run pytest --cov=src # with coverage
uv run ruff check src tests # lint
uv run ruff format src tests # formatLas pruebas nunca tocan la red. La separación es el transporte HTTP y nada más, así que el
guard, la lista de permitidos y cada lector de respuestas se ejercitan como código de producción.
tests/recorded/ contiene respuestas capturadas de una solicitud de extracción real; consulta
docs/architecture.md para saber por qué eso importa más de lo que
parece.
This server cannot be installed
Maintenance
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
- AlicenseNot gradedqualityAmaintenanceEnables AI assistants to interact with Bitbucket Cloud repositories, allowing users to manage pull requests, comments, tasks, and branches through natural language commands.4,1381MIT
- AlicenseAqualityDmaintenanceEnables management of Bitbucket Cloud pull requests through natural language, including creating, reviewing, approving, and commenting on PRs with automatic default reviewer support.791MIT
- AlicenseNot gradedqualityCmaintenanceEnables AI assistants to programmatically manage Bitbucket Cloud resources, including pull requests, repositories, and branches, automating code review workflows.189MIT
- AlicenseAqualityDmaintenanceEnables LLMs to review Bitbucket pull requests with custom checklists and API token authentication.51MIT
Related MCP Connectors
A Model Context Protocol (MCP) application for automated GitHub PR analysis and issue management.…
Screens public GitHub repos and PRs to generate risk maps, findings, and merge-readiness signals.
Risk-scan a diff, flag AI-generated-code tells, find secrets. 5 of 7 tools need no account.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/6shihab/bitbucket-pr-review-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server