In this article
Como criar um MCP Server no Node.js para fornecer documentação atualizada da API
Se você está começando agora com vibe coding, conectando MCP Servers como integrações e explorando o universo da IA agentiva, está no lugar certo. Neste tutorial, vou mostrar como criar um MCP Server básico no Node.js usando o SDK oficial do Anthropic Model Context Protocol (MCP).
Um MCP Server para documentação atualizada da API do Node.js
Nosso MCP Server vai buscar a documentação no site oficial da API do Node.js (https://nodejs.org/api/) em formato JSON e disponibilizá-la como ferramentas que podem ser chamadas por clientes MCP, como os implementados no Claude Desktop, Cursor, Qodo e outros.
O runtime do Node.js recebe atualizações frequentes e oferece suporte a novos métodos e utilitários, mas os LLMs não são treinados com os dados mais recentes. Mesmo quando podem navegar na web, talvez optem por não fazer isso para responder a uma pergunta que já conseguem responder com os dados de treinamento — a menos que o aplicativo host, como o Cursor, tenha sido instruído especificamente a fazer essa busca.
Por isso, vamos criar um MCP Server que disponibiliza ferramentas dedicadas para cada módulo principal integrado do Node.js e para cada seção da estrutura da documentação da API, permitindo que os clientes MCP as chamem.

Arquivos do projeto MCP Server
Vamos começar com os arquivos básicos do projeto MCP Server, incluindo os metadados de dependências e outros dados em package.json:
{
"name": "mcp-server-nodejs-docs",
"version": "1.0.0",
"main": "index.js",
"type": "module",
"description": "A MCP server that provides documentation for Node.js core modules API",
"scripts": {
"start": "node index.js --debug"
},
"dependencies": {
"@modelcontextprotocol/sdk": "^1.11.0",
"pino": "^9.6.0",
"zod": "^3.24.4"
}
}Depois de criar o arquivo package.json com o conteúdo acima, execute npm install para instalar as dependências.
Inicializando um MCP Server no Node.js com o SDK do TypeScript
Em seguida, crie um arquivo index.js e insira o conteúdo a seguir:
#!/usr/bin/env node
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { initializeDocumentationServer } from './server/documentation-server.js';
// Create an MCP server
const server = new McpServer({
name: "Node.js API Documentation",
version: "1.0.0",
capabilities: {
resources: {},
tools: {},
},
});
// Initialize the server with Node.js API documentation
async function startServer() {
try {
await initializeDocumentationServer(server);
// Start receiving messages on stdin and sending messages on stdout
const transport = new StdioServerTransport();
await server.connect(transport);
} catch (error) {
console.error(`Fatal error during server initialization. Check logs for details.`);
process.exit(1);
}
}
// Start the server
startServer();O código acima começa com a sintaxe shebang UNIX do Node.js, #!/usr/bin/env node, que permite executar o arquivo diretamente pela linha de comando, por exemplo, com ./index.js. No entanto, isso não é obrigatório.
Em seguida, importamos a definição do MCP Server do SDK do TypeScript, o tipo de transporte STDIO e o código auxiliar que inicializa o servidor de documentação — vamos falar dele daqui a pouco. Depois, criamos o MCP Server e o conectamos ao tipo de transporte STDIO do processo.
Buscando dados e preparando ferramentas do MCP Server
O que há em ./server/documentation-server.js?
Veja como definir ferramentas para MCP Servers:
// Math tool to find the maximum of two numbers
server.tool(
"math-find-maximum-two-numbers",
{
number1: z.number(),
number2: z.number()
},
async ({ number1, number2 }) => ({
content: [{
type: "text",
text: Math.max(number1, number2))
}]
})
);No entanto, não queremos chamar manualmente essas funções server.tool() para cada módulo integrado do Node.js. Em vez disso, vamos percorrer todos eles de forma programática.
Para isso, primeiro precisamos obter a referência da documentação da API do Node.js como dados JSON.
Na função initializeDocumentationServer, recebemos a variável server (que é a instância do MCP Server) e podemos passá-la aos diferentes métodos que criam definições de ferramentas para o servidor.
import { fetchNodeApiDocs } from '../services/api-docs-service.js';
import { createModuleTool, createSearchTool, createListTool } from '../tools/documentation-tools.js';
export async function initializeDocumentationServer(server) {
const apiDocs = await fetchNodeApiDocs();
// Remove entries without Class or Method
const originalCount = apiDocs.modules?.length;
apiDocs.modules = apiDocs.modules.filter(module =>
module?.classes?.length > 0 || module?.methods?.length > 0
);
// Create tools for each module
apiDocs.modules.forEach(module => {
createModuleTool(server, module);
});
// Create search and list tools
createSearchTool(server, apiDocs.modules);
createListTool(server, apiDocs.modules);
}Para buscar a documentação da API do Node.js, veja a implementação da função fetchNodeAPIDocs no arquivo ../services/api-docs-service.js:
const url = 'https://nodejs.org/docs/latest/api/all.json';
export async function fetchNodeApiDocs() {
try {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status} ${response.statusText}`);
}
const data = await response.json();
return data;
} catch (error) {
// TODO later implement with logging etc
throw error;
}
}
export function findModuleByName(modules, searchName) {
const normalizedSearch = normalizeModuleName(searchName);
return modules.find(module =>
normalizeModuleName(module.name) === normalizedSearch ||
normalizeModuleName(module.textRaw) === normalizedSearch ||
(module.displayName && normalizeModuleName(module.displayName) === normalizedSearch)
);
}
export function normalizeModuleName(name) {
return name.toLowerCase().replace(/[_\s-]/g, '');
}Ao buscar a documentação, também disponibilizamos uma função que facilita encontrar módulos pelo nome e compará-lo com uma das propriedades e convenções de nomenclatura presentes no objeto JSON retornado pela URL https://nodejs.org/docs/latest/api/all.json.
Definição das ferramentas do MCP Server
Agora podemos processar programaticamente todos os módulos principais do Node.js a partir do arquivo JSON e expor cada um como uma ferramenta própria.
Veja a seguir o código de ./tools/documentation-tools.js, que inclui todas as funções referenciadas no arquivo documentation-server.js:
import { z } from "zod";
import { findModuleByName } from '../services/api-docs-service.js';
function createModuleDocumentation(module, { class: classQuery, method: methodQuery } = {}) {
let content = `# ${module.textRaw}\n\n`;
if (module.desc) {
content += `## Description\n${formatContent(module.desc)}\n\n`;
}
const formatItems = (items, title, query) => {
if (!items || items.length === 0) return '';
const filteredItems = query
? items.filter(item =>
item.textRaw.toLowerCase().includes(query.toLowerCase()) ||
(item.desc && item.desc.toLowerCase().includes(query.toLowerCase()))
)
: items;
if (filteredItems.length === 0) return '';
let sectionContent = `## ${title}\n\n`;
filteredItems.forEach(item => {
sectionContent += `### ${item.textRaw}\n`;
if (item.desc) sectionContent += `${formatContent(item.desc)}\n\n`;
});
return sectionContent;
};
content += formatItems(module.classes, 'Classes', classQuery);
content += formatItems(module.methods, 'Methods', methodQuery);
content += formatItems(module.modules, 'Submodules');
return content;
}
export function createModuleTool(server, module) {
const { name, textRaw } = module;
const toolName = `node-${name.toLowerCase().replace(/[^a-zA-Z0-9]/g, '-')}`;
server.tool(
toolName,
{
class: z.string().optional(),
method: z.string().optional()
},
async (params) => {
try {
const content = createModuleDocumentation(module, params);
return { content: [{ type: "text", text: content }] };
} catch (error) {
// TODO
throw error;
}
}
);
}
export function createSearchTool(server, modules) {
server.tool(
"node-search",
{ module: z.string().optional() },
async (params) => {
const moduleName = params?.module;
const foundModule = moduleName ? findModuleByName(modules, moduleName) : null;
if (!foundModule) {
let listContent = 'Available Node.js core modules and their methods:\n\n';
modules.forEach(module => {
listContent += formatModuleSummary(module);
});
return { content: [{ type: "text", text: listContent }] };
}
const content = createModuleDocumentation(foundModule);
return { content: [{ type: "text", text: content }] };
}
);
}
export function createListTool(server, modules) {
server.tool(
"node-list",
{},
async () => {
const content = formatModulesList(modules);
return { content: [{ type: "text", text: content }] };
}
);
}
function formatModuleSummary(module) {
let content = `## ${module.displayName || module.textRaw} (${module.name})\n`;
if (module.methods && module.methods.length > 0) {
content += `### Methods\n`;
module.methods.forEach(method => {
content += `- ${method.textRaw}\n`;
});
} else {
content += `_No methods found_\n`;
}
return content + '\n';
}
function formatModulesList(modules) {
const modulesList = modules.map(module => ({
name: module.name,
displayName: module.displayName || module.textRaw,
description: module.desc || 'No description available'
}));
return `# Available Node.js Modules\n\n${modulesList.map(m =>
`## ${m.displayName}\n*Name:* ${m.name}\n*Description:* ${formatContent(m.description)}\n`
).join('\n')}`;
}
export function formatContent(content) {
if (!content) return '';
return content.replace(/\n/g, '\n\n');
}Depurando o MCP Server do Node.js com o MCP Inspector
Para verificar se o servidor está funcionando corretamente e entender como são as definições das ferramentas, podemos usar o MCP Inspector da Anthropic.
Adicione o conteúdo a seguir à propriedade scripts do arquivo package.json:
{
"scripts": {
"debug": "npx @modelcontextprotocol/inspector node index.js --debug"
}
}Em seguida, instale o pacote npm da Anthorpic @modelcontextprotocol/inspector como dependência de desenvolvimento do projeto:
npm install @modelcontextprotocol/inspector --save-devPor fim, vamos iniciar o MCP Inspector executando o seguinte comando:
npm run debugAcesse o endereço do MCP Inspector para ver todas as ferramentas expostas e suas definições:

O que vem a seguir para os MCP Servers?
O código-fonte completo de um MCP Server funcional para a documentação da API do Node.js está disponível neste repositório do GitHub: https://github.com/snyk-labs/mcp-server-nodejs-api-docs. Ele está atualizado e também inclui registros e recursos expostos do MCP Server, com exemplos mais avançados de como criar MCP Servers.
Se você está procurando MCP Servers para conectar, não deixe de conhecer as barreiras de proteção de segurança de IA da Snyk com Snyk apresentando um MCP Server, parte da Snyk CLI. Assim, você pode adotar uma abordagem mais proativa para vibe coding e para criar aplicações com assistentes de programação com IA.
Use a Snyk para auditar o código do seu assistente de programação com IA generativa quando essas ferramentas sugerirem código e dependências de código aberto. É simples assim:
snyk mcp -t stdio --experimentalE não se esqueça: instalar e conectar MCP Servers pode trazer riscos de segurança, executar código arbitrário e causar outros problemas.
Inscreva-se no Snyk API & Web
Comece hoje mesmo a usar nosso mecanismo DAST desenvolvido para devs
Encontre e exponha vulnerabilidades automaticamente em escala com o mecanismo DAST baseado em IA da Snyk. Antecipe a segurança com automação e orientações para correção que se integram perfeitamente ao seu SDLC.