Claude에게 컴퓨터를 제공하기: 원격 MCP 서버 배포를 통해 배운 다섯 가지
요약
AI 에이전트가 영구적인 클라우드 머신을 갖도록 설계하고, 이를 Claude, ChatGPT 등 LLM에 연결하는 MCP 서버 배포 경험을 공유합니다. 핵심은 비동기적 작업 처리와 사용자 개입의 중요성입니다. 모델에게 루프를 작성하게 하는 것만큼 도구 설계를 정교하게 하는 것이 중요하며, 사용자의 승인권을 유지하여 에이전트가 오용되는 것을 방지하는 방법을 제시합니다.
핵심 포인트
- 에이전트 작업은 비동기적이며, `wait_for_reply`를 통해 상태를 관리해야 합니다.
- 모델은 사용자 대신 답변해서는 안 되며, 명시적인 승인 과정이 필요합니다.
- 사용자에게 허용된 도구만 노출하여 보안과 제어권을 강화해야 합니다.
- MCP 도구는 REST API 위에 구축된 얇은 어댑터 역할을 수행하며 인프로세스 호출을 강제합니다.
챗 어시스턴트는 대화는 잘하지만 컴퓨터를 지속적으로 유지하는 것은 서툽니다. 탭을 닫으면 환경이 사라집니다. 저희 제품은 각자 고유의 영구적인 클라우드 머신을 가진 AI 에이전트를 실행합니다: 저장소(repos), 도구(tools), 실행 중인 애플리케이션 등, 내일도 그대로 있습니다.
이번 주에는 이 에이전트들 앞에 MCP 서버를 배치하여 Claude, ChatGPT, Cursor 또는 Codex가 그들에게 작업을 할당할 수 있도록 했습니다. 서버 자체는 코드가 많지 않습니다. 흥미로운 부분은 MCP 도구가 호출되는 방식과 실제 에이전트 작업이 이루어지는 방식 사이의 불일치였습니다. 여기 다섯 가지 사항을 소개합니다.
1. 도구 호출(Tool calls)은 동기적입니다. 에이전트 작업은 그렇지 않습니다.
MCP 도구 호출은 요청과 응답으로 구성됩니다. 실제 에이전트 작업(이 버그 수정하기, 테스트 스위트 실행하기, 보고서 작성하기 등)은 몇 분이 걸립니다. 만약 도구 호출이 6분 동안 차단된다면, 대부분의 클라이언트는 먼저 시간 초과가 발생합니다.
그래서 위임(delegation)은 두 가지 도구를 사용합니다. send_message는 작업을 시작하고 토픽 ID와 실시간으로 지켜볼 수 있는 링크를 즉시 반환합니다. wait_for_reply는 최대 55초 동안 차단되며 상태를 반환합니다: 응답과 함께 done, 질문이 있을 경우 waiting_on_you, (다시 호출) working, 또는 error입니다. 모델은 최종적인 결과를 얻을 때까지 계속해서 이 함수를 호출합니다.
55초로 제한한 이유는 일반적인 클라이언트 요청 시간 초과 내에 머무르면서도 빠른 작업을 단일 대기(single wait) 내에서 완료할 수 있도록 하기 위함입니다. 나머지 부분은 서버 지침에 포함되어 있으며, 여기에는 '에이전트 작업은 비동기적이며, 상태가 done일 때까지 계속해서 wait_for_reply를 호출하라'고 명확히 나와 있습니다. 모델에게 루프(loop)를 작성하는 것이 도구 설계만큼 중요했습니다.
2. 모델은 사용자 대신 답변해서는 안 됩니다
확히 나와 있습니다. 모델에게 루프(loop)를 작성하는 것이 도구 설계만큼 중요했습니다.
2. 모델은 사용자 대신 답변해서는 안 됩니다
이렇게 하면 인간이 과정에서 빠지게 됩니다. 따라서 waiting_on_you가 별도의 상태이며, 질문과 선택지는 구조화되어 돌아오고, 지침에는 다음과 같이 명시됩니다: 사용자에게 보여주고 그들의 선택으로 answer_decision을 호출하세요. 사용자가 요청하지 않은 한 절대로 대신 답변해서는 안 됩니다. 승인은 에이전트를 소유한 사람에게 남아 있습니다. 심지어 대화가 다른 사람의 앱에서 일어나더라도 말입니다.
3. 사용자에게 허용된 도구만 나열하기
저희는 도구를 다섯 가지 권한으로 분류했습니다: 읽기(Read), 위임(Delegate), 자동화(Automate), 기계(Machine, 에이전트의 컴퓨터에서 명령 실행 및 파일 편집) 그리고 에이전트 관리(Manage agents). 사용자는 동의 화면에서 이를 선택합니다.
서버는 토큰의 스코프(scopes)에 따라 tools/list를 필터링하므로, 읽기(Read)와 위임(Delegate)만 연결된 모델은 셸 도구 자체를 전혀 볼 수 없습니다. 이것이 들리는 것보다 더 중요합니다: 모델은 한 번도 보여지지 않은 도구를 오용하거나 사용하도록 유도될 수 없습니다. 그리고 만약 호출이 권한 장벽에 부딪히면, 오류 메시지는 어떤 권한이 누락되었는지 알려주고 그것을 다시 연결하면 도움이 될 것이라고 하므로, 모델은 맹목적으로 재시도하는 대신 상황을 설명할 수 있습니다.
4. 얇은 어댑터가 되어 접근을 한 번 강제하기
모든 MCP 도구는 기존의 공개 REST API 위에 있는 작은 어댑터이며, 호출자의 자체 토큰으로 인프로세스(in-process)에서 호출됩니다. 워크스페이스 스코핑(Workspace scoping), 사용자별 접근 권한, 속도 제한(rate limits), 라우트 권한은 이미 테스트가 되어 있는 API 내에서 정확히 한 번만 강제됩니다.
새로운 인터페이스에 대한 유혹은
Claude와 ChatGPT는 OAuth를 통해 연결되며, 사양(spec)을 따르면 상당 부분의 작업이 처리됩니다. 인증되지 않은 요청은 WWW-Authenticate 헤더가 보호된 리소스 메타데이터를 가리키며 401 오류를 반환합니다. 이 메타데이터는 동적 클라이언트 등록과 PKCE(Proof Key for Code Exchange)를 제공하는 권한 부여 서버 메타데이터를 가리킵니다. 클라이언트는 자신을 등록하고, 우리의 동의 화면을 열고, 하나의 워크스페이스에 범위가 지정된 토큰을 가지고 돌아옵니다.
사용자 경험은 단순히 'URL 붙여넣기, 로그인하기, 권한 선택하기'입니다. API 키를 선호하는 명령줄 도구도 동일한 범위(scope)의 베어러 키(bearer key)를 전송할 수 있습니다.
전송 방식은 간단합니다: 스트리밍 가능한 HTTP(Streamable HTTP), 상태 비저장(stateless), POST당 하나의 JSON-RPC 메시지, 서버가 시작하는 스트림 없음. 상태 비저장은 기존 API 뒤에서 세션 기록을 유지하지 않고 실행하기 쉽게 만들었습니다.
패턴
프로토콜 부분은 쉬운 부분이었습니다. 비동기 작업, 인간의 승인 및 권한이 다른 쪽 모델에게 어떻게 보여야 할지 결정하는 곳에 대부분의 사고가 집중되었습니다. 만약 여러분의 도구가 느리거나 사람이 필요한 무언가를 한다면, 기다리는 과정과 요청하는 과정을 먼저 설계해야 합니다.
MCP를 통해 자체 제품을 노출했을 때 가장 놀라웠던 점은 무엇인가요? 댓글에서 의견을 비교하고 싶습니다.
저희는 AI 에이전트가 자체 클라우드 머신에서 작동하는 JackHamr를 구축합니다. Claude, ChatGPT, Cursor 및 Codex에 대한 설정은 문서(docs)에서 확인할 수 있습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기