Skip to content
Como Construir um serviço MCP para o seu site de blog

Construindo um Gerador de Posts para Blog com MCP, Nextra e LLMs

Updated on

Como construir um serviço MCP? Neste tutorial, vamos desenvolver um serviço MCP que permite que você escreva e publique artigos apenas conversando com OpenAI ou Claude.

Neste tutorial, criaremos uma solução técnica que permite conversar com um grande modelo de linguagem (LLM) e solicitar que ele gere conteúdo para seu blog baseado em Nextra. O conteúdo será escrito em MDX e automaticamente compromissoado ao repositório GitHub do seu blog como novos posts. Exploraremos duas implementações dessa integração Protocolo de Contexto de Modelo (MCP):

  1. Serverless via GitHub Actions: Usar um fluxo de trabalho do GitHub Actions para gerenciar todo o processo – invocando o LLM e comprometendo o artigo gerado.
  2. Hospedado via API Next.js: Implementar um servidor MCP simples como um endpoint de API do Next.js (usando o jojocys/nextra-agent-blog como exemplo de plataforma de blog) que atua como cliente MCP. Esse endpoint chamará o LLM e enviará novos posts ao GitHub em tempo real.

O MCP é um padrão aberto para conectar assistentes de IA a ferramentas e dados externos. Ele fornece uma interface universal para que modelos de IA interajam com sistemas como serviços em nuvem, bancos de dados – até plataformas como GitHub e Slack – sem necessidade de integração personalizada para cada ferramenta (Explicação do Protocolo de Contexto de Modelo (MCP) (opens in a new tab)). Em outras palavras, o MCP permite que agentes de IA usem “ferramentas” para realizar ações além de seu conhecimento base. Por exemplo, um assistente de IA poderia usar MCP para realizar tarefas como enviar e-mails, implantar mudanças no código ou publicar posts de blog (Construir e implantar servidores do Protocolo de Contexto de Modelo (MCP) na Cloudflare (opens in a new tab)). Aqui, nossa “ferramenta” será a capacidade de criar um novo arquivo MDX e comprometê-lo em um repositório Git (o blog).

Ao final deste guia, você terá uma configuração funcional onde você (como único usuário) poderá solicitar um artigo de blog a um agente de IA e tê-lo exibido automaticamente no seu site. Focaremos em como as peças se conectam (cliente MCP ↔︎ LLM e LLM ↔︎ GitHub) e consideraremos um cenário de usuário único, sem autenticação adicional.

Visão Geral da Solução

Antes de mergulhar no código, vamos delinear a arquitetura e o fluxo de trabalho:

  • Plataforma do Blog: Usamos um site em Next.js com o tema de blog Nextra (como o repositório jojocys/nextra-agent-blog) para hospedar nosso conteúdo. Posts são armazenados como arquivos MDX (Markdown com JSX) no repositório (por exemplo, na pasta pages/posts). O Nextra exibirá qualquer arquivo MDX nesta pasta como um post de blog, usando seus metadados (frontmatter: título, data, etc.) e conteúdo.

  • LLM (Assistente de IA): Usaremos um modelo de IA (por exemplo, GPT da OpenAI ou Claude da Anthropic) para gerar o conteúdo do post do blog. O modelo receberá um prompt (possivelmente via interface de chat ou API) descrevendo o artigo a ser escrito, produzindo uma resposta em formato MDX.

  • Cliente & Servidor MCP: Em termos de MCP, o LLM atua como um host que pode chamar ferramentas externas via uma interface cliente-servidor. Implementaremos uma configuração MCP mínima:

    • Na abordagem Serverless (GitHub Actions), o fluxo do GitHub Actions funciona como cliente MCP. Ele inicia a conversa com o LLM (host) e depois executa a “ferramenta de escrever post” comprometendo no repositório.
    • Na abordagem API Next.js, criaremos uma rota de API personalizada que atua como tanto cliente quanto servidor MCP para nosso repositório de blog (fornecendo a ferramenta de criar commits). Essencialmente, esse endpoint será uma ponte entre o LLM e o GitHub.
  • Integração com GitHub: Ambas as abordagens usarão a API do GitHub para adicionar o novo post ao repositório. Isso pode ser feito via operações Git diretas ou API HTTP do GitHub. Veremos exemplos de ambos. (Vale notar que o ecossistema MCP da Anthropic já inclui um conector pré-construído ao GitHub que suporta operações de repositório (GitHub - modelcontextprotocol/servers (opens in a new tab)), mas aqui aprenderemos construindo por conta própria.)

Com este contexto, começaremos pelo método serverless do GitHub Actions.

Abordagem 1: Gerador de Posts com GitHub Actions sem servidor

Nessa abordagem, usamos um fluxo de trabalho do GitHub Actions para gerar e publicar posts de blog sob demanda. Isso significa que você não precisa rodar servidor dedicado – o GitHub criará um runner para executar os passos sempre que acionado. O fluxo de trabalho fará:

  1. Disparo: Você (o usuário) aciona o fluxo (manual ou por evento de disparo no repositório) e fornece um prompt ou tópico para o post.
  2. Invocação do LLM: O fluxo chama a API do LLM (OpenAI ou Claude) com um prompt solicitando um post em MDX sobre o tópico.
  3. Criação do arquivo: Captura a resposta do LLM (o conteúdo MDX) e salva como um arquivo .mdx novo na pasta de posts do repositório, incluindo um frontmatter YAML (título, data, etc.).
  4. Commit no GitHub: O arquivo é comprometido e enviado ao branch principal, tornando o post ao vivo.

Vamos criar o arquivo de fluxo de trabalho. No seu repositório de blog (que usa Nextra), adicione em .github/workflows/llm-agent.yml:

name: Gerador de Posts do Blog com LLM
 
# Disparador manual
on:
  workflow_dispatch:
    inputs:
      prompt:
        description: "Tópico ou prompt para o post do blog"
        required: true
        type: string
 
permissions:
  contents: write  # permite push no repositório
 
jobs:
  gerar_post:
    runs-on: ubuntu-latest
    steps:
      - name: Checar repositório
        uses: actions/checkout@v3
 
      - name: Instalar jq
        run: sudo apt-get -y install jq
 
      - name: Gerar conteúdo do blog com OpenAI
        env:
          OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
        run: |
          echo "Prompt: ${{ github.event.inputs.prompt }}"
          REQUEST_DATA=$(jq -n --arg prompt "${{ github.event.inputs.prompt }}" '{
              "model": "gpt-3.5-turbo",
              "messages": [
                {"role": "system", "content": "Você é um assistente de blogs técnico. Escreva um post MDX com frontmatter YAML (título, data, descrição, tipo: posts) sobre o tópico fornecido."},
                {"role": "user", "content": $prompt}
              ]
            }')
          RESPONSE=$(curl -sS -H "Content-Type: application/json" \
                          -H "Authorization: Bearer $OPENAI_API_KEY" \
                          -d "$REQUEST_DATA" \
                          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 "Criando novo arquivo de post: $FILENAME"
          echo "$POST_CONTENT" > $FILENAME
 
      - name: Commitar e enviar
        run: |
          git config user.name "github-actions"
          git config user.email "github-actions@users.noreply.github.com"
          git add posts/*.mdx
          git commit -m "Post gerado pelo LLM"
          git push

Explicação rápida:

  • Disparo manual que recebe o tópico do usuário
  • Instala jq para processamento JSON
  • Chama a API do OpenAI com prompt customizado
  • Extrai o conteúdo MDX gerado
  • Cria um arquivo novo na pasta posts/ com timestamp
  • Faz commit e push

Assim, ao rodar este workflow e fornecer um prompt, o sistema gerará e publicará um novo post automaticamente.


Como usar na prática

Na aba Actions do seu repositório, escolha o fluxo "Gerador de Posts do Blog" e clique em "Run workflow". Insira o tópico desejado (exemplo: "Explicação de como usar MCP em Next.js") e execute. Após alguns instantes, o novo arquivo aparecerá na pasta posts/. Se seu blog estiver configurado para gerar páginas automaticamente (como com Vercel + Next.js), a nova postagem estará visível no site pouco tempo depois.

Segurança e limitações

  • O API Key do OpenAI deve estar armazenado em Segredos do repositório (OPENAI_API_KEY)
  • O pipeline push direto ao branch principal é simples, mas para segurança você pode modificar para criar pull requests, revisões, etc.
  • O conteúdo é gerado automaticamente e não passa por revisão humana – ajuste o prompt ou adicione moderação conforme necessário.
  • Para Claude ou outros modelos, basta trocar a API e o payload do passo correspondente.

Abordagem 2: Servidor MCP hospedado via API Next.js

Outra alternativa é criar uma rota de API no seu Next.js que funcione como um servidor MCP. Essa rota receberia uma solicitação de um prompt, acionaria o LLM para gerar o MDX, e comprometeria o arquivo no repositório GitHub — tudo sob demanda, com uma interface web ou chat.

Como fazer:

  1. Configure suas chaves de API (OPENAI_API_KEY, GITHUB_PAT) como variáveis de ambiente (.env.local)
  2. Crie uma API em pages/api/generate-post.js (ou no novo roteador app/api/...)
  3. No código, as funções que fazem a chamada ao LLM e ao GitHub serão similares às do exemplo acima, mas tudo em uma requisição HTTP.

Exemplo de implementação simples (Next.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: "Prompt não fornecido" });
  }
 
  try {
    const openaiConfig = new Configuration({ apiKey: process.env.OPENAI_API_KEY });
    const openai = new OpenAIApi(openaiConfig);
 
    const chatRes = await openai.createChatCompletion({
      model: "gpt-3.5-turbo",
      messages: [
        { role: "system", content: "Você é um assistente técnico que escreve posts MDX com frontmatter YAML para blogs." },
        { role: "user", content: prompt }
      ]
    });
 
    const mdx = chatRes.data.choices[0].message.content;
 
    // Opcional: extrair título do frontmatter para criar o nome do arquivo
    const titleMatch = mdx.match(/^title:\s*\"?(.+)\"?/m);
    const title = titleMatch ? titleMatch[1] : "sem-titulo";
    const slug = title.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "");
    const filename = `posts/${slug || "post"}-${Date.now()}.mdx`;
 
    // Se desejar, inserir data e tipo no frontmatter se não tiver
    let finalContent = mdx;
    if (!/^date:/.test(mdx)) {
      finalContent = finalContent.replace(/^title:.*$/m, `$&\ndate: ${new Date().toISOString()}`);
    }
    if (!/^type:/.test(mdx)) {
      finalContent = finalContent.replace(/^title:.*$/m, `$&\ntype: posts`);
    }
 
    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: `Post automatizado: "${title}"`,
      content: Buffer.from(finalContent).toString("base64"),
      committer: { name: "MCP", email: "mcp@example.com" },
      author: { name: "MCP", email: "mcp@example.com" }
    });
 
    res.status(200).json({ mensagem: "Post criado", arquivo: filename });
  } catch (err) {
    console.error(err);
    res.status(500).json({ erro: err.message });
  }
}

Como usar:

  • Faça uma requisição POST para /api/generate-post com JSON {"prompt": "Seu tema aqui"}
  • A API chamará o LLM, criará o arquivo MDX e o comprometerá no GitHub
  • O seu site se atualizará automaticamente ao reconhecer novo conteúdo

Vantagens:

  • Pode integrar com uma interface web onde você conversa ou insere prompts
  • Controla quando gerar/publicar o post
  • Flexível e facilmente ajustável

Conclusão

Criamos um sistema que conecta um modelo de IA a um repositório de conteúdo, permitindo que a IA gere posts automaticamente e publique-os no seu blog. Apresentamos:

  • Uma solução serverless usando GitHub Actions, ideal para automação simples e direta
  • Uma solução hospedada via API Next.js, útil para interações mais dinâmicas

Ambas exemplificam a ideia do MCP — uma interface padronizada para que IA possa interagir com sistemas externos, como seu blog.

Você pode adaptar e expandir esses exemplos: ajustar os prompts, acrescentar revisão humana, usar outros provedores de LLMs ou criar novos ferramentas MCP. Assim, seu assistente de IA pode fazer muito mais, além de publicar posts!

Fontes:

  1. Anthropic, Introducing the Model Context Protocol (MCP) – Padrão aberto para conexões de IA com sistemas externos (Lacoste, 2024 (opens in a new tab))
  2. Cloudflare, Levar MCP às massas – MCP permite ações como publicação de posts via ferramentas externas (Cloudflare Blog (opens in a new tab))
  3. Repositório de Servidores MCP — inclui um servidor GitHub para operações de repositório (file management, API do GitHub) (GitHub - modelcontextprotocol/servers (opens in a new tab))
📚