안녕하세요! 핀태그 기술 개발팀 입니다!
지난 공지로 핀태그가 MCP를 지원한다고 알려드렸습니다. 그런데 "MCP가 뭔가요?"라는 질문을 여러 번 받았습니다. 오늘은 MCP가 무엇인지 처음부터 설명하고, 금융 데이터를 다루는 서비스로서 저희가 어떤 선택을 했는지 공유합니다.
1. MCP는 AI 앱의 USB-C입니다
AI에게 "우리 회사 이번 달 카드 지출 정리해줘"라고 물으려면, AI가 우리 회사 데이터를 읽을 수 있어야 합니다. 문제는 AI 앱과 데이터를 가진 서비스가 둘 다 여러 개라는 점입니다.
AI 앱이 4개, 연결할 서비스가 10개라면 필요한 연동은 40개입니다. 서비스마다 인증 방식도, 데이터 형식도 다릅니다. 예전에 노트북마다 충전기가 달랐던 상황과 같습니다.
MCP(Model Context Protocol)는 이 연결 방식을 하나로 정한 규격입니다. 서비스가 MCP 규격에 맞춰 창구를 하나 열어두면, 그 규격을 아는 AI 앱은 모두 붙을 수 있습니다. 40개가 14개로 줄어듭니다.

규격이 정하는 것은 세 가지입니다.
- 무엇을 할 수 있는지 알려주는 방법 — 서비스가 제공하는 기능 목록을 AI가 물어볼 수 있습니다.
- 그 기능을 실행하는 방법 — 이름과 인자를 정해진 형식으로 주고받습니다.
- 인증하는 방법 — 누가 요청했고 어디까지 허용되는지 확인합니다.
2. 도구(tool)라는 개념
MCP에서 서비스가 제공하는 기능 하나하나를 도구(tool) 라고 부릅니다. 핀태그로 치면 "계좌 목록 조회", "카드 거래내역 조회", "현금흐름 예측" 같은 것들입니다.
AI 앱이 연결되면 먼저 도구 목록을 요청합니다. 서버는 이렇게 답합니다.
{ "name": "get_card_transactions",
"description": "카드 사용 내역을 기간·조건으로 찾아줍니다",
"inputSchema": { "from": "날짜", "to": "날짜", "cardId": "선택" } }
AI는 이 설명을 읽고 지금 질문에 어떤 도구가 필요한지 스스로 고릅니다. 사용자가 "지난달 법인카드 얼마 썼어?"라고 물으면, AI는 get_card_transactions를 기간 인자와 함께 호출합니다. 개발자가 질문 유형별로 분기를 짜두는 게 아니라, 도구 설명만 잘 써두면 AI가 판단합니다.
3. SDK를 쓰지 않고 직접 구현한 이유
MCP에는 공식 SDK가 있습니다. 저희는 쓰지 않았습니다.
MCP의 전송 방식 중 하나인 stateless Streamable HTTP는 요약하면 이렇습니다.
POST로 들어온 JSON-RPC 요청을 처리해서 JSON으로 답한다. 끝.
Next.js의 라우트 핸들러가 이미 "POST를 받아 JSON을 돌려주는" 구조라, SDK의 세션·전송 계층 추상화가 얹히면 오히려 레이어가 하나 늘어납니다. 저희가 붙여야 할 것은 인증, 권한 필터, 감사 로그였는데 이 셋은 모두 기존 서버 코드에 이미 있었습니다. 그래서 JSON-RPC 규격만 직접 맞추고 나머지는 쓰던 모듈을 그대로 연결했습니다.
대신 규격 준수는 스스로 검증해야 합니다. 저희는 25개 항목의 점검 목록을 만들어 확인했습니다. 디스커버리 문서, 미인증 요청의 응답 형식, 인가 코드 재사용 차단, 도구 목록 필터, 테넌트 격리 같은 것들입니다.
4. 인증 — 비밀번호를 AI 앱에 주지 않는 방법
가장 중요한 부분입니다. AI 앱에 핀태그 아이디와 비밀번호를 입력하게 하면 안 됩니다. 그 앱이 비밀번호를 그대로 갖게 되기 때문입니다.
그래서 OAuth 2.1을 씁니다. 흐름은 이렇습니다.
1) AI 앱이 "핀태그에 연결하고 싶다"고 요청
2) 사용자의 브라우저가 열리고 → 핀태그에서 로그인
3) "이 앱에 어떤 권한을 줄지" 동의 화면 표시
4) 동의하면 핀태그가 그 앱에만 쓸 토큰을 발급
5) 이후 AI 앱은 토큰으로만 요청
비밀번호는 핀태그 화면에서만 입력되고, AI 앱은 토큰만 갖습니다. 마음에 안 들면 그 토큰만 지우면 됩니다.
여기에 저희가 더한 것들입니다.
- PKCE는 S256만 허용합니다. 중간에서 인가 코드를 가로채도 쓸 수 없게 하는 장치인데, 구식 방식(plain)은 아예 거부합니다.
- 토큰 원문을 저장하지 않습니다. 데이터베이스에는 해시만 둡니다. DB를 통째로 열람해도 그 값으로는 API를 호출할 수 없습니다.
- 수명을 짧게 둡니다. 인가 코드 10분·1회, 액세스 토큰 1시간, 리프레시 토큰 30일입니다.

리프레시 토큰은 쓸 때마다 새것으로 바꿉니다(rotation). 그리고 이미 바뀐 옛 토큰이 다시 들어오면, 그건 누군가 탈취해서 쓰고 있다는 신호입니다. 이때는 그 토큰과 같은 계보(family)의 토큰을 전부 폐기합니다. 공격자든 원래 사용자든 둘 다 끊기지만, 금융 데이터에서는 조용히 계속 열려 있는 쪽이 훨씬 위험합니다.
5. 권한 — 연결했다고 다 보이지 않습니다
MCP를 붙일 때 가장 흔한 실수는 **"연결 = 전체 접근"**으로 만드는 것입니다. 핀태그는 세 단계로 걸러냅니다.

첫째, 사용자 권한. 애초에 그 사람이 회사에서 볼 수 있는 범위를 넘을 수 없습니다. 열람 전용 담당자가 AI 앱을 연결해도 데이터를 바꾸는 도구는 나타나지 않습니다.
둘째, 앱별 허용 범위. 같은 사람이라도 앱마다 범위를 따로 정합니다. 어떤 앱에는 조회만 허용할 수 있습니다.
셋째, 실행 직전 재확인. 도구 목록에 보였다고 끝이 아닙니다. 호출 시점에 권한을 다시 확인합니다. 목록을 받은 뒤 사용자의 권한이 회수됐다면 그 호출은 거부됩니다.
여기에 더해 데이터를 바꾸는 도구는 확인 절차를 한 번 더 거칩니다. AI가 일정 생성이나 예산 변경을 시도하면 바로 실행되지 않고 사용자 확인을 요구합니다.
6. 멀티테넌트 — 토큰에 회사 정보를 넣지 않은 이유
토큰 안에 소속 회사 정보를 넣어두면 요청마다 조회할 필요가 없어 빠릅니다. 흔한 설계이기도 합니다. 저희는 넣지 않았습니다.
토큰 수명은 1시간입니다. 그 사이에 직원이 퇴사하거나, 소속이 바뀌거나, 계정이 정지될 수 있습니다. 토큰에 박아둔 정보로 판단하면 최대 한 시간 동안 이전 권한이 그대로 살아 있습니다. 금융 데이터에서 한 시간은 깁니다.
그래서 매 요청마다 사용자 ID로 소속을 다시 조회합니다. 조회 한 번을 더 하는 대신, 권한 변경이 즉시 반영됩니다.
같은 이유로 남용 차단도 서버 쪽에서 합니다. 토큰당 호출 횟수에 상한을 두고, 30일 넘게 쓰이지 않은 앱 등록은 자동으로 정리합니다.
7. 만들면서 느낀 것
MCP 자체는 어렵지 않습니다. JSON-RPC 요청을 받아 답하면 됩니다. 어려운 쪽은 "무엇을 열어줄 것인가"를 정하는 일이었습니다.
- 이 도구를 외부 AI 앱에 노출해도 되는가
- 실행 전에 사람의 확인이 필요한가
- 결과에 마스킹해야 할 값이 있는가
저희는 공동인증서와 계정 비밀번호를 조회 대상에서 제외하고, 계좌번호와 카드번호는 마스킹해서 전달합니다. 앱 화면 전용 도구는 외부에 노출하지 않습니다.
AI가 데이터에 직접 닿는 시대에는 "무엇을 할 수 있는가"보다 "무엇을 하지 못하게 할 것인가"가 더 중요한 설계라고 생각합니다.
📌 쓰시던 AI 앱에서 바로 회사 금융 데이터를 확인해 보세요 핀태그를 한 번 연결하면 Claude·ChatGPT 같은 앱에서 우리 회사 실제 데이터로 답을 받을 수 있습니다. 2주 무료 체험으로 연결부터 확인해 보세요. → app.fintag.kr
핀태그 기술블로그는 핀태그가 서비스를 만들며 내린 기술적 결정과 그 이유를 공유합니다. 문의: support@fintag.kr




