"재고 몇 개 남았어요?"

ONE STOCK — 중소 제조업 ERP 위에 AI를 얹으면 생기는 일

뷰티 제조업체에서 하루에도 수십 번 오가는 질문이다.

영업팀이 물어보고, 생산팀이 물어보고, 대표가 물어본다. 그때마다 누군가는 이카운트 ERP에 접속해서 품목코드를 검색하고, 창고별 수량을 확인하고, Teams로 답변을 보낸다. 한 건당 2-3분. 하루에 열몇 번씩 반복되면 은근히 시간을 잡아먹는다.

나는 제조업 기반의 뷰티 브랜드 회사의 브랜드사업부 팀장으로 근무하고 있다. 그런데 옆자리 영업팀이 "이거 재고 있어?" 확인하느라 매번 흐름이 끊기는 걸 계속 보고 있었다. 시간보다 더 큰 문제는, 질문하는 사람도 답변하는 사람도 자기 할 일을 중단해야 한다는 것이었다.

아무도 이걸 문제라고 말하지 않았다. 그냥 원래 그런 거니까.

흩어진 데이터

  • 재고 → 이카운트 ERP
  • 생산 요청 → Teams 채팅
  • BOM(자재명세서) → 엑셀 파일
  • 생산 계획 → 담당자 머릿속

이 데이터들이 연결되지 않으니, "이 제품 100개 만들려면 원자재 충분해?" 같은 질문에 답하려면 ERP 켜고, 엑셀 열고, 계산기 두드려야 했다.

중소 제조업 163,000개 중 76%가 ERP를 쓰고 있지만, AI를 활용하는 곳은 1%도 안 된다. 데이터는 있는데 연결이 안 되는 거다.


개별 API 지옥에서 MCP로

처음 접근은 단순했다. 이카운트 ERP에 OAPI가 있으니까, API를 하나씩 호출해서 필요한 데이터를 뽑으면 되겠다 싶었다.

막상 해보니 이게 보통 일이 아니었다.

재고 조회 API 따로, 판매 조회 API 따로, BOM API 따로. 각각 인증 방식이 다르고, 응답 포맷이 다르고, 세션 관리도 개별적으로 해야 한다.

나는 마케터다. IT팀도 없고, 외주 예산도 없다.
그런데 이 병목을 해결할 사람이 아무도 없었다.
그래서 직접 만들기로 했다.

AI 에이전트를 활용해서 개발하는 방식을 택했다. 그러다 MCP(Model Context Protocol)를 알게 됐다.

MCP가 뭐길래

핵심은 간단하다. 개별 API들을 하나의 "도구(Tool)" 인터페이스로 통합하는 것. get_inventory, get_bom, get_forecast 같은 도구를 한 번 정의해두면, 어떤 AI 모델이든 같은 방식으로 호출할 수 있다.

개별 API 10개를 따로 관리하는 게 아니라, MCP 서버 하나가 10개의 핸들러를 품고 있는 형태다.

ONE STOCK 시스템 아키텍처

세션 관리, 에러 처리, 캐싱 같은 공통 로직은 MCP 서버 안에서 한 번만 구현하면 전체 핸들러가 공유한다. 비개발자인 내가 이 규모의 시스템을 혼자 만들고 유지할 수 있었던 건, 이 아키텍처 덕분이었다.

ONE STOCK 대시보드

실제 운영 화면은 회사 정보가 포함되어 있어 목업 페이지로 대체했습니다


14일의 기록

백엔드 개발자한테 말 안 하고 외주 줬다가 터진 사건

개발 초기에 대형 사고를 쳤다.

백엔드는 Claude Code로 만들고 있었는데, 어느 날 문득 이런 생각이 들었다. "프론트엔드는 프론트를 잘 만드는 Antigravity한테 시키면 어떨까?"

그래서 백엔드 담당 AI한테 아무 말 없이, 다짜고짜 옆동네 프론트엔드 AI한테 "이거 예쁘게 만들어줘"라고 던졌다. 결과? 백엔드 설정 파일 전부 덮어써졌다. 복구하는 데 반나절이 걸렸다.

This is fine

사람이든 AI든, 소통이 제일 중요하다. 백엔드 담당한테 허락도 없이 옆동네 프론트엔드에 외주 줬다가 전부 꼬여버렸다.

이카운트 내부 API 발견기

이카운트 공식 OAPI에는 BOM 조회 API가 없었다. 판매 현황 API도 상세 데이터를 안 내려준다.

공식 API에 없으면 어떡하지?

여기서 포기할 수도 있었는데, 이카운트 웹 클라이언트의 네트워크 요청을 뜯어보기 시작했다. 개발자 도구(F12) 열고, 버튼 하나씩 눌러보면서 어떤 요청이 날아가는지 관찰했다.

// 이카운트 내부 API - BOM 조회
const bomEndpoint = 'ECAPI/SVC/Inventory/Bom/GetListBomStatus'
 
// 이 한 줄을 찾기까지 이틀이 걸렸다

BOM 2,813건을 한 번에 수집했다. 제품별 원자재 구성, 수량, 공정 정보가 전부 들어왔다. 공식 API에 없다고 포기하지 않길 잘했다.

이카운트 관계자분이 이 글을 보신다면 — 공식 OAPI에 BOM 엔드포인트 추가를 진심으로 부탁드립니다.

세션 관리 버그와의 사투

ERP API 연동에서 가장 골치 아팠던 건 세션 관리. 이카운트는 접속할 때마다 "인증 토큰"을 발급받는데, 이게 30분마다 만료된다.

처음에는 이 토큰을 임의로 만들어서 넣었다가 전체 시스템이 먹통이 됐다.

// ❌ 이렇게 하면 안 된다
const session = Math.random().toString(36)
 
// ✅ 로그인 응답에서 추출해야 한다
const session = loginResponse.split(':')[1]

결국 모든 API 호출 전에 "토큰 유효한지 확인 → 만료됐으면 자동 재로그인" 로직을 넣었다. 이 구조 덕분에 프로덕션에서 인증 관련 에러 0건.

ONE STOCK 재고현황

실제 운영 화면은 회사 정보가 포함되어 있어 목업 페이지로 대체했습니다

실시간 vs 캐시

재고 조회에서 고민이 있었다. 매번 ERP에 직접 물어보면 정확하지만 느리다 (API 호출 간격 1.1초 제한). 미리 저장해둔 데이터를 보여주면 빠르지만 최신이 아닐 수 있다.

결론은 둘 다 제공하되, 사용자가 선택하게 하는 것이었다.

기본은 저장된 데이터에서 즉시 응답하고, 급할 때는 "실시간 확인" 버튼으로 ERP를 직접 호출한다.


Teams 재고봇: 0.8초

대시보드를 만들었지만, 현장 직원들에게 "웹에 접속해서 확인하세요"는 현실적이지 않았다. 이 사람들은 이미 하루 종일 Teams로 소통하고 있다.

그럼 Teams 안에서 바로 확인할 수 있게 만들면 되지 않나?

Power Automate로 Teams 봇을 연결했다. /재고 AZ2505라고 치면 0.8초 만에 창고별 재고 현황이 올라온다.

Teams 재고봇 응답 화면

이전에는 "AZ2505 재고 몇 개야?" → 담당자 확인 → ERP 접속 → 검색 → Teams 답변. 길면 10분, 담당자가 자리를 비우면 답이 올 때까지 기다려야 했다. 지금은 본인이 직접 0.8초 만에 확인한다.

재고 문의 90% 감소의 실체는 간단하다. 시스템이 대단해서가 아니라, 사람들이 이미 쓰고 있는 도구 안에 답을 넣어준 것.


결과

ONE STOCK 생산관리

실제 운영 화면은 회사 정보가 포함되어 있어 목업 페이지로 대체했습니다

14일 만에 개발을 끝내고 화장품 제조업체에 도입했다. 현재 60명이 전사적으로 사용하고 있다.

90%재고 문의 감소
0건요청 누락 (Teams→시스템)
0.8초Teams 봇 응답 시간
2,813BOM 데이터 자동 수집

현재 운영 중인 기능

  • Teams 재고봇/재고 품목코드로 즉시 조회
  • 재고현황 대시보드 — 제품 검색, 창고별 분류, 실시간 확인
  • 생산 허브 — 생산 요청 관리, 긴급 요청, BOM 원자재 체크
  • 품질 관리 — 이슈 등록, 로트번호 추적, 상태 관리
  • AI 수요 예측 — 판매 이력 기반 이동평균/지수평활/계절성 분석
  • ONE BOARD — 매출 대시보드, 플랫폼별 공헌이익 분석

돌아보며

아무도 시키지 않았다. 생산팀 옆자리에서 매일 반복되는 비효율을 보다가, 직접 진단하고 설계하고 배포했다. 지금 60명이 매일 쓰고 있다.

공식 API에 없는 기능이라고 멈추지 않은 것. 이카운트 웹 화면에서 네트워크 탭을 이틀 동안 뜯어본 것. 세션 버그에 매달린 것.

중요한 건 코딩 실력이 아니었다.
문제를 문제로 인식하는 것,
그리고 해결할 도구를 찾아서 끝까지 가져가는 것.

마케터가 ERP 위에 AI를 얹어서 전사 시스템을 만들었다는 게 중요한 게 아니다. 누구든 현장의 병목을 직접 관찰하고, 적절한 도구를 선택하고, 끝까지 실행하면 같은 결과를 만들 수 있다.