티스토리 뷰

반응형
2026년 7월 기준 · Claude Code

사내 DB에 AI를 붙이려면
결국 로컬 MCP다.

원격 MCP와 로컬 MCP는 뭐가 다른지, 그리고 왜 사내망 DB에는 선택지가 하나뿐인지 — PowerShell에서 PostgreSQL을 Claude Code에 연결하는 명령어까지 순서대로 정리했습니다.

🪟 Windows / PowerShell 🐘 PostgreSQL ⏱️ 읽는 시간 8분

원격 MCP와 로컬 MCP

MCP 서버는 크게 두 갈래입니다. Notion·Slack·Linear처럼 벤더가 호스팅하는 원격 MCP(HTTP/SSE 전송), 그리고 내 PC에서 프로세스로 뜨는 로컬 MCP(stdio 전송). 같은 프로토콜이지만 실무에서 부딪히는 지점이 완전히 다릅니다.

항목로컬 MCP (stdio)원격 MCP (HTTP/SSE)
실행 위치내 PC의 자식 프로세스벤더 서버
전송 방식stdin / stdoutHTTPS + SSE / Streamable HTTP
인증없음 — 토큰을 직접 환경변수로 주입OAuth 2.1 브라우저 플로우
데이터 경로내 PC 밖으로 나가지 않음벤더 서버 경유
사내망 접근가능 (내부 IP·localhost 직접)불가 — 벤더가 사내망을 볼 수 없음
설치 · 업데이트npx / uvx, 버전 직접 관리없음 — 항상 최신
지연수 ms수백 ms + 네트워크
팀 공유.mcp.json 커밋링크 / 워크스페이스 단위
주 실패 지점내 PC 프로세스 종료, Node 버전벤더 장애, 방화벽, 프록시, SSL 인스펙션
💡
선택 기준은 한 줄로 정리됩니다. SaaS(Notion·Slack·Linear)는 원격, 사내 시스템·로컬 파일·localhost 서비스는 로컬. 사내 DB가 방화벽 안에 있다면 원격 MCP는 구조적으로 도달할 방법이 없습니다. 취향 문제가 아니라 네트워크 토폴로지 문제입니다.
⚠️
"로컬"이라는 말이 두 가지 뜻으로 섞여 쓰입니다 — stdio 전송을 뜻할 때와 MCP 서버가 내 기기에서 돈다는 뜻일 때. localhost:8080에 HTTP로 붙는 서버도 로컬이지만 stdio는 아닙니다. 이 경우 여러 클라이언트가 한 서버를 공유할 수 있어 디버깅이 편한 대신, 인증이 없으니 반드시 127.0.0.1에 바인딩해야 합니다.

설치 전에 챙길 세 가지

이번 글에서 쓸 서버는 DBHub(@bytebase/dbhub)입니다. PostgreSQL·MySQL·MariaDB·SQL Server·SQLite를 하나의 인터페이스로 다루고, SSH 터널 옵션이 내장돼 있어 배스티온 뒤의 DB에도 붙습니다.

📦

Node.js LTS

npx로 서버를 띄우기 때문에 Node가 필요합니다. node -v가 안 되면 winget install OpenJS.NodeJS.LTS로 설치하세요.

설치 후에는 PowerShell 창을 새로 열어야 PATH가 잡힙니다.

🧱

사내 프록시

회사망에서 npx가 멈추면 십중팔구 프록시입니다. npm 설정에 프록시를 넣어야 패키지가 내려옵니다.

SSL 인스펙션 장비가 있으면 인증서 오류가 추가로 납니다.

🔐

읽기 전용 계정

가장 중요한 준비물입니다. MCP 서버가 제공하는 read-only 옵션은 보조 장치일 뿐, 실질적 안전장치는 DB 권한뿐입니다.

앱 계정을 그대로 쓰지 말고 SELECT만 가진 롤을 새로 만드세요.

PowerShell에서 6단계

아래 순서대로 복사해서 실행하면 됩니다. dbhost, mydb, 비밀번호는 실제 값으로 바꿔주세요.

1

Node 확인

둘 다 버전이 찍히면 다음 단계로 넘어갑니다.

PowerShell
node -v; npm -v

# 없으면 설치 후 창을 새로 열기
winget install OpenJS.NodeJS.LTS
2

사내 프록시 설정 (필요할 때만)

먼저 프록시 주소를 확인하고 npm에 등록합니다. strict-ssl false는 SSL 인스펙션 장비가 있을 때만 켜세요.

PowerShell
netsh winhttp show proxy          # 프록시 주소 확인

npm config set proxy "http://proxy주소:8080"
npm config set https-proxy "http://proxy주소:8080"
npm config set strict-ssl false   # 인증서 오류가 날 때만
3

읽기 전용 롤 생성

MCP 설정보다 이게 먼저입니다. ALTER DEFAULT PRIVILEGES까지 걸어두면 앞으로 추가되는 테이블도 자동으로 조회 대상에 들어옵니다.

psql — mydb
CREATE ROLE claude_ro LOGIN PASSWORD 'strong-password';
GRANT CONNECT ON DATABASE mydb TO claude_ro;
GRANT USAGE ON SCHEMA public TO claude_ro;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO claude_ro;
ALTER DEFAULT PRIVILEGES IN SCHEMA public
  GRANT SELECT ON TABLES TO claude_ro;
4

접속 스모크 테스트

MCP에 등록하기 전에 DSN이 맞는지 먼저 확인합니다. 아무 출력 없이 멈춰 있으면 접속 성공이니 Ctrl+C로 빠져나오면 됩니다. 실패하면 즉시 에러가 뜹니다.

PowerShell
npx -y '@bytebase/dbhub@latest' --transport stdio `
  --dsn "postgres://claude_ro:strong-password@dbhost:5432/mydb?sslmode=disable"
⚠️
'@bytebase/dbhub@latest'반드시 단일 인용부호로 감싸세요. PowerShell은 토큰 맨 앞의 @를 배열·스플래팅 연산자로 해석해서, 따옴표가 없으면 파싱 에러가 납니다. bash에서 복붙한 명령어가 PowerShell에서만 깨지는 대표적인 이유입니다.
5

Claude Code에 등록

DSN을 인자가 아니라 환경변수로 넘깁니다. 프로세스 목록과 셸 히스토리에 비밀번호가 남지 않습니다.

PowerShell
claude mcp add pg --scope local `
  --env DSN="postgres://claude_ro:strong-password@dbhost:5432/mydb?sslmode=disable" `
  -- cmd /c npx -y '@bytebase/dbhub@latest' --transport stdio

cmd /c로 감싸는 게 핵심입니다. Windows에서 npx를 command로 직접 지정하면 .cmd 셰뱅 처리 문제로 프로세스가 뜨지 않습니다.

6

확인

목록에 잡히는지 확인하고, Claude Code 안에서 /mcp를 실행해 pg가 connected로 보이면 끝입니다.

PowerShell
claude mcp list

# Claude Code 세션 안에서
/mcp

수동 설정 방식

.mcp.json을 직접 쓰고 싶다면 이 형태입니다. 비밀번호를 파일에 박지 않고 ${DSN}으로 참조하면 팀원과 파일을 공유할 수 있습니다 — 접속 정보는 각자 시스템 환경변수로 설정하면 됩니다.

.mcp.json
{
  "mcpServers": {
    "pg": {
      "command": "cmd",
      "args": ["/c", "npx", "-y", "@bytebase/dbhub@latest",
               "--transport", "stdio"],
      "env": { "DSN": "${DSN}" }
    }
  }
}
💡
DB가 배스티온 뒤에 있다면 5단계 명령에 --ssh-host bastion --ssh-user id --ssh-key C:\Users\...\.ssh\id_rsa를 붙이면 됩니다. 별도 터널을 띄울 필요가 없습니다.

Windows에서 자주 막히는 곳

대부분 MCP 자체가 아니라 셸·경로·네트워크 문제입니다. 증상만 알면 원인이 바로 특정됩니다.

🅰️

@가 먹히지 않는다

패키지명 앞의 @는 PowerShell 연산자입니다. 단일 인용부호로 감싸세요.

🧩

서버가 뜨지 않는다

commandnpx로 두면 실패합니다. cmd + /c 조합으로 감싸세요.

🔡

비밀번호 인증 실패

DSN은 URL입니다. @ : / ? # %가 들어있으면 URL 인코딩이 필요합니다 (@%40).

🔒

SSL 관련 오류

사내 PostgreSQL이 TLS를 안 쓰면 ?sslmode=disable, 쓰면 require로 맞춰야 합니다.

🐢

npx가 멈춘다

프록시 미설정입니다. 2단계를 적용하고, 사내 npm 미러가 있으면 registry도 함께 지정하세요.

🧾

결과가 비어 보인다

롤에 USAGE ON SCHEMA가 빠졌을 가능성이 큽니다. 테이블 목록 자체가 안 보입니다.

배포 전 보안 체크리스트

읽기 전용 롤로만 접속 — 앱 계정이나 슈퍼유저 재사용 금지. MCP 서버의 read-only 플래그를 방어선으로 믿지 마세요.
운영 DB 직결은 피하기 — 스테이징이나 읽기 전용 복제본부터. 운영 접속은 DBA 승인 대상입니다.
비밀번호를 저장소에 커밋하지 않기--scope project와 평문 DSN 조합은 위험합니다. ${DSN} 참조 + 환경변수로.
개인정보 테이블은 애초에 권한을 주지 않기 — 스키마 전체 GRANT보다 필요한 테이블만 열어주는 편이 안전합니다.
⚠️
쿼리 자체를 통제해야 하는 환경이라면 Google MCP Toolbox for Databases도 후보입니다. tools.yaml에 등록한 SQL만 도구로 노출되기 때문에 임의 쿼리 실행이 구조적으로 불가능하고, 그만큼 보안 심사를 통과하기 쉽습니다. 대신 질문마다 도구를 미리 정의해야 하는 비용이 있습니다.

여기까지 오면 DB가 대화 가능해집니다

스키마를 설명하게 하고, 통계 쿼리를 맡기고, 이상한 데이터를 찾아달라고 하면 됩니다.
시작은 읽기 전용 계정 하나와 명령어 두 줄입니다.