빌드나 보고서 생성이 오래 걸릴 때, 에이전트는 연결을 계속 붙잡고 있어야 할까요? MCP Tasks는 서버가 최종 결과 대신 작업 식별자를 돌려주고, client가 나중에 상태와 결과를 가져오는 방식입니다.[93]
Anthropic은 10월 23일(공식 게시물 표기) Claude Code CLI에서 Tasks와 Elicitations를 사용할 수 있다고 발표했습니다. 이번에 볼 변화는 MCP 자체의 최초 등장보다 기존 비동기 작업 규약을 Claude Code client에서 활용할 수 있다고 공식 안내한 점입니다.[70][93]
💡 💡 핵심은 기다리는 화면을 숨기는 것이 아닙니다. 연결의 수명과 업무의 수명을 분리하고, 재접속·중간 입력·결과 불명 상태를 다루는 계약을 만드는 것입니다.[93]
Claude Code에는 일반 MCP 호출이 오래 걸리면 client 쪽에서 background로 옮기는 기능도 있습니다. 이 경우 기존 호출은 계속 진행되고, timeout도 그대로 적용되며, 세션을 종료하면 해당 client 작업은 유지되지 않습니다.[69]
반면 서버 측 MCP task는 서버가 작업을 받아 식별자를 반환합니다. 원격 서버의 작업은 Claude Code를 종료해도 계속될 수 있고, 같은 세션을 재개하면 결과 추적을 이어갈 수 있습니다.[69]
따라서 /tasks에 작업이 보인다는 사실만으로 서버 측 내구성을 판단하면 안 됩니다. 공식 문서는 stdio 서버의 process는 Claude Code 종료 시 멈추므로, 작업이 process 밖에서도 유지되는지 그 서버 문서를 확인하라고 경고합니다.[69]
외부 개발자의 지원 요청에서도 이 차이가 드러납니다. 해당 작성자는 이전 버전에서 긴 연결을 유지하거나 start_*·get_* 도구 쌍을 직접 만들었던 경험을 설명했습니다. 이는 그 사용자의 과거 관찰이지, 모든 환경의 현재 timeout을 입증하는 측정은 아닙니다.[75]
Tasks extension의 식별자는 io.modelcontextprotocol/tasks입니다. Client가 요청의 capability에 지원을 선언하면, 서버는 그 요청을 일반 결과로 끝낼지 task로 만들지 선택합니다. 지원을 선언하지 않은 client에 task handle을 반환해서는 안 됩니다.[93]
이때 task는 단순한 화면용 할 일 목록이 아니라, 실행 상태와 나중에 조회할 결과를 가진 상태 머신입니다.[93]
tools/call을 보냅니다. 서버는 task 상태를 내구성 있게 만든 다음 resultType: "task"와 taskId를 반환합니다. 명세는 응답 직후 tasks/get으로 그 작업을 찾을 수 있어야 한다고 요구합니다.[93]tasks/get을 호출합니다. working이면 조회를 이어가고, 서버가 제안하는 pollIntervalMs를 참고합니다.[93]input_required와 inputRequests를 반환하면, client가 요청을 처리하고 같은 key에 대응하는 답을 tasks/update로 보냅니다.[93]completed에서는 원래 도구의 결과를, failed에서는 JSON-RPC 오류를 읽습니다. cancelled도 종료 상태입니다.[93]Claude Code의 현재 구현은 결과를 tasks/get 응답으로 받으며 tasks/result·tasks/list·notifications/tasks는 사용하지 않습니다. 오래된 예제의 method 이름이나 명세의 선택적 notification 기능을 client 지원으로 옮겨 생각하면 안 됩니다.[69]
또 하나의 세부사항이 있습니다. 명세의 completed에는 도구 결과가 isError: true인 경우도 포함됩니다. Claude Code는 이를 실패로 보고하므로, 프로토콜상 종료와 실제 업무 성공은 분리해서 확인해야 합니다.[69][93]
다음은 실제 고객 사례가 아닌 설계 제안입니다. 여러 자료를 읽어 보고서를 만드는 사내 도구를 가정해 보겠습니다.
completed라는 문자열만 보고 게시까지 성공했다고 판단하지 않습니다.처음에는 이미 운영하는 job queue와 상태 저장소를 MCP task의 뒤에 연결하는 편이 단순하다는 것이 이 글의 판단입니다. Tasks 규약을 채택했다는 이유만으로 새로운 workflow 플랫폼을 하나 더 도입할 필요는 없습니다.
짧고 재시작 후 결과를 다시 찾을 필요가 없는 도구라면 일반적인 동기 호출이 더 단순할 수 있습니다. 오래 열린 연결의 timeout·재접속 문제를 해결해야 할 때 Tasks의 가치가 생깁니다.[93]
기존 client가 Tasks를 지원하지 않는다면 별도의 시작·상태 조회 도구를 제공할 수도 있습니다. Upstash의 구현은 native Tasks client에는 task handle을, 다른 client에는 일반 도구 결과와 task_status·task_cancel을 제공하는 fallback을 설명합니다. 이 fallback은 해당 구현의 설계이지 모든 MCP 서버가 자동 제공하는 기능은 아닙니다.[64]
운영 부담도 따져야 합니다. 메모리 실행은 단순하지만 process가 재시작하면 상태를 잃습니다. 공유 상태 저장과 외부 실행 전달을 더하면 저장소·worker·인증·재시도 정책을 함께 운영해야 합니다.[64]
Upstash는 Redis에 task를 저장하고 QStash로 별도 함수 실행을 전달하는 구현을 공개했습니다. 글에서는 실행 중 앱을 강제 종료한 뒤 재시작했을 때 QStash가 재전달하여 작업이 완료됐다고 보고합니다. 이는 구현 제공자의 시험 보고이며 이번 글에서 재현한 결과는 아닙니다.[64]
같은 글의 제약도 중요합니다. QStashDispatcher는 작업을 한 번의 함수 실행에서 처리하므로 사용자 답을 기다릴 수 없고, 단계별 실행을 사용하는 WorkflowDispatcher는 함수 실행을 점유하지 않고 기다릴 수 있다고 설명합니다. 이름에 Tasks가 붙었다고 serverless 실행 시간 제한이나 사람 대기가 저절로 해결되지는 않습니다.[64]
제3자 API 서비스를 운영하는 AI Code With는 Claude Code v2.1.309에서 자체 서버로 시험했다고 밝혔습니다. 일반 호출의 background 처리와 elicitation은 동작했지만, 요청 capability에 Tasks extension이 없어 서버 측 MCP task는 활성화되지 않았다고 보고했습니다. 판매자가 자기 서비스 환경을 시험한 제한된 관찰이며, 모든 provider의 결과로 일반화할 수 없습니다.[97]
별도로 Max Nardit는 v2.1.310과 메시지를 기록하는 stdio 서버를 사용해 관찰했습니다. 비대화형 stream-json 실행에서 input_required 뒤 취소 요청이 전송됐으며, 조건별 실행은 한 번씩이었다고 명시합니다. 공식 문서의 제약과 부합하는 외부 보고이지만, 안정성·성능의 반복 검증은 아닙니다.[98]
실제 확인일의 공식 문서 기준으로 Tasks는 CLI의 public beta이며 v2.1.304 이상이 필요합니다. 서버의 지원, protocol revision 2026-07-28, feature flag를 가져오는 세션, main conversation의 호출이라는 조건도 함께 충족해야 합니다.[69]
VS Code extension·desktop app·subagent 호출·one-shot claude -p는 같은 지원 범위가 아닙니다. Agent SDK나 stream-json 실행에는 추가 background 설정과 열린 입력이 필요하며, 단순히 GitHub Actions에서 실행한다는 사실만으로 충분하지 않습니다. Bedrock 같은 제3자 provider나 flag fetching을 끈 환경도 문서의 제외 조건을 확인해야 합니다.[69]
비대화형 task가 사용자 입력을 요구하면 Claude Code는 서버에 취소를 요청합니다. 이 경로에서는 Elicitation hook이나 SDK의 onElicitation callback도 호출하지 않는다고 명시합니다.[69]
설계 판단: 야간 배치에는 필요한 입력을 처음부터 받고, 실행 도중 사람이 꼭 결정해야 하는 작업은 대화형 흐름으로 분리하는 편이 안전합니다. 사람이 없는 실행을 자동 승인으로 대체하면 안 됩니다.
명세의 ttlMs는 생성 시점부터의 task 수명이며, 만료 뒤 서버가 기록을 버릴 수 있습니다. 반면 Claude Code는 TTL이 지났다는 이유만으로 task를 버리지는 않으며, 기본 background task에는 Claude Code 측 시간 제한이 없다고 설명합니다.[69][93]
이 두 설명은 충돌이 아닙니다. 하나는 서버가 기록을 얼마나 유지할지, 다른 하나는 client가 언제 추적을 멈출지에 관한 계약입니다.[69][93]
설계 판단: 실행 deadline, 사용자 입력 대기 만료, 결과 보관 기간, 비용 한도를 각각 정하십시오. Client가 계속 조회한다는 이유로 worker를 무기한 실행하도록 두지 않는 것이 좋습니다.
명세에서 취소는 협력적입니다. 서버의 취소 응답이 곧 실행 중단을 보장하지 않으며, 작업이 이미 끝났다면 다른 종료 상태가 될 수도 있습니다.[93]
Claude Code 문서도 결과를 outcome unknown으로 보고한 뒤 같은 도구를 다시 부르면 업무가 반복될 수 있다고 경고합니다.[69]
이를 다루는 기존 원리는 idempotency입니다. AWS Builders’ Library는 호출자가 제공하는 고유 request identifier로 중복 요청을 식별하고, 해당 token의 기록과 관련 변경을 일관된 atomic 처리로 묶는 설계를 설명합니다.[95]
설계 제안: task를 추적하는 ID와 업무 중복을 막는 key를 같은 개념으로 보지 마십시오. 새 호출이 새 task를 만들더라도 같은 발송·결제·배포를 다시 수행하지 않도록 업무 계층을 설계하고, 외부 시스템이 제공하는 idempotency 기능을 확인해야 합니다. MCP Tasks 자체를 exactly-once 실행 보장으로 설명해서는 안 됩니다.
💡 🔬 검증 범위: 공식 발표·현재 제품 문서·cutoff 이전 명세·구현 제공자와 외부 개발자의 글을 읽고 대조했습니다. Claude Code 설치, 서버 실행, API 호출, 장애 재현, benchmark는 수행하지 않았습니다. 외부의 제한된 시험을 이 글의 직접 실행 결과나 고객 도입 성과로 쓰지 않았습니다.
[64] https://upstash.com/blog/claude-code-mcp-tasks — Upstash: MCP Tasks·Elicitations 구현과 재시도
[69] https://code.claude.com/docs/en/mcp — Claude Code MCP reference — Tasks와 실행 조건
[70] https://x.com/ClaudeDevs/status/2113698007892070527 — ClaudeDevs: Claude Code CLI의 Tasks·Elicitations 발표
[75] https://github.com/anthropics/claude-code/issues/102347 — 외부 개발자의 Tasks extension 지원 요청 #102347
[93] https://raw.githubusercontent.com/modelcontextprotocol/ext-tasks/b3d28aceaa6d49f5f92258e3d06b61ad6f111e84/specification/2026-07-28/tasks.md — MCP Tasks extension specification — cutoff 이전 commit
[95] https://aws.amazon.com/builders-library/making-retries-safe-with-idempotent-APIs — AWS Builders’ Library: idempotent API와 안전한 재시도
[97] https://aicodewith.ai/en/blog/claude-code-mcp-tasks-elicitations — AI Code With: 제3자 API 환경의 v2.1.309 시험 보고
[98] https://max.nardit.com/articles/mcp-tasks-elicitations-claude-code — Max Nardit: v2.1.310 메시지 관찰과 무인 실행의 질문