Forgejo MCP Server

Gestiona repositorios de Forgejo y ejecuta comandos a través de una interfaz de chat compatible con MCP.

Documentación

Forgejo MCP Server

Conecta tu asistente de IA a los repositorios de Forgejo. Gestiona issues, pull requests, archivos y más mediante lenguaje natural.

Qué Hace

Forgejo MCP Server es un plugin de integración que conecta Forgejo con sistemas de Model Context Protocol (MCP). Una vez configurado, puedes interactuar con tus repositorios de Forgejo a través de cualquier asistente de IA compatible con MCP, como Claude, Cursor o extensiones de VS Code.

Ejemplos de comandos que puedes usar:

  • "Lista todos mis repositorios"
  • "Crea un issue titulado 'Bug en la página de inicio de sesión'"
  • "Muéstrame los pull requests abiertos en my-org/my-repo"
  • "Obtén el contenido de README.md de la rama main"
  • "Muéstrame las últimas ejecuciones de workflows de Actions en goern/forgejo-mcp"

Inicio Rápido

1. Instalación

Opción A: Usando Go (Recomendado)

git clone https://codeberg.org/goern/forgejo-mcp.git
cd forgejo-mcp
go install .

Asegúrate de que $GOPATH/bin (normalmente ~/go/bin) esté en tu PATH.

Nota: go install codeberg.org/goern/forgejo-mcp/v2@latest no funciona actualmente. Consulta Problemas conocidos.

Opción B: Descargar el binario

Descarga la última versión desde la página de releases.

Para Arch Linux, usa tu helper de AUR favorito:

yay -S forgejo-mcp      # builds from source
yay -S forgejo-mcp-bin  # uses pre-built binary

Opción C: Nix / NixOS

Puedes ejecutar el servidor directamente usando el gestor de paquetes Nix:

nix-shell -p forgejo-mcp

O usando Flakes:

nix run nixpkgs#forgejo-mcp

Nota: forgejo-mcp actualmente solo está disponible en el canal unstable y aún no forma parte de la versión estable 25.11.

Opción D: Imagen de contenedor

Se publica una imagen OCI multi-etapa firmada en cada release en codeberg.org/goern/forgejo-mcp. Ejecuta el servidor sin compilar desde el código fuente:

# Latest release
podman run --rm -i \
  -e FORGEJO_ACCESS_TOKEN="<your personal access token>" \
  codeberg.org/goern/forgejo-mcp:latest \
  --transport stdio --url https://your-forgejo-instance.org

# Or pin a specific version
podman run --rm -i codeberg.org/goern/forgejo-mcp:v2.24.0 --help
TagSignificado
vMAJOR.MINOR.PATCHInmutable — la versión exacta (p. ej. v2.24.0). Úsala en producción.
latestMóvil — sigue la versión más reciente. Solo por conveniencia.

La imagen es de una sola arquitectura (linux/amd64), está firmada con cosign e incluye un SBOM CycloneDX adjunto. Consulta Verificar la imagen de contenedor para comprobar la firma y la procedencia antes de ejecutarla.

2. Obtén tu token de acceso

  1. Inicia sesión en tu instancia de Forgejo
  2. Ve a SettingsApplicationsAccess Tokens
  3. Crea un nuevo token con los permisos que necesites (repo, issue, etc.)

3. Configura tu asistente de IA

Añade esto a tu archivo de configuración de MCP:

Para modo stdio (el más común):

{
  "mcpServers": {
    "forgejo": {
      "command": "forgejo-mcp",
      "args": [
        "--transport", "stdio",
        "--url", "https://your-forgejo-instance.org"
      ],
      "env": {
        "FORGEJO_ACCESS_TOKEN": "<your personal access token>",
        "FORGEJO_USER_AGENT": "forgejo-mcp/1.0.0"
      }
    }
  }
}

Para modo HTTP streamable (recomendado para remoto/Claude.ai):

{
  "mcpServers": {
    "forgejo": {
      "url": "http://localhost:8080/mcp"
    }
  }
}

Cuando uses el modo HTTP streamable, inicia el servidor primero:

forgejo-mcp --transport http --url https://your-forgejo-instance.org --token <your-token>

Modo HTTP multi-tenant (opcional):

Puedes ejecutar una única instancia centralizada de forgejo-mcp y permitir que cada cliente proporcione su propio token mediante la cabecera HTTP estándar Authorization. Esto permite atender a múltiples usuarios o agentes desde un solo servidor.

  1. Inicia el servidor (opcionalmente sin ningún token global):
    forgejo-mcp --transport http --url https://your-forgejo-instance.org
    
  2. Los clientes incluyen su token específico en cada solicitud:
    • Authorization: token <token> (estilo Forgejo)
    • Authorization: Bearer <token> (estilo OAuth2/MCP)
    • Nota: El esquema (token o Bearer) no distingue entre mayúsculas y minúsculas.

Consulta demos/multi-tenant-http.md para ver un tutorial listo para copiar y pegar.

Justificación del diseño, reglas de resolución de tokens y garantías de aislamiento de solicitudes: consulta el cambio OpenSpec stateless-http-auth (openspec/changes/archive/).

Para modo SSE (basado en HTTP heredado):

{
  "mcpServers": {
    "forgejo": {
      "url": "http://localhost:8080/sse"
    }
  }
}

Cuando uses el modo SSE, inicia el servidor primero:

forgejo-mcp --transport sse --url https://your-forgejo-instance.org --token <your-token>

4. Empieza a usarlo

Abre tu asistente de IA compatible con MCP y prueba:

List all my repositories

Herramientas disponibles

HerramientaDescripción
Usuario
get_my_user_infoObtener información sobre el usuario autenticado
check_notificationsComprobar y listar notificaciones del usuario
get_notification_threadObtener información detallada de un hilo de notificación
mark_notification_readMarcar un hilo de notificación como leído
mark_all_notifications_readConfirmar todas las notificaciones
list_repo_notificationsFiltrar notificaciones limitadas a un único repositorio
mark_repo_notifications_readMarcar como leídas todas las notificaciones de un repositorio específico
search_usersBuscar usuarios
Repositorios
list_my_reposListar todos los repositorios que posees
create_repoCrear un nuevo repositorio
fork_repoHacer un fork de un repositorio
search_reposBuscar repositorios
Ramas
list_branchesListar todas las ramas de un repositorio
create_branchCrear una nueva rama
delete_branchEliminar una rama
Protección de ramas
list_branch_protectionsListar las reglas de protección de ramas de un repositorio. Limitado por page (basado en 1) + limit (tamaño de página); la respuesta repite page/limit para que los llamadores puedan obtener la siguiente página.
get_branch_protectionObtener una única regla por nombre de rule
create_branch_protectionCrear una regla. Requiere branch_name; status_check_contexts es una lista separada por comas de comprobaciones requeridas (p. ej. "ci/build,ci/test").
edit_branch_protectionEditar una regla por nombre de rule. Solo cambian los campos que se pasan; los campos omitidos permanecen sin cambios.
delete_branch_protectionEliminar una regla por nombre de rule
Archivos
get_file_contentObtener el contenido de un archivo. Los opcionales start_line/end_line solicitan un rango de líneas inclusivo basado en 1 (se limita a la extensión del archivo; se ignora cuando with_metadata=true).
create_fileCrear un nuevo archivo
update_fileActualizar un archivo existente
delete_fileEliminar un archivo
Commits
list_repo_commitsListar commits en un repositorio
Incidencias
list_repo_issuesListar incidencias en un repositorio (página/límite)
get_issue_by_indexObtener una incidencia específica
create_issueCrear una nueva incidencia
add_issue_labelsAñadir etiquetas a una incidencia (requiere IDs numéricos de etiqueta)
remove_issue_labelsEliminar etiquetas de una incidencia (requiere IDs numéricos de etiqueta)
update_issueActualizar una incidencia existente (requiere ID numérico de hito)
issue_state_changeAbrir o cerrar una incidencia
list_issue_dependenciesListar las incidencias de las que depende la incidencia dada. Limitado por page (basado en 1) + limit (tamaño de página); la respuesta repite page/limit para que los llamadores puedan obtener la siguiente página.
list_issue_dependentsListar las incidencias que dependen de la incidencia dada. Limitado por page (basado en 1) + limit (tamaño de página); la respuesta repite page/limit para que los llamadores puedan obtener la siguiente página.
add_issue_dependencyHacer que una incidencia dependa de otra
remove_issue_dependencyEliminar una dependencia de una incidencia
list_repo_milestonesListar hitos con sus IDs (usar con update_issue)
list_repo_labelsListar etiquetas con sus IDs. Combina etiquetas de nivel de organización para repositorios propiedad de una organización (establecer include_org_labels=false para excluirse). Cada entrada incluye un campo scope ("repo" o "org").
list_org_labelsListar etiquetas de nivel de organización con sus IDs (usar con add_issue_labels, remove_issue_labels).
create_repo_labelCrear una etiqueta de repositorio (name, color como hex de 6 dígitos, description opcional). Devuelve el id numérico para uso inmediato en add_issue_labels.
edit_repo_labelEditar una etiqueta de repositorio (PATCH: solo cambian los campos proporcionados: name, color, description).
delete_repo_labelEliminar una etiqueta de repositorio. Por defecto se rechaza cuando la etiqueta está en uso (informa del recuento); establecer delete_mode=force para anular.
get_repo_labelObtener una única etiqueta de repositorio por id numérico.
create_org_labelCrear una etiqueta de nivel de organización. Mismos campos que create_repo_label.
edit_org_labelEditar una etiqueta de nivel de organización (semántica PATCH).
delete_org_labelEliminar una etiqueta de nivel de organización. La protección de uso cuenta en los repositorios de la organización visibles (mejor esfuerzo); delete_mode=force anula.
get_org_labelObtener una única etiqueta de nivel de organización por id numérico.
Comentarios
list_issue_commentsListar comentarios en una incidencia o PR
get_issue_commentObtener un comentario específico
create_issue_commentAñadir un comentario a una incidencia o PR
edit_issue_commentEditar un comentario
delete_issue_commentEliminar un comentario
Solicitudes de extracción
list_repo_pull_requestsListar solicitudes de extracción en un repositorio
get_pull_request_by_indexObtener una solicitud de extracción específica
create_pull_requestCrear una nueva solicitud de extracción
update_pull_requestActualizar una solicitud de extracción existente
list_pull_reviewsListar revisiones de una solicitud de extracción
get_pull_reviewObtener una revisión específica de una solicitud de extracción
list_pull_review_commentsListar comentarios en una revisión de solicitud de extracción
list_pull_request_filesListar archivos modificados en una solicitud de extracción (paginado). Usar los nombres de archivo devueltos como argumento file_path para get_pull_request_diff.
get_pull_request_diffObtener el diff unificado de una solicitud de extracción. El file_path opcional devuelve solo los hunks de ese archivo (coincide con la ruta anterior o posterior al cambio de nombre).
merge_pull_requestFusionar una solicitud de extracción (estilo: merge/rebase/rebase-merge/squash; título/mensaje/eliminar-rama/fusión-forzada/esperar-comprobaciones opcionales).
create_pull_reviewCrear una revisión en una solicitud de extracción (estado: APPROVED/REQUEST_CHANGES/COMMENT) con comentarios en línea opcionales.
Acciones
dispatch_workflowActivar una ejecución de flujo de trabajo mediante el evento workflow_dispatch
list_workflow_runsListar ejecuciones de flujo de trabajo con filtrado opcional por estado, evento o SHA
get_workflow_runObtener detalles de una ejecución de flujo de trabajo específica por ID
list_action_run_jobsListar trabajos de una ejecución de flujo de trabajo de Forgejo v16+ con límites de page y limit en el cliente
get_action_job_logsLeer un registro de trabajo de Forgejo v16+ con límites reanudables de offset y max_bytes; por defecto, la parte final
Organizaciones
search_org_teamsBuscar equipos en una organización
Seguimiento de tiempo
list_issue_tracked_timesListar entradas de tiempo registradas en una incidencia o PR
list_repo_tracked_timesListar entradas de tiempo registradas en un repositorio
list_my_tracked_timesListar tus propias entradas de tiempo registradas
add_issue_timeRegistrar tiempo en una incidencia o PR (acepta segundos o duraciones como 15m)
reset_issue_timeEliminar TODAS las entradas de tiempo registradas en una incidencia o PR (destructivo)
delete_issue_time_entryEliminar una única entrada de tiempo registrada por ID
start_issue_stopwatchIniciar un cronómetro en una incidencia o PR
stop_issue_stopwatchDetener un cronómetro en marcha y registrar el tiempo transcurrido
cancel_issue_stopwatchCancelar un cronómetro en marcha sin registrar
list_my_stopwatchesListar cronómetros actualmente en marcha
Adjuntos
list_issue_attachmentsListar adjuntos en una incidencia o PR
get_issue_attachmentObtener metadatos de un único adjunto de incidencia/PR
download_issue_attachmentDescargar un adjunto de incidencia/PR (en línea si es < 1 MiB; metadatos + URL en caso contrario)
create_issue_attachmentSubir un nuevo adjunto a una incidencia o PR (contenido base64)
edit_issue_attachmentRenombrar un adjunto de incidencia/PR
delete_issue_attachmentEliminar un adjunto de incidencia/PR
list_comment_attachmentsListar adjuntos en un comentario de incidencia/PR
get_comment_attachmentObtener metadatos de un único adjunto de comentario
download_comment_attachmentDescargar un adjunto de comentario (en línea si es < 1 MiB; metadatos + URL en caso contrario)
create_comment_attachmentSubir un nuevo adjunto a un comentario de incidencia/PR (contenido base64)
edit_comment_attachmentRenombrar un adjunto de comentario
delete_comment_attachmentEliminar un adjunto de comentario
Lanzamientos
list_releasesListar lanzamientos de un repositorio (página/límite + filtro state en el cliente: all/draft/prerelease/published)
get_release_by_idObtener un lanzamiento por ID numérico
get_release_by_tagObtener un lanzamiento por nombre de etiqueta
get_latest_releaseObtener el último lanzamiento que no sea borrador ni prelanzamiento
create_releaseCrear un nuevo lanzamiento (pasar target_commitish para crear también la etiqueta)
edit_releaseActualizar campos de un lanzamiento existente (solo se envían los campos proporcionados)
delete_releaseEliminar un lanzamiento por ID numérico: destructivo
delete_release_by_tagEliminar un lanzamiento por nombre de etiqueta: destructivo, verificar la etiqueta
list_release_attachmentsListar adjuntos en un lanzamiento (respuesta obtenida completa, dividida en el cliente)
get_release_attachmentObtener metadatos de un único adjunto de lanzamiento
download_release_attachmentDescargar un adjunto de lanzamiento (en línea si es < 1 MiB; metadatos + URL en caso contrario)
create_release_attachmentSubir un nuevo adjunto a un lanzamiento (contenido base64)
edit_release_attachmentRenombrar un adjunto de lanzamiento
delete_release_attachmentEliminar un adjunto de lanzamiento: destructivo
Wiki
list_wiki_pagesListar páginas usando page/limit; devuelve has_next.
get_wiki_pageLeer Markdown decodificado; start_line/end_line opcionales, siempre devuelve total_lines.
get_wiki_revisionsListar historial de revisiones usando page/limit; devuelve has_next.
create_wiki_pageCrear una página y devolver su page_name normalizado por el servidor; los títulos separados por barras son una convención plana de nombres de subpáginas (sin jerarquía ni página principal automática), y un título existente se sobrescribe.
update_wiki_pageActualizar contenido/título por page_name normalizado; el último escritor gana.
delete_wiki_pageEliminar una página por page_name normalizado.
Servidor
get_forgejo_mcp_server_versionObtener la versión del servidor MCP

Recursos

Las plantillas de recursos MCP exponen entidades de Forgejo como recursos direccionables por URI mediante el esquema forgejo://. El esquema de URI es portable entre instancias: la misma forma de URI funciona con cualquier instancia de Forgejo, y no entra en conflicto con los enlaces web de Forgejo. Los clientes que admiten resources/templates/list y resources/read (Claude Code, Claude Desktop, Codex, Cursor) pueden resolver estos URI directamente. Los clientes sin soporte de plantillas de recursos siguen usando las herramientas anteriores: no se elimina ninguna funcionalidad.

Los recursos NO reemplazan ninguna herramienta MCP: todas las herramientas existentes de listado/obtención siguen disponibles; los recursos son una superficie de lectura aditiva y direccionable por URI, pensada para la resolución automática desde el contexto del LLM y para el almacenamiento en caché direccionable por contenido de entidades inmutables como los commits.

Los recursos que incorporan una lista (issue, pr) limitan la matriz incorporada a 30 elementos. Cuando se trunca, la carga útil JSON incluye un centinela que nombra la herramienta list_* correspondiente que el llamador debe invocar para obtener la lista completa.

Cuándo usar recursos frente a herramientas: prefiere un recurso cuando tengas un sha o índice específico; prefiere una herramienta al listar o buscar.

Plantilla de URIEntidadNotas
forgejo://owner/{owner}application/jsonPerfil de usuario u organización identificado por login; resuelve primero el usuario y, si no, la organización.
forgejo://repo/{owner}/{repo}application/jsonResumen del repositorio: identidad + recuentos, sin listas incrustadas.
forgejo://repo/{owner}/{repo}/commit/{sha}Metadatos de commitInmutable por sha. Devuelve JSON + sidecar de markdown. sha debe tener 40 caracteres hexadecimales.
forgejo://repo/{owner}/{repo}/commit/{sha}/statusapplication/jsonEstado de CI combinado para un sha: estado agregado + estados por contexto limitados (máx. 30, nombres centinela de la herramienta de listado get_commit_statuses).
forgejo://repo/{owner}/{repo}/issue/{index}application/json (+ text/markdown sidecar)Metadatos de issue + cuerpo renderizado + comentarios recientes limitados (máx. 30, nombres centinela list_issue_comments).
forgejo://repo/{owner}/{repo}/{kind}/{index}/comment/{id}application/json (+ text/markdown sidecar)Comentario único por id; tipo ∈ {issue, pr}.
forgejo://repo/{owner}/{repo}/pr/{index}application/json (+ text/markdown sidecar)Metadatos de PR, refs head/base, capacidad de fusión, comentarios recientes limitados (máx. 30, centinela list_issue_comments) y revisiones (máx. 30, centinela list_pull_reviews).
forgejo://repo/{owner}/{repo}/label/{id}application/jsonEtiqueta única de repositorio por id numérico.
forgejo://repo/{owner}/{repo}/labels{?page,limit}application/jsonLista limitada de etiquetas de repositorio (máx. 30, nombres centinela list_repo_labels).
forgejo://org/{org}/labels{?page,limit}application/jsonLista limitada de etiquetas a nivel de organización (máx. 30, nombres centinela list_org_labels).
forgejo://repo/{owner}/{repo}/wiki/{pageName}application/json (+ text/markdown sidecar)Página wiki con revisiones limitadas y Markdown limitado a 1 MiB. Usa el page_name normalizado devuelto; codifica un / literal como %2F y los espacios como %20 en la URI (no doble-codifiques un nombre ya normalizado).

Los títulos separados por barras, como Guides/Setup, son útiles como convención de nombres para subpáginas, pero Forgejo almacena las páginas en una lista plana: no crea Guides automáticamente ni registra una relación padre-hijo. Crea el padre por separado cuando los lectores lo necesiten, y siempre dirige las llamadas posteriores con el page_name normalizado devuelto por create o list. El comportamiento REST de wiki documentado aquí fue probado en vivo contra Forgejo 15.0.4+gitea-1.22.0; la demo completa de MCP se reprodujo con éxito contra 16.0.0+gitea-1.22.0. Este es el rango probado, no una garantía para cada implementación intermedia o con proxy diferente.

Compatibilidad de clientes

Clienteresources/templates/listresources/read
Claude Codecompatiblecompatible
Claude Desktopcompatiblecompatible
Codexcompatiblecompatible
Cursor (actual)compatiblecompatible
Clientes antiguos / mínimossolo herramientassolo herramientas

Demostraciones

Recorridos completos, copiables y pegables, de las herramientas anteriores — agrupados por tema (etiquetas, adjuntos, seguimiento de tiempo, notificaciones, organizaciones, revisión de código con E/S limitada, transporte) — viven en demos/. Cada demo combina invocaciones reales de ./forgejo-mcp --cli con la salida que produjeron contra codeberg.org.

Modo CLI

Puedes invocar cualquier herramienta directamente desde la línea de comandos sin ejecutar un servidor MCP. Esto es útil para scripts de shell, pipelines de CI/CD y habilidades de Claude Code.

# List all available tools (grouped by domain)
forgejo-mcp --cli list

# Invoke a tool with JSON arguments
forgejo-mcp --cli get_issue_by_index --args '{"owner":"goern","repo":"forgejo-mcp","index":1}'

# Pipe JSON arguments via stdin
echo '{"owner":"goern","repo":"forgejo-mcp"}' | forgejo-mcp --cli list_repo_issues

# List recent workflow runs (text output)
forgejo-mcp --cli list_workflow_runs \
  --args '{"owner":"goern","repo":"forgejo-mcp"}' \
  --output=text

# List only failed runs
forgejo-mcp --cli list_workflow_runs \
  --args '{"owner":"goern","repo":"forgejo-mcp","status":"failure"}' \
  --output=text

# List jobs and inspect the tail of a failed job (Forgejo v16+)
forgejo-mcp --cli list_action_run_jobs \
  --args '{"owner":"goern","repo":"forgejo-mcp","run_id":123}' \
  --output=text
forgejo-mcp --cli get_action_job_logs \
  --args '{"owner":"goern","repo":"forgejo-mcp","job_id":456,"max_bytes":32768}' \
  --output=text

# Forgejo's run-wide ZIP log endpoint has no Range support. Enumerate jobs and
# fetch their bounded plaintext logs instead.

# Show a tool's parameters
forgejo-mcp --cli create_issue --help

# Control output format (json or text)
forgejo-mcp --cli list --output=json
forgejo-mcp --cli get_my_user_info --args '{}' --output=text

El modo CLI requiere la misma configuración de FORGEJO_URL y FORGEJO_ACCESS_TOKEN que el modo servidor MCP. Los resultados de las herramientas se escriben como JSON en stdout por defecto; los errores van a stderr con un código de salida distinto de cero.

Opciones de configuración

Puedes configurar el servidor usando argumentos de línea de comandos o variables de entorno:

Argumento CLIVariable de entornoDescripción
--urlFORGEJO_URLLa URL de tu instancia de Forgejo
--tokenFORGEJO_ACCESS_TOKENTu token de acceso personal
--debugFORGEJO_DEBUGHabilitar modo de depuración
--transport-Modo de transporte: stdio, sse o http
--sse-port-Puerto para modo SSE (por defecto: 8080)
--http-port-Puerto para modo HTTP transmisible (por defecto: 8080)
--cli-Entrar en modo CLI para invocación directa de herramientas
--user-agentFORGEJO_USER_AGENTCabecera HTTP User-Agent (por defecto: forgejo-mcp/<version>)

Los argumentos de línea de comandos tienen prioridad sobre las variables de entorno.

Verificación de lanzamientos

Los archivos de lanzamiento van acompañados de un archivo checksums.txt y un checksums.txt.sig opcional producido por cosign con el par de claves de lanzamiento del proyecto. Verificar ambos archivos te permite confirmar que el binario que descargaste fue construido por el pipeline de lanzamiento del proyecto y no ha sido manipulado en tránsito.

Aviso: la firma con cosign se introdujo a mediados de 2026. Las etiquetas lanzadas antes de que se activara la firma se distribuyen sin un archivo .sig — la verificación aplica solo desde v2.23.x en adelante, y solo cuando el secreto COSIGN_PRIVATE_KEY estaba configurado en el momento del lanzamiento.

1. Instalar cosign

Sigue la guía de instalación de cosign de upstream para tu plataforma. Rutas rápidas:

# Linux/macOS — pinned binary
COSIGN_VERSION=v2.4.1
curl -sSfL -o /usr/local/bin/cosign \
  "https://github.com/sigstore/cosign/releases/download/${COSIGN_VERSION}/cosign-linux-amd64"
chmod +x /usr/local/bin/cosign

# macOS via Homebrew
brew install cosign

# Arch Linux
sudo pacman -S cosign

Confirma:

cosign version

2. Obtener la clave pública

La fuente normativa de la clave pública de cosign es el repositorio GitOps op1st-emea-b4mad — la misma fuente de verdad que aprovisiona el Secreto cosign-signing-key-artifacts en el namespace op1st-pipelines donde se ejecuta el pipeline de lanzamiento. Esta es la clave de firma de artefactos que firma los blobs de lanzamiento (checksums.txt.sig); es distinta de la clave de firma de imágenes cosign-signing-key-images.pub utilizada en §5–§6 a continuación. Dos formas de obtenerla:

Punta de rama (en vivo, sigue rotaciones futuras de claves):

curl -sSfL -o cosign.pub \
  https://codeberg.org/operate-first/op1st-emea-b4mad/raw/branch/main/manifests/applications/op1st-pipelines-tokens/cosign-signing-key-artifacts.pub

Fijada a commit (a prueba de manipulación, recomendada para CI/scripts):

curl -sSfL -o cosign.pub \
  https://codeberg.org/operate-first/op1st-emea-b4mad/raw/commit/cd3715fa8283a2069a2e3e299744a7b55b1b0260/manifests/applications/op1st-pipelines-tokens/cosign-signing-key-artifacts.pub

El enlace permanente fijado a commit incluye el hash de su contenido en la URL — si alguien reescribe el archivo en ese commit, tu descarga falla o no coincide. Fija el commit más reciente que confíes antes de adoptar la clave en automatización.

3. Descargar los artefactos de lanzamiento

Elige la etiqueta que instalaste (p. ej. v2.23.1) y descarga el archivo de suma de verificación, su firma y el archivo binario:

TAG=v2.23.1
VERSION="${TAG#v}"
BASE="https://codeberg.org/goern/forgejo-mcp/releases/download/${TAG}"

curl -sSfLO "${BASE}/forgejo-mcp_${VERSION}_checksums.txt"
curl -sSfLO "${BASE}/forgejo-mcp_${VERSION}_checksums.txt.sig"
curl -sSfLO "${BASE}/forgejo-mcp_${VERSION}_linux_amd64.tar.gz"   # adjust os/arch

4. Verificar la firma, luego la suma de verificación

Cosign verifica que checksums.txt fue firmado por el titular de la clave privada que coincide con cosign.pub. Una vez que el archivo de suma de verificación es confiable, una comprobación simple de sha256sum -c confirma la integridad del archivo.

# Verify checksums.txt against the signature.
cosign verify-blob \
  --key cosign.pub \
  --signature "forgejo-mcp_${VERSION}_checksums.txt.sig" \
  "forgejo-mcp_${VERSION}_checksums.txt"
# Expected: "Verified OK"

# Verify the downloaded archive against the (now-trusted) checksums.
sha256sum --ignore-missing -c "forgejo-mcp_${VERSION}_checksums.txt"
# Expected: "<archive>: OK"

La cadena de sumas de verificación cubre transitivamente los SBOM y otros activos por archivo — verificar checksums.txt una vez es suficiente para todo lo listado dentro.

5. Verificar la procedencia SLSA para la imagen de release-tools

La imagen de contenedor de release-tools (usada internamente por el pipeline de lanzamiento de Tekton) lleva procedencia SLSA v1.0 generada por https://tekton.dev/docs/chains/. Esta atestación vincula el digest de la imagen con el PipelineRun exacto, el commit de git y la identidad del constructor que la produjo — proporcionando procedencia de cadena de suministro más allá de lo que la firma de cosign sola puede atestar.

Obtén la clave pública cosign-signing-key-images (una clave separada de la clave de firma de artefactos anterior):

curl -sSfL -o cosign-images.pub \
  https://codeberg.org/operate-first/op1st-emea-b4mad/raw/branch/main/manifests/applications/op1st-pipelines-tokens/cosign-signing-key-images.pub

Verifica la atestación contra una etiqueta de imagen específica:

IMAGE_TAG=v1.0.0   # substitute the release-tools tag you want to verify
cosign verify-attestation \
  --type slsaprovenance \
  --key cosign-images.pub \
  "codeberg.org/operate-first/release-tools:${IMAGE_TAG}" \
  | jq .

Una ejecución exitosa imprime la declaración in-toto decodificada (JSON). Comprueba que predicate.buildDefinition.externalParameters.runSpec.params referencia la revisión de git esperada, y que predicate.runDetails.builder.id muestra el constructor de Tekton Chains.

Nota: Las atestaciones de procedencia SLSA están disponibles desde los lanzamientos construidos después de que llegara forgejo-mcp-46j (soporte de Tekton Chains). Las etiquetas de imagen anteriores solo llevan la firma de cosign; no tienen payload verify-attestation.

6. Verificar la imagen de contenedor

La imagen de aplicación codeberg.org/goern/forgejo-mcp (Opción D) está firmada con la misma clave cosign-signing-key-images que la imagen de release-tools, lleva un SBOM CycloneDX adjunto y obtiene procedencia SLSA v1.0 de Tekton Chains. Reutiliza la clave cosign-images.pub obtenida anteriormente.

Verifica la firma:

IMAGE_TAG=v2.24.0   # substitute the release you are pulling
cosign verify \
  --key cosign-images.pub \
  "codeberg.org/goern/forgejo-mcp:${IMAGE_TAG}" \
  | jq .

Verifica la atestación de procedencia SLSA:

cosign verify-attestation \
  --type slsaprovenance \
  --key cosign-images.pub \
  "codeberg.org/goern/forgejo-mcp:${IMAGE_TAG}" \
  | jq .

Verifica y descarga la atestación SBOM CycloneDX firmada:

cosign verify-attestation \
  --type cyclonedx \
  --key cosign-images.pub \
  "codeberg.org/goern/forgejo-mcp:${IMAGE_TAG}" \
  | jq -r '.payload | @base64d | fromjson | .predicate' > forgejo-mcp.cdx.json

El SBOM ahora es una atestación in-toto firmada (cosign attest), no un artefacto attach sbom sin firmar. cosign download sbom ya no aplica.

Debido a que el pipeline de publicación empuja por digest y solo promueve las etiquetas vX.Y.Z / latest después de que la firma y el adjunto del SBOM tengan éxito, cualquier etiqueta que puedas extraer está garantizada como firmada.

Solución de problemas de verificación

  • Error: no matching signatures — el archivo .sig es de un lanzamiento diferente, o cosign.pub es la clave incorrecta. Vuelve a descargar ambos desde la misma etiqueta.
  • Error: cannot read file: checksums.txt.sig — el lanzamiento es anterior a la firma con cosign, o la firma se omitió en esa ejecución porque el secreto no estaba configurado. Recurre a la comprobación solo de suma de verificación (sha256sum -c), que aún detecta corrupción en tránsito pero no manipulación.
  • Desajuste entre cosign.pub y la firma — confirma que obtuviste la clave pública de un commit que incluye la clave en uso en el momento del lanzamiento. Si tienes dudas, obténla de branch/main.

Solución de problemas

Habilita el modo de depuración para ver registros detallados:

forgejo-mcp --transport sse --url <url> --token <token> --debug

O establece la variable de entorno:

export FORGEJO_DEBUG=true

User-Agent personalizado: Si tu instancia de Forgejo o proxy bloquea el user agent predeterminado go-http-client, establece uno personalizado:

# Via environment variable
export FORGEJO_USER_AGENT="forgejo-mcp/1.0.0"

# Or via CLI flag
forgejo-mcp --user-agent "forgejo-mcp/1.0.0" --transport sse --url <url> --token <token>

Obtener ayuda

Este repositorio también está duplicado en Radicle — una red de colaboración de código peer-to-peer. Clona mediante:

rad clone rad:z4PdPpsH9iJQcWfqTbxpFcWaZ9zPL

Para desarrolladores

Consulta DEVELOPER.md para instrucciones de compilación, descripción general de la arquitectura y pautas de contribución.

Problemas conocidos

  • go install ...@latest falla — El go.mod contiene una directiva replace (para un SDK de Forgejo bifurcado), que impide el go install remoto. Usa el flujo de trabajo de clonar y compilar mostrado en Inicio rápido en su lugar. Rastreado en #67.

Contribuidores

forgejo-mcp está moldeado por todos los que reportan problemas, escriben código, revisan PRs y empujan el proyecto hacia adelante. Gracias a todos. 🙏

Contribuidores de código

ColaboradorDestacados
goern (Christoph Görn)Creador y mantenedor del proyecto
Ronmi RenCo-creador; transporte SSE/HTTP, bloqueo de issues, mejoras de CI/CD, logotipo, especificación Glama
twstagg (Tristin Stagg)Soporte de configuración de agente de usuario (PR #89)
mattdm (Matthew Miller)Mejoras de registro, migración FORGEJO_*, README, refactorización de URL
byteflavourcheck_notifications + API completa de gestión de notificaciones (PR #84, #86); autenticación sin estado por solicitud para transportes HTTP/SSE (PR #138); documentación de instalación de NixOS (PR #146); solicitudes de funciones #80, #85
jesterretSoporte de revisiones y comentarios de pull requests (PR #51)
appleboySoporte de puerto SSE personalizado, correcciones de errores
ignasgilHerramienta remove_issue_labels (PR #96)
dmikushin (Dmitry Mikushin)Corrección del análisis de parámetros numéricos codificados como cadenas desde clientes MCP (PR #93)
jiriks74Actualización de dependencia mcp-go v0.44.0 (PR #90)
th (Tomi Haapaniemi)Herramienta update_pull_request
hiifongCorrecciones y actualizaciones tempranas
Lunny XiaoContribuciones tempranas
techknowlogickContribuciones tempranas
yp05327Contribuciones tempranas
mw75Soporte de propietario/org para creación de repos (PR #18)
Dax KelsonGestión de comentarios de issues (PR #34)
Guruprasad KulkarniDocumentación de instalación de Arch Linux AUR (PR #69)
Mario WolffContribuciones
Massimo FraschettiContribuciones
synath (David Paul Turley)Soporte de token con alcance de repositorio mediante sonda ServerVersion (PR #112); verificación de código de estado de fusión (PR #113); empaquetado de extensión de Claude Desktop (.mcpb) (PR #118)
BrilliantKahnget_file_content predeterminado de texto plano (PR #116); herramientas list_repo_contents y get_repo_tree (PR #117). Primera contribución de código abierto — ¡bienvenido a bordo! 🎉

Contribuyentes de la comunidad

Reportadores de issues y participantes en discusiones que dieron forma a la dirección del proyecto:

ColaboradorContribuciones
byteflavourReportó #80 (descubrimiento de hitos/etiquetas), #85 (propuesta de API de notificaciones); revisor activo en discusiones
choucavalierReportó #82 (habilidad de corrección), #70 (lanzamientos macOS arm64), #62 (lanzamientos binarios y soporte de mise)
MalcolmMielleReportó #59 (herramientas de revisión de PR — desde entonces implementado)
redbeardReportó #60 (soporte de Actions — desde entonces implementado)
c6sepl6pReportó #72 (codificación base64), #54 (fusionar pull request — desde entonces implementado)
malikReportó #73 (bandera de versión), #47 (corrección de compilación Nix)
a2800276Reportó #74 (compatibilidad con OpenAI)
simenandreReportó #49 (soporte de go install)
BasdPReportó #42 (soporte de Projects)
BoBeR182Reportó #32 (soporte de wiki)
ignasgilReportó #95 (solicitud de función remove_issue_labels)
VokuarReportó #99 (soporte de transporte HTTP transmisible)
janbaerReportó #98 (responder a comentario de revisión)
fraschm98Reportes tempranos de issues
heathen711Reportó #106 (adjuntos de issues/comentarios — desde entonces implementado); dio forma al diseño de límite en línea de 1 MiB + browser_download_url de respaldo

Contribuyentes ciborg

Este proyecto también recibió contribuciones de agentes de codificación de IA — enviadas como PRs regulares, revisadas por humanos:

AgenteRolContribuciones
brenner-axiom (b4-dev, B4arena)Agente de desarrollo de IAHerramientas de gestión de organizaciones (PR #94); demos showboat (PR #97); herramientas list_repo_milestones, list_repo_labels (PR #83); corrección de condición de carrera (PR #78); documentación de contribuyentes (PR #87, #88); reportó #76; revisiones de código
opencodeAgente de desarrollo de IASoporte de revisiones y comentarios de pull requests (PR #51)
claude-codeAgente de desarrollo de IAPredeterminado de texto plano get_file_content y herramientas list_repo_contents/get_repo_tree, en conjunto con BrilliantKahn (PR #116, #117)
b4mad-release-botAutomatización de lanzamientosRegistro de cambios automatizado y etiquetado de lanzamientos
el bot #B4mad RenovateActualizaciones de dependenciasActualizaciones automáticas de dependencias

¿Quieres contribuir? Abre un issue o pull request: todos son bienvenidos.

Licencia

Este proyecto es de código abierto. Consulta el repositorio para obtener detalles de la licencia.