4강. 실습 준비 - MCP 계정 권한 검증하기

12. 역할별 권한 경계 검증
→ MCP 조회 성공과 UPDATE 차단, inventory_operator의 DELETE·DDL 차단을 직접 확인합니다.
이 강의는 MCP 연결 표시만 확인하고 끝나지 않습니다.
허용한 조회는 성공하고 허용하지 않은 쓰기는 거부되는지 모두 확인해야 합니다.
12.1 MCP에서 세 테이블 조회하기
Claude Code에 다음과 같이 요청합니다.

inventory DB의 테이블 목록과 각 테이블의 행 수를 확인해줘.
조건:
- 실행할 SELECT SQL을 먼저 보여준다.
- products, stock_logs, operation_requests를 확인한다.
- 확인하지 못한 열이나 데이터는 추측하지 않는다.
내가 SQL을 검토하고 승인하기 전에는 실행하지 마.
Claude Code가 제안한 SQL에서 다음 내용을 확인합니다.
SELECT만 포함되어 있는가?- 세 실습 테이블을 모두 조회하는가?
- 데이터 변경 문장이 없는가?
SQL을 검토한 뒤 실행을 승인합니다.


| 테이블 | 기대 행 수 |
products |
8 |
stock_logs |
16 |
operation_requests |
0 |
12.2 MCP에서 UPDATE 차단 확인하기
는 MCP 서버의 쓰기 제한과 inventory_reader의 DB 권한이 함께 적용되는 연결 경로에서 다시 확인합니다.
현재 값을 같은 값으로 다시 저장하는 UPDATE를 요청합니다. 실제 값은 바뀌지 않지만 UPDATE 권한이 필요한 SQL입니다.

inventory.products에서 product_id가 1인 행의
stock_quantity를 현재 값으로 다시 저장하는 UPDATE를 준비해줘.
조건:
- 실행할 SQL을 먼저 보여준다.
- 다른 행과 다른 열은 변경하지 않는다.
- 권한 오류나 읽기 전용 차단 메시지를 그대로 설명한다.
내가 승인하기 전에는 실행하지 마.
검토할 SQL은 다음과 같습니다.
UPDATE inventory.products
SET stock_quantity = stock_quantity
WHERE product_id = 1;
승인 후에도 MCP 서버의 쓰기 제한 또는 MySQL 계정 권한에서 실행이 거부되어야 합니다.

12.3 inventory_operator의 DELETE와 DDL 차단 확인하기
inventory_operator는 이후 강의에서 제한된 변경을 수행하지만, 삭제와 DB 구조 변경은 수행할 수 없어야 합니다. 터미널에서 직접 접속합니다.
mysql \
-h 127.0.0.1 \
-u inventory_operator \
-p \
inventory
존재하지 않는 행을 대상으로 DELETE 권한을 확인합니다.
DELETE FROM stock_logs
WHERE log_id = 0;
테이블 생성 권한을 확인합니다.
CREATE TABLE permission_test (
id INT PRIMARY KEY
);
두 SQL 모두 권한 오류로 거부되어야 합니다.
관리자 연결에서 permission_test가 생성되지 않았는지 확인합니다.
SHOW TABLES LIKE 'permission_test';
조회 결과가 없어야 합니다.
12.4 차단 실습 후 기준 데이터 다시 확인하기
Claude Code의 MCP 조회 또는 inventory_reader 직접 연결에서 다음 SQL을 실행합니다.
SELECT COUNT(*) AS products_count
FROM products;
SELECT COUNT(*) AS stock_logs_count
FROM stock_logs;
SELECT COUNT(*) AS operation_requests_count
FROM operation_requests;
SELECT
product_id,
product_name,
stock_quantity
FROM products
WHERE product_id = 1;
기대 결과는 다음과 같습니다.
products: 8건stock_logs: 16건operation_requests: 0건- 상품 1번의
stock_quantity: 25
▶ 지금 해보세요
- MCP에서 세 테이블의 행 수를 조회합니다.
- 현재 값을 같은 값으로 저장하는
UPDATE를 요청하고 거부를 확인합니다. inventory_operator의DELETE와CREATE TABLE이 거부되는지 확인합니다.- 기준 데이터와 상품 1번 재고가 바뀌지 않았는지 다시 조회합니다.
✔ 보안 원칙: MCP 서버 설정과 MySQL 계정 권한을 함께 사용합니다. 한쪽 설정이 잘못되어도 다른 쪽에서 쓰기를 막을 수 있어야 합니다. MCP에서 세 테이블을 조회할 수 있고, MCP의 UPDATE 요청이 거부되고, inventory_operator의 DELETE와 DDL이 거부되며, 차단 실습 후 기준 데이터가 8 / 16 / 0과 상품 1번 재고 25로 유지됩니다.
13. MySQL 계정과 MCP 연결 오류 해결하기
→ 문제가 생겼을 때 원인을 좁히는 순서와 증상별 확인 항목을 정리합니다.
문제가 생기면 다음 순서로 원인을 좁힙니다. 설정을 무작정 다시 만들지 않습니다.
MySQL 서비스 실행
↓
inventory DB와 세 테이블 존재
↓
inventory_reader 직접 접속과 SELECT
↓
SHOW GRANTS의 계정·호스트 확인
↓
node와 npx 실행
↓
claude mcp get의 등록 정보
↓
Claude Code /mcp 연결 상태
| 증상 | 먼저 확인할 항목 | 해결 방향 |
Unknown database 'inventory' |
db/schema.sql 실행 여부 |
관리자 연결로 스키마 스크립트 실행 |
Access denied |
사용자명, 비밀번호, 계정 호스트 | SHOW GRANTS와 MCP 환경변수 대조 |
npx를 찾을 수 없음 |
Node.js와 npx 실행 상태 |
기존 Node.js 설치 자료로 환경 복구 |
| MCP가 연결되지 않음 | MCP 환경변수와 서버 실행 명령 | claude mcp get mysql-inventory 확인 |
| 조회 결과가 비어 있음 | 기준 데이터 입력 여부 | 직접 조회에서 8 / 16 / 0 상태 확인 |
inventory_reader의 UPDATE가 실행됨 |
연결 계정과 ALLOW_UPDATE_OPERATION |
MCP 제거 후 계정·설정 재구성 |
inventory_operator의 DELETE가 실행됨 |
잘못 부여된 권한 | 관리자 연결에서 권한 회수 후 재검증 |
MCP 등록 정보를 확인하거나 잘못된 설정을 제거할 때 다음 명령을 사용합니다.
claude mcp get mysql-inventory
claude mcp remove mysql-inventory
⚠ 주의: 연결 오류를 해결하기 위해 관리자 계정을 MCP에 연결하거나 inventory_reader의 쓰기 권한을 넓히지 않습니다.
13. 이번 강의 완료 기준
→ 체크리스트로 1강 완료 상태를 점검하고, 2강으로 넘기는 상태를 확인합니다.
13.1 최종 체크리스트
다음 항목을 모두 확인합니다.
- ☐ MySQL, Claude Code, Node.js와
npx가 실행됩니다. - ☐
inventory-mysql-app프로젝트 구조가 존재합니다. - ☐
products,stock_logs,operation_requests가 생성되었습니다. - ☐ 상품 8개, 입출고 이력 16건, 실행 요청 0건입니다.
- ☐ 기존 입출고 이력 16건의
request_id가 모두NULL입니다. - ☐ 구축에 사용한 관리자 연결의 실제 권한을
SHOW GRANTS로 확인했습니다. - ☐
inventory_reader,inventory_operator,inventory_app계정이 분리되어 있습니다. - ☐
inventory_reader는SELECT만 가능합니다. - ☐
inventory_operator는 필요한 DML만 가능하고DELETE·DDL은 불가능합니다. - ☐
inventory_app은 1강에서SELECT만 가능합니다. - ☐ 관리자 계정은 MCP 설정에 사용되지 않았습니다.
- ☐ Claude Code의 MCP 접근과 Python 소스 코드의 Driver 접근을 구분할 수 있습니다.
- ☐
mysql-inventoryMCP가inventory_reader계정으로 연결됩니다. - ☐ MCP 조회에서 세 테이블의 기준 건수
8 / 16 / 0을 확인했습니다. - ☐ MCP의
UPDATE가 차단됩니다. - ☐
inventory_operator의DELETE와 DDL이 차단됩니다. - ☐ 차단 실습 후 기준 데이터가 변경되지 않았습니다.
13.2 완성 구조
inventory-mysql-app/ # ✅ 프로젝트 구조 생성
├── db/
│ ├── schema.sql # ✅ 테이블 설계
│ └── roles.sql # ✅ 계정 설계
├── harness/ # ✅ (빈 폴더)
└── app/ # ✅ (빈 폴더)
inventory DB # ✅ DB 구현
├── products 8건 # ✅ 테이블과 데이터 구현
├── stock_logs 16건 # ✅ 테이블과 데이터 구현
└── operation_requests 0건 # ✅ 테이블과 데이터 구현
DB 접근 경로와 계정
├── Claude Code MCP ───── inventory_reader # ✅ 계정 구현 + MCP 연동
├── Python 하니스 ───── inventory_operator # ✅ 계정만 구현 + 연동X
└── PySide6 앱 ───── inventory_app # ✅ 계정만 구현 + 연동X
13.3 이번 강의에서 아직 하지 않는 작업
- Python 실행 하니스 작성
inventory_operator를 사용한 실제 재고 변경- 트랜잭션과 행 잠금 적용
- 변경 대상 미리 보기
- 실행 승인과 요청 ID 중복 차단
- 요청과 재고 이력의 증거 흐름 분석
- PySide6 화면과
inventory_app쓰기 기능 구현 - MCP, 실행 하니스, 앱 중 작업 위치를 선택하는 세부 판단 기준
위 작업은 3~8강에서 순서대로 수행합니다.
13.4 다음 강의로 넘기는 상태
2강은 다음 상태에서 시작합니다.
inventoryDB가 존재합니다.- 세 테이블의 구조가 확정되어 있습니다.
- 상품 8개와 입출고 이력 16건이 존재합니다.
operation_requests는 비어 있습니다.- Claude Code의 MySQL MCP가 읽기 전용으로 연결되어 있습니다.
- MCP 조회 결과와 MySQL 직접 조회 결과를 대조할 수 있습니다.
2강에서는 이 상태를 이용하여 AI가 생성한 조회 SQL과 결과를 다음 네 요소로 나누어 검증합니다.
자연어 요청
↕
실제 스키마
↕
AI가 생성한 SELECT SQL
↕
실행 결과
13.5 참고 문서
공식 문서: Claude Code MCP 공식 문서
Connect Claude Code to tools via MCP - Claude Code Docs
Learn how to connect Claude Code to your tools with the Model Context Protocol.
code.claude.com
그 밖에 MySQL MCP 서버 후보 저장소를 참고하세요. 이 저장소는 Claude Code 공식 문서와 별개의 공개 구현입니다. 실제 수업에 적용하기 전에 저장소 상태, 라이선스, 요구 Node.js 버전, 환경변수 이름을 다시 확인합니다.
→ 다음 강의 (2강): 이번 강의에서 연결한 읽기 전용 MCP를 사용해, AI가 생성한 조회 SQL과 결과를 요청 조건·실제 스키마와 대조해 검증하는 습관을 만듭니다.
14. 실습 과제
→ 계정·권한 대응표 작성, 최소 권한 오류 찾기, 권한 제한 결과 제출로 1강 내용을 스스로 점검합니다.
14.1 계정과 DB 접근 경로 대응표 작성하기
다음 작업을 수행할 계정과 접근 경로를 선택하고 근거를 작성합니다.
| 작업 | 접근 경로 | 선택할 계정 | 선택 근거 |
| Claude Code에서 상품 목록 조회 | |||
| 5강 실행 하니스에서 재고 수량 갱신 | |||
| PySide6 앱에서 상품 목록 조회 | |||
| 테이블 생성 | |||
| 재고 이력 삭제 |
✔ 완료 기준:
· Claude Code의 DB 조회에 MySQL MCP와 inventory_reader를 선택했습니다.
· 실행 하니스의 승인된 변경에 MySQL Driver와 inventory_operator를 선택했습니다.
· PySide6 앱의 조회에 MySQL Driver와 inventory_app을 선택했습니다.
· 테이블 생성은 세 역할별 계정의 담당 작업이 아니라고 판단했습니다.
· 재고 이력 삭제는 허용하지 않는 작업이라고 판단했습니다.
14.2 최소 권한 오류 찾기
다음 권한 설정의 문제를 찾고 수정합니다.
GRANT ALL PRIVILEGES
ON inventory.*
TO 'inventory_reader'@'127.0.0.1';
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, ALTER, DROP
ON inventory.*
TO 'inventory_operator'@'127.0.0.1';
✔ 완료 기준:
· inventory_reader를 SELECT 전용으로 수정했습니다.
· inventory_operator에서 DELETE와 DDL 권한을 제거했습니다.
· inventory_operator의 UPDATE 범위를 products.stock_quantity로 제한했습니다.
· 필요한 INSERT 대상 테이블을 구분했습니다.
14.3 권한 제한 결과 제출하기
다음 결과를 캡처하거나 텍스트로 기록합니다.
- 관리자 연결의
SHOW GRANTS inventory_reader직접 연결의SELECT성공inventory_reader직접 연결의UPDATE차단 메시지inventory_operator의DELETE차단 메시지inventory_operator의CREATE TABLE차단 메시지- MCP의 세 테이블 조회 성공
- MCP의
UPDATE차단 메시지 - 차단 실습 후
8 / 16 / 0기준 건수
✔ 완료 기준:
· 허용 작업과 차단 작업의 결과가 모두 포함되어 있습니다.
· 오류 메시지를 임의로 성공 메시지로 바꾸지 않고 핵심 문구를 기록했습니다.
· 차단 실습 후 데이터가 변경되지 않았음을 확인했습니다.