Webhook 우선 API 설계: 폴링(Polling) 없는 방식, 단일 서명된 콜백, 그리고 래퍼(Wrapper)가 아닌 MCP 서버
요약
효율적인 에이전트 워크플로우를 위한 Webhook 기반 API 설계와 MCP(Model Context Protocol) 서버 구축 전략을 다룹니다. 폴링 대신 웹훅을 사용하고, MCP를 단순 래퍼가 아닌 퍼스트 클래스 인터페이스로 설계하여 에이전트의 자율성과 비용 관리 능력을 높이는 방법을 제안합니다.
핵심 포인트
- 폴링 대신 Webhook을 사용하여 실시간성을 확보하고 리소스 낭비를 방지함
- 보안을 위해 원시 바디 해싱과 compare_digest를 사용한 서명 검증 권장
- MCP 서버를 REST API의 래퍼가 아닌 독립적인 인터페이스로 설계
- 에이전트가 예산을 확인할 수 있도록 quota 도구를 제공하여 런타임 오류 방지
- 에이전트 루프의 탐색적 특성을 고려하여 호출당 과금이 아닌 통합 미터링 적용
제가 통합해 온 대부분의 비디오 API들은 폴링(Polling)을 요구합니다. 작업을 POST로 요청하고, ID를 받은 다음, 무언가 돌아오거나 타임아웃(Timeout) 예측치가 끝날 때까지 몇 초마다
- 파싱(Parsing) 후 다시 직렬화(Re-serialised)된 JSON이 아니라, 원시(raw) 바디를 해싱(Hash)하세요. 키(Key)의 순서와 공백은 프레임워크를 거치는 왕복 과정(Round trip)에서 유지되지 않습니다.
==대신compare_digest를 사용하세요. 일반적인 문자열 비교는 첫 번째로 다른 바이트에서 조기에 반환되는데, 이는 접두사(Prefix)의 어느 부분까지 맞혔는지에 대한 정보를 유출(Leak)하게 됩니다.
3. MCP를 래퍼(Wrapper)가 아닌 퍼스트 클래스 인터페이스(First class surface)로 취급하기
우리는 에이전트가 파이프라인을 직접 제어할 수 있도록 mcp.openshorts.app/mcp에 MCP 서버를 배포했습니다. 연결 방법은 한 줄이면 충분합니다:
claude mcp add --transport http openshorts https://mcp.openshorts.app/mcp \
--header "Authorization: Bearer osk_..."
Streamable HTTP를 지원하는 클라이언트라면 무엇이든 동일한 방식으로 작동합니다. 서버가 프로토콜을 통해 도구 스키마(Tool schemas)를 포함하여 스스로를 설명하므로, 별도로 설정할 것이 없습니다.
여섯 가지 도구가 파이프라인을 커버합니다: process_video, get_job_status, list_clips, get_quota, add_subtitles 및 publish_clip.
get_quota는 제가 가장 강력하게 주장하고 싶은 부분입니다. 자신의 예산(Budget)을 볼 수 없는 에이전트는 완료할 수 없는 작업을 기꺼이 시작할 것이고, 당신은 20분 뒤에 실패한 웹훅(Webhook)을 보고서야 그 사실을 알게 됩니다. 남은 잔액을 도구로 노출하면 모델이 비용을 쓰기 전에 확인할 수 있으며, 이는 런타임 오류(Runtime failure)를 계획 단계의 결정(Planning decision)으로 전환해 줍니다.
우리가 하지 않기로 거부한 또 다른 것은 MCP 서버를 REST API의 편리한 하위 집합(Subset)을 감싸는 래퍼(Wrapper)로 구축하는 것이었습니다. 각 도구는 웹 앱이 사용하는 것과 동일한 계정, 분(Minutes), 작업 이력을 사용하여 동일한 파이프라인을 호출합니다. 에이전트 인터페이스가 하위 집합이 되는 순간, 동기화해야 할 두 개의 제품이 생기게 되며, 에이전트용 제품은 항상 뒤처지게 됩니다.
미터링(Meter)은 API 설계 결정 사항입니다
이 부분은 제가 중요할 것이라고 예상하지 못했던 부분이었으나, 결과적으로 가장 중요한 부분이 되었습니다.
이 분야의 대부분의 도구들은 에이전트 호출을 소스 분당(per source minute) 또는 작업당(per operation)으로 각각 별도로 측정합니다. 이는 방어 가능한 과금 방식일 수는 있으나, 사용성(ergonomics) 측면에서는 최악입니다. 에이전트 루프(agent loop)는 본질적으로 탐색적입니다. 상태를 확인하고, 클립 목록을 나열하며, 결과가 좋지 않은 것을 재시도합니다. 만약 모든 호출에 비용이 발생한다면, 이에 대한 올바른 공학적 대응은 더 적고, 더 크며, 더 취약한(brittle) 호출을 작성하는 것이 될 것이며, 이는 에이전트에게 기대하는 바와 정확히 반대되는 결과입니다.
우리는 API 호출이 대시보드와 동일한 단일 분당 잔액(flat minute balance)을 사용하도록 만들었습니다. 별도의 측정기(meter)도, 호출당 과금 방식도 없습니다. 셀프 호스팅(self-hosted) 에디션에는 측정기 자체가 없으며, 이것이 바로 항상 켜져 있는 파이프라인(always on pipeline)을 저렴하게 운영할 수 있는 이유입니다.
스케줄링은 이미 사용 중인 무엇이든 가능합니다
작업을 시작하는 것이 단 하나의 POST 요청이기 때문에, 별도의 스케줄러 통합이 필요하지 않습니다. cron 라인, GitHub Action, n8n HTTP Request 노드 등 모든 것이 전용 커넥터 없이도 작동합니다. 위에서 언급한 두 단계의 구조가 통합의 전부이기 때문에 공식적인 n8n 템플릿은 따로 존재하지 않습니다.
직접 실행해 보세요
코드는 GitHub의 mutonby/openshorts에 있으며, 핵심 코드는 MIT 라이선스를 따릅니다. 셀프 호스팅 에디션은 클라우드와 동일한 MCP 엔드포인트(endpoint)를 제공합니다.
웹훅(webhooks)과 에이전트(agents)를 사용하여 무언가를 구축하고 있다면, 요약은 짧습니다: 실패를 이벤트(events)로 전달하고, 본문(body)에 서명(sign)한 뒤 상수 시간(constant time) 내에 이를 비교하며, 예산(budget)을 도구(tool)로 노출하고, 에이전트가 사고하는 데 필요한 호출에 가격을 매기지 마십시오.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기