ROTA · 6 CLASSES · 1 GRUPOS
Servidor MCP em Go
Implemente protocolo, capacidades, ferramentas, recursos e testes de um servidor MCP.
Pré-requisitos orientam, mas nunca bloqueiam. Cinco classes fundamentais e o bônus Go 1.27 são grátis com conta.O ARCO DA ROTA
ORDEM RECOMENDADA
6 classes, do primeiro passo ao fechamento.
Cada classe leva cerca de 15–25 minutos no novo formato de slides. Você pode sair da ordem quando outro nó fizer mais sentido.
- 01Servidor MCP em GoO protocolo: mensagens JSON-RPC pela entrada padrão
JSON-RPC 2.0, IDs, notificações e o enquadramento por linha.
- 02Servidor MCP em GoHandshake e capabilities: negocie antes de servir
initialize, versão negociada e anúncio honesto de capabilities.
- 03Servidor MCP em GoExpondo tools: descreva, valide e execute ações
tools/list, tools/call e resultados estruturados sem efeitos escondidos.
- 04Servidor MCP em GoExpondo resources: ofereça contexto por URI
resources/list, resources/read, MIME type e URI estável.
- 05Servidor MCP em GoTestando seu servidor MCP em memória
sessões determinísticas com strings.Reader, bytes.Buffer e falhas observáveis.
- 06Servidor MCP em GoCapstone: servidor MCP completo para demonstrar
um servidor de catálogo com handshake, tool, resource e transporte em memória.
PRÉVIA DA PRIMEIRA CLASSE
O protocolo: mensagens JSON-RPC pela entrada padrão
scanner := bufio.NewScanner(input) // uma linha = uma mensagem
encoder := json.NewEncoder(output)
for scanner.Scan() {
var request struct {
ID json.RawMessage `json:"id"`
}
json.Unmarshal(scanner.Bytes(), &request)
if len(request.ID) == 0 { continue } // sem id: notificação silenciosa
encoder.Encode(map[string]any{"jsonrpc": "2.0", "id": request.ID})
}
Pense em duas pessoas passando fichas por uma abertura estreita. Cada ficha precisa dizer qual regra segue, qual trabalho pede e, quando houver resposta, qual número permite associar pergunta e retorno. Se uma ficha vier cortada ao meio ou duas forem coladas, o receptor não sabe onde uma termina. Um servidor MCP por entrada e saída padrão enfrenta exatamente essa fronteira: recebe mensagens JSON-RPC 2.0 completas, uma por linha, e escreve mensagens completas sem misturar diagnóstico.
JSON-RPC é o envelope, não o catálogo MCP. O campo jsonrpc fixa a versão "2.0"; method nomeia a operação; params carrega argumentos; id correlaciona uma requisição com sua resposta. MCP define métodos e formatos dentro desse envelope. Essa separação ajuda a diagnosticar: JSON quebrado é erro de parse, método desconhecido é erro de JSON-RPC e argumentos inválidos pertencem à operação.
Uma mensagem com id é requisição e exige resposta. Uma mensagem sem id é notificação e não recebe resposta, inclusive quando o processamento falha. O valor zero é um ID válido; testar id == 0 para reconhecer notificação perde requisições reais. Em Go, json.RawMessage preserva número ou string e permite distinguir ausência pelo comprimento.
No transporte stdio do MCP, cada mensagem ocupa uma linha e não pode conter quebra de linha embutida. json.Encoder.Encode acrescenta o delimitador; bufio.Scanner encontra cada entrada. O stdout pertence ao protocolo. Um fmt.Println de depuração nesse writer vira uma falsa mensagem e derruba o cliente; diagnósticos devem ir a stderr em um binário real.
Antes de executar, preveja quantas linhas aparecem na saída e quais IDs voltam. Depois troque o ID numérico por "req-a" e confirme que ele permanece string. Faça mais duas mudanças: acrescente uma notificação sem id e injete uma linha JSON inválida entre duas requisições. Explique por que a notificação não cria resposta e por que o erro de parse usa null.
package main
import (
"bufio"
"bytes"
"encoding/json"
"fmt"
"strings"
)
func main() {
input := strings.NewReader("{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"ping\"}\n")
scanner := bufio.NewScanner(input)
var output bytes.Buffer
encoder := json.NewEncoder(&output)
for scanner.Scan() {
var message map[string]any
if json.Unmarshal(scanner.Bytes(), &message) == nil {
encoder.Encode(map[string]any{"jsonrpc": "2.0", "id": message["id"], "result": map[string]any{}})
}
}
fmt.Print(output.String())
}
Este programa reduz o transporte ao seu núcleo observável. Os tipos preservam o ID bruto e impedem que a camada de domínio precise conhecer scanner ou delimitador.
Os imports cobrem enquadramento, JSON e uma demonstração em memória.
Entre para continuar nos slides, rodar o código e enfrentar os desafios.
Começar pela rota →ESTA ROTA E TODAS AS OUTRAS
Qualquer plano abre os 192 nós.
Mensal R$19,90 · anual R$149 · lifetime R$499. Todos têm garantia de 7 dias.