LabHub
배우기 러닝패스 코스

에이전트가 내 DB 를 지웠다 · 누가 언제 무엇을 불렀나 · 실습

감사 로그·스키마 검증·타임아웃·호출 제한을 넣는다

LabHub 에서 이어서 보기

목표

앞 실습에서 막은 서버에 운영에 필요한 네 가지를 더합니다. 모든 호출을 남기는
감사 로그, 실행 전 인자 스키마 검증, 도구별 실행 시간 상한, 파괴적 도구의
호출 횟수 제한. 그리고 그 로그를 읽어 요약하는 도구까지 씁니다.

왜 중요한가

사고가 났을 때 첫 질문은 "누가 언제 무엇을 어떤 인자로 불렀나" 입니다. 감사
로그가 없으면 이 질문에 답할 수 없고, 그러면 같은 사고가 다시 납니다. 스펙은
서버가 모든 도구 입력을 검증하고 호출 빈도를 제한해야 한다(MUST)고, 클라이언트는
도구 호출에 타임아웃을 두고 감사를 위해 사용을 기록해야 한다(SHOULD)고 적습니다.
그 문장을 그대로 코드로 옮기는 것이 이 실습입니다. 특히 타임아웃은 클라이언트만
믿으면 안 됩니다 — 서버가 스스로 끊지 않으면 멈춘 도구 하나가 세션 전체를
잡아 둡니다.

단계

1. /root/mcp/audit/seed.sql 을 저장하고 /root/mcp/audit/shop.db 로 적재하세요. customers 5행, orders 8행이어야 합니다.
2. /root/mcp/audit/server.py 를 만드세요. initialize 에 답하고 tools/listlist_customers·count_orders·delete_order(confirm 필요) 세 도구를 냅니다. DB 경로는 MCP_DB(기본 /root/mcp/audit/shop.db)입니다.
3. 모든 tools/call/root/mcp/audit/audit.jsonl(환경변수 MCP_AUDIT_LOG 로 바꿀 수 있게)에 한 줄 JSON 으로 남기세요. 열쇠는 ts, tool, arguments, ok, duration_ms 이고, 도구가 isError 를 냈으면 ok 는 false 입니다.
4. 도구를 실행하기 전에 inputSchema 로 인자를 검사하세요. required 가 빠졌거나 type 이 맞지 않으면(예: status 에 숫자, id 에 문자열) 실행하지 않고 JSON-RPC 오류 -32602 로 답합니다.
5. 도구 slow_report(인자 seconds, integer)를 더하고 도구 하나의 실행 시간을 2초로 제한하세요(환경변수 MCP_TOOL_TIMEOUT, 기본 2). 넘기면 isError: truetimeout 이 들어간 텍스트로 답하고 감사 로그에 ok: false 로 남습니다. seconds: 1 은 정상으로 끝나야 합니다.
6. initialize 의 capabilities 에 logging 을 선언하고, 도구 호출마다 응답 앞에 notifications/message 알림(level 은 RFC 5424 수준 중 하나, logger, data)을 stdout 으로 내보내세요. 실패한 호출은 error 수준입니다.
7. delete_order 를 한 세션에 3회까지만 허용하세요. 네 번째 호출은 지우지 않고 isError: truerate limit 이 들어간 텍스트로 답합니다.
8. /root/mcp/audit/summary.py 를 만드세요. audit.jsonl 을 읽어 도구별 {"calls": n, "failed": m}/root/mcp/audit/summary.json 에 씁니다(환경변수 MCP_SUMMARY_OUT 이 있으면 그 경로). 실제 audit.jsonl 에 호출 기록이 다섯 줄 이상 쌓여 있어야 합니다.

참고

단계 8개

  1. 가게 DB 를 만든다
  2. 기본 서버를 세운다
  3. 모든 호출을 남긴다
  4. 실행 전에 인자를 검사한다
  5. 도구 실행 시간에 상한을 건다
  6. 로그를 프로토콜로 보낸다
  7. 지우는 도구는 횟수를 제한한다
  8. 감사 로그를 읽어 요약한다