UNPKG

topic-scout-mcp

Version:

MCP Server para buscar notícias e identificar tendências sobre tópicos específicos

537 lines (449 loc) 12.2 kB
# 🚀 Guia Completo: Como Criar um MCP Server Este guia mostra como criar um servidor MCP (Model Context Protocol) do zero, usando o exemplo do Weather Brazil Server que acabamos de criar. ## 📋 O que é MCP? MCP (Model Context Protocol) é um protocolo que permite que o Claude Desktop se conecte a servidores externos para acessar ferramentas e dados específicos. É como uma "ponte" entre o Claude e sistemas externos. ## 🎯 Estrutura do Projeto ``` meu-mcp-server/ ├── src/ │ └── index.ts # Código principal do servidor ├── dist/ # Arquivos compilados (gerado automaticamente) ├── package.json # Dependências e scripts ├── tsconfig.json # Configuração TypeScript ├── mcp-config.json # Configuração para Claude Desktop ├── README.md # Documentação └── .gitignore # Arquivos ignorados pelo Git ``` ## 📦 Passo 1: Inicializar o Projeto ### 1.1 Criar estrutura de pastas ```bash mkdir meu-mcp-server cd meu-mcp-server mkdir src ``` ### 1.2 Inicializar package.json ```bash npm init -y ``` ### 1.3 Editar package.json ```json { "name": "meu-mcp-server", "version": "1.0.0", "description": "Descrição do seu MCP server", "main": "dist/index.js", "type": "module", "scripts": { "build": "tsc", "start": "node dist/index.js", "dev": "tsx src/index.ts" }, "dependencies": { "@modelcontextprotocol/sdk": "^0.4.0" }, "devDependencies": { "@types/node": "^20.0.0", "tsx": "^4.0.0", "typescript": "^5.0.0" }, "keywords": ["mcp", "seu-dominio"], "author": "Seu Nome", "license": "MIT" } ``` ## ⚙️ Passo 2: Configurar TypeScript ### 2.1 Criar tsconfig.json ```json { "compilerOptions": { "target": "ES2022", "module": "ESNext", "moduleResolution": "node", "outDir": "./dist", "rootDir": "./src", "strict": true, "esModuleInterop": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true, "declaration": true, "declarationMap": true, "sourceMap": true }, "include": ["src/**/*"], "exclude": ["node_modules", "dist"] } ``` ### 2.2 Instalar dependências ```bash npm install npm install -g typescript # Se necessário ``` ## 🔧 Passo 3: Criar o Servidor MCP ### 3.1 Estrutura básica do servidor ```typescript // src/index.ts import { Server } from "@modelcontextprotocol/sdk/server/index.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js"; class MeuMCPServer { private server: Server; constructor() { // Inicializar servidor MCP this.server = new Server({ name: "meu-mcp-server", version: "1.0.0", }); this.setupToolHandlers(); } private setupToolHandlers() { // 1. Listar ferramentas disponíveis this.server.setRequestHandler(ListToolsRequestSchema, async () => { return { tools: [ { name: "minha_ferramenta", description: "Descrição da sua ferramenta", inputSchema: { type: "object", properties: { // Parâmetros da sua ferramenta parametro1: { type: "string", description: "Descrição do parâmetro", }, }, required: ["parametro1"], }, }, ], }; }); // 2. Executar ferramentas this.server.setRequestHandler(CallToolRequestSchema, async (request) => { const { name, arguments: args } = request.params; if (name === "minha_ferramenta") { return await this.executarMinhaFerramenta(args); } throw new Error(`Ferramenta desconhecida: ${name}`); }); } private async executarMinhaFerramenta(args: any): Promise<any> { // Lógica da sua ferramenta aqui const { parametro1 } = args; // Exemplo de resposta return { content: [ { type: "text", text: `Resultado da sua ferramenta com parâmetro: ${parametro1}`, }, ], }; } async run() { const transport = new StdioServerTransport(); await this.server.connect(transport); console.error("🚀 Meu MCP Server iniciado"); } } // Executar o servidor const server = new MeuMCPServer(); server.run().catch(console.error); ``` ## 🔑 Passo 4: Adicionar Configurações (se necessário) ### 4.1 Variáveis de ambiente ```typescript // No construtor da classe constructor() { this.server = new Server({ name: "meu-mcp-server", version: "1.0.0", }); // Obter configurações do ambiente this.apiKey = process.env.MINHA_API_KEY || ""; if (!this.apiKey) { console.error("⚠️ MINHA_API_KEY não encontrada no ambiente"); } this.setupToolHandlers(); } ``` ### 4.2 Tratamento de erros ```typescript private async executarMinhaFerramenta(args: any): Promise<any> { try { // Sua lógica aqui return { content: [ { type: "text", text: "✅ Sucesso!", }, ], }; } catch (error) { return { content: [ { type: "text", text: `❌ Erro: ${error instanceof Error ? error.message : "Erro desconhecido"}`, }, ], }; } } ``` ## 🏗️ Passo 5: Compilar e Testar ### 5.1 Compilar ```bash npm run build ``` ### 5.2 Criar script de teste ```javascript // test-server.js import { spawn } from 'child_process'; import { fileURLToPath } from 'url'; import { dirname, join } from 'path'; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); console.log('🧪 Testando MCP Server...\n'); const server = spawn('node', [join(__dirname, 'dist', 'index.js')], { stdio: ['pipe', 'pipe', 'pipe'], env: process.env }); setTimeout(() => { console.log('✅ Servidor iniciado com sucesso!'); server.kill(); process.exit(0); }, 2000); server.stderr.on('data', (data) => { console.log('📋 Logs:', data.toString()); }); server.on('error', (error) => { console.error('❌ Erro:', error); process.exit(1); }); ``` ### 5.3 Testar ```bash node test-server.js ``` ## ⚙️ Passo 6: Configurar para Claude Desktop ### 6.1 Criar arquivo de configuração MCP ```json // mcp-config.json { "mcpServers": { "meu-server": { "command": "node", "args": ["/caminho/completo/para/seu/projeto/dist/index.js"], "env": { "MINHA_API_KEY": "sua_chave_aqui" } } } } ``` ### 6.2 Configurar no Claude Desktop 1. Abra o Claude Desktop 2. Vá em **Settings** > **MCP Configuration** 3. Adicione o caminho para o arquivo `mcp-config.json` 4. Adicione a ferramenta: `mcp__meu-server__minha_ferramenta` ## 📝 Passo 7: Documentação ### 7.1 Criar README.md ```markdown # Meu MCP Server Descrição do seu servidor MCP. ## 🚀 Funcionalidades - ✅ Funcionalidade 1 - ✅ Funcionalidade 2 ## 📋 Pré-requisitos - Node.js (versão 18+) - API Key (se necessário) ## 🛠️ Instalação ```bash npm install npm run build ``` ## ⚙️ Configuração Configure sua API key: ```bash export MINHA_API_KEY=sua_chave_aqui ``` ## 🔧 Configuração no Claude Desktop 1. Use o arquivo `mcp-config.json` 2. Adicione a ferramenta: `mcp__meu-server__minha_ferramenta` ## 📖 Como Usar ``` Claude, execute minha ferramenta com o parâmetro X ``` ## 📊 Exemplo de Resposta ``` ✅ Resultado da sua ferramenta com parâmetro: X ``` ``` ## 🔍 Passo 8: Padrões e Boas Práticas ### 8.1 Estrutura de resposta ```typescript // Resposta de sucesso return { content: [ { type: "text", text: "✅ Sucesso! Resultado aqui...", }, ], }; // Resposta de erro return { content: [ { type: "text", text: "❌ Erro: Descrição do erro", }, ], }; ``` ### 8.2 Validação de parâmetros ```typescript private async executarMinhaFerramenta(args: any): Promise<any> { const { parametro1, parametro2 } = args; // Validar parâmetros obrigatórios if (!parametro1) { return { content: [ { type: "text", text: "❌ Erro: parametro1 é obrigatório", }, ], }; } // Sua lógica aqui... } ``` ### 8.3 Logs e debugging ```typescript private async executarMinhaFerramenta(args: any): Promise<any> { console.error("🔍 Executando ferramenta com args:", args); try { // Sua lógica aqui console.error("✅ Ferramenta executada com sucesso"); } catch (error) { console.error("❌ Erro na ferramenta:", error); } } ``` ## 🎯 Exemplos de Casos de Uso ### Exemplo 1: Consulta de API Externa ```typescript import fetch from "node-fetch"; private async consultarAPI(args: any): Promise<any> { const { cidade } = args; const response = await fetch(`https://api.exemplo.com/dados?cidade=${cidade}`); const data = await response.json(); return { content: [ { type: "text", text: `📊 Dados para ${cidade}: ${JSON.stringify(data)}`, }, ], }; } ``` ### Exemplo 2: Execução de Comando Local ```typescript import { exec } from "child_process"; import { promisify } from "util"; const execAsync = promisify(exec); private async executarComando(args: any): Promise<any> { const { comando } = args; try { const { stdout, stderr } = await execAsync(comando); return { content: [ { type: "text", text: `📋 Resultado do comando:\n${stdout}`, }, ], }; } catch (error) { return { content: [ { type: "text", text: `❌ Erro: ${error}`, }, ], }; } } ``` ### Exemplo 3: Leitura de Arquivo ```typescript import { readFile } from "fs/promises"; private async lerArquivo(args: any): Promise<any> { const { caminho } = args; try { const conteudo = await readFile(caminho, "utf-8"); return { content: [ { type: "text", text: `📄 Conteúdo do arquivo ${caminho}:\n${conteudo}`, }, ], }; } catch (error) { return { content: [ { type: "text", text: `❌ Erro ao ler arquivo: ${error}`, }, ], }; } } ``` ## 🐛 Solução de Problemas ### Problema: "Cannot find module" ```bash # Solução: Reinstalar dependências rm -rf node_modules package-lock.json npm install ``` ### Problema: "tsc not found" ```bash # Solução: Instalar TypeScript globalmente npm install -g typescript # Ou usar npx npx tsc ``` ### Problema: "Server não inicia" ```bash # Verificar se o arquivo foi compilado ls dist/ # Recompilar se necessário npm run build ``` ### Problema: "Ferramenta não aparece no Claude" 1. Verificar se o caminho no `mcp-config.json` está correto 2. Verificar se a ferramenta foi adicionada corretamente 3. Reiniciar o Claude Desktop ## 📚 Recursos Adicionais - [Documentação oficial MCP](https://modelcontextprotocol.io/) - [SDK MCP para Node.js](https://github.com/modelcontextprotocol/sdk-js) - [Exemplos de servidores MCP](https://github.com/modelcontextprotocol/servers) ## 🎉 Conclusão Agora você tem um guia completo para criar MCP servers! Lembre-se: 1. **Sempre teste** antes de usar no Claude Desktop 2. **Documente bem** suas ferramentas 3. **Trate erros** adequadamente 4. **Use logs** para debugging 5. **Mantenha o código** organizado e limpo Boa sorte com seus projetos MCP! 🚀