PTENES
MÓDULO 4.4

🌐 Integración con API REST

Crea un MCP Server que consume la API de GitHub: listar repos, buscar issues y crear issues mediante Claude.

6
Temas
45
Minutos
Intermedio
Nivel
Práctico
Tipo
1

🌐 Entendiendo la API de GitHub

La API de GitHub es una de las API REST mejor documentadas y utilizadas del mundo. Permite acceder de forma programática a casi todo lo que haces en la interfaz web: repositorios, issues, pull requests, commits y organizaciones. Para nuestro MCP Server, usaremos esta API como base para crear tools potentes que Claude pueda utilizar para interactuar con tus proyectos en GitHub.

💎 Concepto principal

La API REST de GitHub está disponible en api.github.com. Los principales endpoints que utilizaremos son: GET /user/repos para listar tus repositorios, GET /repos/{owner}/{repo}/issues para buscar issues de un repositorio específico, y POST /repos/{owner}/{repo}/issues para crear nuevas issues. Todas las respuestas están en formato JSON, lo que facilita el análisis y el formato de los datos. La API tiene límites de solicitudes —5.000 requests por hora con autenticación— que tu servidor debe respetar.

📊 Datos e investigación

La API de GitHub procesa más de miles de millones de solicitudes al día y la usan prácticamente todas las herramientas de desarrollo modernas: CI/CD, IDE, bots y dashboards. Con autenticación mediante token, el límite de solicitudes aumenta a 5.000 solicitudes/hora, más que suficiente para un MCP Server personal. Sin autenticación, el límite baja a solo 60 requests/hora, lo que hace inviable cualquier uso práctico.

💡 Consejo práctico

Antes de escribir código, prueba la API manualmente con curl o con herramientas como Insomnia/Postman. Ejecuta curl https://api.github.com/users/{seu-usuario}/repos para ver la estructura del JSON devuelto. Esto facilita mucho la implementación de las tools del MCP Server, porque ya sabrás exactamente qué campos extraer y dar formato.

2

🔑 Autenticación con token

Para acceder a la API de GitHub de forma autenticada —algo esencial para tener límites de solicitudes razonables y acceder a repositorios privados— necesitas un Personal Access Token (PAT). Este token funciona como una contraseña temporal y con permisos controlados, lo que permite que tu MCP Server acceda a la API en tu nombre sin necesitar tu contraseña real.

💎 Concepto principal

Para crear un Personal Access Token: accede GitHub Settings → Developer settings → Personal access tokens → Fine-grained tokens. Selecciona los permisos necesarios: para nuestro proyecto, necesitamos acceso a repos e issues. El token generado debe almacenarse como variable de entorno (por ej.: GITHUB_TOKEN) y se envía mediante headers HTTP como Authorization: Bearer {token}. Nunca pongas el token directamente en el código fuente.

🚨 Alerta

¡NUNCA hagas commit de tokens en el repositorio! Si accidentalmente haces push de un token a GitHub, GitHub Secret Scanning lo revocará automáticamente, pero el daño ya podría estar hecho. Usa siempre variables de entorno, agrega .env a .gitignore, y nunca registres el valor del token en las salidas del servidor.

❌ Evitar
  • •Token codificado directamente en el código fuente
  • •Hacer commit del archivo .env en el repositorio
  • •Token con permisos excesivos (admin)
  • •Token sin fecha de expiración
✅ Hacer
  • •Almacenar el token en una variable de entorno
  • •Agregar .env a .gitignore
  • •Usar los ámbitos mínimos necesarios
  • •Definir una fecha de expiración para el token
3

📋 Tool: Listar repositorios

La primera tool de nuestro MCP Server GitHub será el listado de repositorios. Usando el endpoint GET /user/repos, buscaremos los repositorios del usuario autenticado, los filtraremos por visibilidad, los ordenaremos por fecha de actualización y daremos formato a los resultados para que Claude pueda presentarlos de forma legible al usuario.

💎 Concepto principal

La tool de listado de repositorios usa la biblioteca httpx para hacer requests asíncronos a la API de GitHub. El código esencial:

@server.tool()
async def list_repos(visibility: str = "all") -> str:
    """Lista repositórios do usuário autenticado."""
    async with httpx.AsyncClient() as client:
        resp = await client.get(
            "https://api.github.com/user/repos",
            headers={"Authorization": f"Bearer {GITHUB_TOKEN}"},
            params={"visibility": visibility, "sort": "updated"}
        )
        repos = resp.json()
    lines = []
    for r in repos:
        stars = r["stargazers_count"]
        lang = r.get("language", "N/A")
        lines.append(f"⭐ {stars} | {r['name']} ({lang}) — {r.get('description', 'Sem descrição')}")
    return "\n".join(lines)
💡 Consejo práctico

Formatea la salida de modo que el Claude pueda interpretar fácilmente. Incluye el nombre, la descripción, el lenguaje principal y el número de estrellas. Usa parámetros opcionales como visibility (all, public, private) para darle flexibilidad a Claude al consultar. El parámetro sort=updated garantiza que los repos más recientes aparezcan primero.

📋 Flujo de la tool list_repos
Paso 1

Claude recibe una solicitud del usuario ("lista mis repos") y llama a la tool list_repos con los parámetros adecuados.

Paso 2

El MCP Server hace GET /user/repos con el token de autenticación y recibe la lista de repositorios en JSON.

Paso 3

La tool da formato a los datos (nombre, descripción, lenguaje, stars) y devuelve texto estructurado para que Claude lo presente.

4

🔍 Tool: Buscar issues

La segunda tool permite buscar issues de un repositorio específico. Usando el endpoint GET /repos/{owner}/{repo}/issues, Claude podrá consultar issues abiertas o cerradas, filtrar por labels y presentar información relevante como número, título, autor y labels asignadas.

💎 Concepto principal

La tool de búsqueda de issues recibe owner (propietario del repo), repo (nombre del repositorio) y parámetros opcionales como state (open/closed/all) y labels (filtrar por etiquetas). El endpoint devuelve un array JSON donde cada issue contiene: number, title, user.login, state, labels[] e created_at. Da formato a la salida con número, título, autor y labels para facilitar la lectura.

❌ Evitar
  • •Devolver JSON sin procesar a Claude
  • •Ignorar el manejo de un repo inexistente
  • •No filtrar: devolver cientos de issues
  • •Mezclar issues y pull requests (los PR vienen en el mismo endpoint)
✅ Hacer
  • •Formatear la salida con #número, título y autor
  • •Manejar el 404 con un mensaje claro
  • •Limitar los resultados (ej.: max 30 issues)
  • •Filtrar PR verificando el campo "pull_request"
📊 Datos e investigación

Un detalle importante: el endpoint /repos/{owner}/{repo}/issues devuelve tanto issues como pull requests. Para filtrar solo issues reales, verifica si el campo pull_request falta en el objeto. La API admite paginación mediante los parámetros page e per_page (máximo de 100 por página).

5

➕ Tool: Crear issue

La tercera tool es la más poderosa — y la más peligrosa. Al usar POST /repos/{owner}/{repo}/issues, Claude podrá crear issues directamente en tu repositorio. Esta es una acción de escritura, lo que exige validar cuidadosamente los parámetros y ser conscientes de que estamos dando al modelo la capacidad de modificar datos reales.

💎 Concepto principal

La tool de creación de issues envía un POST con body JSON que contiene title (obligatorio) y body (descripción, opcional pero recomendada). Valida que el título no esté vacío y tenga una longitud razonable. Después de crearla, devuelve la URL de la issue creada para que el usuario pueda acceder directamente:

@server.tool()
async def create_issue(owner: str, repo: str, title: str, body: str = "") -> str:
    """Cria uma nova issue em um repositório GitHub."""
    if not title.strip():
        return "Erro: o título da issue não pode ser vazio."
    async with httpx.AsyncClient() as client:
        resp = await client.post(
            f"https://api.github.com/repos/{owner}/{repo}/issues",
            headers={"Authorization": f"Bearer {GITHUB_TOKEN}"},
            json={"title": title, "body": body}
        )
    if resp.status_code == 201:
        issue = resp.json()
        return f"Issue criada com sucesso! #{issue['number']}: {issue['html_url']}"
    return f"Erro ao criar issue: {resp.status_code}"
🚨 Alerta — Acción destructiva

Crear issues es una acción de escritura — modifica datos reales en tu GitHub. A diferencia de listar o buscar, esta tool tiene efectos secundarios permanentes. Considera agregar una confirmación antes de ejecutar la creación o, al menos, registrar cada issue creada. En un entorno corporativo, esta tool debe tener control de acceso riguroso y un audit trail completo.

💡 Consejo práctico

Siempre devuelve la URL del issue creado en la respuesta — esto permite que Claude le presente al usuario un enlace en el que pueda hacer clic. Valida los parámetros antes de enviar el request: título no vacío, owner y repo con el formato correcto. Considera agregar parámetros opcionales como labels e assignees para crear issues más completas.

6

🧪 Probando la integración

Con las tres tools implementadas —listar repos, buscar issues y crear issues—, es hora de probar la integración completa. Configura el server en Claude Desktop y prueba comandos en lenguaje natural para verificar que todo funcione correctamente. Claude debería poder elegir automáticamente la tool adecuada según tu solicitud.

💎 Concepto principal

Prueba con estos prompts en Claude Desktop:

  • →"Lista mis repositorios" — debe llamar a list_repos y mostrar nombre, lenguaje, stars
  • →"¿Qué issues abiertas hay en el repo X?" — debe llamar a search_issues con state=open
  • →"Crea una issue en el repo Y con el título Z" — debe llamar a create_issue y devolver la URL
  • →"¿Qué repos privados tengo?" — debe llamar a list_repos con visibility=private
📋 Escenario de prueba completo
Prueba 1 — Lectura

Pídele a Claude que liste tus repositorios. Verifica si los datos coinciden con lo que aparece en la interfaz web de GitHub.

Prueba 2 — Consulta

Pídele que busque issues en un repositorio real. Confirma que los números, títulos y labels sean correctos.

Prueba 3 — Escritura

Pídele que cree una issue de prueba. Verifica en GitHub si la issue se creó con el título y el cuerpo correctos.

Prueba 4 — Error

Pídele que busque issues en un repositorio que no existe. Verifica si el error se maneja correctamente.

❌ Evitar
  • •Probar solo el «camino feliz»
  • •Ignorar escenarios de error (repo inválido, sin permisos)
  • •No verificar si los datos devueltos son correctos
  • •Crear issues de prueba en repos de producción
✅ Hacer
  • •Probar todos los escenarios (éxito + error)
  • •Comprobar datos con la interfaz web
  • •Usar un repositorio de prueba para crear issues
  • •Probar con diferentes parámetros (filtros, visibilidad)

📝 Resumen del módulo

  • ✓ La API REST de GitHub en api.github.com proporciona endpoints para repositorios, issues y mucho más, y devuelve JSON.
  • ✓ Autenticación mediante un Personal Access Token almacenado en una variable de entorno; nunca en el código.
  • ✓ La tool list_repos usa GET /user/repos para listar repositorios con nombre, descripción, lenguaje y stars.
  • ✓ La tool search_issues usa GET /repos/{owner}/{repo}/issues para buscar y filtrar issues por estado y labels.
  • ✓ La tool create_issue usa POST para crear issues, valida los parámetros y devuelve la URL de la issue creada.
  • ✓ Las pruebas deben cubrir escenarios de éxito y error, usando repositorios de prueba para las acciones de escritura.

Siguiente Módulo: 4.5 — Combinando varios servidores