문서/설치·운영/DB 연동 가이드
GUIDE인프라/DBAdb-connection-guide.md·읽는 시간 약 30

DB 연동 가이드

PostgreSQL / MySQL / MS SQL / Oracle 별 read-only 계정 + 연결 정보.

대상: 사내 DBA / DB 담당자 — 4개 DB 종류 별 사용자 권한 / 연결 정보 / 트러블슈팅 선행 조건: 커넥터 설치 + 툴킷 사용 가이드 숙지 (Toolkit 사용 가이드) 본 문서는 DB 측 작업 중심 — Studio 폼 입력은 툴킷 가이드 §5 참고


공통 보안 원칙

  1. 읽기 전용 사용자 별도 생성 — 기존 운영 계정 재사용 X
  2. DB 레벨에서 SELECT 만 권한 부여 — DDL / DML 자체 차단 (코드 단의 안전망 외 한 겹 더)
  3. 노출 범위 제한 — 모든 스키마 X. 비즈니스 분석 필요한 view / 테이블만 권한
  4. 비밀번호는 secrets 파일 에만 — Studio / Hub 에 절대 평문 X
  5. 네트워크: 커넥터 호스트에서만 접근 가능하도록 DB 측 ACL 조정 권장

Studio 폼 입력 — placeholder 사용 정책

필드평문 입력placeholder 사용
비밀번호✗ (금지)반드시 ${DB_PASSWORD}
Host / Port / Database / User✅ 가능✅ 가능 — ${DB_HOST}, ${DB_NAME}, ${DB_USER}
  • 본 가이드의 각 dialect 연결 정보 표는 평문 예시 로 적었지만, 어떤 필드든 ${VAR} placeholder 로 치환 가능합니다. 그 경우 secrets 파일 (/etc/mcp-connector/secrets/*.env) 에 같은 이름의 변수도 함께 추가하세요.
  • 사내 보안팀이 토폴로지 (호스트/DB 이름/계정명) 평문 저장도 금지 한다면 모두 placeholder 로, 그렇지 않으면 비밀번호만 placeholder — 두 방식 다 정상 동작.
  • 자세한 정책은 Toolkit 사용 가이드 §3 참고.

1. PostgreSQL

1-1. 읽기 전용 사용자 생성

-- 슈퍼유저로 접속
CREATE USER mcp_reader WITH PASSWORD 'Pa55word!2024';
GRANT CONNECT ON DATABASE erp TO mcp_reader;

\c erp
GRANT USAGE ON SCHEMA public TO mcp_reader;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO mcp_reader;

-- 미래 생성될 테이블도 자동 SELECT 권한
ALTER DEFAULT PRIVILEGES IN SCHEMA public
  GRANT SELECT ON TABLES TO mcp_reader;

1-2. 노출 범위 좁히기 (선택)

특정 테이블만 노출:

REVOKE SELECT ON ALL TABLES IN SCHEMA public FROM mcp_reader;
GRANT SELECT ON public.orders, public.customers TO mcp_reader;

비즈니스 view 만 노출 (가장 안전):

CREATE VIEW analytics.v_orders_summary AS
  SELECT id, customer_id, total, created_at FROM orders;

GRANT USAGE ON SCHEMA analytics TO mcp_reader;
GRANT SELECT ON analytics.v_orders_summary TO mcp_reader;

1-3. 연결 정보 (Studio 폼 입력값)

필드
Hostpg-erp.internal
Port5432
Databaseerp
Usermcp_reader
비밀번호${DB_PASSWORD}
SSL사용 (CA 검증 없음) — 사내 자체서명일 때<br>사용 (시스템 CA) — Let's Encrypt 등 공인 CA

1-4. secrets 파일

/etc/mcp-connector/secrets/pg.env:

DB_PASSWORD=Pa55word!2024

1-5. 사전 연결 테스트 (커넥터 호스트에서)

psql "postgres://mcp_reader:Pa55word!2024@pg-erp.internal:5432/erp" -c "SELECT 1"
# 출력: ?column? \n ---------- \n 1

1-6. 트러블슈팅

증상원인 / 해결
password authentication failed사용자/비밀번호 재확인 — \password 로 재설정 가능
connection refusedPG 의 pg_hba.conf 에 커넥터 호스트 IP 허용 라인 추가 필요
permission denied for table XGRANT SELECT 누락 — 위 1-1 절 다시
SSL connection failedpg_hba.conf 의 method 가 hostssl 이면 SSL 필수. Studio 의 SSL 옵션 require 이상으로

2. MySQL / MariaDB

2-1. 읽기 전용 사용자 생성

CREATE USER 'mcp_reader'@'%' IDENTIFIED BY 'Pa55word!2024';
GRANT SELECT ON appdb.* TO 'mcp_reader'@'%';
FLUSH PRIVILEGES;

2-2. 노출 범위 좁히기

-- 특정 테이블만
GRANT SELECT ON appdb.orders, appdb.customers TO 'mcp_reader'@'%';

-- view 만 (권장)
CREATE VIEW appdb.v_orders_summary AS
  SELECT id, customer_id, total, created_at FROM orders;
GRANT SELECT ON appdb.v_orders_summary TO 'mcp_reader'@'%';

2-3. 연결 정보

필드
Hostmysql-app.internal
Port3306
Databaseappdb
Usermcp_reader
비밀번호${DB_PASSWORD}
SSL사용 (CA 검증 없음) 권장

2-4. secrets 파일

/etc/mcp-connector/secrets/mysql.env:

DB_PASSWORD=Pa55word!2024

2-5. 사전 연결 테스트

mysql -h mysql-app.internal -P 3306 -u mcp_reader -p'Pa55word!2024' appdb -e "SELECT 1"

2-6. 트러블슈팅

증상원인 / 해결
Access denied for user 'mcp_reader'@'커넥터호스트''mcp_reader'@'%' 가 아닌 특정 호스트만 허용된 사용자. % 또는 커넥터 호스트 IP 명시
Unknown database 'appdb'DB 이름 오타 — 대소문자 구분 (SHOW DATABASES; 확인)
MySQL 5.7 + caching_sha2_password 인증 오류커넥터의 mysql2 드라이버 호환. 비밀번호를 mysql_native_password 로 재설정 또는 MySQL 8 권장
TLS handshake errorSSL 옵션 mismatch — MySQL 의 require_secure_transport=ON 이면 SSL require 필수

3. MS SQL Server

3-1. 읽기 전용 로그인 + 사용자 생성

USE master;
CREATE LOGIN mcp_reader WITH PASSWORD = 'Pa55word!2024';

USE ERPProd;
CREATE USER mcp_reader FOR LOGIN mcp_reader;

-- 데이터베이스 전체 읽기
EXEC sp_addrolemember 'db_datareader', 'mcp_reader';

3-2. 노출 범위 좁히기

특정 스키마만:

USE ERPProd;
REVOKE SELECT FROM mcp_reader;  -- db_datareader 제거
GRANT SELECT ON SCHEMA::dbo TO mcp_reader;

특정 테이블 / view 만:

GRANT SELECT ON dbo.orders TO mcp_reader;
GRANT SELECT ON dbo.v_summary TO mcp_reader;

3-3. 연결 정보

필드
Hostmssql-erp.internal
Port1433
DatabaseERPProd
Usermcp_reader
비밀번호${MSSQL_PASS}
SSL사용 (CA 검증 없음) 또는 사용 안함 (사내 네트워크)

3-4. secrets 파일

/etc/mcp-connector/secrets/mssql.env:

MSSQL_PASS=Pa55word!2024

비밀번호에 @ 가 들어가면 SQL Server 연결 문자열에서 따옴표 escape 가 까다로움. 가능하면 @ 제외한 강력한 비밀번호 사용.

3-5. 사전 연결 테스트

# sqlcmd (microsoft/mssql-tools 이미지) 또는 사내 환경의 SQL 도구
docker run --rm -it mcr.microsoft.com/mssql-tools \
  /opt/mssql-tools/bin/sqlcmd \
  -S mssql-erp.internal,1433 -U mcp_reader -P 'Pa55word!2024' \
  -d ERPProd -Q "SELECT 1"

3-6. 트러블슈팅

증상원인 / 해결
Login failed for user 'mcp_reader'SQL Server 인증 모드 (Windows / Mixed) 확인 — Mixed Mode 필수
Cannot open database "ERPProd"사용자가 그 DB 의 사용자로 추가 안 됨 — USE ERPProd; CREATE USER 다시
TLS handshake (encrypted connection)SQL Server 2019+ 는 default 암호화. Studio SSL 옵션 require 권장
SELECT ... TOP 100 외 결과 잘림정상 동작 — execute_query 가 100 행 제한 (안전 측면)

4. Oracle DB

4-1. 읽기 전용 사용자 생성

-- DBA 로 접속
CREATE USER mcp_reader IDENTIFIED BY "Pa55word!2024"
  DEFAULT TABLESPACE users
  TEMPORARY TABLESPACE temp
  QUOTA 0 ON users;

GRANT CREATE SESSION TO mcp_reader;

-- 특정 스키마 / 테이블 SELECT 권한
GRANT SELECT ON erp_owner.orders TO mcp_reader;
GRANT SELECT ON erp_owner.customers TO mcp_reader;
GRANT SELECT ON erp_owner.v_summary TO mcp_reader;

4-2. SERVICE_NAME 확인 (중요)

Oracle 은 SID 가 아닌 SERVICE_NAME 사용:

SELECT value FROM v$parameter WHERE name = 'service_names';
-- 또는
SHOW PARAMETER service_names;

출력 예: ERPSVC, XEPDB1, FREEPDB1

4-3. 연결 정보

필드
Hostoracle-erp.internal
Port1521
DatabaseSERVICE_NAME (위에서 확인한 값)
Usermcp_reader
비밀번호${ORACLE_PASS}
SSL사용 안함 (사내 네트워크) 또는 사용 (CA 검증 없음) (TCPS)

미리보기에 표시되는 baseUrl: oracle://mcp_reader:${ORACLE_PASS}@oracle-erp.internal:1521/ERPSVC

4-4. secrets 파일

/etc/mcp-connector/secrets/oracle.env:

ORACLE_PASS=Pa55word!2024

4-5. 사전 연결 테스트

# sqlplus 가 있을 때
sqlplus 'mcp_reader/"Pa55word!2024"@//oracle-erp.internal:1521/ERPSVC'
# 비밀번호의 특수문자는 따옴표로 감싸기

# 또는 docker 로
docker run --rm -it gvenzl/oracle-free:23-slim sqlplus \
  'mcp_reader/Pa55word!2024@//oracle-erp.internal:1521/ERPSVC'

4-6. Oracle 버전 호환

Oracle 버전우리 커넥터 호환
12c (12.1+) / 18c / 19c / 21c / 23ai✅ 호환 (Thin 모드 자동)
11g 이하 (2013 이전 release)❌ 별도 Thick 모드 이미지 필요 — 별도 문의

우리 커넥터는 oracledb v6 Thin 모드 사용 — Instant Client 설치 불필요. 단 Oracle 11g 이하는 미지원 (보안 패치 EOL 이라 사실상 거의 없음).

4-7. 트러블슈팅

증상원인 / 해결
ORA-12154: TNS could not resolve4-3 의 baseUrl 형식 오류. //host:port/SERVICE_NAME 형식 확인
ORA-12541: TNS:no listener1521 포트 차단 — 사내 방화벽 / DB 호스트 listener 상태 확인
ORA-01017: invalid username/password비밀번호 특수문자. secrets 파일에 따옴표 없이 그대로 (escape X)
ORA-00942: table or view does not existGRANT SELECT 누락. erp_owner schema 의 객체는 fully qualified (erp_owner.orders) 로 권한 부여
LOB / CLOB 컬럼이 깨짐안전상 large object 는 string 변환 — 너무 크면 truncate. SELECT ... DBMS_LOB.SUBSTR(...) 로 좁히기

5. DB 4종 공통 점검 체크리스트

새 DB 툴킷 만들기 전:

  • 읽기 전용 사용자 생성 (DDL/DML 권한 없음)
  • 노출할 스키마 / 테이블만 GRANT
  • 비밀번호 강도 충분 (특수문자 포함, @ 가급적 회피)
  • 커넥터 호스트에서 DB 호스트로 telnet / 사내 SQL 도구로 직접 연결 가능
  • SSL 정책 결정 (사내 사설 인증서 → CA 검증 없음 / 공인 → 검증 사용)
  • secrets 파일 권한 600, 폴더 700
  • Studio 폼의 비밀번호 필드 = ${VAR} placeholder (평문 금지). Host / Database / User 는 정책에 따라 평문 또는 placeholder
  • 사용자 운영 모니터링 — DB 측 audit log 도 같이 기록 권장

6. AI 뷰 추천 (가상 뷰)

DB 툴킷은 기본으로 두 가지 도구 (describe_schema · execute_query) 를 제공합니다 — AI 가 스키마를 직접 보고 SQL 을 짜는 자유 질의 방식입니다. 여기에 더해, 자주 쓰는 조회를 이름 붙은 가상 뷰 도구로 만들 수 있습니다. 두 방식은 함께 쓸 수 있고, 뷰를 추가해도 자유 질의 도구는 그대로 남습니다.

가상 뷰의 장점

  • 반복 업무에서 매번 SQL 을 새로 짜지 않아 안정적입니다
  • "일별 매출 집계" 처럼 업무 언어로 대화할 수 있습니다
  • 뷰에 적힌 컬럼만 AI 에 보여주므로 개인정보 노출이 줄어듭니다 (데이터베이스에는 아무것도 만들지 않습니다 — 뷰는 커넥터에 저장된 이름 붙은 SQL 입니다)

사용 방법 (Studio → DB 툴킷 상세 → 도구 탭)

  1. AI 뷰 추천 받기 — 업무 설명 한 줄 (선택) 을 넣으면 AI 가 스키마를 분석해 뷰 후보를 제안합니다. 개인정보로 보이는 컬럼 (이메일 · 전화번호 등) 은 기본으로 제외되고, 제외된 컬럼과 사유가 카드에 표시됩니다.
  2. 검증 실행 — 후보의 SQL 을 1행만 실제로 실행해 문법 · 컬럼 오류를 미리 확인합니다.
  3. 도구로 등록 — 클릭하면 이 뷰가 툴킷의 도구 목록에 추가됩니다.
  4. 뷰 정의 복사 → 붙여넣기 — 카드의 [뷰 정의 복사] 버튼은 "이름": { ... } 형태의 조각(바깥 중괄호 없음)을 복사합니다. 이미 /etc/mcp-connector/secrets/db-views.json 파일이 있다면 파일의 { } 안에 그대로 붙여넣으세요 (항목 사이에는 쉼표가 필요합니다). 파일을 처음 만드는 경우엔 후보 목록 아래 [파일 전체 복사] 버튼으로 지금 보이는 모든 후보를 완전한 JSON 파일 형태로 한 번에 복사해 저장하세요 (단, 이미 직접 추가한 항목이 있는 파일이면 통째로 덮어쓰지 말고 필요한 항목만 옮기세요). 파일 저장 즉시 반영되며 재시작이 필요 없습니다.
{
  "daily_sales_summary": {
    "description": "지정한 기간의 일별 주문 건수와 총 매출액 집계",
    "sql": "SELECT date_trunc('day', ordered_at) AS order_date, count(*) AS order_count, sum(amount) AS total_amount FROM orders WHERE ordered_at BETWEEN $1 AND $2 GROUP BY 1 ORDER BY 1",
    "params": [
      { "name": "start_date", "type": "string", "description": "집계 시작일 (ISO 8601)" },
      { "name": "end_date", "type": "string", "description": "집계 종료일 (ISO 8601)" }
    ]
  }
}

권한 안내 — AI 는 계정에 SELECT 권한이 있는 테이블만 볼 수 있습니다. 읽기 전용 계정 + 업무 스키마 SELECT 권한을 권장하며, 민감 테이블 (급여 · 인사 등) 은 계정 권한에서 제외하면 원천 차단됩니다 (위 1-1 · 1-2 절 참고).


7. 문의

  • DB 권한 / 사내 정책 협의: 사내 DBA / 보안 담당자
  • 도구 설명 정확도 / 호출 빈도 튜닝: WRKS 담당자

같이 보세요: