Model Context Protocol (MCP)
O Model Context Protocol (MCP) é um padrão aberto que padroniza a forma como aplicações de IA se comunicam com fontes de dados e ferramentas externas. Enquanto o Function Calling permite ao LLM invocar funções locais da aplicação, o MCP vai além: ele define um protocolo de comunicação que permite ao LLM interagir com servidores remotos de forma segura, bidirecional e agnóstica de linguagem.
Criado pela Anthropic e adotado amplamente pela comunidade, o MCP funciona como um “conector universal” entre agentes de IA e o ecossistema de ferramentas e dados ao redor. Um servidor MCP pode ser escrito em qualquer linguagem (Python, TypeScript, Java) e ser consumido por qualquer cliente MCP compatível.
Arquitetura MCP
A arquitetura do MCP é composta por dois papéis principais: o MCP Server e o MCP Client.
A imagem acima ilustra um exemplo concreto de agente MCP: a partir de um prompt do usuário, o AI Agent orquestra três ferramentas em sequência:
- City Extractor Tool: extrai o nome da cidade mencionada no prompt (executa localmente, usando o próprio LLM como ferramenta de extração).
- Geocoding Tool: converte o nome da cidade em coordenadas geográficas (latitude/longitude), consultando uma API externa.
- Weather Forecast Service: usa as coordenadas para buscar a previsão do tempo em uma API meteorológica remota.
O resultado de cada tool alimenta a próxima etapa, e o agente combina todas as informações para entregar a resposta final ao usuário. Esse encadeamento de ferramentas é exatamente o que o MCP padroniza: uma forma comum de expor e invocar ferramentas, locais ou remotas, de qualquer aplicação de IA.
┌─────────────────────────────────────────────────────────┐
│ Aplicação (MCP Client) │
│ │
│ AI Service ──── @McpToolBox ──── MCP Client │
│ │ │
└────────────────────────────────────────┼────────────────┘
│ HTTP/SSE
▼
┌───────────────────────┐
│ MCP Server (remoto) │
│ │
│ @Tool getForecast() │
│ @Tool getStocks() │
│ ... │
└───────────────────────┘
O fluxo de comunicação segue os mesmos princípios do Function Calling local, mas com a execução das ferramentas ocorrendo em um processo separado, potencialmente em outra máquina:
- O LLM recebe a lista de tools disponíveis no servidor MCP (via
@McpToolBox). - O LLM decide invocar uma tool e retorna uma tool call request.
- O MCP Client (na aplicação) transmite a requisição ao MCP Server via HTTP/SSE.
- O MCP Server executa a tool e retorna o resultado.
- O MCP Client repassa o resultado ao LLM.
- O LLM formula a resposta final ao usuário.
Criando um MCP Server com Quarkus
Dependências
Para criar um servidor MCP com Quarkus, adicione a extensão quarkus-mcp-server-sse e o REST Client para consumir APIs externas:
quarkus create app dev.langchain4j.quarkus.workshop:mcp-server:1.0-SNAPSHOT \
-x quarkus-mcp-server-sse \
-x quarkus-rest-client-jackson
Ou adicione as dependências manualmente ao pom.xml:
<dependency>
<groupId>io.quarkiverse.mcp</groupId>
<artifactId>quarkus-mcp-server-sse</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-rest-client-jackson</artifactId>
</dependency>
Definindo um REST Client
O servidor MCP pode chamar APIs externas para enriquecer as respostas. No exemplo do workshop, é criado um cliente REST que consulta previsões meteorológicas:
@Path("/v1/forecast")
@RegisterRestClient(configKey = "weatherclient")
public interface WeatherClient {
@GET
String getForecast(
@RestQuery double latitude,
@RestQuery double longitude,
@RestQuery int forecastDays,
@RestQuery String hourly
);
}
Definindo Tools no MCP Server
Assim como no Function Calling local, as tools do MCP Server são métodos Java anotados com @Tool. A diferença é que agora essas ferramentas ficam em um processo separado e são expostas remotamente via protocolo MCP:
public class Weather {
@RestClient
WeatherClient weatherClient;
@Tool(description = "Get weather forecast for a location.")
String getForecast(
@ToolArg(description = "Latitude of the location") double latitude,
@ToolArg(description = "Longitude of the location") double longitude) {
return weatherClient.getForecast(
latitude,
longitude,
16,
"temperature_2m,snowfall,rain,precipitation,precipitation_probability");
}
}
Note o uso de @ToolArg (em vez de apenas nomear o parâmetro) para fornecer ao LLM uma descrição semântica de cada argumento.
Configurando o MCP Server
No application.properties do servidor MCP:
# Porta diferente da aplicação cliente
quarkus.http.port=8081
# Identificação e logs do servidor MCP
quarkus.mcp.server.server-info.name=Weather Service
quarkus.mcp.server.traffic-logging.enabled=true
quarkus.mcp.server.traffic-logging.text-limit=100
# REST Client para a API meteorológica
quarkus.rest-client.logging.scope=request-response
quarkus.rest-client.follow-redirects=true
quarkus.rest-client.logging.body-limit=50
quarkus.rest-client."weatherclient".uri=https://api.open-meteo.com/
Configurando o MCP Client (aplicação principal)
Dependência
Na aplicação que consome o MCP Server, adicione a dependência:
<dependency>
<groupId>io.quarkiverse.langchain4j</groupId>
<artifactId>quarkus-langchain4j-mcp</artifactId>
</dependency>
Ou via CLI:
./mvnw quarkus:add-extension -Dextensions="quarkus-langchain4j-mcp"
Configuração do transporte
No application.properties da aplicação cliente, aponte para o servidor MCP:
quarkus.langchain4j.mcp.weather.transport-type=http
quarkus.langchain4j.mcp.weather.url=http://localhost:8081/mcp/sse/
O nome weather é o identificador do servidor MCP. Ele será referenciado na anotação @McpToolBox.
Configurando o AI Service com @McpToolBox
Para expor as tools do servidor MCP ao LLM, use a anotação @McpToolBox no AI Service:
@SessionScoped
@RegisterAiService
public interface CustomerSupportAgent {
@SystemMessage("""
You are a customer support agent of a car rental company 'Miles of Smiles'.
You are friendly, polite and concise.
If the question is unrelated to car rental, you should politely redirect
the customer to the right department.
When calling tools or functions, strictly use JSON objects,
do not wrap in quotes or use plain strings.
When asked to provide details about a reservation,
provide weather details and gently try to upsell the customer
based on this info.
Today is {current_date}.
""")
@ToolBox(BookingRepository.class)
@McpToolBox("weather")
String chat(String userMessage);
}
Dois pontos importantes:
@McpToolBox("weather"): referencia o servidor MCP pelo nome configurado emapplication.properties. O Quarkus LangChain4j descobre automaticamente as tools disponíveis no servidor e as inclui nas requisições ao LLM.@ToolBoxe@McpToolBoxpodem coexistir: é possível combinar tools locais (Function Calling) com tools remotas (MCP) no mesmo AI Service.
Function Calling Local vs. MCP
Ambas as abordagens permitem ao LLM executar ações além de responder perguntas. A escolha depende do contexto:
| Aspecto | Function Calling (@ToolBox) | MCP (@McpToolBox) |
|---|---|---|
| Localização | Execução local, dentro da aplicação | Execução remota, em servidor separado |
| Reusabilidade | Limitada à aplicação | Alta: qualquer cliente MCP pode usar |
| Linguagem | Java | Qualquer linguagem |
| Transporte | In-process | HTTP com SSE |
| Complexidade | Baixa | Moderada |
| Ideal para | Lógica de negócio própria | APIs externas, ferramentas compartilhadas |
As duas técnicas são complementares e podem ser combinadas no mesmo AI Service.
Referência
Quarkus LangChain4j Workshop, Step 08

CC BY 4.0 DEED