Introdução
MCP (Model Context Protocol) é um protocolo criado pela Anthropic para conectar modelos de IA a ferramentas e fontes de dados externas. GitHub Copilot, Claude, Cursor e outras ferramentas de IA já oferecem suporte ao protocolo.
Um servidor MCP próprio atende a necessidades como chamar uma API interna pelo Copilot ou permitir que a IA execute comandos específicos de um projeto.
Este artigo mostra como implementar um servidor MCP em TypeScript e conectá-lo ao GitHub Copilot no VS Code. O conteúdo vai da configuração inicial ao desenho das ferramentas e às práticas de operação.
Conceitos básicos do MCP
flowchart TD
A[Agente do Copilot no VS Code] -->|MCP| B[Servidor MCP]
B --> C[Ferramentas externas]
B --> D[API]
B --> E[Banco de dados]Um servidor MCP pode disponibilizar três tipos principais de capacidades.
| Tipo | Descrição | Exemplos |
|---|---|---|
| Ferramentas | Funções que o LLM pode invocar | Chamadas de API, operações em arquivos |
| Recursos | Dados disponíveis para leitura | Documentos, arquivos de configuração |
| Prompts | Modelos de prompt reutilizáveis | Revisão de código, investigação de incidentes |
A comunicação ocorre por JSON-RPC sobre stdio ou Streamable HTTP.
Arquitetura e princípios de design do MCP
Por que o MCP foi criado
Antes do MCP, cada cliente de IA implementava sua própria integração com sistemas externos. Para usar a mesma API interna em várias ferramentas de IA, era preciso criar uma integração separada para cada cliente.
[Antes do MCP]
GitHub Copilot -> Integração personalizada A -> API interna
Claude -> Integração personalizada B -> API interna (duplicada)
Cursor -> Integração personalizada C -> API interna (duplicada)
[Com MCP]
GitHub Copilot -+
Claude +-> Servidor MCP -> API interna (uma implementação)
Cursor -+
O MCP resolve essa fragmentação por meio de um protocolo padrão. Depois de implementar um servidor, não é necessário reimplementar a mesma capacidade para cada cliente. Na prática, os recursos disponíveis ainda dependem da versão do MCP, do transporte e dos métodos de autenticação compatíveis com cada cliente de IA.
O princípio central: LLMs raciocinam; servidores executam
O princípio central do MCP é a separação de responsabilidades.
- LLM (como o Copilot): interpreta o contexto e decide qual ferramenta chamar e quais argumentos fornecer
- Servidor MCP: executa a ferramenta e retorna os resultados
Um LLM não acessa sistemas externos diretamente. Cada chamada passa por uma interface explícita de ferramenta, o que permite centralizar autenticação, validação e registros no servidor.
sequenceDiagram
participant U as Usuário
participant L as LLM (Copilot)
participant S as Servidor MCP
participant A as API externa
U->>L: "Verifique as issues abertas"
L->>S: tools/call search_github_issues
S->>A: GET /search/issues
A-->>S: JSON de resultado
S-->>L: Resultado da execução da ferramenta
L-->>U: Resposta formatadaComunicação com JSON-RPC 2.0
A comunicação usa JSON-RPC 2.0. Após a conexão, o fluxo de mensagens segue estas três etapas.
| Etapa | Método | Descrição |
|---|---|---|
| 1 | initialize |
Cliente e servidor trocam versões e capacidades compatíveis |
| 2 | tools/list |
O cliente obtém a lista de ferramentas, com nomes e esquemas |
| 3 | tools/call |
O cliente pede a execução de uma ferramenta |
Veja um exemplo de chamada e resposta para search_github_issues:
// Chamada
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "search_github_issues",
"arguments": {
"query": "authentication",
"repo": "owner/my-repo",
"state": "open"
}
}
}
// Resposta
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{
"type": "text",
"text": "[{\"number\": 42, \"title\": \"Fix OAuth token refresh\", ...}]"
}
]
}
}
O LLM recebe esse content, transforma-o em uma resposta em linguagem natural e a devolve ao usuário.
O papel dos transportes
O MCP define dois transportes padrão: stdio e Streamable HTTP. O transporte HTTP+SSE mais antigo permanece por compatibilidade com versões anteriores, mas novas implementações devem usar Streamable HTTP.
| stdio | Streamable HTTP | |
|---|---|---|
| Mecanismo | Inicia o servidor como subprocesso e se comunica pela entrada e saída padrão | Envia e recebe JSON-RPC por HTTP POST/GET, usando SSE para streaming quando necessário |
| Indicado para | Desenvolvimento local e uso individual | Compartilhamento em equipe, gestão centralizada e vários clientes |
| Custo inicial | Baixo (pode iniciar a cada chamada) | Pressupõe um serviço em execução contínua |
Para uso local no VS Code, stdio costuma ser a escolha adequada. A seção “Escolhendo entre stdio e Streamable HTTP” retoma essa decisão mais adiante.
Quando criar um MCP em vez de usar habilidades
O GitHub Copilot no VS Code tem dois mecanismos para estender seu comportamento com arquivos Markdown. Arquivos de instruções personalizados (.github/copilot-instructions.md, .instructions.md e outros) definem orientações enviadas à IA, enquanto habilidades do agente (SKILL.md) descrevem fluxos de trabalho reutilizáveis que podem incluir procedimentos, scripts e recursos de apoio. Neste artigo, ambos são chamados de “personalização baseada em instruções”. Antes de criar um servidor MCP, avalie se esses mecanismos são suficientes.
Casos atendidos por personalização baseada em instruções
- Fornecer à IA informações estáticas, como convenções de código ou estrutura do projeto
- Reutilizar um procedimento conhecido como modelo de prompt
- Definir um fluxo de trabalho que não exija acesso a sistemas externos
A personalização baseada em instruções não exige um servidor dedicado. Scripts incluídos em uma Skill podem ser executados por um agente com ferramentas existentes, como o terminal, mas a disponibilidade da execução, as aprovações e o formato da saída dependem dos recursos do ambiente hospedeiro. Esse deve ser o primeiro caminho a avaliar.
Habilidades também podem ensinar a chamar uma API externa
Quando o requisito é “usar uma API externa”, você pode documentar a chamada em Skills e fazer com que o Copilot gere código ou um comando curl.
<!-- Exemplo de SKILL.md -->
O endpoint da API interna de status é https://api.internal/status
Para autenticação, especifique um token Bearer no cabeçalho Authorization.
Exemplo de chamada com curl: curl -H "Authorization: Bearer $TOKEN" https://api.internal/status
Essa abordagem funciona quando o objetivo é que o Copilot gere código. Em ambientes nos quais um agente pode chamar uma API pelo terminal ou por uma extensão existente, o procedimento de execução, aprovação e tratamento dos resultados continua dependente do host.
O ponto em que o MCP se torna necessário
As habilidades deixam de ser suficientes quando uma das situações abaixo se aplica.
| Situação | Personalização baseada em instruções | MCP |
|---|---|---|
| Ensinar o Copilot a chamar uma API | Sim | — |
| Definir um procedimento para executar uma API com ferramentas fornecidas pelo host | Sim | — |
| Expor uma API como ferramenta tipada e dedicada | Não | Sim |
| Padronizar autenticação, validação de entrada e formato de resultado no servidor | Não | Sim |
| Expor a mesma capacidade a vários clientes MCP | Não | Sim |
As habilidades ensinam ao agente o que fazer e em qual ordem. O MCP, por sua vez, fornece um contrato de ferramenta tipada e dedicada que os clientes podem chamar. Com o MCP, o servidor executa as chamadas e devolve resultados em um formato definido para o contexto do Copilot. Esse controle e essa portabilidade orientam a decisão.
Casos que exigem um servidor MCP
Crie um servidor MCP quando requisitos como os abaixo forem difíceis de controlar apenas com personalização baseada em instruções.
| Requisito | Razão |
|---|---|
| Usar os resultados de uma API no raciocínio do Copilot | Os resultados da execução entram diretamente no contexto, permitindo perguntas complementares e transformações |
| Acessar recursos autenticados | Tokens e credenciais podem permanecer em variáveis de ambiente, sem serem expostos aos usuários |
| Executar operações de escrita ou atualização | Operações com efeitos colaterais, como criar issues, atualizar rótulos ou alterar registros |
| Obter dados em tempo real | Recupera o estado atual do CI ou valores recentes do banco de dados que não cabem em arquivos estáticos |
| Tratar dados grandes ou dinâmicos | Documentos grandes demais para prompts ou dados que mudam com frequência |
| Executar processamento ou conversões complexas | Análise de arquivos, agregação e conversão de formato que devem ocorrer no código |
| Compartilhar entre projetos ou equipes | Centraliza a gestão de ferramentas chamadas por vários desenvolvedores e repositórios |
Fluxo de decisão
flowchart TD
A[Há algo que você quer fazer] --> B{É preciso acessar um<br/>sistema externo?}
B -->|Não| C[A personalização baseada em instruções pode resolver]
B -->|Sim| D{O Copilot precisa receber<br/>o resultado e raciocinar sobre ele?}
D -->|Não: gerar código basta| C
D -->|Sim| E{Há autenticação, efeitos colaterais<br/>ou dados dinâmicos?}
E -->|Não| F[Verifique se um servidor MCP existente<br/>pode atender ao caso]
E -->|Sim| G[Crie um servidor MCP]
F -->|Se não houver um| GO principal limite entre a personalização baseada em instruções e o MCP é a necessidade de controlar, no servidor, um contrato de ferramenta dedicado, a autenticação e a validação de entrada.
Configuração
mkdir my-mcp-server
cd my-mcp-server
npm init -y
npm install @modelcontextprotocol/server zod
npm install -D typescript @types/node tsx
// tsconfig.json
{
"compilerOptions": {
"target": "ES2022",
"module": "Node16",
"moduleResolution": "Node16",
"outDir": "./dist",
"strict": true
},
"include": ["src/**/*"]
}
// package.json (trecho)
{
"type": "module",
"scripts": {
"dev": "tsx src/index.ts",
"build": "tsc",
"start": "node dist/index.js"
}
}
Implementação de um servidor MCP básico
// src/index.ts
import { McpServer } from '@modelcontextprotocol/server'
import { serveStdio } from '@modelcontextprotocol/server/stdio'
import * as z from 'zod/v4'
import { fetchWeather } from './tools/weather.js'
interface GithubIssueSearchResponse {
items: Array<{
number: number
title: string
state: string
html_url: string
}>
}
function createServer(): McpServer {
const server = new McpServer({
name: 'my-custom-tools',
version: '1.0.0',
})
server.registerTool(
'get_weather',
{
description: 'Obtém o clima atual da cidade especificada',
inputSchema: z.object({
city: z.string().describe('Nome da cidade para consultar o clima (ex.: Tokyo, Osaka)'),
}),
},
async ({ city }) => {
const weather = await fetchWeather(city)
return {
content: [{
type: 'text',
text: `Clima atual em ${city}: ${weather.description}, temperatura: ${weather.temp}°C`,
}],
}
}
)
server.registerTool(
'search_github_issues',
{
description: 'Pesquisa issues em um repositório do GitHub',
inputSchema: z.object({
query: z.string().describe('Consulta de pesquisa'),
repo: z.string().regex(/^[^/]+\/[^/]+$/).describe('Nome do repositório (formato owner/repo)'),
state: z.enum(['open', 'closed', 'all']).default('open').describe('Estado da issue'),
}),
},
async ({ query, repo, state }) => {
const token = process.env.GITHUB_TOKEN
if (!token) {
return {
content: [{ type: 'text', text: 'GITHUB_TOKEN não está configurado' }],
isError: true,
}
}
const stateQualifier = state === 'all' ? '' : ` state:${state}`
const url = new URL('https://api.github.com/search/issues')
url.searchParams.set(
'q',
`${query} is:issue repo:${repo}${stateQualifier}`
)
const response = await fetch(url.toString(), {
headers: {
Authorization: `Bearer ${token}`,
Accept: 'application/vnd.github.v3+json',
},
})
if (!response.ok) {
return {
content: [{ type: 'text', text: `GitHub API error: ${response.status}` }],
isError: true,
}
}
const data = await response.json() as GithubIssueSearchResponse
const issues = data.items.slice(0, 5).map((issue) => ({
number: issue.number,
title: issue.title,
state: issue.state,
url: issue.html_url,
}))
return {
content: [{ type: 'text', text: JSON.stringify(issues, null, 2) }],
}
}
)
return server
}
void serveStdio(createServer)
console.error('O servidor MCP foi iniciado')
Exemplos práticos de implementação de ferramentas
API de clima (chamada de API externa)
// src/tools/weather.ts
interface WeatherData {
description: string
temp: number
humidity: number
}
export async function fetchWeather(city: string): Promise<WeatherData> {
const apiKey = process.env.OPENWEATHER_API_KEY
if (!apiKey) throw new Error('OPENWEATHER_API_KEY não está configurada')
const url = `https://api.openweathermap.org/data/2.5/weather?q=${encodeURIComponent(city)}&appid=${apiKey}&units=metric&lang=ja`
const response = await fetch(url)
if (!response.ok) {
throw new Error(`Falha ao obter dados meteorológicos: ${response.statusText}`)
}
const data = await response.json()
return {
description: data.weather[0].description,
temp: Math.round(data.main.temp),
humidity: data.main.humidity,
}
}
Pesquisa de documentos internos (arquivos locais)
// src/tools/docs-search.ts
import * as fs from 'fs/promises'
import * as path from 'path'
import { pathToFileURL } from 'url'
interface DocResult {
title: string
excerpt: string
url: string
}
export async function searchDocs(
query: string,
limit: number
): Promise<DocResult[]> {
const docsDir = process.env.DOCS_DIR ?? './docs'
const files = await fs.readdir(docsDir)
const results: DocResult[] = []
for (const file of files.filter((f) => f.endsWith('.md'))) {
const content = await fs.readFile(path.join(docsDir, file), 'utf-8')
if (content.toLowerCase().includes(query.toLowerCase())) {
const lines = content.split('\n')
// Ignore o frontmatter (o primeiro bloco ---) e use o primeiro H1 como título
let bodyStart = 0
if (lines[0]?.trim() === '---') {
const end = lines.findIndex((l, i) => i > 0 && l.trim() === '---')
bodyStart = end >= 0 ? end + 1 : 0
}
const h1 = lines.slice(bodyStart).find((l) => /^#\s/.test(l))
const title = h1 ? h1.replace(/^#\s*/, '') : path.basename(file, '.md')
const matchIndex = content.toLowerCase().indexOf(query.toLowerCase())
const excerpt = content.slice(
Math.max(0, matchIndex - 50),
matchIndex + 150
)
results.push({
title,
excerpt,
url: pathToFileURL(path.resolve(docsDir, file)).toString(),
})
if (results.length >= limit) break
}
}
return results
}
Implementação de recursos
Os recursos fornecem dados somente leitura que a IA pode consultar. São adequados para informações que o modelo precisa acessar de forma confiável, como políticas internas, procedimentos operacionais e documentação de API.
// Adicione no início de src/index.ts
import { readFile } from 'node:fs/promises'
import path from 'node:path'
// Adicione antes de return server em createServer
server.registerResource(
'project-guide',
'docs://project-guide',
{
title: 'Guia do projeto',
description: 'Guia do projeto para consultar durante o desenvolvimento',
mimeType: 'text/markdown',
},
async (uri) => {
const docsDir = process.env.DOCS_DIR ?? path.join(process.cwd(), 'docs')
const content = await readFile(
path.join(docsDir, 'project-guide.md'),
'utf-8'
)
return {
contents: [
{
uri: uri.href,
mimeType: 'text/markdown',
text: content,
},
],
}
}
)
Bons candidatos a recursos:
- Guias de design e convenções de codificação
- Runbooks operacionais
- Resumos de especificações de API
- Perguntas frequentes internas
O principal benefício é poder consultar essas informações sem inseri-las em cada conversa.
Uso de prompts
Além de ferramentas, o MCP pode fornecer prompts. Eles são úteis para reutilizar procedimentos e critérios de revisão.
- Prompt para análise de segurança
- Prompt para gerar descrições de pull requests
- Prompt para investigação inicial de incidentes
Pense nas ferramentas como meios de execução e nos prompts como padrões de pensamento para identificar cenários em que cada um se aplica.
Conectando ao VS Code
// .vscode/mcp.json
{
"servers": {
"my-custom-tools": {
"type": "stdio",
"command": "node",
"args": ["${workspaceFolder}/dist/index.js"],
"env": {
"GITHUB_TOKEN": "${env:GITHUB_TOKEN}",
"OPENWEATHER_API_KEY": "${env:OPENWEATHER_API_KEY}"
}
}
}
}
Durante o desenvolvimento, é possível executá-lo diretamente com tsx, sem uma etapa de compilação.
{
"servers": {
"my-custom-tools-dev": {
"type": "stdio",
"command": "npx",
"args": ["tsx", "${workspaceFolder}/src/index.ts"]
}
}
}
Uso no Copilot Chat
Depois de reiniciar o VS Code, as ferramentas MCP ficam disponíveis no Copilot Chat.
"Como está o tempo em Tóquio?"
-> O Copilot chama automaticamente a ferramenta get_weather
"Encontre issues abertas sobre \"memory leak\""
-> O Copilot chama automaticamente a ferramenta search_github_issues
Também é possível filtrar ferramentas pelo nome do servidor.
#my-custom-tools Liste as issues abertas sobre "authentication" em owner/my-repo
-> Chama a ferramenta search_github_issues por meio deste servidor
Dicas de depuração
# Teste ferramentas interativamente com o MCP Inspector
npx @modelcontextprotocol/inspector npx tsx src/index.ts
Abra no navegador o URL exibido pelo Inspector para inspecionar visualmente as chamadas de ferramenta e os valores retornados.
Boas práticas para o design de ferramentas
Comece decidindo o que não permitir
As ferramentas MCP são úteis, mas concentrar poder demais em uma única ferramenta é arriscado.
| Mau exemplo | Bom exemplo |
|---|---|
manage_project |
list_open_issues, update_issue_labels |
run_anything |
get_pipeline_status |
execute_sql |
search_customers |
As ferramentas são mais confiáveis quando seus nomes deixam claros os efeitos colaterais, os parâmetros de entrada são poucos e o comportamento em caso de falha é simples de explicar.
Projete inputSchema com cuidado
O esquema de entrada de uma ferramenta não serve apenas para validação: também é a interface do LLM. Descrições vagas reduzem a precisão ao preencher argumentos.
const updateIssueInput = {
type: 'object',
properties: {
repo: { type: 'string', pattern: '^[^/]+/[^/]+$' },
issueNumber: { type: 'integer', minimum: 1 },
labels: {
type: 'array',
items: { type: 'string' },
maxItems: 10,
},
},
required: ['repo', 'issueNumber', 'labels'],
additionalProperties: false,
}
Pontos principais:
- Escreva valores de
descriptionespecíficos - Use
enumsempre que possível - Declare
requiredexplicitamente - Use
additionalProperties: falsepara evitar parâmetros não intencionais
Separe as responsabilidades de Zod e JSON Schema
inputSchema é o contrato externo, enquanto Zod faz a revalidação em tempo de execução. Em especial, não dispense a revalidação no servidor para ferramentas que chamam uma API ou um banco de dados externo.
case 'update_issue': {
// Defina no JSON Schema a estrutura exposta ao modelo
// e valide com Zod os valores aceitos pelo servidor
const input = z.object({
repo: z.string().regex(/^[^/]+\/[^/]+$/),
issueNumber: z.number().int().positive(),
labels: z.array(z.string()).max(10),
}).parse(args)
// ...
}
Princípios para o tratamento de erros
Organizar os erros em pelo menos estas três categorias facilita o tratamento.
- Erros de entrada (falhas de validação)
- Erros de autenticação/autorização
- Falhas de serviço externo
function toToolErrorMessage(error: unknown): string {
if (error instanceof z.ZodError) {
return 'A entrada é inválida. Verifique os campos obrigatórios e os formatos dos valores.'
}
if (error instanceof Error) {
return `A execução da ferramenta falhou: ${error.message}`
}
return 'A execução da ferramenta falhou.'
}
As mensagens retornadas não devem revelar detalhes internos em excesso e precisam indicar claramente a próxima ação.
Gestão de credenciais
Nunca passe segredos em prompts ou argumentos; leia-os de variáveis de ambiente ou de um ambiente de execução seguro.
| Faça | Não |
|---|---|
| Leia tokens de API do ambiente | Inclua segredos nos argumentos da ferramenta |
| Use tokens com o menor privilégio possível | Grave tokens nos logs |
| Separe os ambientes de produção e desenvolvimento | Inclua segredos em mensagens de erro |
Mantenha as permissões mínimas
- Use um token somente leitura para pesquisar issues do GitHub
- Use um usuário somente com SELECT em uma ferramenta de leitura de banco de dados
- Use apenas permissão de leitura de workflows em uma ferramenta de verificação de implantação
Para uso em equipe, é mais seguro separar ferramentas somente leitura das ferramentas de atualização e isolar as ferramentas destinadas à produção.
Projeto operacional
Timeouts, retentativas e falhas parciais
Um experimento local pode funcionar bem enquanto a produção permanece instável. Evite escrever código supondo que todas as chamadas terão sucesso.
async function withTimeout<T>(promise: Promise<T>, ms: number): Promise<T> {
return await Promise.race([
promise,
new Promise<T>((_, reject) => {
setTimeout(() => reject(new Error(`Timed out after ${ms}ms`)), ms)
}),
])
}
Elementos mínimos:
- Timeouts
- Limites de retentativas
- Limitação de taxa
- Normalização de mensagens de erro
Observabilidade (design de logs)
Durante a depuração, saber apenas o que foi chamado não basta. Registre:
- Nome da ferramenta
- Horário da chamada e duração da execução
- Categoria de sucesso ou falha e motivo da falha
Mas não registre em excesso: mantenha dados pessoais, tokens de acesso, instruções SQL completas e respostas completas da API externa fora dos logs.
Estratégia de teste
Separar as implementações das ferramentas em funções permite testar sua lógica fora do protocolo MCP.
// Separe a lógica de negócios para torná-la testável
export async function searchGithubIssues(input: SearchIssuesInput) {
// Processamento real
}
server.registerTool(
'search_github_issues',
{ inputSchema: SearchIssuesInputSchema },
async (input) => formatResult(await searchGithubIssues(input))
)
Camadas de teste recomendadas:
- Testes unitários da validação de entrada
- Testes unitários dos manipuladores de ferramentas
- Testes de integração que incluam o transporte
- Verificação manual com o MCP Inspector
Escolhendo entre stdio e Streamable HTTP
| Perspectiva | stdio | Streamable HTTP |
|---|---|---|
| Configuração local | Muito simples | Exige um pouco mais de estrutura |
| Auditoria central | Fraco | Forte |
| Governança da autenticação | Depende de usuários individuais | Mais simples |
| Depuração | Fácil | Mais fatores de rede |
| Distribuição | npm/binário | URL do serviço |
Comece validando a usabilidade com stdio. Quando o compartilhamento em equipe ou a gestão centralizada se tornarem necessários, considere Streamable HTTP. Se o servidor for exposto por HTTP, implemente validação de origem, vinculação ao host local e autenticação.
Separando servidores MCP
Concentrar tudo em um servidor tende a ampliar suas responsabilidades. Dividir por unidades como estas facilita a operação.
- Ferramentas relacionadas ao GitHub
- Ferramentas relacionadas a APIs internas
- Ferramentas de leitura de banco de dados
- Servidores de recursos dedicados à documentação
A separação também facilita a organização de permissões e variáveis de ambiente.
Padrões de falha frequentes
1. Criar uma ferramenta genérica que pode fazer qualquer coisa
Ferramentas como run_anything ou execute_sql (SQL arbitrário) tendem a reduzir a segurança e a reprodutibilidade.
2. Deixar o inputSchema permissivo demais
O modelo tem dificuldade para montar argumentos de modo confiável, o que aumenta o número de chamadas malsucedidas.
3. Receber segredos como argumentos
Eles podem vazar facilmente por logs ou pelo histórico da conversa.
4. Misturar operações de leitura e atualização com a mesma permissão
Isso aumenta a probabilidade de incidentes operacionais.
5. Escrever implementações de ferramentas diretamente nos manipuladores
Isso torna as implementações difíceis de testar e manter.
Uma sequência prática de adoção
Para o primeiro servidor MCP, esta ordem é realista:
- Crie um servidor exclusivamente local com stdio
- Crie apenas uma ou duas ferramentas somente leitura
- Adicione recursos e prompts
- Melhore os logs e o tratamento de erros
- Adicione ferramentas de atualização cuidadosamente, apenas quando necessário
Essa sequência facilita o equilíbrio entre segurança e utilidade.
Bons candidatos iniciais:
- Pesquisa de configuração do projeto
- Pesquisa de documentos internos
- Verificações de status do CI
- Pesquisa de pull requests e issues
Adicione ferramentas de atualização somente quando a confiança dos usuários e o desenho de auditoria estiverem estabelecidos.
Resumo
- Servidores MCP se comunicam por JSON-RPC via stdio ou Streamable HTTP, e o atual
@modelcontextprotocol/serversimplifica a implementação em TypeScript - A combinação de ferramentas (meios de execução), recursos (dados de referência) e prompts (padrões de pensamento) amplia as capacidades do Copilot
- Registrar um servidor em
.vscode/mcp.jsonpermite chamá-lo pelo GitHub Copilot no VS Code - Comece o desenho da ferramenta decidindo o que não permitir; um
inputSchemabem projetado melhora a precisão do raciocínio do LLM - Gerencie segredos por variáveis de ambiente e mantenha as permissões mínimas
- Comece com stdio e uma ou duas ferramentas somente leitura; expanda depois de consolidar o uso
