Introdução

Servidores MCP permitem conectar fontes de dados personalizadas e disponibilizá-las para uso dentro do Cursor. Isso é especialmente útil quando tu precisas de contexto de lugares como navegadores, bancos de dados ou logs de erros e do sistema. Configurar um servidor MCP é simples e, com o Cursor, dá para fazer isso rapidamente. Neste guia, vamos mostrar como construir um servidor MCP para Postgres. Nosso objetivo é permitir que o Cursor execute consultas SQL diretamente em um banco de dados Postgres e exponha os esquemas das tabelas de forma estruturada.
Este tutorial foi feito para ensinar os fundamentos de construção de servidores MCP.

O que é um MCP Server?

Um servidor MCP é um processo que se comunica com o Cursor e fornece acesso a dados ou ações externas. Ele pode ser implementado de várias maneiras, mas aqui a gente vai usar o método mais simples: um servidor que roda localmente no teu computador via stdio (fluxos de entrada/saída padrão). Isso evita preocupações de segurança complicadas e permite que a gente foque na lógica do MCP em si. Um dos casos de uso mais comuns do MCP é o acesso a bancos de dados. Ao construir dashboards, rodar análises ou criar migrações, muitas vezes é necessário consultar e inspecionar um banco. Nosso servidor MCP para Postgres vai dar suporte a duas capacidades principais: executar consultas arbitrárias e listar schemas de tabelas. Embora ambas as tarefas possam ser feitas com SQL puro, o MCP oferece funcionalidades que as tornam mais poderosas e, de modo geral, mais úteis. Tools fornecem uma forma de expor ações como executar consultas, enquanto resources permitem compartilhar contexto padronizado, como informações de schema. Mais adiante neste guia, a gente também vai ver prompts, que habilitam fluxos de trabalho mais avançados. Por baixo dos panos, vamos usar o pacote npm postgres para executar instruções SQL no banco de dados. O SDK do MCP vai servir como um wrapper em torno dessas chamadas, permitindo integrar a funcionalidade do Postgres ao Cursor de forma fluida.

Como construir o servidor MCP

O primeiro passo para construir o servidor é configurar um novo projeto. Vamos começar criando uma nova pasta e inicializando um projeto Bun
> mkdir postgres-mcp-server
> Bun init
Aqui, vamos selecionar o projeto Blank. Quando o boilerplate estiver pronto, precisamos instalar as dependências necessárias. zod é necessário para definir schemas de entrada/saída no SDK do MCP
bun add postgres @modelcontextprotocol/sdk zod
Em seguida, vamos até os repositórios de cada biblioteca e pegar o link para o conteúdo bruto dos respectivos READMEs. Vamos usar isso como contexto ao construir o servidor Agora, vamos definir como queremos que o servidor se comporte. Para isso, vamos criar um spec.md e descrever os objetivos de alto nível
# Spec

- Allow defining DATABASE_URL through MCP env configuration
- Query postgres data through tool
  - By default, make it readonly
  - Allow write ops by setting ENV `DANGEROUSLY_ALLOW_WRITE_OPS=true|1`
- Access tables as `resources`
- Use Zod for schema definitions
Como dá pra ver, é uma especificação bem leve. Fica à vontade para adicionar mais detalhes conforme necessário. Junto com os links dos READMEs, vamos montar o prompt final
Read the following and follow @spec.md to understand what we want. All necesary dependeies are installed
- @https://raw.githubusercontent.com/modelcontextprotocol/typescript-sdk/refs/heads/main/README.md
- @https://raw.githubusercontent.com/porsager/postgres/refs/heads/master/README.md
Com esses três componentes em mãos (a especificação, a documentação do MCP SDK e a documentação da biblioteca Postgres), dá pra usar o Cursor para gerar o esqueleto da implementação do servidor. O Cursor vai ajudar a juntar as peças, gerando o código que conecta o MCP SDK ao Postgres. Depois de algumas iterações de prompt, agora temos uma primeira versão do servidor MCP rodando. Para testar, dá pra usar o MCP Inspector
npx @modelcontextprotocol/inspector bun run index.ts

Testando o servidor MCP

Depois que a implementação inicial estiver concluída, a gente pode testá-la usando o MCP Inspector. O Inspector oferece uma forma de ver o que o servidor expõe e verificar se as ferramentas e os recursos se comportam como esperado. A gente deve confirmar que as consultas podem ser executadas e que as informações de esquema são retornadas corretamente. Interface do MCP Inspector Quando tudo estiver ok, dá pra conectar o servidor ao próprio Cursor e testá-lo em um ambiente real. Nesse ponto, o Cursor vai conseguir usar o servidor MCP do Postgres como se fosse um recurso nativo, permitindo consultar e inspecionar o banco de dados diretamente.

Próximos passos

Executar o servidor MCP localmente via stdio é um ótimo ponto de partida, mas as equipes muitas vezes precisam de acesso compartilhado ao mesmo banco de dados por meio do servidor MCP. Nesses cenários, implantar o servidor MCP como um serviço HTTP centralizado se torna necessário. Um servidor MCP implantado oferece várias vantagens em relação a instâncias individuais via stdio:
  • Acesso compartilhado ao banco de dados: Vários membros da equipe podem consultar a mesma instância de banco de dados pelo Cursor
  • Configuração centralizada: Atualizações de esquema e mudanças de permissão são gerenciadas em um só lugar
  • Segurança aprimorada: Autenticação adequada, rate limiting e controles de acesso podem ser implementados
  • Observabilidade: Padrões de uso e métricas de desempenho podem ser monitorados por toda a equipe
Para conseguir isso, você mudaria o método de transporte de stdio para HTTP. Embora a gente não vá cobrir toda a configuração, aqui vai um prompt inicial que você pode passar para o Cursor
Based on the existing MCP server, create a new file that implements the HTTP protocol.

Move shared logic to mcp-core, and name each transport implementation by name (mcp-server-stdio, mcp-server-http)

@https://raw.githubusercontent.com/modelcontextprotocol/typescript-sdk/refs/heads/main/README.md 
Os resultados finais podem ser vistos aqui: pg-mcp-server