Joule Agent와 MCP로 S/4HANA에 자연어로 질문하기
구조부터: 질문 하나가 지나가는 길
Joule Studio의 Agent Builder는 외부 MCP(Model Context Protocol) 서버를 도구로 붙일 수 있습니다. S/4HANA 데이터를 자연어로 묻는 에이전트를 만든다면, 질문은 대략 이런 길을 지나갑니다.
ASPN BAC 사업부는 S/4HANA Public Cloud의 재무 분석용 CDS 뷰(운전자본, 매출채권, 매입채무, 재고, 판매 등)를 OData로 노출하고, 이를 MCP 서버로 감싸 Joule과 범용 AI 클라이언트 양쪽에 연결해 검증했습니다. 아래는 그 과정에서 정리한 실무 포인트입니다.
연결 설정: 문서에서 놓치기 쉬운 두 가지
Joule Studio에서 MCP 서버를 쓰려면 BTP 서브계정에 HTTP Destination을 만들고 Agent Builder의 Tools 패널에서 선택합니다. 이때 두 가지를 놓치면 목록에 서버가 나타나지 않거나 연결이 실패합니다.
추가 속성
sap-joule-studio-mcp-server = true— 이 속성이 없으면 Joule Studio의 MCP 서버 선택 목록에 해당 Destination이 표시되지 않습니다.URL에
/mcp를 붙이지 않는다 — Destination URL은 서버 루트까지만 적습니다. 경로는 Joule Studio 쪽에서 붙입니다.
교훈 1. 집계는 서버가 해야 한다
가장 큰 교훈은 도구 설계에 있었습니다. 초기 MCP 서버는 CDS 뷰의 원시 행(전표 라인)을 돌려주는 도구 위주였습니다. "회사별 거래유형 분포를 보여 줘" 같은 질문이 들어오면, 에이전트는 수십~수백 KB의 원시 데이터를 받아 스스로 GROUP BY를 하려다 실패했습니다.
로그를 시간 순으로 맞춰 보니 양상이 분명했습니다.
MCP 서버의 도구 응답 시간은 건당 1초 안팎으로, 전체 실행 시간의 극히 일부였습니다.
마지막 도구 호출 이후 전체 시간의 70% 이상 동안 도구를 더 부르지 않고 모델 내부에서만 처리하다 반복 한도에 걸려 종료되었습니다.
일부 응답은 실제 데이터에 존재하지 않는 건수와 금액을 제시했습니다.
원인은 크기 그 자체보다 집계 책임이 서버에 없었다는 데 있었습니다. 질문 유형에 맞는 집계 도구(축과 필터를 파라미터로 받아 서버에서 집계해 돌려주는 도구)를 추가하자, 같은 질문의 응답이 약 148KB에서 1.2KB로 줄었고 결과도 원천 데이터와 정확히 일치했습니다.
정리하면 이렇습니다.
하지 말 것 | 할 것 |
|---|---|
원시 행을 넘기고 모델에게 계산을 맡김 | 서버가 집계하고 결과만 반환 |
행 수 제한으로 조용히 잘라서 반환 | 잘렸으면 잘렸다고 응답에 명시 |
회사·기간 미지정 시 기본값을 조용히 대입 | 적용한 조건을 응답에 함께 반환 |
거래유형 등 코드값만 반환 | 코드 텍스트를 조인해서 반환 |
마지막 항목도 실제로 겪은 일입니다. 서버가 거래유형 코드만 돌려주자 모델이 코드의 의미를 영문 이니셜로 추측해 풀이했고, 그중 일부는 틀렸습니다. 모델이 추측할 여지를 남기지 않는 것이 도구 설계의 기본입니다.
교훈 2. 권한은 "누가 묻는가"까지 이어져야 한다
재무 데이터를 AI에 연결할 때 가장 먼저 받는 질문은 "아무나 다 볼 수 있게 되는 것 아니냐"입니다. 저희가 검증한 구조는 세 층입니다.
행 수준 권한 (CDS DCL) — Principal Propagation으로 사용자 본인의 신원이 S/4HANA까지 전달되면, CDS 뷰의 DCL이 그 사용자가 볼 수 있는 회사코드의 데이터만 반환합니다. AI가 아니라 ERP의 권한 체계가 범위를 정합니다.
노출 수준 (마스킹) — 같은 데이터라도 AI 채널로 나갈 때 거래처명 같은 식별 정보를 가리는 정책을 사용자별로 적용합니다.
감사 로그 — 누가, 어떤 도구로, 어떤 조건으로, 몇 건을 조회했는지를 구조화해 기록합니다.
다만 검증 시점(2026년 7~8월) 기준으로, Joule이 Destination을 통해 MCP 서버를 호출할 때는 서비스 신원으로 호출되어 사용자 신원이 첫 단계에서 이어지지 않았습니다. 그래서 설계를 나눴습니다.
민감도가 낮은 마스터·구조 조회 → 기술 사용자 + 도구 단위 권한 통제로 Joule에 개방
사용자별 데이터 범위가 필수인 조회 → 사용자 신원 전파가 되는 경로로 분리
장기적으로는 SAP의 MCP Gateway 등 공식 경로의 발전을 따라감
플랫폼 기능은 빠르게 바뀌고 있으므로, 도입 시점에 신원 전파 방식부터 다시 확인하는 것을 권합니다.
교훈 3. 배포에서 반복해서 만난 함정
MCP 서버를 BTP Cloud Foundry에 배포하며 반복해서 겪은 문제들입니다. 로컬 테스트로는 잡히지 않는 유형이라 기록해 둘 가치가 있습니다.
의존성 버전은 반드시 고정한다. 버전을 고정하지 않았더니 배포 시점에 MCP SDK의 메이저 버전이 올라가 있었고, 모듈 경로가 바뀌어 기동하지 못했습니다. 로컬은 이전 버전이라 문제가 보이지 않았습니다.
Host 헤더 검사에 배포 도메인을 등록한다. MCP의 HTTP 전송은 DNS 리바인딩 방지를 위해 Host 헤더를 검사하는데, 기본 허용 목록이 localhost 계열이라 CF 라우트로 들어온 요청이 거부됩니다. 허용 목록은 하드코딩보다 런타임 환경변수에서 읽는 편이 라우트 변경에도 안전합니다.
로컬 stdio 모드에서는 표준출력에 아무것도 쓰지 않는다. stdio 전송에서는 표준출력이 곧 통신 채널이라, 진단용 print 한 줄이 연결을 깨뜨립니다. 로그는 표준오류로 보내야 합니다.
자격증명은 manifest에 쓰지 않는다. user-provided service로 묶어 두면 비밀번호 교체 시 한 곳만 바꾸면 됩니다.
교훈 4. 평가 방식도 바꿔야 한다
에이전트를 테스트할 때 처음에는 "성공/실패"로 기록했습니다. 그런데 응답이 그럴듯하게 돌아왔다고 해서 맞는 것은 아니었습니다. 실제로 응답에 나온 건수와 금액을 원천 데이터와 대조해 보니, 형식은 완벽한데 내용은 근거가 없는 경우가 있었습니다.
그래서 결과를 세 가지로 나눠 기록합니다.
정답 확인됨 — 원천 데이터와 대조해 일치
응답은 있으나 검증 필요 — 아직 대조하지 않음
무응답 — 도구 미호출, 반복 한도 초과 등
그리고 가능하면 도구가 실제로 실행한 질의문을 응답에 함께 돌려주도록 만듭니다. 모델이 "이렇게 조회했다"고 설명하는 것과, 서버가 "이 문장을 실행했다"고 증명하는 것은 다릅니다.
정리
Joule과 MCP의 조합은 S/4HANA 데이터를 AI 에이전트에 연결하는 표준 경로로 자리 잡아 가고 있습니다. 연결 자체는 어렵지 않습니다. 어려운 것은 도구를 어떻게 나누고, 무엇을 서버가 책임지게 할 것인가입니다. 모델의 추론 능력에 기대기보다 서버가 계산하고, 권한을 따지고, 근거를 남기도록 설계할수록 에이전트의 답은 안정됩니다.
참고
SAP Learning, Leveraging Tools and Model Context Protocol (MCP) for custom Joule agents
SAP Community, SAP Joule Agent with SAP oData MCP Issue
글쓴이 Data&AI — ASPN BAC사업부에서 SAP BDC·Datasphere, 지식그래프, Joule·MCP 기반 AI Agent 구축을 다룹니다. 직접 구성하고 검증하며 얻은 실무 경험을 정리해 공유합니다.