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 에디터가 표시됩니다.

확인 포인트(QA): 두 탭이 모두 보이는지, 고급 탭에 Monaco 에디터와 "검토 대기" 안내가 함께 나오는지 확인합니다.
2. 고급 작성 → EXPLAIN 비용 미리보기 (S2)
고급 탭에서 도구 이름(snake_case), 대상 테이블 FQN(필수, catalog.schema.table), 그리고 SELECT SQL 을 입력합니다. 검토 요청(Submit for review) 을 누르면 도구가 검토 대기 로 등록되고 "검토 요청됨" 안내가 뜹니다.

EXPLAIN은 등록된 도구에 대해 동작하므로, 검토 요청 후 EXPLAIN(비용 미리보기) 버튼이 활성화됩니다. 클릭하면 비용 미리보기 패널이 나타나며, 다음 중 하나를 보여줍니다.
- 예상 스캔 행 / 예상 스캔 바이트 + 쿼리 플랜 — 테이블 통계가 있을 때.
- "통계 없음 — 검토자가 스캔 범위를 수동 확인해야 함" 경고 —
estimate_available=false(통계 부재)일 때. 이 경우 숫자(0/0) 대신 경고를 노출해 "아무 것도 스캔 안 함" 오해를 막습니다.

확인 포인트(QA): 비용 미리보기 패널에 스캔 행/바이트 또는 통계 부재 경고 중 하나가 뜨고, 쿼리 플랜이 함께 보이는지 확인합니다. (비용 상한 초과·SqlGuard 거부 시에는 빨간 오류 박스로 표시됩니다.)
3. 검토 요청 → 목록의 검토 대기 배지 (S3)
검토 요청한 도구는 MCP Tools 목록(/workspace/mcp-tools)에 나타나며, 상태 열에 노란 검토 대기(Pending review) 배지가 붙습니다.

확인 포인트(QA): 방금 등록한 도구가 목록에 보이고 상태가 검토 대기인지 확인합니다(자가 활성화가 일어나지 않음).
4. ws-admin 검토 큐 — 승인/거부 (S4)
검토 대기 도구가 있으면 목록 상단에 검토 큐(ws-admin 전용)가 나타납니다. 각 행은 검토 가능한 raw-SQL 코드 미리보기를 함께 보여줍니다(승인 전에 실제 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는 이를 인라인 오류 박스로 분명히 표시하며(절대 조용히 아무 일 안 일어나지 않음), 도구는 생성되지 않습니다.

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

확인 포인트(QA): 인라인 오류가 뜨고 "검토 요청됨" 안내는 나오지 않아야 하며, 목록에 해당 도구가 생성되지 않아야 합니다.
QA 체크리스트 요약
| # | 시나리오 | 기대 결과 |
|---|---|---|
| S1 | 등록 화면 탭 | 마법사·고급 탭 모두 표시, 고급 탭에 Monaco + 검토 안내 |
| S2 | 고급 작성 → EXPLAIN | 비용 미리보기(스캔 행/바이트) 또는 통계 부재 경고 + 쿼리 플랜 |
| S3 | 검토 요청 | 목록에 검토 대기 배지로 등장 |
| S4 | 검토 큐 승인/거부 | raw-SQL 미리보기 노출, 승인→활성, 거부→비활성 |
| S5 | SqlGuard 음성 | 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소프트 삭제이며, 같은 이름을 나중에 다시 등록할 수 있습니다.