PostgreSQL MCP가 연결하는 것#
PostgreSQL에 접근하는 MCP 서버는 여러 구현이 있으므로 서버별 도구와 권한을 따로 확인해야 합니다. 다음 표는 특정 서버의 기능 보증이 아니라 PostgreSQL 자체의 권한 기준입니다.
| 점검 항목 | PostgreSQL 공식 문서의 기준 |
|---|---|
| 객체 권한 | 스키마 USAGE와 테이블·열의 SELECT는 별도입니다. 소유권과 상속·PUBLIC 권한도 확인해야 합니다. |
| 함수 실행 | 함수와 프로시저에는 기본적으로 PUBLIC 실행 권한이 부여될 수 있습니다. SELECT만 부여했다고 다른 실행 경로가 사라지는 것은 아닙니다. |
| 읽기 전용 트랜잭션 | 여러 변경 명령을 제한하지만 임시 테이블 예외가 있고 모든 디스크 쓰기를 막지는 않습니다. 세션 기본값도 개별 트랜잭션에서 바뀔 수 있습니다. |
| 행 보안 | 테이블 소유자, 슈퍼유저와 BYPASSRLS 역할은 행 보안 정책을 우회할 수 있습니다. |
출처: PostgreSQL 권한, 트랜잭션 접근 모드, 행 보안 정책, 2026-11-01 확인.
- 운영 DB 대신 민감정보를 제거한 테스트 DB와 별도 계정을 준비합니다.
- 필요한 스키마와 객체의 권한, 상속·함수 실행 및 행 보안 적용 여부를 관리자와 함께 검토합니다.
- 격리된 환경에서 허용할 조회와 거부해야 할 변경을 각각 검증하고, 실제 결과만 기록합니다.
추가 검증 필요: 테스트 DB의 제한된 역할 생성·권한 부여와 스키마 범위, 상속·함수·행 보안을 포함한 실효 권한, 허용된 조회와
EXPLAIN출력 및 파괴적 쿼리 거부 결과, PostgreSQL MCP 서버 설치 기록과 Mirr 연결·실행 기록은 아직 확보하거나 확인하지 못했습니다.
읽기 전용 역할, 스키마 한정과 파괴적 쿼리 차단을 실제 데이터베이스에서 검증한 결과가 아직 없습니다. PostgreSQL 문서 설명이나 별도 SQL 실험은 Mirr/MCP 연결 검증을 대신하지 않습니다.
준비물과 권한#
읽기 전용을 목표로 해도 조회 결과에 민감정보가 포함될 수 있습니다. 계정에 직접 부여된 권한뿐 아니라 소유권, 역할 상속, 함수 실행과 데이터 접근 범위를 검토하세요.
설치와 연결#
Mirr Code 설치 문서와 외부 도구 연결 안내를 참고하세요. 사용할 PostgreSQL MCP 서버의 배포자와 연결 방법은 별도로 확인해야 하며, 이 페이지에서는 설치를 실행하지 않았습니다.
PostgreSQL MCP 설정의 현재 범위: 이 글은 PostgreSQL 자체의 권한 기준을 선택했지만 특정 MCP 서버 구현은 아직 선정하지 않았습니다. PostgreSQL 접속 문자열은 MCP HTTP 주소가 아니므로 DB 주소를 그대로 Mirr의 --http 인자에 넣지 마세요. 다음은 서버를 고르기 전에 완료할 수 있는 설정 검토 순서입니다.
- 담당자와 승인된 테스트 DB·데이터 범위·허용할 스키마와 조회, 거부해야 할 변경을 문서로 정합니다. DB 소유자·관리자 계정 대신 실제 연결 계정의 실효 권한을 설계합니다. 이 절의 SQL 예시는 그 검토의 일부일 뿐 완성된 계정 설정이 아닙니다.
- 사용할 MCP 서버의 공식 저장소·유지보수 상태·릴리스·라이선스와 설치 방법을 확인하고, 제공 도구와 임의 SQL 허용 범위를 목록으로 남깁니다. 이름에 PostgreSQL이 있다는 이유로 PostgreSQL 프로젝트가 운영하는 공식 서버라고 가정하지 마세요.
- 선택 서버가 로컬 프로세스인지 원격 HTTP인지, DB 인증·TLS·비밀값 저장을 어떻게 처리하는지 확인합니다. Mirr 문서는 일반 HTTP 등록만 설명하므로 해당 전송·인증 조합과 버전의 실제 지원은 별도 확인해야 합니다. DB 비밀번호나 접속 문자열을 프롬프트·공유 로그에 넣지 않습니다.
- 선정이 끝난 뒤 승인된 환경에서 서버 설치, Mirr 연결·도구 목록, 제한 역할의 허용 조회·대상 밖 스키마 접근·파괴적 쿼리 거부를 나눠 시험하도록 계획합니다. 실행 기록에는 서버·DB·Mirr 버전과 실제 연결 역할, 명령·출력을 함께 남깁니다.
근거는 앞서 링크한 PostgreSQL 권한 문서와 Mirr MCP 연결 문서입니다. 특정 서버의 설치·연결 절차와 인증 호환성은 여전히 미확정이며, 서버 선정·실효 권한·거부 결과가 아직 없습니다.
실제 작업 예제#
예를 들어 테스트 DB에서 허용된 테이블의 스키마를 조회하고, 별도로 변경 요청이 거부되는지 확인할 수 있습니다. 실제 실행 기록과 권한 검사 결과는 아직 확보하지 못했습니다.
관리자와 검토할 미실행 SQL 예시입니다. reporting과 monthly_totals는 가상의 승인 대상이며 이미 존재하는 테스트 객체라는 가정입니다. 로그인 비밀값은 예시에 넣지 않았습니다. 이 명령만으로 읽기 전용 계정이 완성되거나 다른 접근이 차단되지는 않습니다.
CREATE ROLE mcp_report_reader NOLOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE NOINHERIT NOBYPASSRLS;
GRANT USAGE ON SCHEMA reporting TO mcp_report_reader;
GRANT SELECT ON TABLE reporting.monthly_totals TO mcp_report_reader;
실제 연결 계정에 이 역할을 어떻게 부여하고 활성화하는지, 다른 역할과 PUBLIC에서 어떤 권한을 얻는지는 별도 설계·검증 대상입니다. 예시를 운영 DB에 복사해 실행하지 마세요. 근거: 역할 생성, GRANT, EXPLAIN(2026-11-02 문서 확인).
보안과 제한#
조회도 정보 유출이나 부하를 일으킬 수 있습니다. 읽기 전용 트랜잭션은 권한 설계를 대신하지 않으며, 역할의 실효 권한과 서버의 실행 범위를 별도로 확인해야 합니다. 데이터 변경은 별도 승인과 검증이 필요합니다.
문제 해결과 자주 묻는 질문#
연결 장애와 객체 권한 문제를 나눠 살펴보세요. 다음은 진단 기준이지 성공·거부 결과가 아닙니다.
| 증상 | 확인 순서 | 확대하면 안 되는 권한·동작 |
|---|---|---|
| 인증·접속 실패 | 서버 주소·DB명·TLS·네트워크 정책·계정 인증을 관리자와 확인 | TLS 검증을 끄거나 운영 자격 증명 공유 |
| 스키마 또는 테이블 접근 거부 | 실제 접속 역할과 스키마 USAGE, 해당 객체의 SELECT를 각각 점검 | 전체 스키마·전체 테이블 권한을 일괄 부여 |
| 예상보다 많은 데이터 조회 | 소유권, 상속 역할, PUBLIC, 행 보안 우회 여부 점검 | 필터가 있으니 안전하다고 판단 |
| 결과가 없거나 일부만 보임 | 대상 DB·스키마·데이터와 적용되는 행 보안 정책 확인 | 곧바로 슈퍼유저로 재시도 |
| 조회가 오래 걸림 | 반환량과 쿼리 계획, 관리자와 정한 시간 제한 확인 | 확인 없이 EXPLAIN ANALYZE 실행 |
EXPLAIN ANALYZE는 문장을 실행합니다. 일반 EXPLAIN과 구분하고, 실패한 쓰기 차단 검사는 운영 데이터가 없는 승인된 환경에서만 계획하세요. 검증 기록에는 접속 역할과 서버 버전, 허용한 객체, 거부돼야 할 명령과 실제 출력을 함께 남겨야 합니다. 조회도 데이터 유출과 DB 부하를 일으킬 수 있습니다.
서버 선정과 DB 권한 설계를 별도 과제로 두기#
PostgreSQL MCP라는 이름은 하나의 표준 배포판을 뜻하지 않습니다. 선택할 구현의 운영 주체, 공식 저장소, 릴리스와 라이선스를 먼저 확인해야 합니다. 도구가 정해진 조회만 제공하는지 임의 SQL을 받는지, 연결 풀과 트랜잭션을 어떻게 다루는지도 검토하세요. 서버의 읽기 전용 옵션이 있다면 실제로 어떤 명령을 제한하는지 문서와 테스트로 확인해야 합니다. 옵션 이름만 보고 DB 권한 설계를 대신할 수는 없습니다.
전송 방식과 인증도 나눕니다. DB 접속은 PostgreSQL 프로토콜과 DB 계정의 문제이고 Mirr와 MCP 서버 사이의 연결은 선택한 구현의 전송·인증 문제입니다. DB 접속 문자열을 HTTP MCP URL처럼 사용하지 마세요. 로컬 프로세스와 원격 서버는 비밀값을 보관하고 전달하는 경로도 다를 수 있습니다. 현재 이 글은 특정 서버를 선정하지 않았으므로 작동하는 설치 명령이나 Mirr 호환성을 만들어 제시하지 않습니다.
| 서버 선정 질문 | 확인할 실제 자료 | 확인 전 남길 제한 |
|---|---|---|
| 누가 배포하는가 | 공식 저장소·릴리스·라이선스 | PostgreSQL 프로젝트 공식 서버로 부르지 않기 |
| 어떤 SQL을 받는가 | 도구 스키마·문서·실제 목록 | 이름만으로 파괴적 쿼리 차단 추정 금지 |
| 누가 DB에 접속하는가 | 실제 로그인 역할과 활성 역할 | 관리자 대리 실행을 제한 계정 증거로 쓰지 않기 |
| 세션을 어떻게 쓰는가 | 연결 풀·트랜잭션·설정 처리 | 기본 읽기 전용 값만으로 전체 통제 주장 금지 |
| 어디로 데이터가 가는가 | 서버·호스트·모델의 처리 경로 | 로컬 DB라는 이유로 외부 전송 없음 추정 금지 |
| Mirr와 맞는가 | 같은 버전의 전송·인증·도구 실행 | 타 클라이언트 성공을 호환 증거로 대체 금지 |
표의 자료가 없으면 해당 항목은 미확정입니다. 다만 서버를 고르기 전에도 허용 데이터와 쿼리, 거부 조건과 결과 공개 범위를 정할 수 있습니다. 운영 원본을 복사해 쓰는 대신 승인된 합성 데이터로 필요한 관계와 오류 조건을 표현하는 방식을 검토하세요. 데이터가 작아도 실제 고객 식별자가 들어 있으면 합성 자료가 아닙니다. 준비 단계에서 개인정보와 비밀값을 제외해야 합니다.
실효 권한을 확인해야 하는 이유#
역할에 직접 SELECT만 부여했다고 그 역할이 조회만 할 수 있는 것은 아닙니다. 다른 역할의 멤버십, 활성화 가능한 역할과 PUBLIC 권한을 함께 봐야 합니다. 객체 소유자는 별도 권한을 가지며 슈퍼유저나 행 보안 우회 역할도 제한 검증에 적합하지 않습니다. 실제 MCP 연결 계정과 쿼리 실행 시점의 역할을 확인해야 하는 이유입니다. 관리자 계정으로 대신 실행한 결과는 제한 계정의 거부 증거가 아닙니다.
스키마 USAGE와 객체 SELECT도 구분합니다. 스키마 이름에 접근하는 권한과 그 안의 모든 데이터를 읽는 권한은 같은 것이 아닙니다. 열 단위 권한이나 제한 뷰를 사용할지, 행 보안이 필요한지는 데이터 담당자가 결정해야 합니다. 단순히 쿼리에 WHERE를 붙이는 것은 계정의 범위를 강제하지 않습니다. 사용자나 모델이 다른 쿼리를 보낼 수 있는 서버라면 서비스와 DB 양쪽에서 범위를 검토해야 합니다.
권한을 회수할 때도 직접 부여한 항목 하나만 지웠다고 끝나지 않을 수 있습니다. 같은 권한을 다른 역할이나 PUBLIC에서 얻을 수 있기 때문입니다. 실제 접근 경로를 나눠 확인하고 기존 서비스의 권한까지 임의로 제거하지 마세요. PUBLIC 권한을 바꾸는 작업은 다른 사용자에게 영향을 줄 수 있습니다. 이 글의 SQL은 설계 검토용이며 운영 환경에서 권한을 생성·변경·회수하는 승인이 아닙니다.
함수·뷰·행 보안의 경계#
조회 문장은 함수를 호출할 수 있습니다. 함수의 실행 권한과 보안 특성, 소유자와 search_path를 검토하지 않고 “SELECT라서 부작용이 없다”고 단정하면 안 됩니다. 공식 문서는 새 함수에 기본적으로 PUBLIC 실행 권한이 있을 수 있음을 설명하고 SECURITY DEFINER 함수를 안전하게 작성하는 별도 주의사항을 제공합니다. 이 글은 모든 함수를 실행해 조사하라는 뜻이 아닙니다. 관리자와 허용할 경로를 먼저 정해야 합니다.
뷰를 제공하는 경우에도 뷰가 어떤 데이터와 함수에 접근하는지 확인합니다. 이름에 reporting이 있다고 민감정보가 자동으로 제거되는 것은 아닙니다. 필요한 열과 행만 제공하는 계약을 담당자가 검토하고 실제 연결 역할로 결과를 확인하세요. 행 보안은 소유권과 역할 특성에 따라 다르게 적용될 수 있습니다. 빈 결과는 정책이 작동한 증거일 수도 있지만 실제 데이터가 없는 것일 수도 있어 기대 상태를 알고 시험해야 합니다.
새 테이블과 함수가 생길 때의 권한도 별도입니다. 현재 객체에 대한 부여와 앞으로 생성되는 객체의 기본 권한은 같은 범위가 아닙니다. 누가 객체를 생성하는지와 기본 권한의 적용 범위를 관리자와 검토하세요. 지금 허용된 객체를 읽었다고 앞으로 생길 모든 객체도 안전하게 제한된다고 보장할 수 없습니다. 변경 후에는 승인된 테스트 객체로 다시 확인할 계획을 남겨야 합니다.
읽기 전용 트랜잭션과 부하 제한#
읽기 전용 트랜잭션은 여러 변경 명령을 제한하지만 모든 디스크 쓰기와 부작용을 막는 보안 경계는 아닙니다. 임시 테이블 같은 예외와 세션 설정의 변경 가능성도 공식 문서에서 확인해야 합니다. 역할 권한, 서버의 도구 제한과 클라이언트 승인에 더해 사용할 보완 통제로 검토하세요. 기본값을 설정했다는 사실과 실제 모든 요청이 그 제한 아래 실행된다는 사실은 다릅니다. 연결 풀을 쓰면 세션 처리도 선정 서버에서 확인해야 합니다.
조회만 해도 많은 행을 반환하거나 긴 쿼리로 부하를 만들 수 있습니다. 허용할 열·행 범위와 시간 제한, 결과 크기를 정하세요. LIMIT는 반환량을 줄일 수 있지만 앞선 계산의 모든 비용을 제한한다고 가정하지 않습니다. 쿼리 계획과 실제 데이터 분포가 관련될 수 있으므로 담당자가 검토해야 합니다. 이 글은 성능 측정이나 특정 제한 값의 적정성을 실측하지 않았습니다. 예시 숫자를 운영 권장값처럼 제시하지 않습니다.
EXPLAIN을 실행 결과와 구분하기#
일반 EXPLAIN은 계획 정보를 보여 주는 데 사용되지만 EXPLAIN ANALYZE는 문장을 실제로 실행합니다. 특히 변경 문장과 부작용이 있는 함수에 주의해야 합니다. 계획에 예상 행 수가 보인다고 실제 반환 행 수를 확인한 것은 아닙니다. 실행하지 않은 계획의 비용을 밀리초나 처리량으로 바꾸어 설명하지 마세요. 실제 실행 검증이 필요하면 승인된 격리 환경과 부작용 검토가 먼저입니다.
실제 쿼리를 검토하는 EXPLAIN 출력은 해당 테스트 DB와 쿼리에서 얻어야 합니다. 문서 예시나 SQLite의 계획을 PostgreSQL 실행 결과로 대신할 수 없습니다. 서버·DB 버전과 연결 역할, 쿼리와 대상 객체를 함께 남기세요. 민감한 테이블 이름과 데이터가 공개되면 안 되는 경우에는 공개 가능한 합성 객체를 준비해야 합니다. 필요한 정보를 가린 뒤에도 어떤 검사를 했는지 설명할 수 있어야 합니다.
허용과 거부를 함께 검증할 행렬#
검증 계획에는 허용한 테이블 조회, 범위 밖 스키마 접근과 거부해야 할 변경을 각각 넣습니다. 쓰기 검사는 실패해도 안전한 합성 DB에서만 계획해야 합니다. 차단이 잘못돼 실제로 실행될 수 있기 때문입니다. 운영 DB에 DROP이나 변경 문장을 보내 거부되는지 확인하는 방법은 권하지 않습니다. 테스트 대상에 민감한 데이터가 없어야 하고 복구 가능한 환경이라는 조건도 담당자가 확인해야 합니다.
거부 결과에는 오류 코드와 가린 출력, 실제 사용 역할과 명령을 남깁니다. “프롬프트가 실행하지 말라고 했다”는 기록은 DB 차단 증거가 아닙니다. 클라이언트가 도구 호출을 막은 결과와 서버가 SQL을 거부한 결과, DB 권한이 거부한 결과도 나눠 적어야 합니다. 어느 경계가 작동했는지 알아야 이후 다른 클라이언트나 서버로 바뀌었을 때 다시 검증할 범위를 정할 수 있습니다.
결과 공개와 복구의 별도 절차#
조회 결과에는 개인정보와 비공개 업무 정보가 포함될 수 있습니다. 필요한 열만 승인된 형태로 반환하도록 검토하고 원문 행 전체를 모델 문맥과 로그에 넣지 않는 방법을 살펴보세요. DB가 내부 네트워크에 있어도 MCP 서버·클라이언트·모델을 거치며 정보가 이동할 수 있습니다. 각 운영 주체의 보관과 삭제 조건을 확인해야 합니다. 읽기 전용은 기밀성을 자동으로 보장하는 기능이 아닙니다.
잘못된 변경이 일어났다면 파일의 /rewind로 복구되지 않습니다. DBA의 백업·복구와 서비스별 정정 절차가 필요합니다. 토큰과 연결 계정의 권한 철회도 별도 작업입니다. 현재 이 글은 실제 DB나 MCP 서버를 실행하지 않았으므로 허용 조회, 파괴적 쿼리 거부와 복구 성공을 주장하지 않습니다. 특정 서버 선정과 실효 권한·스키마·거부 transcript가 아직 없습니다.
추가 근거: 권한의 합산과 REVOKE, 함수 보안, SECURITY DEFINER 주의사항, 기본 권한. PostgreSQL 자체 설명이며 선정 전 MCP 서버의 동작 보증은 아닙니다.
파괴적 쿼리 차단을 검증할 때의 중단 기준#
쓰기 차단 검사는 차단이 실패할 가능성을 전제로 설계해야 합니다. 따라서 승인된 합성 DB와 객체만 대상으로 하고 실제 업무 자료가 없다는 것을 먼저 확인합니다. 처음 예상과 다른 역할이나 객체가 보이면 검사를 중단하고 연결 대상을 확인하세요. 접속 문자열의 이름이 test라고 안전한 환경인 것은 아닙니다. 실제 서버와 DB, 계정과 데이터의 출처를 담당자가 확인해야 합니다. 이 글은 그 환경을 만들거나 접속하지 않았습니다.
검사 중 허용되지 않은 변경이 성공했다면 뒤의 파괴적 요청을 계속 보내지 않습니다. 어느 경계가 예상과 달랐는지 조사하고 실제 영향을 기록해야 합니다. 테스트 환경의 정리도 승인된 복구 절차로 수행하세요. 실패한 차단을 숨기고 다른 쿼리의 거부만 골라 안전하다고 주장하면 안 됩니다. 한 명령이 거부됐다는 사실은 모든 쓰기 경로가 막혔다는 증거가 아닙니다. 역할 상속과 함수, 다른 도구 경로의 확인 범위를 함께 남기는 이유입니다.
조회 결과를 최소한으로 전달하는 방법#
업무 질문에 집계값만 필요하다면 원본의 개인정보 열을 모두 모델에 전달할 이유가 있는지 검토하세요. 제한 뷰와 열 권한, 승인된 집계 쿼리 같은 선택지는 데이터 담당자가 설계해야 합니다. 결과를 줄이는 목적과 접근을 강제하는 권한은 구분합니다. 쿼리의 필터가 있다고 사용자가 다른 쿼리를 못 보내는 것은 아닙니다. 서버가 임의 SQL을 허용한다면 그 위험을 별도로 검토해야 합니다. 이 글은 특정 구현이 안전하게 제한한다고 보장하지 않습니다.
로그에도 필요한 증거만 남깁니다. 쿼리 원문에 비밀값이나 고객 식별자가 들어 있다면 공개용으로 그대로 보관하지 마세요. 승인된 합성 식별자로도 검사 의미를 설명할 수 있는지 준비 단계에서 정하는 편이 좋습니다. 결과 행 전체 대신 검사한 객체, 기대 조건과 오류 코드가 충분한 경우도 있습니다. 다만 중요한 정보를 모두 가려 무엇을 시험했는지 모르게 만든 자료는 검증 근거가 약합니다. 공개 가능한 합성 과제를 먼저 정해야 하는 이유입니다.
검증 후 권한을 유지할지 결정하기#
일회성 검증 뒤에도 서버와 DB 계정을 계속 열어 둘 필요가 있는지 담당자가 판단해야 합니다. 연결 제거, 서버 종료와 DB 역할·토큰 회수는 서로 다른 행동입니다. 예를 들어 클라이언트에서 서버 이름을 지웠더라도 DB 역할과 서버 설정이 그대로라면 서비스 측 접근 경로를 정리한 것으로 보고할 수 없습니다. 실제로 종료·철회한 항목과 남은 항목을 나누세요. 계정 변경은 별도 승인 범위이며 임의로 수행하지 않습니다. 현재는 선정 서버와 제한 역할, Mirr 연결·차단 transcript 자체가 없으므로 철회나 차단을 시험했다는 주장도 할 수 없습니다.
SQL 차단 기록과 조회 데이터의 공개 승인도 별도입니다. 명령이 거부됐다고 로그 전체를 안전한 공개 자료로 판단하지 마세요.
다음에 연결할 것#
연결 전에는 도구와 권한 안내에서 Mirr Code의 작업 권한도 함께 확인하세요.
READ ONLY 트랜잭션이 막는 것과 막지 않는 것#
PostgreSQL 문서는 READ ONLY 트랜잭션에서 INSERT, UPDATE, DELETE, MERGE, COPY FROM(쓰는 대상이 임시 테이블이 아닌 경우), 모든 CREATE·ALTER·DROP, COMMENT, GRANT, REVOKE, TRUNCATE를 금지한다고 설명합니다. 실행할 명령이 목록에 있는 EXPLAIN ANALYZE와 EXECUTE도 금지됩니다(PostgreSQL SET TRANSACTION 문서).
이 문서는 이것이 디스크 쓰기를 모두 막는 것이 아니라 높은 수준의 읽기 전용이라고 명시합니다. 그래서 트랜잭션 모드만으로 보안 경계를 주장하지 않습니다.
같은 문서는 DEFERRABLE 속성이 SERIALIZABLE이면서 READ ONLY인 트랜잭션에서만 효과가 있다고 설명합니다(PostgreSQL SET TRANSACTION 문서). 이 글의 검증 행렬은 DEFERRABLE을 쓰지 않았으므로 그 효과를 주장하지 않습니다.
역할 권한은 트랜잭션 모드와 별개로 확인해야 하며, 이 글은 실제 역할 권한을 조회하지 않았습니다.
관련#
편집 메모 (2026-11-02): 제한 역할의 미실행 예시와 권한·접속 진단을 보충했습니다. 실제 역할·스키마·파괴적 쿼리 거부 결과와 서버 설치·Mirr 연결 기록은 확보하지 않았습니다.
