Studio 에이전트 채팅에서 MCP 작업 입력 요청에 응답합니다
README 링크에서 발견 · today
입력이 필요한 MCP 도구 호출을 일시 중단한 다음, 채팅에서 응답합니다.
What they did
작성자가 Mastra 모노레포에 기능을 구현하여, `input_required`를 보고하는 MCP 작업이 도구 호출을 실패시키는 대신 Studio의 에이전트 채팅에서 직접 응답될 수 있도록 했다. `@mastra/mcp`에서 작업 기반 도구 호출이 `input_required`를 보고하고, `inputRequests` 핸들러가 구성되지 않았으며, 호출이 에이전트나 워크플로 내에서 실행될 때, `MCPClient`는 이제 `{ type: 'mcp-input-request', serverName, toolName, taskId, createdAt, requests }` 페이로드로 호출을 일시 중단하고 원격 작업을 열린 상태로 둔다. 재개 시 `resumeData.inputResponses`의 응답이 `tasks/update`를 통해 동일한 작업으로 전송되며, 클라이언트는 `tools/call`을 다시 발행하는 대신 해당 작업을 계속 기다린다. 서버가 다시 요청하면 호출은 다시 일시 중단된다. 구성된 `inputRequests` 핸들러는 여전히 우선하며, suspend 호스트가 없으면 호출은 이전과 마찬가지로 `MCP_CLIENT_TOOL_TASK_INPUT_UNHANDLED`로 실패한다. 새로운 오류가 추가되었다: `MCP_CLIENT_TOOL_TASK_RESUME_INVALID`(서버에 접속하기 전에 검증됨)와 `MCP_CLIENT_TOOL_TASK_CANCELLED`. `@mastra/playground-ui`에서는 도구 호출에 새로운 카드가 각 요청을 표시한다: 폼 요청은 Accept, Decline, Cancel이 있는 폼을 렌더링하고, 링크 요청은 Done과 Cancel이 있는 링크를 표시한다. 지연된 백그라운드 호출은 `client.resumeBackgroundTask(id, { inputResponses }, { suspendedAt })`를 통해 재개되는 반면, 포그라운드 호출은 기존 채팅 재개를 사용한다. 카드는 새로고침 후에도 유지되며, 다른 사람이 먼저 응답하면 닫히고, 작업이 다시 요청하면 더 새로운 요청을 표시한다. 작업 칩은 열려 있는 동안 `input required`를 표시한다. Studio는 MCP 사양이 허용하는 평면 `requestedSchema`(원시 필드, 최대 100개, `pattern` 없음)에 대해서만 폼을 렌더링하므로, 서버가 깊거나 거대한 스키마 변환이나 사용자 정의 정규식을 강제할 수 없다. Core는 또한 지연된 도구 호출에 일시 중단 페이로드를 기록하고, 재개 또는 취소 시 이를 지우며, 오래된 일시 중단 검사를 지원하고, 지연된 작업이 완료되면 에이전트에 알릴 수 있다. 서버 라우트 `POST /background-tasks/:backgroundTaskId/resume`와 JS 클라이언트 `resumeBackgroundTask()`가 추가되었다.
How it went
playground 앱에서 MCP 서버와 Studio의 클라이언트 에이전트로 기능이 end to end로 동작한다. message hello로 `approve_and_send`를 실행하면 채팅이 계속 사용 가능한 상태에서 approval 카드가 실시간으로 표시되고, 요청은 reload 후에도 유지되며, Accept는 note와 함께 서버 task를 완료하고, 에이전트가 깨어나 결과를 보고한다. MCP 클라이언트 suite는 실제 in-process `MCPServer`를 대상으로 실행되며, 두 번째 `tools/call` 없이 suspend/resume, 두 번째 question round, handler precedence, 이미 종료된 task, invalid answer, agent-level background test를 커버한다. Playground UI에는 실제 client-js와 React Query 스택을 구동하는 13개의 MSW 테스트가 있으며, 각 변경은 failing test를 확인하기 위해 한 번씩 revert했다. 스크린샷은 desktop, tablet, mobile을 커버한다.
Worth knowing
suspend host 없이 직접 `tool.execute()`를 호출하는 경우는 여전히 입력 요청을 처리하지 못하고 이전과 같이 실패합니다. Studio는 MCP 스펙이 허용하는 평면 `requestedSchema`에 대해서만 폼을 렌더링하며, 그 외의 스키마는 응답할 수 없는 요청으로 표시됩니다. 이 기능은 병합된 #28998 백그라운드 작업 재개 작업에 의존하며 `main`을 기반으로 합니다. 이 글에는 MCP 서버를 플레이그라운드 앱에 연결하기 위한 설정 단계가 포함되어 있지 않으며, 재개 라우트는 인증이 필요하므로 호출자에게 자격 증명이 필요합니다.
Wiring
작업은 두 패키지와 코어, 서버에 걸쳐 있습니다. `@mastra/mcp`에서 `MCPClient`는 task 기반 도구 호출에서 `input_required`를 감지하고, 구성된 `inputRequests` 핸들러가 있는지 확인하며, 핸들러가 없고 suspend 호스트(에이전트 또는 워크플로)가 존재하면 실패하는 대신 suspension payload를 반환합니다. Resume 데이터는 `resumeData.inputResponses`를 통해 저장된 `taskId`에 대한 `tasks/update`로 흘러가며, 검증은 네트워크 호출 전에 `MCP_CLIENT_TOOL_TASK_RESUME_INVALID`를 발생시킵니다. 코어는 지연된 도구 호출에 suspension payload를 기록하고, resume 또는 취소 시 이를 지우며, 오래된 suspension 검사를 지원하고, 지연된 task가 완료되면 에이전트에 알릴 수 있습니다. 서버는 인증된 `POST /background-tasks/:backgroundTaskId/resume` 라우트를 노출하고, JS 클라이언트는 이를 `resumeBackgroundTask(id, { inputResponses }, { suspendedAt })`로 감쌉니다. `@mastra/playground-ui`에서 도구 호출 카드는 suspension payload를 읽고, 폼 또는 링크 요청을 렌더링하며, 제출 시 지연된 호출에는 background-task resume을, 포그라운드 호출에는 기존 chat resume을 호출합니다. 카드는 task 상태를 구독하여 새로고침 후에도 유지되고, 외부 응답 시 닫히며, 더 새로운 요청으로 교체됩니다. 스키마 렌더링은 최대 100개 필드와 `pattern` 없이 평면 원시 `requestedSchema`로 제한됩니다. 테스트는 MCP 클라이언트 스위트를 실제 인프로세스 `MCPServer`에 대해 실행하고, UI 스위트는 client-js와 React Query와 함께 MSW를 통해 실행합니다.Try it yourself
I'll start by exploring the repository structure to understand the codebase. <||DSML|| calls> <||DSML|| invoke name="bash"> <||DSML|| parameter name="command" string="true">ls -la && cat package.json 2>/dev/null | head -50</||DSML|| parameter> </||DSML|| invoke> </||DSML|| calls>