MCP Events: 구독이 취소할 수 없는 자격 증명이 될 때
핵심 요약
- MCP Events는 에이전트에 세 번째 기상 트리거를 추가했습니다 — cron 일정과 사람의 메시지를 넘어, MCP 서버가 연결된 앱에서 변화가 생기면 서명된 웹훅을 ChatGPT로 푸시할 수 있게 되었습니다.
- 구독은 그것을 생성한 액세스 토큰보다 오래 지속됩니다 —
ttlMs: null은 만료 없는 구독을 요청하고, 구독을 식별하는 튜플에는 토큰, 범위, 만료가 포함되지 않습니다. - ChatGPT는 웹훅 전송 모드를 지원하지만 초안의
terminated취소 엔벨로프는 지원하지 않습니다 — 남은 유일한 취소 신호는-32012 Forbidden을 반환하는 실패한 갱신입니다. - 워킹 그룹 자신의 성공 기준 — SEP 제출 — 은 아직 출하되지 않았습니다 — 헌장 표는 "Ideating" 상태이며 챔피언은 "TBD", 변경 로그는 2026년 3월 24일 단 한 건입니다.
- WorkOS는 구독을 자격 증명으로 규정합니다 — 한 사용자의 액세스 토큰 아래 생성된 영속적인 레코드로, 토큰이 만료된 지 오래후에도 해당 사용자의 데이터를 에이전트로 푸시할 권한을 서버에 부여합니다.
지금까지 AI 에이전트가 깨어나는 이유는 두 가지였습니다: cron 일정이 발동하거나, 사람이 메시지를 입력하는 것. 2026년 9월 29일 DevDay에서 OpenAI는 제안된 MCP Events 사양 지원을 추가한다고 발표했으며, 이제 플러그인은 연결된 앱에서 무언가 발생할 때 자동화를 시작할 수 있습니다. 문서는 MCP 서버가 ChatGPT로 업데이트를 푸시하는 방법을 설명합니다 — 채널로 필터된 message.created 이벤트, 문서로 필터된 comment.created 이벤트 — 버그 보고가 도착하거나 리뷰 댓글이 게시되면, 물어보는 것을 기억할 때가 아니라 에이전트가 움직입니다. Notion에서 제품 디자인을 담당하는 Nathan Baschez는 10월 3일에 게시하며 이에 대해 별로 환호가 없었다고 말했습니다: "이벤트 기반 트리거는 엄청난 일입니다."
이 글은 MCP Events가 실제로 구현하는 것, 그 중심에 있는 자격 증명 수명 격차, 그리고 프로덕션 MCP 서버가 웹훅을 출하하기 전에 저장하고 검증해야 하는 것을 매핑합니다. 스테이트리스 코어를 다룬 MCP 2026-07-28: What the Stateless Protocol Means for B2B Agent Deployments를 토대로, 여기서는 이벤트 기반 확장과 워킹 그룹이 아직 사양화를 끝내지 못한 구독 수명 주기 문제에 초점을 맞춥니다.
ChatGPT가 실제로 구현하는 것
MCP Triggers and Events 워킹 그룹 헌장은 진행 중인 작업 항목을 하나만 나열합니다: "SEP: Events in MCP v1 RFC", 상태 "Ideating", 목표일 "End April", 챔피언 "TBD". 헌장의 변경 로그는 한 건뿐이며, 날짜는 2026-03-24: "Initial charter". 워킹 그룹은 AWS의 Clare Liguori와 Anthropic의 Peter Alexander가 이끕니다.
인큐베이션 저장소는 다른 이야기를 들려줍니다. 그곳에는 "Status: Draft proposal"로 표시된 디자인 스케치가 있으며, 작성자는 Peter Alexander, 날짜는 2026-02-19입니다. README는 단호합니다: 내용은 탐색적이며 "MCP의 공식 사양이나 권고를 대표하지 않는다". 구현자들은 이미 그에 대한 현장 보고서를 제출하고 있습니다. 그러나 제출된 SEP — 헌장 자신이 밝힌 성공 기준 "트리거/콜백 메커니즘과 그 구독 수명 주기를 정의하는 수락된 SEP" — 는 존재하지 않습니다.
ChatGPT는 이 미완성 문서의 일부를 구현합니다. OpenAI의 MCP Events 가이드는 MCP 2.0과 프로토콜 버전 2026-07-28을 요구하며, 초안의 웹훅 전송과 콜백 검증을 지원합니다. 폴링, 스트리밍, 그리고 초안의 gap과 terminated 제어 알림은 지원되지 않습니다. 마지막 항목이 중요합니다.
메커니즘은 단순합니다. 서버는 server/discover 응답에서 events 케이퍼빌리티를 알립니다. 사용자는 ChatGPT에게 무엇을 모니터링하고 어떻게 응답할지 알려줍니다. ChatGPT는 이벤트 이름, 필터 인수, 콜백 URL, 서명 시크릿을 담아 events/subscribe를 호출합니다. 서버는 일회성 챌린지로 콜백을 검증하고, 구독을 저장하고, 일치하는 이벤트를 서명된 웹훅으로 푸시합니다. 세 가지 메서드 — events/list, events/subscribe, events/unsubscribe — 는 도구와 동일한 인증된 엔드포인트에서 실행됩니다.
구독은 자격 증명이다
주목할 부분은 초안이 서버에게 저장하라고 요구하는 것입니다. WorkOS의 분석이 규정하듯, 이벤트 구독은 자격 증명입니다: 한 사용자의 액세스 토큰 아래 생성된 영속적인 레코드로, 그것을 생성한 토큰이 만료된 지 오래후에도 해당 사용자의 데이터를 에이전트로 푸시할 권한을 당신의 MCP 서버에 부여합니다.
구독을 그 호출을 승인한 토큰과 비교해 보십시오. 2026-07-28 인증 사양에 따르면 서버는 액세스 토큰이 자신을 위해 특별히 발급되었는지 검증해야 하고, 인증은 모든 HTTP 요청에 포함되어야 하며, 유효하지 않거나 만료된 토큰은 401을 받아야 합니다. 수명은 짧고, 범위는 좁으며, 매 요청마다 재검증됩니다. 구독은 그 어떤 것도 상속하지 않습니다. 디자인 스케치는 웹훅 구독을 튜플 (principal, delivery.url, name, arguments)로 키잉합니다 — principal은 인증된 주체에 대한 서버의 정규 식별자입니다. 튜플에는 토큰 자체, 그 범위, 만기가 포함되지 않습니다. 그리고 수명은 영원까지 협상 가능합니다: ttlMs: null은 만료 없는 구독을 요청하고, 그것을 허용한 서버는 refreshBefore: null을 반환합니다.
| 액세스 토큰 | 이벤트 구독 | |
|---|---|---|
| 수명 | 짧고, 고정된 만료 | 당신이 허용한 TTL에 따라, 무만료(ttlMs: null)까지 |
| 바인딩 대상 | 당신의 서버를 오디언스로, 범위 추가 | (principal, url, name, arguments) — 토큰, 범위, 만기 없음 |
| 검사 | 모든 HTTP 요청마다, 만료 시 401 | 구독 시 필수(MUST); 이후 "주기적으로"(SHOULD), 간격 없음 |
| 끝나는 시점 | 만료하거나 인증 서버가 철회할 때 | TTL이 끝나거나, 클라이언트가 구독 해지하거나, 당신의 서버가 종료할 때 |
액세스 토큰은 만료됩니다. 그것이 만든 구독은 계속 전송됩니다.
ChatGPT에서 취소는 비대칭적입니다
초안은 의무에 대해서는 명확하지만 주기에 대해서는 모호합니다. 구독 시점에 principal은 인증되고 승인되어야 합니다. 전송 시점에는: "서버는 주기적으로(SHOULD) 권한을 재검증해야 합니다. 사용자의 접근이 철회되면(예: Slack 채널에서 제거), " 서버는 구독을 종료합니다. OpenAI의 가이드도 같은 의무를 반복합니다: "구독 수명 주기 동안 사용자의 접근을 재확인하고, 접근이 철회되면 전송을 중단하십시오."
"주기적으로"가 그 문장에서 많은 일을 하고 있습니다. 간격이 없고, MUST가 없으며, 그 뒤에 적합성 시험도 없습니다.
다음은 신호 자체입니다. 초안에서 각 전송 모드는 고유한 "중지" 방식을 가집니다. 웹훅의 경우 콜백 URL에 서명된 {"type":"terminated"} 엔벨로프를 POST하는 것입니다. 그 후 구독은 더 이상 존재하지 않으므로, 종료 사유가 남아 있다면 이후 갱신은 -32012 Forbidden을 반환합니다. 그 엔벨로프가 프로토콜이 에이전트에게 "중지되었고, 이유는 이것이다"라고 알리는 방식입니다. 그것은 ChatGPT 통합이 지원하지 않는 두 가지 제어 알림 중 하나이기도 합니다.
| 전송 모드 | 초안이 "중지"를 말하는 방식 | ChatGPT에서 |
|---|---|---|
| 폴링 | 다음 폴링에서 오류 | 모드 미지원 |
| 푸시 스트림 | notifications/events/terminated |
모드 미지원 |
| 웹훅 | 서명된 terminated 엔벨로프를 콜백에 POST |
모드 지원, 엔벨로프 미지원 |
| 모든 모드 | 다음 갱신 실패 시 -32012 Forbidden |
유일하게 남은 신호 |
ChatGPT 통합에서 유일하게 남은 취소 신호는 실패한 갱신입니다. 사용자의 접근이 철회되고 당신의 서버가 전송을 중단해도, 에이전트는 구독 TTL이 끝나고 갱신이 실패할 때만 그것을 알게 됩니다. ttlMs: null을 허용했다면 에이전트는 영원히 모릅니다.
당신의 서버가 검증해야 하는 것
초안과 OpenAI의 가이드는 합쳐서 실제 보안 표면을 규정합니다. 협상 불가능한 부분:
- 인증된 principal을 요구합니다.
events/subscribe와events/unsubscribe는 인증된 principal과 함께 호출되어야 하며, 승인에 실패한 호출은-32012 Forbidden을 받습니다. - 첫 실제 전송 전에 엔드포인트를 검증합니다. HMAC은 위조를 막지만 홍수는 막지 못합니다. 챌린지 핸드셰이크, 허용 목록, 사전 대역외 검증 중 하나로 엔드포인트가 전송을 받을 의사가 확인되기 전까지는, 서버가 콜백 URL로의 전송을 시작해서는 안 됩니다.
- 전송 시점에 SSRF 검사를 실행합니다. 콜백 URL은 HTTPS를 사용해야 합니다. 매 연결마다 목적지 주소를 해석하고 검증하고, 사설 및 로컬 대역을 차단하고, 리디렉션을 절대 따르지 않으며, 그 모든 것을 검증 요청에도 전송과 똑같이 적용합니다.
- 페이로드를 최소로 유지합니다. 이벤트 페이로드는 도구 결과와 같은 주입 위험을 지닙니다. OpenAI 가이드는 요약을 보내고 전체 레코드용 읽기 도구를 노출하며, 사용자 작성 텍스트를 데이터로 취급하고, 페이로드 안에 모델의 행동을 지시하는 내용을 추가하지 말 것을 요구합니다.
- 쓰기를 멱등하게 만듭니다. 이벤트는 순서가 뒤바뀌어 도착할 수 있으므로 반복 호출이 변경을 복제해서는 안 됩니다. 전송은 256 KiB로 제한되며, 410과 413 응답은 재시도하지 않습니다.
- 수신 시점이 아니라 행동 시점에 승인합니다. 이벤트 수신은 행동 승인을 구성하지 않습니다. 에이전트가 응답으로 수행하는 도구 호출은 당신의 일반 검사 — OAuth 범위를 넘어 MCP 도구 호출을 검사하는 바로 그 검사 — 를 통과합니다.
여기까지의 내용은 모두 문서에 있습니다. 문서에 없는 두 가지: 접근을 얼마나 자주 재검증하는지, 그리고 사용자나 관리자가 자신의 계정이 무엇을 푸시하는지 어떻게 볼 수 있는지.
당신 스스로 내려야 할 세 가지 결정
구독 수명 주기는 바로 워킹 그룹이 헌장에서 스스로에게 부과한 사양화 과제이지만 아직 SEP를 출하하지 못했습니다. 그때까지 세 가지 결정은 당신의 몫이며, 기본값은 그곳을 나쁘게 결정합니다.
첫째, 짧은 유한 TTL을 부여하고 ttlMs: null을 거부하십시오. TTL은 철회된 구독이 클라이언트에 보이는 간격입니다. 만료 없는 구독은 아무도 볼 수 없는 OAuth 승인입니다.
둘째, 한 문장으로 말할 수 있는 일정으로 접근을 재검증하십시오 — "주기적으로"가 아니라. "15분마다 재확인한다"고 말하고 그 작업을 가리킬 수 없다면, 당신이 의존하는 것은 간격도 적합성 시험도 없는 SHOULD입니다.
셋째, 사용자별 구독 인덱스를 유지하십시오. 그것이 없다면 사용자 퇴사 처리는 그들의 구독이 죽었다고 가정하는 것을 의미하며, 확인하는 것이 아닙니다. 직원이 떠날 때 철회 질문은 "토큰이 만료됐는가"가 아니라 "그가 승인한 모든 웹훅이 중단됐는가"입니다.
MCP Events는 에이전트의 트리거 모델을 바꿉니다. 그것이 진짜 아키텍처 변화입니다. 그러나 프로덕션 배포를 먼저 물어뜯는 부분은 자격 증명 수명 격차입니다. 프로토콜은 서버를 스테이트리스로 만들었습니다. 이벤트 확장은 서버를 다시 스테이트풀로 만들었습니다 — 그리고 그 상태가 보유한 것은 취소 주기가 규정되지 않은 자격 증명입니다.
아래 다이어그램은 구독 수명 주기, 자격 증명 수명 격차, 비대칭 취소 표면을 매핑합니다:```svg
Related reading
- MCP 2026-07-28: What the Stateless Protocol Means for B2B Agent Deployments — 모 문서: 스테이트리스 코어가 MCP Events의 이벤트 기반 능력으로 확장되는 과정. 스테이트리스 프로토콜이 서버를 스테이트리스로 만들고, 이벤트 확장이 다시 스테이트풀로 만든 이유
- MCP Security Hardening Checklist for Production Deployments — 거버넌스 모듈 테제와 이벤트 구독에 적용되는 보안 통제: SSRF, 페이로드 주입, 시크릿 로테이션, 콜백 검증
- A2A vs MCP: Choosing the Right Protocol — MCP Events가 MCP에 이벤트 기반 능력을 추가하면서 프로토콜 비교가 어떻게 달라지는지
중견 SaaS 기업이 고객 지원용 MCP 서버 — ChatGPT를 티켓 시스템과 지식 베이스에 연결하는 유형 — 를 운영하며, 새로운 고우선순위 티켓이 도착하면 에이전트가 답변 초안을 작성하도록 이벤트 기반 트리거를 추가하고자 합니다. 엔지니어링 팀은 events/subscribe를 구현하고, 구독을 저장하고, 웹훅 전송을 출하했습니다. 3주 후, 지원 담당자 한 명이 퇴사합니다. 액세스 토큰은 한 시간 만에 만료됐습니다. 그러나 그 토큰 아래 생성된 이벤트 구독은 아무도 유한한 TTL을 허용하지 않았고 사용자별 구독 인덱스가 존재하지 않아 ChatGPT로의 웹훅을 계속 쏘고 있습니다. 통합에서 ChatGPT에게 "중단됐다"고 알렸을 terminated 엔벨로프는 지원되지 않습니다. 에이전트는 퇴사한 담당자가 소스 시스템에서 더 이상 볼 수 없는 티켓으로 계속 움직입니다.
범위가 명확한 구축을 요청하십시오. 일주일의 디스커버리. 시스템 인벤토리, 워크플로 맵, 고정된 범위를 받습니다 — 우리와 함께 만들지 여부와 관계없이.
귀하의 시스템을 위해 이것을 구축하고 싶으신가요?
여기의 각 문서는 실제 프로덕션 작업에서 나왔습니다. 대상 시스템과 워크플로가 있다면, 1주 내에 빌드를 범위 정의할 수 있습니다.
범위 정의 빌드 요청1주 발견. 시스템 인벤토리, 워크플로 맵, 고정 범위를 받습니다 — 우리와 빌드할지 여부와 관계없이.