ClawOps Node.js SDK 완전 가이드: TypeScript로 AI 전화 에이전트 만들기
ClawOps Node.js SDK 완전 가이드: TypeScript로 AI 전화 에이전트 만들기

Python 진영이 AI 개발의 중심이지만, 실제 서비스 백엔드는 Node.js/TypeScript로 구축하는 팀이 압도적으로 많습니다. ClawOps는 공식 Node.js SDK(@teamlearners/clawops)를 제공해 TypeScript의 타입 안전성과 AI 음성 에이전트를 동시에 활용할 수 있습니다.
이 글에서는 설치부터 REST API 호출, AI Agent 구축, Tool 등록, MCP 연동까지 Node.js SDK의 모든 기능을 실전 코드와 함께 다룹니다.
왜 Node.js SDK인가?
- TypeScript 퍼스트 — 모든 메서드에 타입 정의와 JSDoc이 포함돼 IDE 자동완성이 완벽합니다
- AI Agent 내장 —
ClawOpsAgent로 인바운드·아웃바운드 전화를 AI가 처리합니다. ngrok 불필요 - REST + Agent 통합 — 하나의 패키지에서 REST API와 Voice Agent를 모두 사용 가능
- Node.js 18+ — ESM 환경에서
await기반의 깔끔한 코드
1단계: 설치 및 환경 설정
패키지 설치
용도에 따라 설치 범위가 다릅니다:
# REST API만 사용 (전화 발신, 문자, 번호 관리)
npm install @teamlearners/clawops
# AI Agent 모드 (OpenAI Realtime)
npm install @teamlearners/clawops ws openai
# AI Agent 모드 (Gemini Realtime)
npm install @teamlearners/clawops ws @google/genai
# AI Agent — Pipeline (Deepgram STT + OpenAI LLM + ElevenLabs TTS)
npm install @teamlearners/clawops ws @deepgram/sdk openai elevenlabs
환경변수 설정
export CLAWOPS_API_KEY="sk_live_..."
export CLAWOPS_ACCOUNT_ID="AC1a2b3c4d"
export OPENAI_API_KEY="sk-..." # AI Agent 사용 시
ClawOps 대시보드에서 API Key와 Account ID를 확인할 수 있습니다.
2단계: REST API — 전화·문자·번호 관리
클라이언트 초기화
import ClawOps from '@teamlearners/clawops';
// 환경변수가 설정돼 있으면 인자 생략 가능
const client = new ClawOps();
// 또는 직접 지정
const client2 = new ClawOps({
apiKey: 'sk_live_...',
accountId: 'AC1a2b3c4d',
});
전화번호 발급·관리
// 070 번호 발급
const number = await client.numbers.create({
webhookUrl: 'https://my-app.com/voice',
});
console.log(number.phoneNumber); // "07012340001"
// 번호 목록 조회
const numbers = await client.numbers.list();
// 웹훅 URL 변경
await client.numbers.update('07012340001', {
webhookUrl: 'https://my-app.com/new-voice',
});
// 번호 해제
await client.numbers.delete('07012340001');
전화 발신
const call = await client.calls.create({
to: '01012345678',
from: '07052358010',
url: 'https://my-app.com/twiml',
statusCallback: 'https://my-app.com/status',
statusCallbackEvent: 'initiated ringing answered completed',
});
console.log(call.callId); // "CA..."
통화 목록·상세 조회
// 목록 (자동 페이지네이션)
for await (const call of (await client.calls.list()).autoPagingIter()) {
console.log(call.callId, call.status);
}
// 단건 조회
const detail = await client.calls.get('CA1a2b3c4d5e6f7890');
console.log(detail.status, detail.direction);
// 진행 중 통화 종료
await client.calls.update('CA1a2b3c4d5e6f7890', { status: 'completed' });
SMS/MMS 발송
// SMS (단문)
await client.messages.create({
to: '01012345678',
from: '07052358010',
body: '안녕하세요, ClawOps입니다.',
});
// MMS (이미지 첨부)
await client.messages.create({
to: '01012345678',
from: '07052358010',
body: '사진을 보내드립니다.',
type: 'mms',
subject: '알림',
mediaUrl: ['https://example.com/photo.jpg'],
});
3단계: AI Agent — 전화를 AI가 받고 거는 코드
Node.js SDK의 ClawOpsAgent는 ngrok 없이 WebSocket 역방향 연결로 동작합니다. 로컬에서 바로 테스트 가능합니다.
인바운드 (전화 수신)
import { ClawOpsAgent, OpenAIRealtime } from '@teamlearners/clawops/agent';
const agent = new ClawOpsAgent({
from: '07012341234', // 발급받은 070 번호
session: new OpenAIRealtime({
systemPrompt: '친절한 고객 상담원입니다. 한국어로 응대합니다.',
voice: 'marin',
language: 'ko',
}),
});
await agent.serve(); // Ctrl+C로 종료
실행 후 070-1234-1234로 전화하면 AI가 받습니다.
아웃바운드 (전화 발신)
const agent = new ClawOpsAgent({
from: '07012341234',
session: new OpenAIRealtime({
systemPrompt: '예약 확인 전화를 하는 도우미입니다.',
language: 'ko',
}),
});
const session = await agent.call('01012345678', { timeout: 30 });
console.log(`발신 중... (callId: ${session.callId})`);
await session.wait(); // 통화 종료까지 대기
await agent.disconnect();
Tool 등록 — AI에게 기능을 부여하기
const agent = new ClawOpsAgent({
from: '07012341234',
session: new OpenAIRealtime({
systemPrompt: '주문 상담원입니다. 고객이 주문 상태를 물으면 확인해주세요.',
voice: 'marin',
language: 'ko',
}),
});
// AI가 호출할 수 있는 Tool 등록
agent.tool(
'check_order',
'주문 상태를 확인합니다.',
{ orderId: { type: 'string' } },
async ({ orderId }) => {
// 실제로는 DB나 API를 조회
return `주문 ${orderId}은 배송 중입니다. 내일 도착 예정입니다.`;
},
);
await agent.serve();
이벤트 핸들링
agent.on('call_start', async (call) => {
console.log(`통화 시작: ${call.fromNumber} -> ${call.toNumber}`);
});
agent.on('call_end', async (call) => {
console.log(`통화 종료 (${call.callId})`);
});
MCP 서버 연동
외부 MCP 서버를 연결해 AI 에이전트의 능력을 확장할 수 있습니다:
npm install @teamlearners/clawops ws @modelcontextprotocol/sdk
import {
ClawOpsAgent, OpenAIRealtime,
mcpServerStdio, mcpServerHTTP,
} from '@teamlearners/clawops/agent';
const agent = new ClawOpsAgent({
from: '07012341234',
session: new OpenAIRealtime({
systemPrompt: '다양한 도구를 활용하는 AI 상담원입니다.',
}),
mcpServers: [
mcpServerStdio('npx', {
args: ['@modelcontextprotocol/server-google'],
env: { GOOGLE_API_KEY: '...' },
}),
mcpServerHTTP('https://my-mcp-server.com', {
headers: { Authorization: 'Bearer token' },
}),
],
});
await agent.serve();
4단계: 에러 처리
SDK는 계층적 예외를 제공합니다:
import ClawOps, {
AuthenticationError,
NotFoundError,
RateLimitError,
APIStatusError,
} from '@teamlearners/clawops';
const client = new ClawOps();
try {
await client.calls.get('CA_invalid_id');
} catch (e) {
if (e instanceof NotFoundError) {
console.log(`통화를 찾을 수 없습니다: ${e.message}`);
} else if (e instanceof AuthenticationError) {
console.log('API 키가 유효하지 않습니다.');
} else if (e instanceof RateLimitError) {
console.log(`동시 통화 한도 초과: ${e.message}`);
} else if (e instanceof APIStatusError) {
console.log(`API 에러: HTTP ${e.statusCode} - ${e.message}`);
}
}
자동 재시도(지수 백오프, 기본 2회)가 내장되어 있어 일시적 오류는 자동 처리됩니다:
const client = new ClawOps({ maxRetries: 5 }); // 재시도 5회로 변경
const client2 = new ClawOps({ maxRetries: 0 }); // 비활성화
5단계: Webhook 서명 검증
프로덕션에서는 반드시 webhook 서명을 검증하세요:
import express from 'express';
import ClawOps, { WebhookVerificationError } from '@teamlearners/clawops';
const app = express();
const client = new ClawOps();
app.post('/webhook', express.urlencoded({ extended: false }), (req, res) => {
try {
client.webhooks.verify({
url: 'https://my-app.com/webhook',
params: req.body,
signature: req.headers['x-signature'] as string,
signingKey: 'your_signing_key',
});
} catch (e) {
if (e instanceof WebhookVerificationError) {
return res.status(401).send('Unauthorized');
}
}
const callId = req.body.CallId;
// ... 이벤트 처리
res.sendStatus(204);
});
Python SDK와의 비교
| 기능 | Python SDK | Node.js SDK |
|---|---|---|
| 설치 | pip install clawops | npm install @teamlearners/clawops |
| AI Agent | pip install clawops[agent,openai] | npm install @teamlearners/clawops ws openai |
| 타입 지원 | 타입 힌트 (mypy) | TypeScript 네이티브 |
| 비동기 | AsyncClawOps / asyncio | 기본 async/await |
| Agent 패턴 | @agent.tool 데코레이터 | agent.tool() 메서드 |
| 발신자 번호 | from_= (예약어 회피) | from: (객체 키) |
| MCP 연동 | MCPServerStdio() | mcpServerStdio() |
실전 예시: Express + ClawOps 전화 상담 서버
import express from 'express';
import { ClawOpsAgent, OpenAIRealtime, BuiltinTool } from '@teamlearners/clawops/agent';
import ClawOps from '@teamlearners/clawops';
const app = express();
const client = new ClawOps();
// AI 전화 에이전트 (인바운드 수신)
const agent = new ClawOpsAgent({
from: '07012341234',
session: new OpenAIRealtime({
systemPrompt: `카페 예약 상담원입니다.
- 영업시간: 10:00-22:00
- 예약은 2인 이상만 가능합니다.
- 복잡한 문의는 상담원에게 전환하세요.`,
voice: 'marin',
language: 'ko',
}),
builtinTools: [BuiltinTool.HANG_UP, BuiltinTool.TRANSFER_CALL],
});
// Tool: 예약 가능 여부 확인
agent.tool(
'check_availability',
'특정 날짜와 시간의 예약 가능 여부를 확인합니다.',
{ date: { type: 'string' }, time: { type: 'string' }, people: { type: 'number' } },
async ({ date, time, people }) => {
// 실제로는 DB 조회
return `${date} ${time}에 ${people}명 예약 가능합니다.`;
},
);
// 통화 로그
agent.on('call_start', async (call) => {
console.log(`[${new Date().toISOString()}] 통화 시작: ${call.fromNumber}`);
});
// REST API: 최근 통화 조회
app.get('/api/calls', async (req, res) => {
const page = await client.calls.list({ pageSize: 20 });
res.json(page.data);
});
// 서버 시작
agent.serve();
app.listen(3000, () => console.log('API 서버 시작: http://localhost:3000'));
마무리
ClawOps Node.js SDK는 TypeScript의 타입 안전성과 AI 음성 에이전트를 결합해, 기존 Node.js 백엔드에 자연스럽게 AI 전화 기능을 추가할 수 있게 해줍니다.
- npm: @teamlearners/clawops
- GitHub: learners-superpumped/clawops-node
- API 문서: claw-ops.com/docs/sdk/node
3일 무료 Trial로 바로 시작해보세요 → claw-ops.com
관련 글: ClawOps Python SDK 완전 입문 · AI 전화 에이전트 만들기 · 웹훅으로 전화 자동화 구현하기
관련 글 더 보기
OpenAI 말고 Gemini·Claude로 AI 전화 에이전트 만들기: Pipeline 모드 완전 가이드
ClawOps Voice Agent SDK의 Gemini Realtime과 Pipeline 모드로 OpenAI 외 AI 엔진을 사용하는 방법. Deepgram STT + Claude LLM + ElevenLabs TTS 조합, 커스텀 Provider 구현까지.
가이드AI 전화 에이전트에 Tool 연동하기: 예약 조회, DB 검색, 외부 API 호출
ClawOps Voice Agent SDK의 Tool 등록 기능으로 AI 전화 에이전트가 DB 조회, 예약 확인, 외부 API 호출을 수행하게 만드는 방법. Python/Node.js 실전 코드 포함.
가이드AI 전화 에이전트 Call Transfer 구현 가이드: AI가 상담원에게 전화를 넘기는 법
ClawOps Voice Agent의 Call Transfer 기능으로 AI가 상담원에게 전화를 전환하는 방법. Blind Transfer, Warm Transfer, 전환 후 AI 복귀까지 Python/Node.js 코드와 함께 설명합니다.
가이드Twilio 한국 070 안 된다 — ClawOps로 5분 마이그레이션
Twilio 한국 070 안 된다 — ClawOps로 5분 마이그레이션
가이드한국 SMS/LMS/MMS API 완벽 가이드: Python으로 문자 보내기
한국에서 SMS, LMS, MMS를 API로 발송하는 방법. ClawOps Python SDK로 단문·장문·이미지 문자를 보내고, 수신 웹훅으로 자동 응답하는 실전 가이드입니다.