AI 지원 SaaS에 MCP를 추가할 때 여전히 인간의 판단이 필요한 이유
요약
SaaS 제품에 MCP(Model Context Protocol)를 통합할 때 발생하는 실무적 도전 과제를 다룹니다. AI 에이전트가 도구를 호출하는 것보다, 어떤 도구의 권한을 부여하고 모호성을 어떻게 제어할지 결정하는 인간의 판단이 중요함을 강조합니다.
핵심 포인트
- 대화형 인터페이스는 기존 양식(Form)보다 데이터 모호성을 유발할 수 있음
- 멀티 테넌트 환경에서 보안을 위해 회사 범위(Scope)는 반드시 인증된 세션에서 가져와야 함
- 범용적인 도구보다 목적이 명확하고 범위가 좁은(Narrow) 도구가 AI 추론에 더 유리함
- AI가 구현 속도는 높여주지만, 신뢰 경계(Trust Boundary) 설정은 인간의 책임임
저는 여전히 수첩이나 스프레드시트로 직원의 근무 시간을 관리하는 브라질 기업들을 위한 매우 작은 SaaS를 구축하고 있습니다.
제품 이름은 PontoBarato입니다. 이 제품은 상당한 AI의 도움을 받아 빠르게 구축되었습니다.
이것은 완벽하게 설계된 하이퍼스케일 (hyperscale) 시스템에 관한 이야기가 아닙니다. 또한 프롬프트 (prompt)가 보안 설계를 대체할 수 있다고 주장하는 튜토리얼도 아닙니다. 이것은 제가 애플리케이션에 Model Context Protocol (MCP) 인터페이스를 추가했을 때, 여전히 인간의 판단이 필요했던 부분에 대한 제품 수준의 기록입니다.
놀라운 점은 어시스턴트 (assistant)가 도구 (tool)를 호출하도록 만드는 것이 아니었습니다. 어려운 점은 어시스턴트가 무엇을 할 수 있도록 허용해야 하는지를 결정하는 것이었습니다.
기능은 생각보다 단순하지 않았습니다
초기 아이디어는 간단했습니다:
비즈니스 소유자가 제품을 ChatGPT 또는 Claude에 연결하여 자연어 (natural language)로 일상적인 작업을 관리할 수 있게 한다.
현재 공개된 MCP 인터페이스는 다음과 같은 워크플로 (workflows)를 지원합니다:
- 직원 생성 및 업데이트;
- 주간 일정 조회 및 편집;
- 교대 근무 목록화, 생성 및 할당;
- 최근 시간 입력 내역 확인;
- 예상, 근무 및 잔여 시간 조회;
- 초과 근무 및 야간 근무 합계 읽기;
- 선택된 회사 설정 조회 또는 업데이트.
서류상으로는 이것이 기존 기능에 대한 또 다른 인터페이스일 뿐입니다.
실제로 대화형 인터페이스는 일반적인 양식 (forms)이 피할 수 있는 모호함을 도입합니다. 양식에는 필수 필드, 드롭다운, 유효성 검사 메시지 및 가시적인 상태가 있습니다. 사용자는 어떤 회사, 직원 또는 교대 근무가 선택되었는지 볼 수 있습니다.
모델 (model)은 문장을 받습니다.
“Ana를 오전 근무로 옮겨줘”라는 문장은 시스템에 Ana라는 이름의 직원이 두 명 있거나, 동일한 계정에 여러 회사가 있거나, 문자 그대로 “오전”이라고 이름 붙여진 교대 근무가 없을 때까지는 명확하게 들립니다.
따라서 통합 (integration)에는 더 많은 도구가 필요하기 전에 경계 (boundaries)가 필요했습니다.
모델이 테넌트 (tenant)를 선택해서는 안 됩니다
PontoBarato는 멀티 테넌트 (multi-tenant) 방식입니다. 즉, 각 회사는 오직 자신의 직원, 일정 및 시간 기록에만 접근할 수 있어야 합니다.
가장 중요한 제품 규칙은 간단합니다:
회사 범위(Company scope)는 모델이 만들어내거나 제공한 식별자가 아니라, 인증된 세션(authenticated session)으로부터 가져와야 합니다.
설령 도구(tool)가 직원 식별자(employee identifier)를 전달받더라도, 서버는 여전히 해당 직원이 인증된 회사에 속해 있는지 확인해야 합니다.
이는 당연하게 들릴 수 있습니다. 하지만 개발이 생성된 엔드포인트(endpoint)와 해피 패스(happy-path) 테스트의 급격한 연속이 될 때, 사라지기 쉬운 종류의 디테일이기도 합니다.
AI 지원은 구현 속도를 높여주었지만, 신뢰 경계(trust boundary)를 결정해주지는 않았습니다. 그것은 여전히 인간의 책임으로 남았습니다.
범위가 좁은 도구(Narrow tools)가 추론하기 더 쉬웠다
update_record와 같은 범용적인 도구는 빠르게 노출(expose)할 수 있었을 것입니다. 하지만 이를 설명하고, 권한을 부여하며, 검증하고, 감사(audit)하기는 어려웠을 것입니다.
저는 비즈니스 소유자가 인식할 수 있는 작업에 매핑되는 도구들을 선호했습니다:
- 직원 생성 (create an employee)
- 교대 근무 할당 (assign a shift)
- 주간 일정 변경 (change a weekly schedule)
- 시간 잔액 확인 (inspect an hours balance)
- 지오펜스(geofence) 요구사항 업데이트 (update the geofence requirement)
범위가 좁은 도구는 초기에 더 많은 작업을 요구하지만, 나중에 모호함을 줄여줍니다.
또한 더 나은 대화를 만들어냅니다. 만약 어시스턴트(assistant)에게 직원의 이름, 교대 근무, 그리고 선택적인 역할이 필요하다면, 도구 스키마(tool schema)가 정확히 그것을 명시할 수 있습니다. 정보가 누락되었다면, 어시스턴트에게는 질문할 명분이 생깁니다.
목표는 모델에게 데이터베이스로 들어가는 유연한 경로를 제공하는 것이 아니었습니다. 목표는 작은 규모의 비즈니스 기능(business capabilities) 세트를 노출하는 것이었습니다.
읽기 및 쓰기 작업은 다르게 느껴져야 한다
“이번 달 잔액을 보여줘”와 “이 직원을 비활성화해줘”는 동일한 수준의 마찰(friction)을 가져서는 안 됩니다.
저는 도구의 표면(tool surface)을 세 가지 그룹으로 나누어 생각하기 시작했습니다:
| 유형 | 예시 | 주요 고려 사항 |
|---|---|---|
| 읽기 (Read) | 교대 근무 목록 또는 최근 시간 입력 항목 나열 | 범위(scope) 및 데이터 최소화 (data minimization) |
| ... |
이것은 정교한 프레임워크가 아닙니다. 모든 성공적인 도구 호출(tool call)이 동일한 결과를 초래하지 않는다는 점을 상기시켜주는 실용적인 조언입니다.
예를 들어, 시간 추적 (time-tracking) 제품에서는 과거 기록이 여전히 중요하기 때문에 삭제 (deletion)보다는 비활성화 (deactivation)가 보통 더 안전합니다. 대화형 인터페이스 (conversational interface)가 메인 애플리케이션에서보다 파괴적인 동작 (destructive actions)을 더 쉽게 만들어서는 안 됩니다.
애플리케이션은 계산해야 하며, 모델은 설명해야 합니다
시간 추적에는 예상 시간, 근무 시간, 잔액 (balances), 초과 근무 카테고리, 야간 근무와 같은 계산이 포함됩니다.
모델에 가공되지 않은 항목 (raw entries)을 전달하고 결과를 계산해 달라고 요청하고 싶은 유혹이 생길 수 있습니다. 저는 그것을 일반적인 경로로 만드는 것을 피했습니다.
만약 애플리케이션에 이미 계산을 위한 도메인 로직 (domain logic)이 있다면, MCP 도구는 해당 애플리케이션의 결과값을 반환해야 합니다. 그러면 어시스턴트 (assistant)는 그 결과를 요약하거나 설명할 수 있습니다.
그렇지 않으면 대시보드, 내보낸 보고서, 그리고 AI 응답이 서로 일치하지 않을 수 있습니다.
이러한 구분은 디버깅 (debugging)도 더 쉽게 만들었습니다:
- 제품은 비즈니스 규칙 (business rules)에 대한 책임을 유지합니다.
- MCP 레이어 (layer)는 인증 (authentication), 검증 (validation), 그리고 번역 (translation)을 담당합니다.
- 모델은 도구 선택 (choosing tools)과 결과 전달 (communicating results)을 담당합니다.
모델이 비공식적인 급여 엔진 (payroll engine)이 되어서는 안 됩니다.
더 작은 응답이 더 나은 응답이었습니다
저의 첫 번째 본능은 완전한 객체 (complete objects)를 반환하는 것이었습니다. 개발 중에는 데이터가 이미 사용 가능하기 때문에 그것이 쉽습니다.
하지만 어시스턴트에게 실제로 필요한 경우는 드뭅니다.
시간 잔액 (hours-balance) 질문에 대한 유용한 응답에는 다음이 포함됩니다:
- 직원 (employee);
- 기간 (period);
- 예상 분 (expected minutes);
- 근무 분 (worked minutes);
- 잔액 분 (balance minutes);
- 관련 초과 근무 합계 (relevant overtime totals).
내부 플래그 (internal flags), 관련 없는 설정 (unrelated settings), 프레임워크 메타데이터 (framework metadata), 또는 저장된 모든 필드가 필요하지는 않습니다.
압축된 응답 (Compact responses)은 의도치 않은 노출을 줄이고 어시스턴트의 최종 답변을 검증하기 더 쉽게 만듭니다.
명시적인 단위 (explicit units)도 중요합니다. 75를 반환하는 것은 모호합니다. balanceMinutes: 75를 반환하는 것이 훨씬 더 안전합니다.
AI 지원 개발로 인해 검증의 필요성이 증가했습니다
AI 지원은 다음과 같은 작업에 탁월했습니다:
- 반복적인 핸들러 (handlers) 생성;
- 스키마 (schemas) 초안 작성;
- 검증 케이스 (validation cases) 제안;
- 테스트 스캐폴딩 (test scaffolding) 생성;
- 유사한 도구 정의 (tool definitions) 리팩토링;
- 초기 문서 작성.
하지만 다음과 같은 결정에 대한 대체재는 아니었습니다:
- 테넌트 범위 (tenant scope)가 어디에서 오는지;
- 어떤 작업이 너무 파괴적인지;
- 응답이 불필요한 데이터를 노출하는지;
- 어떤 계산이 권위 있는 (authoritative) 것인지;
- 사용자가 무엇을 확인해야 하는지;
- 변경된 레코드를 어떻게 감사 (audited) 할 수 있는지.
생성된 코드는 근본적인 결정이 완료되기 전에도 종종 완성된 것처럼 보입니다.
이것이 이 기능의 핵심 교훈이었습니다: 구현 속도가 빨라질수록 신뢰 경계 (trust boundaries)에서 속도를 늦추는 것의 중요성이 커집니다.
더 많은 도구를 추가하기 전에 내가 할 일
현재 인터페이스는 의도적으로 제한되어 있으며, 제품 자체도 여전히 진화하고 있습니다.
확장하기 전에 나의 체크리스트는 다음과 같습니다:
- 모든 도구에 대해 테넌트 격리 (tenant isolation)를 검증할 것;
- 모호한 이름과 누락된 리소스를 테스트할 것;
- 쓰기 결과는 간결하고 검사 가능하게 유지할 것;
- 되돌릴 수 있는 변경을 선호할 것;
- 반환되는 직원 데이터를 최소화할 것;
- 애플리케이션의 계산 로직을 재사용할 것;
- 민감한 작업은 명확한 의도를 요구하도록 만들 것;
- 무엇이 변경되었는지 이해할 수 있도록 충분한 정보를 기록할 것;
- 성공적인 데모뿐만 아니라 실패 사례도 테스트할 것;
- 기능을 점진적으로 추가할 것.
이 중 어느 것도 MCP에만 국한된 사항은 아닙니다. 대화형 데모가 마법처럼 느껴지기 때문에 MCP는 단지 이러한 사항들을 간과하기 더 쉽게 만들 뿐입니다.
솔직한 결론
상당한 AI의 도움을 받아 유용한 SaaS를 구축할 수 있습니다. 하지만 생성된 코드를 권한 부여 (authorization) 및 비즈니스 규칙이 올바르다는 증거로 취급한다면, 매우 빠르게 심각한 문제를 일으킬 수도 있습니다.
나에게 가치 있는 작업은 모든 줄을 수동으로 입력하는 것이 아니었습니다. 어떤 줄이 존재해야 하는지, 어떤 작업이 노출되지 않아야 하는지, 그리고 내가 실제로 검증할 수 있는 클레임 (claims)이 무엇인지를 결정하는 것이었습니다.
PontoBarato의 MCP 서버는 다음에서 확인할 수 있습니다:
메인 제품은 pontobarato.com에 있습니다.
다른 멀티 테넌트 (multi-tenant) 제품을 위해 MCP 인터페이스를 구축하고 있는 분들의 피드백이 특히 궁금합니다:
기술적으로 구현하기 쉬웠음에도 불구하고, 노출하지 않기로 결정한 작업(operations)은 무엇인가요?
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기