Forgejo MCP Server
Gestiona repositorios de Forgejo y ejecuta comandos a través de una interfaz de chat compatible con MCP.
Documentación
Servidor MCP de Forgejo
📦 Este proyecto se ha movido. El desarrollo, los problemas, los lanzamientos y las imágenes de contenedor ahora viven en https://git.b4mad.industries/agentic-forges/forgejo-mcp. El repositorio de Codeberg en
codeberg.org/goern/forgejo-mcppermanece solo como un espejo de solo lectura, y su registro de contenedores ya no publica imágenes — extrae degit.b4mad.industries/agentic-forges/forgejo-mcpen su lugar. Los números de problemas se conservan en el traslado. Las contribuciones de humanos y agentes de IA son bienvenidas en la nueva ubicación.git clone https://git.b4mad.industries/agentic-forges/forgejo-mcp.gitSi tienes un remoto o un marcador apuntando a
forgejo.b4mad.net, ese es el mismo forge bajo su nombre anterior — renombrado el 2026-07-29, no movido de nuevo. El nombre antiguo aún resuelve y sirve en el puerto 2222 con la misma clave de host, por lo que los clones existentes siguen funcionando; reconfigúralos cuando quieras:git remote set-url origin \ ssh://git@git.b4mad.industries:2222/agentic-forges/forgejo-mcp.git ssh-keyscan -p 2222 git.b4mad.industries >> ~/.ssh/known_hosts
Conecta tu asistente de IA a los repositorios de Forgejo. Gestiona problemas, solicitudes de extracción, archivos y más mediante lenguaje natural.
Qué Hace
Forgejo MCP Server es un plugin de integración que conecta Forgejo con sistemas 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 problema titulado 'Error en la página de inicio de sesión'"
- "Muéstrame las solicitudes de extracción abiertas en mi-org/mi-repo"
- "Obtén el contenido de README.md de la rama principal"
- "Muéstrame las últimas ejecuciones de flujos de trabajo de Actions en agentic-forges/forgejo-mcp"
Inicio Rápido
1. Instalación
Opción A: Usando Go (Recomendado)
git clone https://git.b4mad.industries/agentic-forges/forgejo-mcp.git
cd forgejo-mcp
go install .
Asegúrate de que $GOPATH/bin (típicamente ~/go/bin) esté en tu PATH.
Nota: también puedes instalar directamente desde la ruta del módulo, sin clonar:
go install git.b4mad.industries/agentic-forges/forgejo-mcp/v3@latest
Opción B: Descargar Binario
Descarga la última versión desde la página de lanzamientos.
Para Arch Linux, usa tu ayudante 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-mcpactualmente solo está disponible en el canalunstabley aún no forma parte de la versión estable 25.11.
Opción D: Imagen de contenedor
Una imagen OCI multi-etapa firmada se publica en cada lanzamiento en
git.b4mad.industries/agentic-forges/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>" \
git.b4mad.industries/agentic-forges/forgejo-mcp:latest \
--transport stdio --url https://your-forgejo-instance.org
# Or pin a specific version
podman run --rm -i git.b4mad.industries/agentic-forges/forgejo-mcp:v3.1.0 --help
| Etiqueta | Significado |
|---|---|
vMAJOR.MINOR.PATCH | Inmutable — la versión exacta (p. ej. v3.1.0). Úsala en producción. |
latest | Móvil — sigue la versión más reciente. Solo por conveniencia. |
La imagen es de una sola arquitectura (linux/amd64), firmada con cosign, y lleva un
SBOM CycloneDX adjunto. Consulta Verificar la imagen del contenedor
para comprobar la firma y la procedencia antes de ejecutarla.
2. Obtén Tu Token de Acceso
- Inicia sesión en tu instancia de Forgejo
- Ve a Configuración → Aplicaciones → Tokens de Acceso
- 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 transmisible (recomendado para remoto/Claude.ai):
{
"mcpServers": {
"forgejo": {
"url": "http://localhost:8080/mcp"
}
}
}
Cuando uses el modo HTTP transmisible, inicia el servidor primero:
forgejo-mcp --transport http --url https://your-forgejo-instance.org --token <your-token>
Modo HTTP multiinquilino (opcional):
Puedes ejecutar una única instancia centralizada de forgejo-mcp y dejar que cada cliente proporcione su propio token mediante el encabezado HTTP estándar Authorization. Esto permite atender a múltiples usuarios o agentes desde un solo servidor.
- Inicia el servidor (opcionalmente sin ningún token global):
forgejo-mcp --transport http --url https://your-forgejo-instance.org - Los clientes incluyen su token específico en cada solicitud:
Authorization: token <token>(estilo Forgejo)Authorization: Bearer <token>(estilo OAuth2/MCP)- Nota: El esquema (
tokenoBearer) no distingue entre mayúsculas y minúsculas.
Consulta demos/multi-tenant-http.md para un recorrido copiable y pegable.
Exponer el servidor a una red
Por defecto, los transportes sse y http escuchan solo en loopback, por lo que nada fuera de
esta máquina puede alcanzarlos. Esto sigue la guía del Model Context Protocol para
servidores ejecutados localmente, y es un cambio de comportamiento: las versiones anteriores escuchaban en
cada interfaz de red. El valor predeterminado, localhost, vincula ambas familias de loopback, por lo que un
cliente que resuelve localhost a 127.0.0.1 o ::1 se conecta. Si el puerto ya está
ocupado en cualquiera de las familias, el servidor se niega a iniciarse, en lugar de servir en la
otra familia mientras algunos clientes alcanzan lo que sea que tenga el puerto. Una familia que la máquina
no puede usar en absoluto — IPv6 deshabilitado, por ejemplo — se omite, y el registro de inicio lo indica.
Pasa una dirección en lugar de un nombre — --host 127.0.0.1 o --host ::1 — para vincular esa
familia sola. Úsalo cuando la otra familia no sea utilizable en esta máquina de una manera que el
servidor no pueda reconocer como "ausente", de modo que de otro modo se negaría a iniciarse.
Si ejecutas el servidor en un contenedor, o atiendes clientes remotos, ahora debes decirlo explícitamente. El valor predeterminado no aceptará conexiones desde fuera de la máquina — o, en un contenedor, desde fuera del contenedor:
- establece
--hosta una dirección que la red pueda alcanzar (0.0.0.0para todas las interfaces, que es la elección habitual dentro de un contenedor); - y establece
--allowed-hostsa los nombres de host que usan tus clientes. Esto es obligatorio, no opcional: el servidor se niega a iniciarse en una dirección alcanzable por la red sin ello, en lugar de iniciarse y rechazar cada solicitud.
Las solicitudes se rechazan con 403 Forbidden cuando su encabezado Host no es uno que hayas
declarado. Los nombres de loopback siempre se aceptan en un listener de loopback, por lo que declarar el
nombre de host de un proxy no te impide conectarte directamente desde la misma máquina.
Clientes de navegador. Una solicitud que lleva un encabezado Origin se rechaza a menos que ese
origen esté listado en --allowed-origins, que está vacío por defecto. Los orígenes se
comparan en su totalidad — esquema, host y puerto — porque el puerto de un Origin pertenece a la
página que hace la solicitud, no a este servidor. Las solicitudes sin encabezado Origin en absoluto
no se ven afectadas, que es el caso normal: un cliente MCP no es un navegador.
Autenticación en sse y http
En estos transportes, cada solicitud debe llevar su propio encabezado Authorization. Una solicitud
sin uno se rechaza con 401 Unauthorized, en lugar de servirse usando el
token configurado del propio servidor. Esto es lo que la configuración multiinquilino anterior espera
de todos modos, y es por eso que esa configuración es segura de exponer.
En stdio, el token configurado sigue sustituyendo a un encabezado ausente exactamente como
antes. Nada sobre stdio cambia.
Si ejecutas una implementación de un solo usuario sobre sse o http y quieres el comportamiento anterior,
--allow-operator-token-fallback lo restaura. Entiende lo que significa antes de usarlo:
cualquier cliente que pueda alcanzar el puerto actúa como la identidad detrás de tu token, sin
presentar una credencial. El registro de inicio lo dice, en voz alta, siempre que esté activado.
Para modo SSE (HTTP heredado basado en):
{
"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>
Operación remota como servidor de recursos OAuth
Con --auth-mode resource-server, el transporte http se convierte en un servidor de recursos OAuth 2.0
tal como lo define la especificación de autorización de MCP. Los clientes ya no
envían un token de Forgejo. Inician sesión en un proveedor OpenID Connect que elijas
y envían su token de acceso JWT. El servidor valida ese token, firma un JWT que
vive cinco minutos para el llamante, y lo presenta a Forgejo a través de una
Integración Autorizada de Forgejo 16. No se configura ningún token de forge en ningún lugar, y el
token de acceso del llamante nunca llega a Forgejo.
El modo necesita:
- Forgejo 16.0 o más reciente;
- un proveedor OpenID Connect que emita tokens de acceso JWT y pueda añadir una reclamación
por usuario (por defecto
forgejo_aud) que contenga la audiencia de la Integración Autorizada de ese usuario; - un origen HTTPS público para el servidor, porque Forgejo obtiene los documentos del emisor del servidor desde él;
- un archivo de clave de firma: EC P-256 o P-384, Ed25519, o RSA de al menos 2048 bits.
forgejo-mcp --transport http --url https://forgejo.example.org \
--host 0.0.0.0 --allowed-hosts mcp.example.org \
--auth-mode resource-server \
--authorization-server https://id.example.org \
--resource https://mcp.example.org/mcp \
--forgejo-jwt-issuer https://mcp.example.org/issuer \
--forgejo-jwt-signing-key-file /run/credentials/forgejo-mcp.service/signing-key
El modo es opcional: sin --auth-mode, todo lo anterior se comporta como antes. En
este modo, el servidor responde solo a /mcp, los metadatos del recurso protegido, y al
documento de descubrimiento y conjunto de claves bajo la ruta del emisor. Se niega a iniciarse en una
configuración que no puede servir de manera segura, y la negativa nombra la configuración a corregir.
La clave de firma actúa para cada usuario cuya integración confía en el emisor, así que protégela
como el token de forge que reemplaza.
- Guía del operador: requisitos del proveedor de identidad, orden de implementación, reglas de proxy, rotación de claves y un ejemplo trabajado de Zitadel.
- Guía del usuario: creación de la Integración
Autorizada, la regla de reclamación
subobligatoria y la configuración de un cliente MCP.
4. Empieza a Usarlo
Abre tu asistente de IA compatible con MCP y prueba:
List all my repositories
Herramientas Disponibles
| Herramienta | Descripción |
|---|---|
| Usuario | |
get_my_user_info | Obtener información sobre el usuario autenticado |
check_notifications | Comprobar y listar notificaciones del usuario |
get_notification_thread | Obtener información detallada de un hilo de notificación individual |
mark_notification_read | Marcar un hilo de notificación individual como leído |
mark_all_notifications_read | Confirmar todas las notificaciones |
list_repo_notifications | Filtrar notificaciones limitadas a un único repositorio |
mark_repo_notifications_read | Marcar todas las notificaciones de un repositorio específico como leídas |
search_users | Buscar usuarios |
| Repositorios | |
list_my_repos | Listar todos los repositorios que posees |
get_repo | Obtener un único repositorio por propietario y nombre |
create_repo | Crear un nuevo repositorio |
fork_repo | Hacer un fork de un repositorio |
edit_repo | Editar la configuración del repositorio. Solo cambian los campos que pasas; los campos omitidos se dejan sin cambios. No proporcionar ningún campo es un error. |
search_repos | Buscar repositorios |
| Temas | |
list_repo_topics | Listar los temas de un repositorio. Limitado por page (predeterminado 1) + limit (predeterminado 100); devuelve {topics, page, limit, count}. |
set_repo_topics | Reemplazar todos los temas. topics es una cadena separada por comas obligatoria; una cadena vacía los elimina. Los nombres no válidos se rechazan antes de la solicitud. |
add_repo_topic | Añadir un tema |
delete_repo_topic | Eliminar un tema |
| Ramas | |
list_branches | Listar todas las ramas de un repositorio |
create_branch | Crear una nueva rama |
delete_branch | Eliminar una rama |
| Protección de ramas | |
list_branch_protections | Listar 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_protection | Obtener una única regla por nombre de rule |
create_branch_protection | Crear una regla. Requiere branch_name; status_check_contexts es una lista separada por comas de comprobaciones obligatorias (p. ej., "ci/build,ci/test"). |
edit_branch_protection | Editar una regla por nombre de rule. Solo cambian los campos que pasas; los campos omitidos se dejan sin cambios. |
delete_branch_protection | Eliminar una regla por nombre de rule |
| Webhooks | |
list_repo_hooks | Listar webhooks del repositorio. Limitado por page (predeterminado 1) + limit (predeterminado 30, sin límite impuesto por el servidor); devuelve total_count cuando Forgejo informa X-Total-Count. |
get_repo_hook | Obtener un único webhook del repositorio por ID |
create_repo_hook | Crear un webhook del repositorio. El secreto se acepta pero nunca se repite en la respuesta. |
edit_repo_hook | Editar un webhook del repositorio. Solo cambian los campos que pasas; los campos omitidos se dejan sin cambios. |
delete_repo_hook | Eliminar un webhook del repositorio por ID |
test_repo_hook | Activar una entrega de prueba para un webhook del repositorio — ADVERTENCIA: activa una entrega HTTP en vivo |
| Archivos | |
get_file_content | Obtener el contenido de un archivo. Los opcionales start_line/end_line solicitan un rango de líneas inclusivo basado en 1 (se ajusta a la extensión del archivo; se ignora cuando with_metadata=true). |
list_repo_contents | Listar archivos y directorios en una ruta. path="" lista la raíz del repositorio. Devuelve un nivel; para un árbol completo usa get_repo_tree con recursive=true. |
get_repo_tree | Obtener el árbol Git. recursive=true devuelve el árbol de archivos completo en una respuesta (sujeto al límite de tamaño del endpoint de árbol del servidor); recursive=false (predeterminado) devuelve un nivel. |
create_file | Crear un nuevo archivo |
update_file | Actualizar un archivo existente |
delete_file | Eliminar un archivo |
| Commits | |
list_repo_commits | Listar commits en un repositorio |
get_commit_statuses | Listar estados de commit por contexto para un SHA completo de 40 caracteres. Limitado por page (predeterminado 1) + limit (predeterminado 30, máximo 50); devuelve {sha, statuses, page, limit, count, total_count} — total_count está presente solo cuando Forgejo informa X-Total-Count. El agregado combinado permanece en el recurso de estado del commit. No son ejecuciones de Actions (list_workflow_runs). |
| Incidencias | |
list_repo_issues | Listar incidencias en un repositorio (página/límite). El opcional sort ordena en el servidor: relevance, latest, oldest, recentupdate, leastupdate, mostcomment, leastcomment, nearduedate, farduedate (los dos últimos son las direcciones de fecha límite). |
search_issues | Buscar incidencias en todos los repositorios de un propietario (página/límite); devuelve {issues,page,limit,count,has_next,total_count} — total_count está presente solo cuando Forgejo informa X-Total-Count |
get_issue_by_index | Obtener una incidencia específica |
create_issue | Crear una nueva incidencia. Los opcionales labels (nombres o IDs separados por comas), assignees (nombres de usuario separados por comas) y milestone (ID numérico) se aplican en la misma solicitud que crea la incidencia. |
add_issue_labels | Añadir etiquetas a una incidencia. labels acepta nombres de etiqueta o IDs numéricos separados por comas; un nombre no reconocido es un error y no se aplica nada. |
remove_issue_labels | Eliminar etiquetas de una incidencia. labels acepta nombres de etiqueta o IDs numéricos separados por comas. |
update_issue | Actualizar una incidencia existente (requiere ID de hito numérico). due_date establece la fecha límite (RFC3339); clear_due_date=true la elimina. Los dos son mutuamente excluyentes — establecer ambos es un error, y omitir ambos deja la fecha límite sin cambios. set_labels reemplaza el conjunto completo de etiquetas de la incidencia (nombres o IDs); una cadena vacía elimina todas las etiquetas. |
issue_state_change | Abrir o cerrar una incidencia |
list_issue_dependencies | Listar 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_dependents | Listar 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_dependency | Hacer que una incidencia dependa de otra. La dependencia puede estar en un repositorio diferente: los opcionales depends_on_owner/depends_on_repo se predeterminan a owner/repo. |
remove_issue_dependency | Eliminar una dependencia de una incidencia. Para una dependencia entre repositorios, los opcionales dependency_owner/dependency_repo se predeterminan a owner/repo. |
list_repo_milestones | Listar hitos con sus IDs (usar con update_issue) |
list_repo_labels | Listar etiquetas con sus IDs. Fusiona etiquetas de nivel de organización para repositorios propiedad de una organización (establece include_org_labels=false para optar por no participar). Cada entrada lleva un campo scope ("repo" o "org"). |
list_org_labels | Listar etiquetas de nivel de organización con sus IDs. Las herramientas de asignación aceptan nombres de etiqueta directamente, así que esto es para descubrimiento y para el nombre raro que existe tanto en el ámbito del repositorio como en el de la organización. |
create_repo_label | Crear una etiqueta de repositorio (name, color como hex de 6 dígitos, description opcional). Devuelve el id numérico; add_issue_labels también acepta el nombre. |
edit_repo_label | Editar una etiqueta de repositorio (PATCH — solo cambian los campos proporcionados: name, color, description). |
delete_repo_label | Eliminar una etiqueta de repositorio. Se niega por predeterminado cuando la etiqueta está en uso (informa el recuento); establece delete_mode=force para anular. |
get_repo_label | Obtener una única etiqueta de repositorio por id numérico. |
create_org_label | Crear una etiqueta de nivel de organización. Mismos campos que create_repo_label. |
edit_org_label | Editar una etiqueta de nivel de organización (semántica PATCH). |
delete_org_label | Eliminar una etiqueta de nivel de organización. La protección de uso cuenta en los repos visibles de la organización (mejor esfuerzo); delete_mode=force anula. |
get_org_label | Obtener una única etiqueta de nivel de organización por id numérico. |
| Comentarios | |
list_issue_comments | Listar comentarios en una incidencia o PR |
get_issue_comment | Obtener un comentario específico |
create_issue_comment | Añadir un comentario a una incidencia o PR |
edit_issue_comment | Editar un comentario |
delete_issue_comment | Eliminar un comentario |
| Solicitudes de extracción | |
list_repo_pull_requests | Listar solicitudes de extracción en un repositorio |
get_pull_request_by_index | Obtener una solicitud de extracción específica |
create_pull_request | Crear una nueva solicitud de extracción |
update_pull_request | Actualizar una solicitud de extracción existente |
list_pull_reviews | Listar revisiones de una solicitud de extracción |
get_pull_review | Obtener una revisión específica de solicitud de extracción |
list_pull_review_comments | Listar comentarios en una revisión de solicitud de extracción |
list_pull_request_files | Listar archivos modificados en una solicitud de extracción (paginado). Usa los nombres de archivo devueltos como argumento file_path para get_pull_request_diff. |
get_pull_request_diff | Obtener el diff unificado de una solicitud de extracción. El opcional file_path devuelve solo los hunks de ese archivo (coincide con la ruta previa o posterior al renombrado). |
merge_pull_request | Fusionar una solicitud de extracción (estilo: merge/rebase/rebase-merge/squash; título/mensaje/eliminar-rama/fusión-forzada/esperar-comprobaciones opcionales). |
create_pull_review | Crear una revisión en una solicitud de extracción (estado: APPROVED/REQUEST_CHANGES/COMMENT) con comentarios en línea opcionales. |
submit_pull_review | Enviar una revisión de solicitud de extracción pendiente |
dismiss_pull_review | Desestimar una revisión de solicitud de extracción |
delete_pull_review | Eliminar una revisión de solicitud de extracción pendiente |
create_review_requests | Solicitar revisiones de usuarios o equipos específicos |
delete_review_requests | Cancelar solicitudes de revisión pendientes |
| Paquetes | |
list_packages | Listar versiones de paquetes de un usuario u organización (una fila por versión). Opcionales type y q. Paginado por servidor mediante page/limit (predeterminado 30, máximo 50). Envoltorio {packages, page, limit, count, has_next, total_count?}. Un propietario ausente es un error, no una lista vacía |
get_package | Obtener una versión de paquete. No incluye usuarios propietario/creador |
delete_package | Eliminar una versión de paquete (no todas las versiones del nombre). Sin verificación previa. Los 4xx/5xx siguen siendo errores |
list_package_files | Listar archivos de una versión de paquete. Paginado por cliente mediante page/limit (predeterminado 30, máximo 50); envoltorio {files, page, limit, count, has_next, total_count} (total_count es la longitud de la lista obtenida) |
| Actions | |
dispatch_workflow | Activar una ejecución de flujo de trabajo mediante el evento workflow_dispatch |
list_workflow_runs | Listar ejecuciones de flujo de trabajo con filtrado opcional por estado, evento o SHA |
get_workflow_run | Obtener detalles de una ejecución de flujo de trabajo específica por ID |
list_action_run_jobs | Listar 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_logs | Leer un registro de trabajo de Forgejo v16+ con límites reanudables de offset y max_bytes; se predetermina a la cola |
cancel_workflow_run | Cancelar una ejecución de flujo de trabajo pendiente o en curso. Las ejecuciones ya finalizadas también devuelven éxito (HTTP 204); la ejecución se deja sin cambios |
delete_workflow_run | Eliminar una ejecución de flujo de trabajo completada. Una ejecución en vivo es un error de API. Elimina la ejecución y sus registros de trabajo; Forgejo marca los artefactos de esa ejecución como eliminados |
list_action_run_artifacts | Listar artefactos de una ejecución de flujo de trabajo. Paginado por servidor mediante page/limit (predeterminado 30, máximo 50); filtro name opcional. Envoltorio {artifacts, page, limit, count, total_count?} |
get_action_artifact | Obtener metadatos de un artefacto de Actions. No descarga el zip |
| Organizaciones | |
list_my_orgs | Listar mis organizaciones |
list_user_orgs | Listar las organizaciones de un usuario |
get_org | Obtener detalles de la organización |
create_org | Crear una organización |
edit_org | Editar la configuración de la organización |
delete_org | Eliminar una organización — destructivo e irreversible: todos los repos, equipos y datos se eliminan permanentemente |
list_org_members | Listar miembros de una organización |
check_org_membership | Comprobar si un usuario es miembro de una organización |
remove_org_member | Eliminar un miembro de una organización |
list_org_teams | Listar equipos en una organización |
search_org_teams | Buscar equipos en una organización |
create_org_team | Crear un equipo en una organización |
add_team_member | Agregar un usuario a un equipo |
remove_team_member | Eliminar un usuario de un equipo |
add_team_repo | Agregar un repositorio a un equipo |
remove_team_repo | Eliminar un repositorio de un equipo |
| Seguimiento de tiempo | |
list_issue_tracked_times | Listar entradas de tiempo registradas en un issue o PR |
list_repo_tracked_times | Listar entradas de tiempo registradas en un repositorio |
list_my_tracked_times | Listar tus propias entradas de tiempo registradas |
add_issue_time | Registrar tiempo en un issue o PR (acepta segundos o duración como 15m) |
reset_issue_time | Eliminar TODAS las entradas de tiempo registradas en un issue o PR (destructivo) |
delete_issue_time_entry | Eliminar una sola entrada de tiempo registrada por ID |
start_issue_stopwatch | Iniciar un cronómetro en un issue o PR |
stop_issue_stopwatch | Detener un cronómetro en ejecución y registrar el tiempo transcurrido |
cancel_issue_stopwatch | Cancelar un cronómetro en ejecución sin registrar |
list_my_stopwatches | Listar cronómetros actualmente en ejecución |
| Adjuntos | |
list_issue_attachments | Listar adjuntos en un issue o PR |
get_issue_attachment | Obtener metadatos de un solo adjunto de issue/PR |
download_issue_attachment | Descargar un adjunto de issue/PR (en línea si es < 1 MiB; metadatos + URL en caso contrario) |
create_issue_attachment | Subir un nuevo adjunto a un issue o PR (contenido base64 o una ruta de archivo en el host MCP) |
edit_issue_attachment | Renombrar un adjunto de issue/PR |
delete_issue_attachment | Eliminar un adjunto de issue/PR |
list_comment_attachments | Listar adjuntos en un comentario de issue/PR |
get_comment_attachment | Obtener metadatos de un solo adjunto de comentario |
download_comment_attachment | Descargar un adjunto de comentario (en línea si es < 1 MiB; metadatos + URL en caso contrario) |
create_comment_attachment | Subir un nuevo adjunto a un comentario de issue/PR (contenido base64 o una ruta de archivo en el host MCP) |
edit_comment_attachment | Renombrar un adjunto de comentario |
delete_comment_attachment | Eliminar un adjunto de comentario |
| Lanzamientos | |
list_releases | Listar lanzamientos de un repositorio (página/límite + filtro state del lado del cliente: todos/borrador/prelanzamiento/publicado) |
get_release_by_id | Obtener un lanzamiento por ID numérico |
get_release_by_tag | Obtener un lanzamiento por nombre de etiqueta |
get_latest_release | Obtener el último lanzamiento que no sea borrador ni prelanzamiento |
create_release | Crear un nuevo lanzamiento (pasa target_commitish para también crear la etiqueta) |
edit_release | Actualizar campos de un lanzamiento existente (solo se envían los campos proporcionados) |
delete_release | Eliminar un lanzamiento por ID numérico — destructivo |
delete_release_by_tag | Eliminar un lanzamiento por nombre de etiqueta — destructivo, verificar etiqueta |
list_release_attachments | Listar adjuntos en un lanzamiento (respuesta obtenida completa, segmentada del lado del cliente) |
get_release_attachment | Obtener metadatos de un solo adjunto de lanzamiento |
download_release_attachment | Descargar un adjunto de lanzamiento (en línea si es < 1 MiB; metadatos + URL en caso contrario) |
create_release_attachment | Subir un nuevo adjunto a un lanzamiento (contenido base64 o una ruta de archivo en el host MCP) |
edit_release_attachment | Renombrar un adjunto de lanzamiento |
delete_release_attachment | Eliminar un adjunto de lanzamiento — destructivo |
| Wiki | |
list_wiki_pages | Listar páginas usando page/limit; devuelve has_next y, cuando Forgejo informa X-Total-Count, total_count. total_count cuenta las entradas del árbol wiki sin procesar del servidor, por lo que puede superar el número de páginas listadas en una wiki con subdirectorios — un límite superior, no un total exacto. |
get_wiki_page | Leer Markdown decodificado; start_line/end_line opcionales, siempre devuelve total_lines. |
get_wiki_revisions | Listar historial de revisiones usando page/limit; devuelve has_next y total_count, el recuento total de revisiones de la página según se informa en el cuerpo de la respuesta. |
create_wiki_page | Crear 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_page | Actualizar contenido/título por page_name normalizado; el último escritor gana. |
delete_wiki_page | Eliminar una página por page_name normalizado. |
| Servidor | |
get_forgejo_mcp_server_version | Obtener la versión del servidor MCP |
Recursos
Las plantillas de recursos de MCP exponen entidades de Forgejo como recursos direccionables por URI mediante el esquema forgejo://. El esquema URI es portable entre instancias — la misma forma de URI funciona contra cualquier instancia de Forgejo — y no colisiona 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 continúan usando las herramientas anteriores — no se elimina ninguna funcionalidad.
Los recursos NO reemplazan ninguna herramienta MCP — cada herramienta existente de listar/obtener sigue disponible; los recursos son una superficie de lectura aditiva y direccionable por URI destinada a la auto-resolución desde el contexto de LLM y al almacenamiento en caché direccionable por contenido de entidades inmutables como commits.
Los recursos que incorporan una lista (issue, pr) limitan el arreglo incorporado 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 vs herramientas: prefiera un recurso cuando tenga un sha o índice específico en mano; prefiera una herramienta al listar o buscar.
| Plantilla URI | Entidad | Notas |
|---|---|---|
forgejo://owner/{owner} | application/json | Perfil de usuario u organización direccionado por login; resuelve usuario primero, y si no, organización. |
forgejo://repo/{owner}/{repo} | application/json | Resumen del repositorio: identidad + conteos, sin listas incorporadas. |
forgejo://repo/{owner}/{repo}/commit/{sha} | Metadatos de commit | Inmutable por sha. Devuelve JSON + sidecar markdown. El sha debe tener 40 caracteres hexadecimales. |
forgejo://repo/{owner}/{repo}/commit/{sha}/status | application/json | Estado CI combinado para un sha: estado agregado + estados por contexto limitados (máx. 30, el centinela nombra la herramienta de lista get_commit_statuses). |
forgejo://repo/{owner}/{repo}/issue/{index} | application/json (+ sidecar text/markdown) | Metadatos de issue + cuerpo renderizado + comentarios recientes limitados (máx. 30, el centinela nombra list_issue_comments). |
forgejo://repo/{owner}/{repo}/issues{?state,labels,page,limit} | application/json | Lista limitada de issues como filas — índice, título, estado, autor, etiquetas, asignados, hito, conteo de comentarios, marcas de tiempo, fecha de vencimiento — y sin cuerpos. state ∈ {open, closed, all} (por defecto open); labels separados por comas; máx. 30, el centinela nombra list_repo_issues. Lea el recurso de issue individual para obtener un cuerpo. |
forgejo://repo/{owner}/{repo}/{kind}/{index}/comment/{id} | application/json (+ sidecar text/markdown) | Comentario individual por id; kind ∈ {issue, pr}. |
forgejo://repo/{owner}/{repo}/{kind}/{index}/comments{?page,limit} | application/json | Hilo de comentarios limitado con cuerpos completos (el recurso de issue individual los extrae a 200 caracteres); kind ∈ {issue, pr}; máx. 30, el centinela nombra list_issue_comments. |
forgejo://repo/{owner}/{repo}/pr/{index} | application/json (+ sidecar text/markdown) | 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}/branch_protections | application/json | Lista limitada de reglas de protección de ramas. |
forgejo://repo/{owner}/{repo}/branch_protection/{rule} | application/json | Regla individual de protección de ramas. Los nombres de reglas son patrones de ramas, así que codifique un / literal como %2F y los espacios como %20 (release%2Fv1); un / crudo no se resuelve. |
forgejo://repo/{owner}/{repo}/hooks | application/json | Lista limitada de webhooks del repositorio (máx. 30, el centinela nombra list_repo_hooks). El secreto nunca se devuelve. |
forgejo://repo/{owner}/{repo}/hook/{id} | application/json | Webhook individual del repositorio por id. El secreto nunca se devuelve. |
forgejo://repo/{owner}/{repo}/label/{id} | application/json | Etiqueta individual del repositorio por id numérico. |
forgejo://repo/{owner}/{repo}/labels{?page,limit} | application/json | Lista limitada de etiquetas del repositorio (máx. 30, el centinela nombra list_repo_labels). |
forgejo://org/{org}/labels{?page,limit} | application/json | Lista limitada de etiquetas a nivel de organización (máx. 30, el centinela nombra list_org_labels). |
forgejo://repo/{owner}/{repo}/wiki/{pageName} | application/json (+ sidecar text/markdown) | Página wiki con revisiones limitadas y Markdown limitado a 1 MiB. Use el page_name normalizado devuelto; codifique un / literal como %2F y los espacios como %20 en el URI (no doble-codifique un nombre ya normalizado). |
Los títulos separados por barras como Guides/Setup son útiles como convención de nombres de subpáginas,
pero Forgejo almacena las páginas en una lista plana: no crea Guides automáticamente ni
registra una relación padre-hijo. Cree la página padre por separado cuando los lectores la necesiten, y
siempre direccione llamadas posteriores con el page_name normalizado devuelto por crear o listar.
El comportamiento REST de wiki documentado aquí fue probado en vivo contra Forgejo
15.0.4+gitea-1.22.0; la demostración MCP completa se reprodujo exitosamente 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
| Cliente | resources/templates/list | resources/read |
|---|---|---|
| Claude Code | compatible | compatible |
| Claude Desktop | compatible | compatible |
| Codex | compatible | compatible |
| Cursor (actual) | compatible | compatible |
| Clientes antiguos / mínimos | solo herramientas | solo herramientas |
Demostraciones
Recorridos completos, copiables y pegables de las herramientas anteriores — agrupados por
tema (etiquetas, adjuntos, seguimiento de tiempo, notificaciones, organizaciones, E/S
limitada de revisión de código, transporte) — viven en demos/. Cada
demostración empareja invocaciones reales de ./forgejo-mcp --cli con la salida que
produjeron contra codeberg.org.
Modo CLI
Puede 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.
# List artifacts of a run, then read one artifact's metadata (no zip download)
forgejo-mcp --cli list_action_run_artifacts \
--args '{"owner":"goern","repo":"forgejo-mcp","run_id":123,"limit":30}' \
--output=text
forgejo-mcp --cli get_action_artifact \
--args '{"owner":"goern","repo":"forgejo-mcp","artifact_id":789}' \
--output=text
# List package versions for an owner, then inspect one version's files
forgejo-mcp --cli list_packages \
--args '{"owner":"OWNER","type":"container","limit":30}' \
--output=text
forgejo-mcp --cli get_package \
--args '{"owner":"OWNER","type":"container","name":"app","version":"1.0.0"}' \
--output=text
forgejo-mcp --cli list_package_files \
--args '{"owner":"OWNER","type":"container","name":"app","version":"1.0.0"}' \
--output=text
# delete_package removes one version. Do not invoke it against a registry you do not own.
# cancel_workflow_run is 204 even when the run already finished.
# delete_workflow_run only succeeds for a completed run; a live run is an error.
# 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
Puede configurar el servidor usando argumentos de línea de comandos o variables de entorno:
| Argumento CLI | Variable de Entorno | Descripción |
|---|---|---|
--url | FORGEJO_URL | La URL de su instancia de Forgejo |
--token | FORGEJO_ACCESS_TOKEN | Su token de acceso personal |
--debug | FORGEJO_DEBUG | Habilitar 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) |
--host | FORGEJO_MCP_HOST | Dirección a la que se vinculan los transportes sse y http (por defecto: localhost, alcanzable solo desde esta máquina, vinculando tanto 127.0.0.1 como ::1; pase una de esas direcciones para vincular solo esa familia) |
--allowed-hosts | FORGEJO_MCP_ALLOWED_HOSTS | Nombres de Host separados por comas a los que este servidor responde; requerido cuando --host no es loopback |
--allowed-origins | FORGEJO_MCP_ALLOWED_ORIGINS | Orígenes web separados por comas permitidos para enviar un encabezado Origin, como orígenes completos (https://console.example.org). Vacío por defecto |
--allow-operator-token-fallback | FORGEJO_MCP_ALLOW_OPERATOR_TOKEN_FALLBACK | En sse/http, atender solicitudes sin encabezado Authorization usando el token propio de este servidor. Desactivado por defecto |
--auth-mode | FORGEJO_MCP_AUTH_MODE | passthrough (por defecto) o resource-server; consulte Operación remota como servidor de recursos OAuth |
--authorization-server | FORGEJO_MCP_AUTHORIZATION_SERVER | Modo resource-server: URL del emisor del proveedor OpenID Connect, comparada byte por byte |
--resource | FORGEJO_MCP_RESOURCE | Modo resource-server: URI canónico del endpoint MCP, por ejemplo https://mcp.example.org/mcp; su ruta debe ser /mcp |
--resource-audience | FORGEJO_MCP_RESOURCE_AUDIENCE | Modo resource-server: valor que debe contener el aud de un token de acceso (por defecto: el valor de --resource) |
--scopes-supported | FORGEJO_MCP_SCOPES_SUPPORTED | Modo resource-server: ámbitos separados por espacios publicados en los metadatos y el desafío 401 (por defecto: ninguno publicado) |
--forgejo-audience-claim | FORGEJO_MCP_FORGEJO_AUDIENCE_CLAIM | Modo resource-server: reclamo del token de acceso que contiene la audiencia de la Integración Autorizada de Forgejo del llamador (por defecto: forgejo_aud) |
--forgejo-jwt-issuer | FORGEJO_MCP_FORGEJO_JWT_ISSUER | Modo resource-server: URL del emisor bajo la cual el servidor firma JWTs para Forgejo, por ejemplo https://mcp.example.org/issuer; https, sin barra final |
--forgejo-jwt-signing-key-file | FORGEJO_MCP_FORGEJO_JWT_SIGNING_KEY_FILE | Modo resource-server: clave privada PEM que firma los JWTs para Forgejo (EC P-256 o P-384, Ed25519, o RSA de al menos 2048 bits) |
--forgejo-jwt-published-key-files | FORGEJO_MCP_FORGEJO_JWT_PUBLISHED_KEY_FILES | Modo resource-server: claves PEM separadas por comas publicadas junto a la clave de firma, para rotación de claves |
--cli | - | Entrar en modo CLI para invocación directa de herramientas |
--user-agent | FORGEJO_USER_AGENT | Encabezado HTTP User-Agent (por defecto: forgejo-mcp/<version>) |
| - | FORGEJO_MCP_ALLOW_FILE_PATH_UPLOAD | Permitir que las cargas de adjuntos de file_path lean el sistema de archivos del host (1/true/yes/on; desactivado por defecto) |
| - | FORGEJO_MCP_UPLOAD_ROOT | Confinar las cargas de file_path a este directorio (por defecto: cualquier lugar que el proceso pueda leer) |
Los argumentos de línea de comandos tienen prioridad sobre las variables de entorno.
Los ajustes de resource-server se rechazan en modo passthrough, por lo que una configuración que los establece pero olvida --auth-mode resource-server no se inicia.
Carga de adjuntos desde el sistema de archivos del host
create_issue_attachment, create_comment_attachment y
create_release_attachment aceptan content en base64 o un file_path en
la máquina que ejecuta forgejo-mcp. La forma de ruta evita expandir en base64 un
artefacto de release grande a través del transporte MCP.
Está desactivado por defecto, porque le da a lo que sea que impulse el cliente MCP la
capacidad de leer cualquier archivo que el proceso del servidor pueda leer — un agente
inyectado por prompt podría cargar ~/.ssh/id_ed25519 como un activo de release público. Actívelo
deliberadamente y prefiera confinarlo:
export FORGEJO_MCP_ALLOW_FILE_PATH_UPLOAD=1
export FORGEJO_MCP_UPLOAD_ROOT=/home/you/build/dist # optional but recommended
Con FORGEJO_MCP_UPLOAD_ROOT establecido, una ruta que se resuelva fuera de ese directorio
— por ser absoluta, por .., o a través de un enlace simbólico — se rechaza antes de que se lea
nada. Las cargas de content en base64 no se ven afectadas por ninguna de las variables.
Verificación de Releases
Los archivos de release están acompañados por un archivo checksums.txt y un
checksums.txt.sig opcional producido por cosign
con el par de claves de release del proyecto. Verificar ambos archivos le permite confirmar
que el binario que descargó fue construido por el pipeline de release 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 configurara la firma se distribuyen sin un archivo
.sig— la verificación aplica solo desdev2.23.xen adelante, y solo cuando el secretoCOSIGN_PRIVATE_KEYse configuró en el momento del release.
1. Instalar cosign
Siga la guía de instalación de cosign de upstream para su 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
Confirme:
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 release. Esta es la clave de firma de artefactos que
firma los blobs de release (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 por 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 por commit incluye su contenido en la URL — si alguien alguna vez reescribe el archivo en ese commit, su descarga falla o no coincide. Fije al commit más reciente que confíe antes de adoptar la clave en automatización.
3. Descargar los artefactos del release
Elige la etiqueta que instalaste (p. ej. v3.1.0) y descarga el archivo de suma de verificación,
su firma y el archivo binario:
TAG=v3.1.0
VERSION="${TAG#v}"
BASE="https://git.b4mad.industries/agentic-forges/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. Verifica la firma y 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
verificació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 suma de verificación cubre transitivamente los SBOM y otros archivos por archivo:
verificar checksums.txt una vez es suficiente para todo lo
enumerado dentro de él.
5. Verifica la procedencia SLSA para la imagen de release-tools
La imagen de contenedor de release-tools (utilizada internamente por el pipeline de lanzamiento de Tekton) lleva procedencia SLSA v1.0 generada por Tekton Chains. Esta atestación vincula el digesto de la imagen con la ejecución exacta de PipelineRun, el commit de git y la identidad del constructor que la produjo, lo que proporciona procedencia de la cadena de suministro más allá de lo que la firma de cosign puede atestiguar por sí sola.
Obtén la clave pública de 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 haga referencia a la
revisión de git esperada, y predicate.runDetails.builder.id muestre el
constructor de Tekton Chains.
Nota: Las atestaciones de procedencia SLSA están disponibles para los lanzamientos creados después de que forgejo-mcp-46j (soporte de Tekton Chains) se implementara. Las etiquetas de imagen anteriores solo llevan la firma de cosign; no tienen carga útil de
verify-attestation.
6. Verifica la imagen del contenedor
La imagen de la aplicación git.b4mad.industries/agentic-forges/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=v3.1.0 # substitute the release you are pulling
cosign verify \
--key cosign-images.pub \
"git.b4mad.industries/agentic-forges/forgejo-mcp:${IMAGE_TAG}" \
| jq .
Verifica la atestación de procedencia SLSA:
cosign verify-attestation \
--type slsaprovenance \
--key cosign-images.pub \
"git.b4mad.industries/agentic-forges/forgejo-mcp:${IMAGE_TAG}" \
| jq .
Verifica y descarga la atestación SBOM CycloneDX firmada:
cosign verify-attestation \
--type cyclonedx \
--key cosign-images.pub \
"git.b4mad.industries/agentic-forges/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 artefactoattach sbomsin firmar.cosign download sbomya no aplica.
Debido a que el pipeline de publicación empuja por digesto y solo promueve las
etiquetas vX.Y.Z / latest después de que la firma y la fijación del SBOM se completen correctamente, cualquier etiqueta
que puedas extraer está garantizada como firmada.
Solución de problemas de verificación
Error: no matching signatures— el archivo.siges de un lanzamiento diferente, ocosign.pubes 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 de cosign, o la firma se omitió en esa ejecución porque el secreto no estaba configurado. Recurre a la verificación solo con suma de verificación (sha256sum -c), que aún detecta corrupción en tránsito, pero no manipulación.- Desajuste entre
cosign.puby 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 desdebranch/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 de 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
- Reportar problemas — errores, preguntas, solicitudes de funciones
- ¿Encontraste un problema de seguridad? No uses el rastreador de problemas. Consulta SECURITY.md para saber cómo reportarlo de forma privada.
- Ver código fuente
- Chatear en Matrix —
#forgejo-mcp:b4mad.net
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
-
Instalación desde la ruta de módulo antigua de Codeberg —
go install codeberg.org/goern/forgejo-mcp/v2@latestaún se resuelve, contra el espejo de solo lectura, pero ese espejo está desactualizado respecto al lanzamiento actual. Usagit.b4mad.industries/agentic-forges/forgejo-mcp/v3@latesten su lugar.Esta entrada solía decir que la nueva ruta no era instalable hasta que un lanzamiento llevara el
go.modrenombrado. Ese lanzamiento ya ocurrió —v3.0.0en adelante declaranmodule git.b4mad.industries/agentic-forges/forgejo-mcp/v3— por lo que la nueva ruta se instala normalmente. El bloqueador anterior de la directivareplace(#67) también desapareció;go.modya no contiene uno.
Contribuyentes
forgejo-mcp está moldeado por todos los que reportan problemas, escriben código, revisan PRs y empujan el proyecto hacia adelante. Gracias a todos. 🙏
Contribuyentes de código
| Contribuyente | Destacados |
|---|---|
| goern (Christoph Görn) | Creador y mantenedor del proyecto |
| Ronmi Ren | Co-creador; transporte SSE/HTTP, bloqueo de problemas, mejoras de CI/CD, logotipo, especificación Glama |
| twstagg (Tristin Stagg) | Soporte de configuración de user agent (PR #89) |
| mattdm (Matthew Miller) | Mejoras de registro, migración FORGEJO_*, README, refactorización de URL |
| byteflavour | check_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 NixOS (PR #146); endurecimiento del transporte de red — enlace de bucle local por defecto, comprobaciones de Host/Origin, credencial por solicitud (PR #545, implementado como #573; #586, #585, #589); modo servidor de recursos OAuth — validación JWT entrante y firma de integración autorizada saliente de Forgejo 16, con guías de operador y usuario y 40 escenarios de demostración anclados (PR #584, investigado en #582); FORGEJO_MCP_EXEC de entorno de desarrollo (PR #580); solicitudes de funciones #80, #85 |
| jesterret | Soporte de revisiones y comentarios de pull requests (PR #51) |
| appleboy | Soporte de puerto SSE personalizado, correcciones de errores |
| ignasgil | Herramienta 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) |
| jiriks74 | Actualización de dependencia mcp-go v0.44.0 (PR #90) |
| th (Tomi Haapaniemi) | Herramienta update_pull_request |
| hiifong | Correcciones de errores y actualizaciones tempranas |
| Lunny Xiao | Contribuciones tempranas |
| techknowlogick | Contribuciones tempranas |
| yp05327 | Contribuciones tempranas |
| mw75 | Soporte de propietario/org para creación de repositorios (PR #18) |
| Dax Kelson | Gestión de comentarios de problemas (PR #34) |
| Guruprasad Kulkarni | Documentación de instalación Arch Linux AUR (PR #69) |
| Mario Wolff | Contribuciones |
| Massimo Fraschetti | Contribuciones |
| synath (David Paul Turley) | Soporte de token con ámbito de repositorio mediante sonda ServerVersion (PR #112); verificación de código de estado de fusión (PR #113); empaquetado de extensión de escritorio Claude (.mcpb) (PR #118, #123); due_date de problemas + ordenación del lado del servidor (PR #483); recursos acotados de listas de problemas y hilos de comentarios (PR #487); total_count en sobres paginados de X-Total-Count (PR #507); endurecimiento de tiempo de espera de create_*_attachment (PR #534, #536); dependencias de problemas entre repositorios (PR #535) |
| BrilliantKahn | Predeterminado de texto plano get_file_content (PR #116); herramientas list_repo_contents y get_repo_tree (PR #117). Primera contribución de código abierto de la historia — ¡bienvenido a bordo! 🎉 |
| nesvet (Eugene Nesvetaev) | get_repo/edit_repo (PR #527); herramientas de temas de repositorio (PR #528); cancelar/eliminar ejecuciones de Actions y artefactos de ejecución (PR #533); get_commit_statuses (PR #542); herramientas de paquetes listar/obtener/eliminar/archivos (PR #543); nombres de etiquetas aceptados en creación, asignación y reemplazo de problemas (PR #591) |
| pisco (Marco Pisco) | Cargas file_path para archivos adjuntos de problemas, comentarios y lanzamientos, con multipart de transmisión para que los archivos grandes de lanzamiento ya no pasen por base64 (PR #481) |
Contribuyentes de la comunidad
Reportadores de problemas y participantes en discusiones que moldearon la dirección del proyecto:
| Contribuyente | Contribuciones |
|---|---|
| byteflavour | Reportó #80 (descubrimiento de hitos/etiquetas), #85 (propuesta de API de notificaciones); revisor activo en discusiones |
| choucavalier | Reportó #82 (corrección de skill), #70 (lanzamientos macOS arm64), #62 (lanzamientos binarios y soporte de mise) |
| MalcolmMielle | Reportó #59 (herramientas de revisión de PR — implementadas desde entonces) |
| redbeard | Reportó #60 (soporte de Actions — implementado desde entonces) |
| c6sepl6p | Reportó #72 (codificación base64), #54 (fusionar pull request — implementado desde entonces) |
| malik | Reportó #73 (indicador de versión), #47 (corrección de compilación Nix) |
| a2800276 | Reportó #74 (compatibilidad con OpenAI) |
| simenandre | Reportó #49 (soporte de go install) |
| BasdP | Reportó #42 (soporte de Projects) |
| BoBeR182 | Reportó #32 (soporte de wiki) |
| ignasgil | Reportó #95 (solicitud de función remove_issue_labels) |
| Vokuar | Reportó #99 (soporte de transporte HTTP transmisible) |
| janbaer | Reportó #98 (responder a comentario de revisión) |
| fraschm98 | Reportes de problemas tempranos |
| heathen711 | Reportó #106 (archivos adjuntos de problemas/comentarios — implementado desde entonces); dio forma al diseño de límite en línea de 1 MiB + respaldo de browser_download_url |
| decarvalhoaa (Antonio De Carvalho) | Reportó #593 (límite de tamaño de respuesta del lado del servidor) desde un desbordamiento real del contexto de ventana detrás de Open WebUI, con la medición que impulsó el trabajo de carga útil de list_repo_pull_requests en #596 |
| chris420 (Chris Oloff) | Reportó #452 (búsqueda de problemas a nivel de org — implementado desde entonces como search_issues); revisión de diseño en PR #458 que reemplazó la sonda de página siguiente con aplicación de límite de instancia, y detectó que el sobre de respuesta informaba incorrectamente su propio limit |
Contribuyentes cyborg
Este proyecto también recibió contribuciones de agentes de codificación de IA — enviadas como PRs regulares, revisadas por humanos:
| Agente | Rol | Contribuciones |
|---|---|---|
| brenner-axiom (b4-dev, B4arena) | Agente de desarrollo de IA | Herramientas de gestión de organizaciones (PR #94); demostraciones 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 |
| opencode | Agente de desarrollo de IA | Soporte de revisiones y comentarios de pull requests (PR #51) |
| claude-code | Agente de desarrollo de IA | Predeterminado de texto plano get_file_content y herramientas list_repo_contents/get_repo_tree, en conjunto con BrilliantKahn (PR #116, #117) |
| b4mad-release-agent | Automatización de lanzamientos | Registro de cambios automatizado y etiquetado de lanzamientos |
| el bot #B4mad Renovate | Actualizaciones de dependencias | Actualizaciones automatizadas de dependencias |
¿Quieres contribuir? Abre un problema o pull request — todos son bienvenidos.
Licencia
Este proyecto es de código abierto. Consulta el repositorio para obtener detalles de la licencia.