소개

MCP 서버를 사용하면 커스텀 데이터 소스에 연결하고 Cursor 안에서 바로 쓸 수 있어. 브라우저, 데이터베이스, 오류·시스템 로그 같은 데서 컨텍스트가 필요할 때 특히 유용해. MCP 서버 설정은 간단하고, Cursor랑 같이 하면 금방 끝낼 수 있어. 이 가이드에서는 Postgres용 MCP 서버를 만드는 방법을 살펴볼 거야. 목표는 Cursor가 Postgres 데이터베이스에 직접 SQL 쿼리를 실행하고, 테이블 스키마를 구조화된 방식으로 제공하도록 하는 거야.
이 튜토리얼은 MCP 서버를 만드는 기본기를 익히도록 설계됐어.

MCP Server란 뭐야?

MCP server는 Cursor랑 통신하면서 외부 데이터나 액션에 접근할 수 있게 해주는 프로세스야. 구현 방법은 몇 가지가 있지만, 여기선 가장 간단한 방법을 쓸 거야: 네 컴퓨터에서 stdio (표준 입력/출력 스트림)로 로컬 실행되는 서버. 이렇게 하면 복잡한 보안 이슈를 피하고 MCP 로직 자체에 집중할 수 있어. MCP의 가장 흔한 사용 사례 중 하나는 데이터베이스 액세스야. 대시보드를 만들거나, 분석을 돌리거나, 마이그레이션을 만들 때는 데이터베이스를 조회하고 살펴볼 일이 자주 생겨. 우리가 만들 Postgres MCP server는 두 가지 핵심 기능을 지원해: 임의 쿼리 실행과 테이블 스키마 나열. 이 두 작업은 순수 SQL만으로도 할 수 있지만, MCP는 이를 더 강력하고 범용적으로 유용하게 만드는 기능을 제공해. tools는 쿼리 실행 같은 액션을 노출하는 방법을 제공하고, resources는 스키마 정보 같은 표준화된 컨텍스트를 공유할 수 있게 해줘. 가이드 뒤쪽에선 더 고급 워크플로를 가능하게 하는 prompts도 살펴볼 거야. 내부적으로는 postgres npm 패키지에 의존해 데이터베이스에 SQL 문을 실행할 거야. MCP SDK는 이 호출들을 감싸는 래퍼로 동작해서, Postgres 기능을 Cursor에 자연스럽게 통합할 수 있게 해줘.

MCP 서버를 빌드하는 방법

서버를 빌드하는 첫 단계는 새 프로젝트를 설정하는 거야. 새 폴더를 만들고 Bun 프로젝트를 초기화하는 것부터 시작하자.
> mkdir postgres-mcp-server
> Bun init
여기서 Blank 프로젝트를 선택하면 돼. 보일러플레이트가 준비되면 필요한 의존성을 설치하자. MCP SDK에서 I/O 스키마를 정의하려면 zod가 필요해.
bun add postgres @modelcontextprotocol/sdk zod
이제 각 라이브러리의 레포지토리로 가서 각 README의 원본(raw) 파일 링크를 가져오자. 서버를 빌드할 때 컨텍스트로 쓸 거야. 이제 서버가 어떻게 동작하길 원하는지 정의하자. 그러려면 spec.md를 만들고 상위 목표를 적어보자.
# 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
보다시피 꽤 가벼운 스펙이야. 필요하면 디테일을 더 추가해도 돼. README 링크와 함께 최종 프롬프트를 구성하자.
Read the following and follow @spec.md to understand what we want. All necessary dependencies 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
이 세 가지 구성 요소(스펙, MCP SDK 문서, Postgres 라이브러리 문서)가 준비되면 Cursor로 서버 구현을 스캐폴딩할 수 있어. Cursor가 조각들을 엮어 MCP SDK와 Postgres를 연결하는 코드를 생성해 줄 거야. 몇 번 프롬프트를 주고받은 끝에 MCP 서버의 첫 버전이 돌아가기 시작했어. 직접 써보려면 MCP Inspector를 사용하면 돼.
npx @modelcontextprotocol/inspector bun run index.ts

MCP 서버 테스트하기

초기 구현이 완료되면 MCP Inspector로 테스트할 수 있어. Inspector는 서버가 어떤 항목을 노출하는지 확인하고, 도구와 리소스가 기대대로 동작하는지 검증하는 방법을 제공해. 쿼리가 실행되는지와 스키마 정보가 올바르게 반환되는지를 확인해야 해. MCP Inspector 인터페이스 모든 게 괜찮아 보이면 서버를 Cursor에 직접 연결해서 실제 환경에서 테스트해 볼 수 있어. 이때부터 Cursor는 Postgres MCP 서버를 기본 기능처럼 사용할 수 있고, 데이터베이스를 바로 쿼리하고 살펴볼 수 있게 돼.

다음 단계

stdio로 로컬에서 MCP 서버를 띄우는 건 훌륭한 출발점이지만, 팀 단위에선 MCP 서버를 통해 같은 데이터베이스에 공동 접근해야 할 때가 많아. 이런 경우엔 MCP 서버를 중앙 집중형 HTTP 서비스로 배포하는 게 필요해. 배포형 MCP 서버는 개별 stdio 인스턴스 대비 몇 가지 이점이 있어:
  • 공유 데이터베이스 접근: 여러 팀원이 Cursor를 통해 동일한 DB 인스턴스를 조회할 수 있어
  • 중앙 집중형 구성: 스키마 업데이트와 권한 변경을 한 곳에서 관리해
  • 보안 강화: 올바른 인증, 레이트 리미팅, 접근 제어를 적용할 수 있어
  • 가시성: 팀 전반의 사용 패턴과 성능 메트릭을 모니터링할 수 있어
이걸 달성하려면 전송 방식을 stdio에서 HTTP로 전환하면 돼. 전체 설정을 전부 다루진 않지만, Cursor에 이렇게 시작 프롬프트를 던져봐
기존 MCP 서버를 기반으로 HTTP 프로토콜을 구현하는 새 파일을 만들어줘.

공유 로직은 mcp-core로 이동하고, 각 전송 구현은 이름으로 구분해줘 (mcp-server-stdio, mcp-server-http)

@https://raw.githubusercontent.com/modelcontextprotocol/typescript-sdk/refs/heads/main/README.md 
최종 결과는 여기에서 확인할 수 있어: pg-mcp-server