Após compreendermos o conceito no Guia sobre Model Context Protocol, é chegada a hora de colocarmos a mão na massa.
Seja provendo acesso ao seu banco de dados interno ou manipulando arquivos, a criação de um Servidor MCP personalizado confere "superpoderes" à sua IDE e aos seus LLMs favoritos. E a melhor maneira de iniciar hoje é por meio do Node.js com TypeScript.
Pré-requisitos e Instalação
Para construir a fundação, utilizaremos o SDK TypeScript Oficial do MCP.
Inicialize o seu projeto e instale o pacote principal:
npm init -y
npm install @modelcontextprotocol/sdk
Para um projeto moderno e escalável, recomendamos o formato ECMAScript Modules (ESM) no package.json e o TypeScript devidamente configurado (com tipos para NodeJS e ts-node ou build rápido via tsup/esbuild).
Estrutura Base de um Servidor MCP
A configuração inicial do seu arquivo server.ts envolverá injetar dados do seu projeto e lidar com os ciclos vitais (Transport). Pela nossa abordagem usaremos a conexão padrão recomendada para IDEs: o StdioServerTransport (transporte focado em terminal standard I/O).
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import {
ListToolsRequestSchema,
CallToolRequestSchema,
Tool,
} from "@modelcontextprotocol/sdk/types.js";
const server = new Server(
{
name: "meu-primeiro-mcp-server",
version: "1.0.0",
},
{
capabilities: {
tools: {}, // Habilitando Ferramentas Interativas Actions
prompts: {}, // (Opção) Habilitando Prompts e templates
resources: {} // (Opção) Habilitando extração de resources URIs
},
}
);
tools: {} na propriedade capabilities, caso contrário o SDK deduzirá que o seu servidor destina-se puramente a Prompts ou Resources, ignorando os callbacks de Tools.
Definindo sua Tool (Ferramenta IA)
Digamos que você quer permitir ao modelo de Inteligência Artificial consultar o clima em real-time a partir da sua infraestrutura. Para o LLM entender, você precisa usar a estrutura rígida de JSON Schema para declarar o formato (Tool Definition):
const WEATHER_TOOL: Tool = {
name: "get_internal_weather",
description: "Busca o alerta de tempestades atual do sensor privado do escritório.",
inputSchema: {
type: "object",
properties: {
location: {
type: "string",
description: "Local que a IA quer saber o clima ex: 'São Paulo', 'Data Center'",
},
},
required: ["location"],
},
};
Registrando os Handlers
O servidor não fará nada até você amarrar as "pontas": criar o handler dizendo pro SDK retornar a lista de ferramentas declaradas (List) e criar o executor lógico delas (Call). O uso da biblioteca zod é extremamente benéfico para injetar Typesafety durante o executor, embora não seja obrigatório.
// 1. O LLM descobrirá da sua existência pedindo a lista.
server.setRequestHandler(ListToolsRequestSchema, async () => {
return { tools: [WEATHER_TOOL] };
});
// 2. Quando o LLM decidir 'tocar' no método get_internal_weather
server.setRequestHandler(CallToolRequestSchema, async (request) => {
const { name, arguments: args } = request.params;
if (name === "get_internal_weather") {
// Garantimos e destruturamos o location do JSON injetado pela IA
const location = String(args?.location);
// Faça seu processamento de Backend Real, fetch na DB, etc.
const resultado = location === 'Data Center'
? "Tempestade na sala do Servidor: ALERTA CRÍTICO."
: `Previsão para ${location} é limpo.`
// Devolvemos o log para o modelo na estrutura nativa obrigatória
return {
content: [{ type: "text", text: resultado }],
};
}
throw new Error("Tool desconhecida pelo Servidor");
});
Iniciando o Transporte
A fase final consiste em atar o Stdio transport em uma coroutine (main), garantindo os logs via Error Output para você conseguir debugar o fluxo (já que a saída padrão console.log() do Stdio é sequestrada inteiramente para o tráfego JSON do MCP).
async function runServer() {
const transport = new StdioServerTransport();
await server.connect(transport);
// Imprimiremos em sys.stderr pra IDE não quebrar
console.error("🚀 MCP Server TypeScript inciado perfeitamente no Studio");
}
runServer().catch(console.error);
Adicionando na sua IDE (Cursor / Claude Desktop)
Faça o build ou instanciamento nativo usando TS-Node para gerar o executável final em seu ambiente local. Em seguida:
1. Para o Claude Desktop, edite o arquivo primário config:~/Library/Application Support/Claude/claude_desktop_config.json (Mac) ou %APPDATA%/Claude/claude_desktop_config.json (Windows).
2. Adicione os comandos para a inicialização no dict mcpServers:
{
"mcpServers": {
"weather_office": {
"command": "node",
"args": [
"C:/Seu/Projeto/build/server.js"
]
}
}
}
Reinicie o Desktop Client (ou o reload no Cursor) e você notará a get_internal_weather devidamente autorizada no chat.
A partir daqui, os seus agentes são irrestritos, possuindo total autonomia e visão analítica sobre tabelas no PostgreSQL da empresa e execuções profundas pelo File System, sob os limites da sua arquitetura Typescript.
