본문으로 건너뛰기

Workspace MCP Tool 고급(raw-SQL) + 검토 게이트 QA 가이드 (#2044)

이 문서는 Workspace MCP Tool 고급(raw-SQL) 작성 모드ws-admin 검토 게이트QA가 화면에서 직접 따라 검증할 수 있도록 단계별 스크린샷과 함께 정리한 것입니다. 모든 화면은 실제 GenD prod 환경의 데모 워크스페이스에서 캡처했습니다.

개요

MCP Tool은 워크스페이스 관리자가 등록하는 읽기 전용(SELECT-only) MCP 도구입니다. 등록 경로는 두 가지입니다.

  • 마법사(Wizard) — 5단계 구조화 경로(SqlBuilderWizard). 컬럼 선택·필터·정렬을 GUI로 조립합니다(안전 경로).
  • 고급(Advanced — raw SQL) — JOIN·서브쿼리 등 마법사로 표현하기 어려운 SELECT 문을 Monaco 에디터에 직접 작성합니다(P2.1, #2044).

고급 모드의 핵심은 검토 게이트입니다.

  • 직접 작성한 SQL은 항상 검토 대기(pending_review) 상태로 등록됩니다 — 자가 활성화 불가.
  • 워크스페이스 admin검토 큐에서 raw-SQL을 직접 확인하고 승인(활성화) 해야 비로소 활성(active) 이 됩니다. 거부하면 비활성(disabled) 으로 떨어집니다.
  • 백엔드는 작성 시점에 SqlGuard로 재검증합니다 — SELECT 단일 문만 허용하고, DDL/DML/다중 문은 422로 거부합니다.
  • 작성 후 EXPLAIN 비용 미리보기(POST /{id}/explain)로 예상 스캔 행/바이트(또는 통계 부재 경고)와 쿼리 플랜을 검토자에게 보여줍니다.

권한: 등록 화면(/workspace/mcp-tools/new) 진입·작성과 검토 큐의 승인/거부는 모두 워크스페이스 admin(글로벌 admin 역할 또는 Keycloak /tenants/<slug>/admins 멤버) 만 가능합니다. 비-admin 의 활성화/거부 차단(403)은 화면에서 재현할 수 없어(아래 참고) API/단위 테스트로 검증합니다.


사전 준비 / 시드

별도 시드 스크립트는 필요 없습니다. 이 가이드의 모든 상태(검토 대기활성/비활성)는 검증 절차 자체가 화면에서 생성합니다. E2E 스펙(ui/tests/mcp-tool-p21-e2e.spec.ts)도 동일하게 각 시나리오에서 zz_e2e_mcp_* 도구를 직접 만들고, 끝나면 API로 소프트 삭제합니다.

  • 계정: 워크스페이스 admin 계정(글로벌 admin 역할이면 충족).
  • 타깃 테이블: 예시는 iceberg.silver.orders 를 씁니다. 환경에 해당 테이블이 없어도 검토 대기 등록·검토 게이트 흐름은 그대로 검증됩니다(EXPLAIN의 통계 부재 경고만 환경에 따라 달라짐).
  • 검증 후 만든 도구는 목록에서 ⋯ 삭제(소프트 삭제) 로 정리할 수 있습니다.

1. 등록 화면 — 마법사 / 고급 탭 (S1)

좌측 사이드바 MCP Tools → [도구 등록] 으로 들어가면 등록 화면에 마법사(Wizard)고급(Advanced — raw SQL) 두 탭이 보입니다. 기본은 마법사 탭입니다.

등록 화면 — 마법사/고급 탭

고급(Advanced — raw SQL) 탭을 클릭하면 raw-SQL 작성 영역이 열립니다. 상단에 "직접 작성한 SQL은 항상 '검토 대기'로 등록되며, 워크스페이스 admin 승인 후에만 활성화된다" 는 노란 안내가 떠 있고, Monaco SQL 에디터가 표시됩니다.

고급 탭 — raw-SQL 에디터 + 검토 안내

확인 포인트(QA): 두 탭이 모두 보이는지, 고급 탭에 Monaco 에디터와 "검토 대기" 안내가 함께 나오는지 확인합니다.


2. 고급 작성 → EXPLAIN 비용 미리보기 (S2)

고급 탭에서 도구 이름(snake_case), 대상 테이블 FQN(필수, catalog.schema.table), 그리고 SELECT SQL 을 입력합니다. 검토 요청(Submit for review) 을 누르면 도구가 검토 대기 로 등록되고 "검토 요청됨" 안내가 뜹니다.

검토 요청 완료 — 제출 안내

EXPLAIN은 등록된 도구에 대해 동작하므로, 검토 요청 후 EXPLAIN(비용 미리보기) 버튼이 활성화됩니다. 클릭하면 비용 미리보기 패널이 나타나며, 다음 중 하나를 보여줍니다.

  • 예상 스캔 행 / 예상 스캔 바이트 + 쿼리 플랜 — 테이블 통계가 있을 때.
  • "통계 없음 — 검토자가 스캔 범위를 수동 확인해야 함" 경고 — estimate_available=false(통계 부재)일 때. 이 경우 숫자(0/0) 대신 경고를 노출해 "아무 것도 스캔 안 함" 오해를 막습니다.

EXPLAIN 비용 미리보기 — 스캔 행/바이트 또는 통계 부재 경고

확인 포인트(QA): 비용 미리보기 패널에 스캔 행/바이트 또는 통계 부재 경고 중 하나가 뜨고, 쿼리 플랜이 함께 보이는지 확인합니다. (비용 상한 초과·SqlGuard 거부 시에는 빨간 오류 박스로 표시됩니다.)


3. 검토 요청 → 목록의 검토 대기 배지 (S3)

검토 요청한 도구는 MCP Tools 목록(/workspace/mcp-tools)에 나타나며, 상태 열에 노란 검토 대기(Pending review) 배지가 붙습니다.

목록 — 검토 대기 배지

확인 포인트(QA): 방금 등록한 도구가 목록에 보이고 상태가 검토 대기인지 확인합니다(자가 활성화가 일어나지 않음).


4. ws-admin 검토 큐 — 승인/거부 (S4)

검토 대기 도구가 있으면 목록 상단에 검토 큐(ws-admin 전용)가 나타납니다. 각 행은 검토 가능한 raw-SQL 코드 미리보기를 함께 보여줍니다(승인 전에 실제 SQL을 눈으로 확인).

검토 큐 — raw-SQL 코드 미리보기

4-1. 승인(활성화)

행의 승인(Approve) 을 누르면 /activate 가 호출되어 도구가 활성(active) 으로 바뀝니다.

승인 → 활성

4-2. 거부(비활성)

다른 검토 대기 도구의 거부(Reject) 를 누르면 /reject 가 호출되어 비활성(disabled) 으로 떨어집니다.

거부 → 비활성

확인 포인트(QA): 검토 큐에 raw-SQL 미리보기가 보이는지, 승인 시 활성·거부 시 비활성 으로 상태가 정확히 바뀌는지 확인합니다.


5. SqlGuard 음성(negative) — DDL/다중 문 거부 (S5)

고급 탭에 DDL 또는 다중 문(예: DROP TABLE …, 또는 SELECT 1; SELECT 2)을 넣고 검토 요청하면, 백엔드 SqlGuard가 422로 거부합니다. UI는 이를 인라인 오류 박스로 분명히 표시하며(절대 조용히 아무 일 안 일어나지 않음), 도구는 생성되지 않습니다.

DDL/다중 문 → 인라인 422 오류, 도구 미생성

목록으로 돌아가 거부된 이름이 어디에도 없는지 확인합니다(생성되지 않았음).

목록 — 거부된 도구는 생성되지 않음

확인 포인트(QA): 인라인 오류가 뜨고 "검토 요청됨" 안내는 나오지 않아야 하며, 목록에 해당 도구가 생성되지 않아야 합니다.


QA 체크리스트 요약

#시나리오기대 결과
S1등록 화면 탭마법사·고급 탭 모두 표시, 고급 탭에 Monaco + 검토 안내
S2고급 작성 → EXPLAIN비용 미리보기(스캔 행/바이트) 또는 통계 부재 경고 + 쿼리 플랜
S3검토 요청목록에 검토 대기 배지로 등장
S4검토 큐 승인/거부raw-SQL 미리보기 노출, 승인→활성, 거부→비활성
S5SqlGuard 음성DDL/다중 문 → 인라인 422 오류, 도구 미생성
비-admin 활성화/거부 403(화면 불가) API/단위 테스트로 검증

비-admin 403은 화면으로 검증 불가: E2E 계정이 admin 이라 비-admin 의 활성화/거부 차단(403)은 브라우저로 재현할 수 없습니다. 이는 API/단위 테스트 apps/api/tests/test_workspace_mcp_tool_pending_review.py 가 검증합니다(비-admin 활성화/거부 → 403, 검토 대기 가 아닌 도구 활성화 → 409).


알아두기

  • 자가 활성화 불가: 직접 작성한 raw-SQL은 작성자 본인이 활성화할 수 없습니다 — 반드시 별도 ws-admin 검토를 거칩니다.
  • 읽기 전용 보증: SqlGuard가 작성 시점에 SELECT 단일 문만 통과시킵니다. workspace_id 격리는 백엔드가 주입합니다.
  • EXPLAIN은 등록 후: 비용 미리보기는 도구가 만들어진 뒤(검토 대기 상태)에 실행됩니다.
  • 소프트 삭제: 삭제는 status=deleted 소프트 삭제이며, 같은 이름을 나중에 다시 등록할 수 있습니다.