Skip to content
Cómo construir un servicio MCP para tu sitio de blog

Creando un generador de publicaciones de blog impulsado por MCP con Nextra y LLMs

Updated on

¿Cómo construir un servicio MCP? En este tutorial, crearemos un servicio MCP que te permitirá escribir y publicar artículos simplemente chateando con OpenAI o Claude.

En este tutorial, crearemos una solución técnica que te permitirá chatear con un gran modelo de lenguaje (LLM) y pedirle que genere contenido para tu blog basado en Nextra. El contenido será escrito en MDX y se comprometerá automáticamente en el repositorio de GitHub de tu blog como nuevas publicaciones. Exploraremos dos implementaciones de esta integración de Protocolo de Contexto del Modelo (MCP):

  1. Serverless vía GitHub Actions: Usa un flujo de trabajo de GitHub Actions para manejar todo el proceso: invocar al LLM y confirmar la publicación generada.
  2. Hospedado vía API de Next.js: Implementa un servidor MCP simple como un endpoint API de Next.js (usando el ejemplo jojocys/nextra-agent-blog) que actúe como cliente MCP. Este endpoint llamará al LLM y enviará nuevas publicaciones a GitHub en tiempo real.

MCP es un estándar abierto para conectar asistentes de IA con herramientas y datos externos. Proporciona una interfaz universal para que los modelos IA interactúen con sistemas como servicios en la nube, bases de datos — incluso plataformas como GitHub y Slack — sin necesidad de integraciones personalizadas para cada herramienta (Explicación del Protocol de Contexto del Modelo (MCP) (opens in a new tab)). En otras palabras, MCP permite que los agentes IA usen “herramientas” para realizar acciones más allá de su conocimiento base. Por ejemplo, un asistente IA podría usar MCP para tareas como enviar correos, desplegar cambios en código o publicar publicaciones de blog (Construye y despliega servidores remotos del Protocolo de Contexto del Modelo (MCP) (opens in a new tab)). Aquí, nuestra “herramienta” será la habilidad de crear un nuevo archivo MDX y confirmarlo en un repositorio Git (el blog).

Al finalizar esta guía, tendrás un sistema operativo donde tú (como único usuario) podrás solicitar a un agente IA un artículo de blog y que aparezca automáticamente en tu sitio. Nos enfocaremos en cómo se conectan las partes (cliente MCP ↔︎ LLM y LLM ↔︎ GitHub) y asumiremos un escenario de usuario único sin autenticación adicional.

Visión general de la solución

Antes de sumergirnos en el código, definamos la arquitectura y el flujo de trabajo:

  • Plataforma de blog: Usamos un sitio Next.js con el tema “blog” de Nextra (por ejemplo, en el repositorio jojocys/nextra-agent-blog) para alojar nuestro contenido. Las publicaciones se almacenan como archivos MDX (Markdown con JSX) en el repositorio (por ejemplo, en un directorio pages/posts). Nextra mostrará cualquier archivo MDX en esta carpeta como una publicación de blog, usando su frontmatter (título, fecha, etc.) y contenido.

  • LLM (Asistente de IA): Utilizaremos un modelo de IA (por ejemplo, GPT de OpenAI o Claude de Anthropic) para generar contenido de publicaciones. El modelo recibe un prompt (posiblemente mediante una interfaz de chat o llamada API) describiendo qué artículo escribir, y produce un artículo en formato MDX en respuesta.

  • Cliente y Servidor MCP: En términos de MCP, el LLM actúa como un host que puede invocar herramientas externas mediante una interfaz cliente-servidor. Implementaremos una configuración MCP mínima:

    • En el enfoque Serverless, el flujo de trabajo de GitHub Actions actúa como cliente MCP. Inicia la conversación con el LLM (host) y luego ejecuta la “herramienta de escribir post” confirmando en el repo.
    • En el enfoque API de Next.js, crearemos una ruta API personalizada que funcione como cliente y servidor MCP para nuestro repo del blog (proporcionando la herramienta para crear commits). Es decir, este endpoint será el puente entre el LLM y GitHub.
  • Integración con GitHub: Ambos enfoques usarán la API de GitHub para añadir el nuevo post en el repositorio. Esto puede hacerse mediante operaciones directas con Git o usando la API HTTP de GitHub. Veremos ejemplos de cada uno. (Vale la pena mencionar que el ecosistema MCP de Anthropic ya incluye un conector preconstruido para GitHub, que soporta operaciones en repositorios (GitHub - modelcontextprotocol/servers (opens in a new tab): sistemas de archivos, bases de datos con inspección de esquema), pero aquí aprenderemos a construirlo nosotros mismos).

Con esto en mente, empezamos con el método serverless usando GitHub Actions.

Enfoque 1: Generación serverless de posts con GitHub Actions

En este método, usamos un flujo de trabajo de GitHub Actions para generar y publicar publicaciones bajo demanda. Esto evita que tengas que correr un servidor dedicado: GitHub dispersa un runner que ejecuta los pasos cuando se dispara. El flujo realiza estos pasos:

  1. Disparo: Tú (el usuario) disparas el flujo (ej. manualmente o mediante repository_dispatch) y proporcionas un prompt o tema para la publicación.
  2. Invocación LLM: El flujo llama al modelo (por ejemplo OpenAI o Claude) con un prompt solicitando un post MDX sobre el tema indicado.
  3. Creación del archivo: Captura la respuesta del LLM (el contenido MDX) y lo guarda en un nuevo archivo .mdx en el repo del blog, incluyendo un frontmatter YAML (título, fecha, etc.).
  4. Confirmar en GitHub: El archivo nuevo se confirma y empuja al branch principal, haciendo que la publicación esté en vivo.

Creamos el archivo de flujo de trabajo. En tu repo de blog (el que usa Nextra), añade .github/workflows/llm-agent.yml con:

name: Generador de Posts de Blog con LLM
 
# Disparo manual
on:
  workflow_dispatch:
    inputs:
      prompt:
        description: "Tema o prompt para la publicación del blog"
        required: true
        type: string
 
permissions:
  contents: write  # permisos para pushing
 
jobs:
  generate_post:
    runs-on: ubuntu-latest
    steps:
      # Paso 1: Clonar el repo
      - name: Check out repo
        uses: actions/checkout@v3
 
      # Paso 2: Instalar jq (procesar JSON)
      - name: Instalar jq
        run: sudo apt-get -y install jq
 
      # Paso 3: Llamar API del LLM para generar contenido
      - name: Generar contenido con OpenAI
        env:
          OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
        run: |
          echo "Prompt: ${{ github.event.inputs.prompt }}"
          REQUEST=$(jq -n --arg prompt "${{ github.event.inputs.prompt }}" '{
              "model": "gpt-3.5-turbo",
              "messages": [
                {"role": "system", "content": "Eres un asistente técnico para blogs. Escribe un post MDX con frontmatter YAML (título, fecha, descripción, tipo: posts) sobre el tema dado."},
                {"role": "user", "content": $prompt}
              ]
            }')
          RESPONSE=$(curl -sS -H "Content-Type: application/json" \
                          -H "Authorization: Bearer $OPENAI_API_KEY" \
                          -d "$REQUEST" \
                          https://api.openai.com/v1/chat/completions)
          POST_CONTENT=$(echo "$RESPONSE" | jq -r '.choices[0].message.content')
          TIMESTAMP=$(date +"%Y-%m-%d-%H%M")
          FILENAME="posts/llm-post-$TIMESTAMP.mdx"
          echo "Creando archivo: $FILENAME"
          echo "$POST_CONTENT" > $FILENAME
 
      # Paso 4: Confirmar y subir
      - name: Confirmar cambios
        run: |
          git config user.name "github-actions"
          git config user.email "github-actions@users.noreply.github.com"
          git add posts/*.mdx
          git commit -m "Agregar nuevo post generado por LLM"
          git push

Este flujo realiza:

  • Disparo manual, con entrada prompt.
  • Clona el repo y prepara el entorno.
  • Llama a la API de OpenAI con instrucciones similares a las del ejemplo anterior: genera contenido MDX con frontmatter.
  • Escribe la respuesta en un archivo MDX nuevo en posts/.
  • Hace commit y push para publicar.

Luego de ejecutarlo, tendrás en tu repo un nuevo archivo MDX con contenido generado. Si tu sitio usa despliegue automático, el post estará visible en tu blog. Puedes probar desde la pestaña Actions en GitHub, ejecutando el flujo con un tema.

Nota: también puedes usar la API de Claude en lugar de OpenAI: solo cambia la llamada API y el endpoint. La lógica es similar.


Enfoque 2: Servidor MCP hospedado vía API de Next.js

En esta alternativa, creamos una API en Next.js que implementa la lógica MCP: recibe una petición (con un prompt o instrucciones), invoca al LLM para generar MDX, y luego confirma en GitHub. Así, tienes una interfaz web interactiva para pedir posts y actualizar tu blog en vivo.

Para esto, tu Next.js necesita acceso a GitHub. Generalmente, añades una variable de entorno GITHUB_PAT con un token con permisos de escritura. También necesitas tus claves API de LLM.

Ejemplo en pages/api/generate-post.js:

import { Octokit } from "@octokit/rest";
import { Configuration, OpenAIApi } from "openai";
 
export default async function handler(req, res) {
  const { prompt } = req.body;
  if (!prompt) {
    return res.status(400).json({ error: "Falta el prompt" });
  }
 
  try {
    // API de OpenAI
    const openai = new OpenAIApi(new Configuration({ apiKey: process.env.OPENAI_API_KEY }));
    const response = await openai.createChatCompletion({
      model: "gpt-3.5-turbo",
      messages: [
        { role: "system", content: "Eres un asistente técnico para blogs. Escribe un post MDX con frontmatter YAML (título, fecha, descripción, tipo: posts) sobre el tema dado." },
        { role: "user", content: prompt }
      ]
    });
    const mdx = response.data.choices[0].message.content;
 
    // Extraer título y formar slug
    const matchTitle = mdx.match(/^title:\s*\"?(.+)\"?/m);
    const title = matchTitle ? matchTitle[1] : "sin-titulo";
    const slug = title.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "");
    const dateStr = new Date().toISOString();
    const filename = `posts/${slug || "post"}-${Date.now()}.mdx`;
 
    // Añadir frontmatter fechas si falta
    let finalMDX = mdx;
    if (!/^date:/m.test(mdyx)) {
      finalMDX = `date: ${dateStr}\n` + finalMDX;
    }
    if (!/^type:\s*posts/m.test(finalMDX)) {
      finalMDX = finalMDX.replace(/^title:\s*.*$/m, `$&\ntype: posts`);
    }
 
    // Usar Octokit para guardar en GitHub
    const octokit = new Octokit({ auth: process.env.GITHUB_PAT });
    await octokit.rest.repos.createOrUpdateFileContents({
      owner: process.env.GITHUB_REPO_OWNER,
      repo: process.env.GITHUB_REPO_NAME,
      path: filename,
      message: `Crear publicación "${title}" vía MCP`,
      content: Buffer.from(finalMDX, "utf-8").toString("base64"),
      committer: {
        name: "MCP Bot",
        email: "mcp-bot@example.com"
      },
      author: {
        name: "MCP Bot",
        email: "mcp-bot@example.com"
      }
    });
 
    res.status(200).json({ mensaje: "Post creado", filename });
  } catch (err) {
    console.error("Error:", err);
    res.status(500).json({ error: err.message });
  }
}

Con esto, puedes solicitar desde tu interfaz web o desde un cliente REST que te genere una publicación en tu repositorio. Automáticamente, el artículo aparecerá en tu blog tras el despliegue.


Resumen

Hemos visto dos maneras de conectar un modelo IA con tu blog usando MCP:

  • Serverless con GitHub Actions: dispara automáticamente la generación de posts, sin mantener un servidor propio.
  • API personalizada en Next.js: interacción en tiempo real para crear posts desde tu página web o app.

Ambas opciones muestran cómo los estándares MCP permiten que la IA no solo responda preguntas, sino que también realice acciones en sistemas externos con un protocolo uniforme. Es un ejemplo concreto de cómo expandir las capacidades de los modelos IA.

Elige la opción que mejor se adapte a tu flujo de trabajo y necesidades, o combínalas para aprovechar lo mejor de ambos mundos. ¡Felices publicaciones con tu colaboración IA!


Recursos adicionales

📚