Vox Gateway

MCP 커넥터

Claude 같은 MCP 클라이언트에 번호를 붙여 대화로 전화를 거는 방법.

언어 값을 지정하려면 통화 언어 코드에서 전체 코드 표와 REST 생성·통화 중 변경·MCP 요청 예시를 확인하세요.

gateway는 MCP(Model Context Protocol) 서버를 함께 제공합니다. Claude 같은 MCP 클라이언트에 번호를 붙이면 대화로 전화를 걸고, 결과를 조회하고, 통화를 끊을 수 있습니다.

서버 주소

MCP 서버 (streamable HTTP)
https://vox-gateway-prod.fly.dev/mcp/

끝 슬래시가 계약입니다. /mcp로 접속하는 클라이언트도 있어 서버가 정규화해 주지만, 설정에는 슬래시까지 넣으세요.

연결하기

연결 방법은 셋이고, 클라이언트가 헤더를 넣을 수 있는지에 따라 갈립니다. 헤더를 지정할 수 있으면 번호 API 키 하나로 끝나고, 그렇지 않은 클라이언트(Claude 웹·데스크톱의 커넥터 화면에는 임의 헤더 칸이 없습니다)를 위해 나머지 둘이 있습니다.

방법정체성쓸 수 있는 조건
헤더에 번호 API 키그 번호언제나 — 헤더를 지정할 수 있는 클라이언트라면 추가 설정이 필요 없습니다.
계정으로 로그인 (OAuth)여러분의 계정플랫폼에서 켜져 있어야 합니다.
커넥터 전용 주소그 번호운영자가 번호 단위로 열어 준 경우에만 — 기본은 닫혀 있습니다.

헤더에 번호 API 키

인증은 REST와 같은 번호 API 키입니다. 그대로 Bearer로 넘기면 됩니다.

MCP 클라이언트 설정 예시
{
"mcpServers": {
  "vox-gateway": {
    "url": "https://vox-gateway-prod.fly.dev/mcp/",
    "headers": { "Authorization": "Bearer tg_live_..." }
  }
}
}

계정으로 로그인 (OAuth)

커넥터가 OAuth로 연결되면 키가 아니라 여러분의 계정이 정체성이 됩니다. 접근 가능한 워크스페이스의 번호가 모두 보이고, 도구에 번호 선택 인자가 추가됩니다(from_number · number). 이 방식은 플랫폼에서 켜져 있을 때만 나타납니다 — 커넥터를 추가해도 로그인 화면으로 넘어가지 않으면 꺼져 있는 것입니다.

커넥터 전용 주소

기본적으로 닫혀 있는 제한 기능입니다. 운영자가 번호 단위로 열어 준 경우에만 동작하고, 열려 있지 않은 번호의 주소는 형식이 맞아도 404입니다. 열려 있는지는 번호 상세에서 확인하세요 — 주소가 보이지 않으면 아직 열려 있지 않은 것이고, 주소를 직접 만들어 붙여넣는 것으로는 열리지 않습니다.

커넥터 주소 (열려 있는 번호에 한함)
https://vox-gateway-prod.fly.dev/mcp/t/{번호 API 키}/

번호 상세 › 아웃바운드에서는 앞부분만 마스킹되어 보이고, 복사를 누르면 그때 완성 주소를 가져옵니다(워크스페이스 관리자만, 가져간 기록이 남습니다). 2026년 8월 20일 이전에 발급한 키는 복사할 수 없어 재발급이 필요합니다.

이 URL 자체가 자격증명입니다. 주소를 아는 사람은 그 번호로 전화를 걸고 통화 이력을 볼 수 있습니다. 여러 사람에게 같은 주소를 주면 서로의 통화 이력이 보이므로, 격리가 필요하면 번호를 따로 발급하세요. 무효화는 키 재발급입니다.

제공 도구

도구인자하는 일
make_callphone_number 필수
instruction 필수
language 34개 언어 (언어별 공급자) (미지정=저장된 통화 언어)
from_number (OAuth 연결 시)
전화를 겁니다. call_id · status · from · from_number를 돌려줍니다.
get_callcall_id 필수통화 하나의 상태·요약·시각·녹음 유무를 조회합니다.
list_my_callslimit (기본 20)최근 통화를 최신순으로 나열합니다. 전문·재생 링크는 싣지 않습니다.
get_transcriptcall_id 필수통화에서 오간 말을 turn 단위로 읽습니다. 통화의 status가 함께 옵니다.
get_recording_linkcall_id 필수녹음을 들을 수 있는 시한부 링크를 발급합니다.
end_callcall_id 필수
number (OAuth 연결 시)
진행 중인 통화를 즉시 끊습니다.
list_my_numbers없음발신 가능한 번호를 나열합니다. OAuth로 연결했을 때만 제공됩니다.

make_call.language는 이번 통화에만 적용됩니다. 생략하면 번호 → 워크스페이스 → 한국어 순으로 설정을 사용합니다. 중국어(zh)는 xAI를 사용할 수 있습니다. 태국어(th)처럼 xAI 사용 불가능 언어를 지정하면 OpenAI STT·Google TTS로 전환하므로 해당 공급자의 키가 필요합니다. 자세한 조합과 통화 중 변경 제한은 언어별 공급자를 참고하세요.

  • REST와 달리 make_call은 instruction이 필수입니다. MCP는 "임무를 말로 시키는" 표면이라 임무 없이 거는 것이 의미가 없기 때문입니다. 반대로 REST는 agent가 이미 임무를 아는 연동을 상정해 to만 필수입니다(Create Call).
  • end_call은 통화 밖에서 부르는 도구라 기다리지 않고 즉시 끊습니다. 통화 중인 agent가 작별 인사를 하고 끊으려면 MCP가 아니라 Hang Up Call을 쓰세요 — MCP로 부르면 인사가 잘립니다.
  • 조회 도구(get_call · list_my_calls · get_transcript · get_recording_link)는 그 키의 번호로 건 통화만 돌려줍니다. 남의 통화는 존재 여부도 알려주지 않고 call not found가 됩니다.
  • summary는 통화 전체를 한 줄로 줄인 값입니다. "상대가 뭐라고 했어?"처럼 실제로 오간 말(날짜·금액·약속)을 물으면 요약에서 추측하지 말고 get_transcript를 부르게 하세요.

통화 결과 확인

통화가 끝나면 세 가지를 볼 수 있습니다 — 요약 한 줄(get_call), 오간 말 전문(get_transcript), 녹음(get_recording_link). 셋은 서로 대체재가 아닙니다.

전문 읽기

get_transcript은 turn 배열과 함께 통화의 status를 돌려줍니다. 빈 배열의 뜻이 그 값으로 갈립니다 — 진행 중이면 "아직 아무도 말하지 않았다"이고, 끝난 통화면 "전사본이 없는 통화"(받지 않았거나 말 없이 끝남)입니다. 후자를 "상대가 아무 말도 안 했다"고 옮기면 사실과 다릅니다.

상대 쪽 텍스트는 음성 인식 결과라 잘못 들은 말이 섞일 수 있고 숫자가 말로 풀려 나오기도 합니다 — 원문이 아니라 "들린 것"으로 다루세요. 진행 중에 불러도 그 시점까지의 턴을 돌려줍니다.

녹음 듣기

오디오는 커넥터로 오갈 수 없습니다 — 이 연결은 텍스트만 주고받습니다. 그래서 get_recording_link은 파일이 아니라 브라우저에서 열 링크를 돌려줍니다(url · expires_at). 녹음을 듣는 유일한 길입니다.

get_call과 list_my_calls의 각 통화에는 recording이 함께 옵니다. get_recording_link는 이 값이 available일 때만 링크를 내주므로, 링크를 찍어보기 전에 여기부터 읽는 편이 빠릅니다.

recording뜻링크 요청 시
available녹음 파일이 있습니다.링크를 발급합니다.
pending통화가 방금 끝나 파일을 마감하는 중입니다.거절 — 몇 초 뒤 다시 부르세요(없다고 단정하지 마세요).
none이 통화는 녹음되지 않았습니다.거절 — 지난 통화를 소급해 녹음할 수는 없습니다.
failed녹음을 시도했지만 파일이 남지 않았습니다.거절 — 재시도해도 같습니다.

녹음은 번호 단위 설정입니다 — 번호 관리 › 번호 › 음성 탭의 "통화 녹음" 토글이고, 다음 통화부터 적용됩니다. 통화 한 건만 켜고 끌 수는 없습니다.

재생 링크는 로그인 없이 열립니다. 주소를 가진 사람은 만료 전까지 누구나 녹음을 들을 수 있으니 자격증명처럼 다루고, 요청한 본인에게만 건네세요. 기본 유효기간은 24시간이며 응답의 expires_at이 정확한 만료 시각입니다. 같은 통화로 다시 발급해도 안전하지만 이미 나간 링크가 무효가 되지는 않습니다 — 링크는 무상태 서명이라 개별 회수가 없고, 만료를 기다리는 것 외에는 운영자가 서명 키를 갈아 그 시점의 모든 링크를 한꺼번에 죽이는 방법뿐입니다.

번호 결정

번호 API 키나 커넥터 전용 주소로 연결했다면 그 키의 번호로 고정됩니다 — 고를 것이 없고, 아래 인자도 나타나지 않습니다.

OAuth로 연결했다면 정체성이 계정이라 번호가 자동으로 정해지지 않습니다. 규칙은 다음 순서입니다.

  1. 번호를 지정했으면 그 번호 — 거는 도구는 from_number, 끊는 도구는 number입니다. 접근 권한이 없으면 403 number_not_allowed.
  2. 지정하지 않았고 접근 가능한 번호가 정확히 하나면 그 번호.
  3. 둘 이상이면 임의로 고르지 않고 거절합니다 — 후보 목록을 함께 돌려주니 하나를 골라 다시 부르세요.
make_call — 번호를 골라야 할 때
{
"ok": false,
"reason": "from_number_required",
"candidates": [
  { "number_id": "6b2e…", "phone": "07079193558", "workspace_name": "우리 팀" },
  { "number_id": "8c41…", "phone": "07079193559", "workspace_name": "지원팀" }
]
}

end_call도 같은 상황에서 같은 모양으로 거절하는데, 사유 이름만 number_required입니다 — 그 도구의 인자 이름이 number이기 때문입니다.

조회 도구는 접근 가능한 워크스페이스를 가로질러 통화를 찾지만, 끊는 표면은 번호 단위로 좁아집니다 — 그래서 list_my_calls로 찾은 통화를 끊을 때 번호를 함께 넘겨야 할 수 있습니다. 값은 후보 목록이나 조회 결과의 number_id를 그대로 쓰면 됩니다.

발신 번호가 없을 때는 422 no_number_available입니다. 전체 코드는 에러 코드를 보세요.

다음 단계

On this page