MCP 도구 50개를 짜며 깨달은 것: 함수 호출은 비정상적으로 친밀한 관계였다

3 hours ago 2

주말 이틀 동안 자산 관리 도구를 SQLite 기반 CLI와 MCP 서버로 옮긴 경험을
바탕으로, MCP 도구 설계가 RPC와 결정적으로 어디서 갈라지는지를 정리한 글.
필자는 CLI 커맨드 30여 개와 MCP 도구 50여 개를 짰는데, 분량이 무색하게도
가장 오래 붙잡고 있었던 건 코드가 아니라 함수의 설명이었다는 발견에서 출발함.

  • 같은 함수를 CLI와 MCP에 동시에 노출했을 때, 시그니처/인자/반환값이 모두 같은데도 두 인터페이스가
    다르게 굴러갔음
    . 바뀐 건 호출자가 인간인지 LLM인지뿐
  • 시그니처는 함수가 무엇을 받는지는 설명하지만 언제 불려야 하는지는 거의 설명하지 못함. 함수 이름은
    사전의 한 줄에 가까워서 단어 자체로는 어떤 문장 위에 놓일지 결정하지 못함
  • LLM 호출자에게는 단일 책임 원칙(SRP)으로 잘게 쪼갠 도구보다 의도에 직접 닿는 무거운 도구가 더
    자연스러움
  • MCP는 형태만 놓고 보면 RPC 계보(JSON-RPC, 시그니처, 스키마)지만, 결정적 차이는 신뢰의 방향이
    뒤집힌다는 점
    . RPC는 호출자가 호출 대상을 신뢰하지만, MCP는 도구를 만든 쪽이 호출자(LLM)를 신뢰해야 함
  • 시그니처는 선언이고 설명은 부탁. 한쪽은 강제이고 한쪽은 설득. 도구 설계에 설득의 언어가 들어오기
    시작한 셈
  • 이건 새로운 변화이기보다 회귀에 가까움. 산업 디자인, 건축, UX는 이미 오래전부터 같은 자리에 있었고,
    프로그래밍이 그동안 유난히 친밀한 한쪽 끝에 머물러 있었던 것뿐

시그니처가 말하지 않는 것

  • Firma의 add_txn(트랜잭션), add_balance(자산 스냅샷), add_flow(소득/지출)는 시그니처가 모두
    명확하고 인자 타입도 zod 스키마로 엄격히 정의되어 있었지만, LLM은 사용자 발화에서 어느 도구를 부를지
    자주 헷갈렸음
  • 처음엔 LLM 모델 문제로 의심했지만, 실제 문제는 시그니처 자체에 있었음. add_txn이라는 이름은
    "사용자가 매매를 말했다면 이 도구를 써라"는 호출 시점을 담고 있지 않음
  • description을 "Use this when... Do NOT use this for..." 형태로 호출 시점과 다른 도구와의 경계를
    명시한 뒤에야 호출이 안정됨
  • 함수의 의도가 시그니처에서 함수 설명 쪽으로 이동한 것. 망치 손잡이가 사용 방법을 형태로 시사하듯,
    MCP 함수의 설명은 LLM에게 사실상 도구의 어포던스(도널드 노먼)에 해당함

SRP vs 어포던스, 그리고 신뢰의 방향

  • 처음엔 단일 책임 원칙대로 get_holdings, get_prices, get_pnl처럼 잘게 나누려 했지만, 사용자가 "내
    포트폴리오 어때?"라고 물으면 LLM이 네다섯 번의 호출을 조합해야 하고 응답이 느려지며 어긋날 여지가 커짐
  • 결국 show_portfolio를 보유 종목/평균 매수가/현재 가격/평가금액/누적 손익을 한 번에 반환하는 무거운
    도구로 설계함. get_brief는 더 나아가 거시 지표와 인사이트까지 한 번에 반환
  • SRP는 함수를 만드는 사람의 미덕, 어포던스는 도구를 쓰는 사람의 미덕. 호출자가 인간이면 조립이 되고
    LLM이면 의도에 직접 닿는 도구가 나음
  • 쓰기 도구에서 신뢰의 방향이 가장 뚜렷하게 드러남. add_txn에 **"Always confirm with the user before
    recording"**로 적었더니 LLM이 매번 묻고 사용자는 매번 "ㅇㅋ" 답하는 결과 — 자연어 인터페이스의 장점이
    사라짐
  • 결국 "즉시 기록하라, 모호할 때만 물어라, 잘못되면 되돌릴 수 있다" 형태로 책임을 다시 분담함. 이런
    지침은 도구의 형식적 설명이 아니라 호출자에게 주는 운영 원칙

함수 호출이 오히려 특수한 경우였는지도 모른다

  • 인간은 원래 자기가 만들지 않은 도구를 써왔음. 도공이 만든 그릇, 대장장이가 만든 칼, 개발자가 만든
    프로그램까지 모두 그러함
  • 함수 호출은 호출자와 작성자가 많은 맥락을 공유하고 타입 시스템/IDE/문서가 그 친밀함을 계속 보강해주는
    꽤 특수한 관계였던 셈
  • 호출자가 인간이 아니라면 선택지는 둘. (1) LLM에게 더 많은 맥락을 넣어 친밀한 호출자로 만들기, (2) 도구
    쪽에서 거리를 메우기. MCP는 후자에 가까움
  • 인터페이스를 설계하는 방식 자체가 조용히 바뀌고 있는 시기일 수 있음. 시그니처에서 설명으로, 강제에서
    설득으로, 친밀함의 가정에서 거리에 대한 인정으로 무게중심이 옮겨가고 있음
Read Entire Article