Um MCP Server é um servidor que implementa o Model Context Protocol (MCP) — um padrão criado pela Anthropic para conectar modelos de linguagem (LLMs) a ferramentas, dados e serviços externos de forma estruturada, segura e reutilizável. O MCP define como um LLM descobre, descreve e usa capacidades externas, como:
- APIs e microserviços
- Bancos de dados
- Sistemas internos (CRM, ERP, logs, etc.)
- Ferramentas (Git, Docker, Kubernetes, blockchain, etc.)
Resumindo e fazendo uma analogia, assim como o REST permite expor funcionalidades e dados do seu servidor para outras aplicações consumirem de forma padronizada, o MCP faz a mesma coisa mas para o consumo via LLMs. Ele serve para padronizar algo que antes era feito com plugins, function calling ou integrações ad-hoc. Pense nele como um “adaptador universal” entre as LLMs e outras aplicações e isso é possível graças ao conceito de tools (ferramentas), que seguindo a analogia, funcionam como se fossem os endpoints do servidor, mesmo conceito que expliquei outro dia no tutorial sobre agentes de IA.
Neste tutorial eu vou te ensinar a criar um primeiro servidor MCP, que vai expor funcionalidades de uma corretora de criptomoedas para que possam ser usadas por LLMs como Claude, ChatGPT e outros. No entanto, este é apenas um exemplo e o seu servidor MCP pode expor o que você quiser.
Se preferir, você pode acompanhar este tutorial pelo vídeo abaixo, o conteúdo é o mesmo.
Vamos lá!
#1 – Configurando o Projeto
O primeiro passo é garantir que você tenha o ambiente necessário para o projeto. Eu vou utilizar aqui a tecnologia Node.js. Também vou escrever os códigos utilizando o Visual Studio Code e vou versioná-los no GitHub. Precisando de auxílio para instalação de qualquer um destes itens, o vídeo abaixo cobre todos.

Além disso, vou utilizar a linguagem TypeScript neste tutorial, que é bem parecida com o JS tradicional. Caso você nunca tenha programado TS antes, este não é o melhor primeiro contato mas se souber bem JS, vai conseguir acompanhar. Querendo pegar uma base de TS, esta série aqui do site é o ideal e inclui vídeos.
Para os testes do nosso MCP Server vamos precisar de um MCP Client. Eu usarei o Claude Desktop da Anthropic para isso, então recomendo que baixe e instale ele na sua máquina também. Ele vai exigir autenticação depois de instalado, mas pode usar sua conta do Google para isso sem qualquer cadastro adicional.
Com o ambiente preparado, vamos começar criando a pasta do projeto, inicializando o mesmo, depois instalando e inicializando o TypeScript e por fim, instalando as dependências (que explicarei mais à frente), tudo com os comandos abaixo.
|
1 2 3 4 5 6 7 8 |
mkdir mcp-server-example cd mcp-server-example npm init -y npm i -D typescript @types/node npx tsc --init npm i @modelcontextprotocol/sdk zod axios |
As dependências que instalamos acima são:
- TypeScript: para suporte a TS em nosso projeto;
- @types/node: tipos básicos do Node para reconhecimento no TS;
- @modelcontextprotocol/sdk: biblioteca para criação de servidores MCP;
- zod: biblioteca para definição e verificação de tipos dos dados que serão usados nas tools do servidor;
- Axios: cliente HTTP para fazer às chamadas das tools;
Agora vamos criar um arquivo src/index.ts com um ‘olá mundo’ dentro e ajustar nosso package.json com o script de start usando o ts-node que instalamos antes. Aproveite e ajuste também o type do projeto para module, a fim de usar a sintaxe mais moderna.
|
1 2 3 4 5 6 |
"scripts": { "start": "node ./dist/index.js", "build": "npx tsc" }, |
E no tsconfig.json, ajuste as seguintes configurações para máxima compatibilidade com o código que vou ensinar:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
{ "compilerOptions": { "module": "ES2022", "target": "ES2022", "moduleResolution": "node", "esModuleInterop": true, "outDir": "dist", "types": [ "node" ], "sourceMap": true, "declaration": true, "declarationMap": true, "noUncheckedIndexedAccess": true, "exactOptionalPropertyTypes": true, "strict": true, "jsx": "react-jsx", "verbatimModuleSyntax": true, "isolatedModules": true, "noUncheckedSideEffectImports": true, "moduleDetection": "force", "skipLibCheck": true, } } |
Para testar, basta rodar npm run build e depois start no terminal e verá o seu ‘olá mundo’, bem como o terminal vai ficar aguardando por atualizações para se recarregar sozinho.
Com isso, temos tanto o ambiente quanto o projeto preparados para nosso tutorial.

#2 – Criando as MCP Tools
Nosso servidor MCP servirá para fornecer informações do mercado de criptomoedas para algum LLM local à sua escolha, sendo que vou usar o Claude Desktop como exemplo. Para obtenção dos dados vamos usar as APIs públicas da Binance, mais especificamente a API de resumo 24h de um par de moedas, cuja documentação oficial você encontra aqui. Portanto, a primeira coisa que vamos fazer é um módulo helper para acesso à essa API, usando o Axios e tipando corretamente, como abaixo, em um arquivo src/BinanceService.ts
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
import axios from "axios"; interface Binance24hTicker { symbol: string; lastPrice: string; priceChangePercent: string; } export async function fetch24hTicker(symbol: string): Promise<Binance24hTicker> { const response = await axios.get<Binance24hTicker>(`https://api.binance.com/api/v3/ticker/24hr?symbol=${symbol}`); return response.data; } |
Recomendo testar a URL utilizada diretamente no navegador antes de prosseguir, informando algum par de moedas que você conheça, como BTCUSDT (Bitcoin em Tether/USD).
Com o BinanceService pronto, é hora de criarmos as tools que usarão ele. Crie um arquivo src/BinanceTools.ts e comece pelas seguintes definições:
|
1 2 3 4 5 6 7 8 |
import { z } from "zod"; import { fetch24hTicker } from "./BinanceService.js"; const SymbolSchema = z.object({ symbol: z.string().describe("Par de negociação (ex: BTCUSDT)") }); |
Aqui fizemos a importação do zod e definição de um schema com apenas um parâmetro, symbol (string). Esse schema será usado logo mais adiante. Também fizemos o carregamento da função do BinanceService que vamos usar nas tools.
A primeira tool que vamos precisar é a getCurrentPrice, que você vê abaixo. Uma tool pode fazer qualquer coisa que você quiser, sendo que nesse exemplo vamos usar a API da Binance para pegar o último preço registrado para o symbol informado, mas poderíamos utilizar uma API sua, uma conexão direta no banco de dados, um processamento qualquer, etc. Repare no entanto que o return é padronizado no MCP como abaixo.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
export async function getCurrentPrice(args: any) { const { symbol } = SymbolSchema.parse(args); const data = await fetch24hTicker(symbol.toUpperCase()); return { content: [ { type: "text", text: `O preço atual do par ${data.symbol} é ${data.lastPrice}` } ] }; } |
Da mesma forma, vamos fazer a segunda tool, que traz a variação percentual nas últimas 24h:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
export async function get24hPriceChangePercent(args: any) { const { symbol } = SymbolSchema.parse(args); const data = await fetch24hTicker(symbol.toUpperCase()); return { content: [ { type: "text", text: `A variação percentual nas últimas 24h para ${data.symbol} é ${data.priceChangePercent}%` } ] }; } |
Por fim, precisamos criar uma função que retorne um array de tools, onde cada tool terá um nome único, uma descrição e o schema de input, ou seja, os parâmetros que ela precisa/espera, no formato do zod que criamos mais cedo.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
export function getTools() { return [ { name: "getCurrentPrice", description: "Retorna o preço atual de um par de moedas na Binance", inputSchema: SymbolSchema }, { name: "get24hPriceChangePercent", description: "Retorna a variação percentual nas últimas 24h", inputSchema: SymbolSchema } ] } |
É com base nesse array de tools que a LLM vai saber quais as tools você está fornecendo no seu servidor, para quê cada uma serve e como chamá-la. Falando em servidor MCP, é hora de criarmos ele.

#3 – Criando o MCP Server
Para criar o Servidor MCP em si, escreva em um arquivo src/MCPServer.ts, iniciando pelas importações abaixo que usaremos e explicarei mais adiante.
|
1 2 3 4 5 |
import { Server } from "@modelcontextprotocol/sdk/server/index.js"; import { ListToolsRequestSchema, CallToolRequestSchema } from "@modelcontextprotocol/sdk/types.js"; import { getCurrentPrice, get24hPriceChangePercent, getTools } from "./BinanceTools.js"; |
O primeiro passo é a inicialização do servidor MCP, vazio, como abaixo.
|
1 2 3 4 5 6 7 8 9 10 |
const server = new Server({ name: "binance-mcp-server", version: "1.0.0" }, { capabilities: { tools: {} } }); |
Todo servidor MCP possui uma lista de ferramentas que é solicitada pelo LLM para ele entender como pode utilizá-lo. Esse handler é chamado de List Tools Request e precisa ser implementada informando para cada ferramenta, seu nome, descrição e schema de entrada (input). Como já criamos uma função que retorna essas informações, basta chamarmos ela.
|
1 2 3 4 5 |
server.setRequestHandler(ListToolsRequestSchema, async () => { return { tools: getTools() }; }); |
Note que é apenas uma listagem de ferramentas, a chamada delas mesmo é nossa próxima missão definindo o handler Call Tool Request, que pode ser implementado de diversas maneiras onde dado um nome de tool, devemos chamar a função correta que importamos anteriormente do módulo BinanceTools.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
server.setRequestHandler(CallToolRequestSchema, async (request) => { const { name, arguments: args } = request.params; switch (name) { case "getCurrentPrice": return getCurrentPrice(args); case "get24hPriceChangePercent": return get24hPriceChangePercent(args); default: throw new Error(`Tool desconhecida: ${name}`); } }); export default server; |
Note que exportei o objeto server ao final do arquivo. Para usá-lo, devemos inicializar o servidor em nosso index.ts, como abaixo. Existem duas formas de subir um MCP Server, a forma local (StdIO) e a forma online (HTTP). Para uso com LLM local, como Claude Desktop, a forma StdIO é a mais indicada e rápida, mas em outras situações você pode precisar ajustar o código abaixo para HTTP.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import server from "./MCPServer.js"; async function main() { const transport = new StdioServerTransport(); await server.connect(transport); console.log("MCP Server running on stdio"); } main().catch((error) => { console.error("Fatal error in main():", error); process.exit(1); }); |
Agora rode o projeto com npm run build e depois start e…nada vai acontecer, exceto a mensagem no terminal, pois precisamos integrar um cliente MCP ao nosso servidor.
#4 – Testando o MCP Server
Agora que temos nosso servidor funcionando (ao menos subindo), podemos plugar ele em algum LLM. Como já citei antes, vou usar aqui o Claude Desktop e imagino que a essa altura do tutorial você já tenha ele instalado e funcionando na sua máquina. Com o Claude Desktop aberto, vá em Settings/Configurações > Developer/Desenvolvedor e mande editar as configurações, abrindo no VS Code.
|
1 2 3 4 5 6 7 8 9 10 11 12 |
{ "mcpServers": { "binance": { "command": "node", "args": [ "/Users/luiztools/NodeProjects/node-misc-examples/mcp-server-example/dist/index.js" ] } } } |
Nessa configuração nós damos o nome ao servidor de MCP e também o comando da sua inicialização, para que o Claude possa executar ele por conta própria quando necessário. Atenção especial aqui ao caminho até os arquivo de inicialização do ts-node-esm e do servidor (index.ts) que tem de ser ABSOLUTO, ou seja, completo. No meu caso estou em um Mac, por isso que o caminho começa em “/”, enquanto que em ambientes Windows ele vai começar provavelmente com “C://” ou algo do tipo.
Quer se certificar de que o Claude vai conseguir executar este comando? Abra uma janela de terminal fora do VS Code e rode o comando completo:
|
1 2 3 |
node <caminho-absoluto-ate-dist/index.js> |
Se funcionar em um terminal avulso, vai funcionar no Claude (muito provavelmente), apenas certifique-se de derrubar quaisquer processos do seu servidor de MCP para ter apenas o que o Claude vai subir.
Depois de editar o arquivo de configuração, salve e reinicie o Claude Desktop para que ele carregue as novas configurações. Caso você abra e ele não apresente erros, vá novamente em Settings > Developer e verifique se o servidor consta como rodando (imagem abaixo). Se você abrir o Claude novamente e avisar de erro ao carregar o servidor MCP, abra os logs e dê uma investigada no que pode ser.

Tudo estando certo, você pode perguntar o preço atual de algum par de moedas e se o servidor foi criado corretamente, o Claude vai te pedir permissão para executar a tool, como abaixo.

Ao dar a permissão, ele vai executar a função correta e te devolver o resultado, como abaixo.

Isso mostra que nosso servidor MCP está funcionando em conjunto com o Claude Desktop e que também vai funcionar com qualquer outro serviço compatível com MCP que rode local na sua máquina. Apenas atente-se ao fato de que como estamos usando um caminho literal para inicializar o servidor, você não pode movê-lo de pasta, ok?
Um abraço e até a próxima!

Olá, tudo bem?
O que você achou deste conteúdo? Conte nos comentários.
