개발자 가이드

커넥터 설치·운영

커넥터는 고객사 서버에서 돌아가는 작은 프로그램이에요. 운영 DB를 읽기 전용으로 보고 발송 대상을 서버 안에서 계산합니다 — 원본 데이터는 밖으로 나가지 않아요.

커넥터와 플랫폼 MCP(외부 AI 연결)가 헷갈리면 → 연동 구조 한눈에 보기를 먼저 보세요. 이 페이지는 그중 커넥터(브라우저 로그인)를 다룹니다.
🐤 Claude Code가 처음이세요? (3분 준비)
  1. Node 22+ 설치 — 터미널에서 node -v로 확인 (없으면 nodejs.org).
  2. Claude Code 설치npm install -g @anthropic-ai/claude-code → 터미널에서 claude 입력해 로그인.
  3. 절차 A(설치) — 아래 “절차 A”대로 npx @crmforall/connect logininit. 끝에 “MCP 등록할까요? Y”.
  4. 절차 B(대화) — 터미널에 claude → 세션에서 /crmforall-connector:onboard. 선택지 카드대로 고르면 끝!

터미널·세션 구분이 헷갈리면: claude mcp add·npx터미널(쉘)에서,/crmforall-connector:onboardclaude를 실행한 세션 안에서 칩니다.

핵심은 두 절차예요: ① 설치 실행(일반 터미널/쉘) — 커넥터를 깔고 DB에 연결·MCP 등록. ② AI로 진단·연결·매핑(Claude Desktop·Code) — Claude에게 말로 시켜 온보딩을 끝냄. 전산담당자가 분리된 조직을 위한 수동 토큰 전달 경로는 맨 아래 부록에 따로 뒀어요.
두 트랙 구분: 이 커넥터는 데이터 트랙(누구에게 보낼지 — 고객 DB)입니다. 발송 준비(카카오)는 별도 트랙이에요 — 카카오 디벨로퍼스 앱 등록·채널 연동은 카카오 디벨로퍼스 연동에서 진행합니다. 커넥터 설치에는 카카오 등록이 필요 없고, 실제 발송 직전에만 필요해요.

요구 사항

  • Node.js 22 이상 (서버에 설치돼 있어야 해요)
  • PostgreSQL 운영 DB + 읽기 전용 계정 (권장 권한은 절차 A 2단계)
  • 아웃바운드 HTTPS (플랫폼 API 호출용) — 인바운드 포트 개방 불필요

절차 A — 설치 실행 (일반 터미널/쉘에서)

커넥터를 깔고 DB에 연결한 뒤 Claude Code에 MCP로 등록하는 단계예요. 운영자가 한 번 로그인해두면 설치 토큰을 손으로 발급·복사할 필요가 없어요.

실제 화면 컴포넌트 — 콘솔과 항상 동일
# 1) 로그인 — 브라우저가 열리면 코드 확인 후 "승인" 클릭 npx @crmforall/connect login # 2) 연결 — DB 정보만 입력하면 등록까지 자동, 끝에 "MCP 등록? Y" npx @crmforall/connect init # 3) 대화 (절차 B) claude → /crmforall-connector:onboard
① login은 브라우저 코드 승인 1회. ② init은 DB 정보만 — 등록은 자동. ③ claude 세션에서 온보딩.
1
로그인 (디바이스 코드) — 승인은 머신당 1회
실제 화면 컴포넌트 — 콘솔과 항상 동일
npx @crmforall/connect login
브라우저가 열리고 코드를 확인해 승인하면 끝. 토큰 복사 불필요.

디바이스 코드 방식이에요. 브라우저를 못 쓰면 login --paste로 콘솔 토큰을 붙여넣을 수도 있어요. 승인은 머신당 1회면 됩니다 — 로그인 직후 신원이 저장되므로, 다음 DB 연결 단계 전에 끊기거나 다시 시작해도 재승인 없이 이어집니다 (resume, 0.1.19+).

브라우저 디바이스 승인 화면 — 터미널이 띄운 기기 코드를 확인하고 '이 기기 승인'을 누른다
login이 띄운 기기 코드를 콘솔 /device 화면에서 확인·승인. 재현 데모 — 실제 코드·계정 미사용.
2
DB 계정 준비 (최소 권한)
실제 화면 컴포넌트 — 콘솔과 항상 동일
CREATE ROLE cfa_reader LOGIN PASSWORD '…'; GRANT CONNECT ON DATABASE mydb TO cfa_reader; GRANT USAGE ON SCHEMA public TO cfa_reader; GRANT SELECT ON ALL TABLES IN SCHEMA public TO cfa_reader; GRANT CREATE ON DATABASE mydb TO cfa_reader; -- CRM 전용 스키마용
권장 권한 — SELECT만 + CRM 전용 스키마 생성. 원본 테이블 쓰기 권한이 있으면 설치가 거부돼요.
3
연결·등록 (init)
실제 화면 컴포넌트 — 콘솔과 항상 동일
npx @crmforall/connect init
대화형 — 호스트·DB·계정·비밀번호(가림)를 한 줄씩 물어봐요. 비대화형(컨테이너)은 CRMFORALL_DB_URL 환경변수 사용.

설치가 하는 일: ① 플랫폼 등록(코드→자격증명 교환) ② 권한 검사(아래 게이트) ③ CRM 전용 스키마 crmforall 생성 ④ 설정 저장(~/.crmforall/connector.json, 0600) ⑤ 끝에 “Claude Code에 MCP 등록할까요? (Y/n)”Y claude mcp add로 자동 등록(범위는 그때 선택).

npx init → 설치 마법사 → 호스트·DB·계정·비밀번호 입력 → SSL 선택 → 확인 → ✓ 완료
연결 마법사: npx 설치 확인(Ok to proceed?) → 호스트·DB·계정·비밀번호(가림) 입력 → SSL 선택 → 확인 → ✓ init 완료. 재현 데모 — 실제 자격증명·데이터 미사용.

나중에 다시 등록하려면 npx @crmforall/connect mcp --scope user. 플러그인으로 한 번에 설치하려면 절차 B 1단계를 보세요.

절차 B — AI로 진단·연결·매핑하기 (Claude Desktop·Code)

커넥터는 MCP 서버(@crmforall/connector)로 떠서, 전산담당자가 쓰는 AI에게 말로 시켜 진단·연결·매핑을 끝낼 수 있어요. 커넥터가 흐름을 스스로 안내하고, 결정 지점에서는 선택지 카드(AskUserQuestion)로 물어 고르기만 하면 됩니다.

claude 세션에서 /crmforall-connector:onboard 실행 → 단계 진행 → 매핑 확정 선택지 카드 → 고객 규모 요약 → 다음 단계 선택지 카드
AI 온보딩(Claude Code 기준): /crmforall-connector:onboard → 진단·스키마·매핑 → 선택지 카드로 매핑 확정 → 고객 규모 요약 → 다음 단계 선택. 재현 데모.
1
MCP 등록 (절차 A의 init이 자동, 또는 플러그인)

절차 A의 init 끝에서 Y를 눌렀다면 이미 등록돼 있어요. 처음부터 플러그인으로 한 번에 깔려면 Claude Code 세션에서:

실제 화면 컴포넌트 — 콘솔과 항상 동일
/plugin marketplace add HosungYou/crmforall-marketplace /plugin install crmforall-connector@crmforall
Claude Code 세션 안에서 입력 — MCP 등록 + 슬래시 커맨드가 함께 들어와요.

수동 등록(직접):

실제 화면 컴포넌트 — 콘솔과 항상 동일
claude mcp add crmforall-connector -- npx -y @crmforall/connector
일반 터미널(쉘)에서 실행하는 claude CLI 명령.
실제 화면 컴포넌트 — 콘솔과 항상 동일
{ "mcpServers": { "crmforall-connector": { "command": "npx", "args": ["-y", "@crmforall/connector"] } } }
Claude Desktop — claude_desktop_config.json에 추가하고 앱 재시작.
2
온보딩 시작 (Claude 세션 안에서)

Claude 세션 안에서 /crmforall-connector:onboard를 입력하세요(또는 “크렘포올 커넥터 온보딩 진행해줘”). 커넥터가 순서대로 수행해요: onboarding_statustest_connectioninspect_schema propose_field_mappingvalidate_mappingaudience_summary.

아직 DB 연결이 없다면, 터미널 없이 세션 안에서 바로 연결할 수도 있어요 —setup_login(브라우저 승인) → setup_database(입력창). 비밀번호는 입력창에서 서버로 직접 전달되어 AI(모델)에 노출되지 않아요.

3
결정 지점 — 선택지 카드(AskUserQuestion)

중요한 갈림길에서는 자유 서술 대신 선택지 카드가 떠요(onboard 커맨드가 지시). 네 지점입니다:

  1. 연결 방법 — 미설정이면 “세션 안 셋업 / 터미널 init / 이미 했음”
  2. 과권한 대응 — 쓰기 권한 감지 시 “축소 SQL 받기 / 읽기전용 재연결 / 중단”
  3. 매핑 확정 — “제안대로 확정 / 일부 수정 / 컬럼별 상세 보기”
  4. 다음 단계 — 요약 후 “대상 스냅샷 / 동기화 설정 / 종료”
매핑 확정
제안된 표준 필드 매핑을 확정할까요?
❯ 제안대로 확정 (권장)
  일부 필드 수정 후 확정
  컬럼별 상세 먼저 보기

위는 실제 Claude Code의 AskUserQuestion 카드 모습(재현). 입력창(elicitation)을 지원하지 않는 클라이언트는 텍스트로 안내하며 절차 A(터미널)로 폴백합니다.

4
첫 성과 — audience_summary
audience_summary고객 N명 · 발송 동의 M명 · 발송 가능 후보 K명을 바로 보여줘요(프로젝트 불필요). 이어서 “다음 단계” 선택지 카드가 떠요. 동기화는 /crmforall-connector:sync, 진단은 /crmforall-connector:doctor.
안전 경계: AI는 컬럼명·집계·인원수만 다뤄요(비밀번호·개인정보 원문 비노출). 쓰기·발송 도구(create_target_snapshot·send_kakao_message 등)는 콘솔에서 사람이 승인한 단회용 토큰이 있어야만 실행됩니다. 호출 규약은 API 레퍼런스, 직접 실습은 GitHub 레포의 ONBOARDING.md 테스트킷을 보세요.

Connection Readiness Gate — doctor가 검사하는 것

npx @crmforall/connect doctor로 언제든 재진단할 수 있어요:

검사통과 조건
node_versionNode 22 이상
platform_url_configured플랫폼 URL 설정됨
connectDB 접속 성공
operational_select운영 테이블 SELECT 가능
source_table_write_blocked원본 테이블에 INSERT/UPDATE/DELETE 권한 없음 — 있으면 활성화 차단 + 권한 축소 SQL 출력
crm_schema_existscrmforall 스키마 존재
crm_schema_writeCRM 스키마 쓰기 가능 (예약 기록용)

보안 모델

  • 원본 비유출 — 대상 계산은 서버 안, 플랫폼엔 인원수·제외 집계·해시만
  • 읽기 전용 강제 — 과권한이면 게이트가 활성화를 막아요
  • 쓰기는 승인 토큰 — CRM 스키마에 쓰는 작업(예약 기록 등)은 콘솔 승인으로 발급된 단회용 토큰이 있어야만 실행
  • 시크릿 비저장 — 설치 코드·커넥터 시크릿은 해시만 서버에 남아요

실시간 동기화 (주기 폴링)

발송 후 결과(성공·실패·반응)를 고객사 CRM 스키마로 계속 반영하려면 동기화를 켜세요. 진행 중인 발송 작업을 플랫폼에서 가져와 로컬 crm_send_jobs·crm_send_results에 반영합니다 — 단방향(플랫폼→로컬)이라 원본 운영 테이블은 건드리지 않아요.

실제 화면 컴포넌트 — 콘솔과 항상 동일
npx @crmforall/connect sync
단발 실행 — cron에 걸어도 됨.
실제 화면 컴포넌트 — 콘솔과 항상 동일
npx @crmforall/connect sync --watch --interval=300
주기 폴링 데몬 — 기본 300초(최소 30초). Ctrl+C로 종료.

AI로도 시킬 수 있어요(MCP 도구 sync_all): “지금 발송 결과 동기화해줘”. cron 예시(5분마다):

실제 화면 컴포넌트 — 콘솔과 항상 동일
*/5 * * * * cd /path && npx @crmforall/connect sync --json >> sync.log 2>&1
crontab -e

커넥터 MCP 도구 (전체)

도구역할승인
onboarding_status현재 단계·다음 할 일 안내불필요
test_connection · inspect_schema연결·권한 점검 / 컬럼 탐색불필요
propose_field_mapping · validate_mapping매핑 제안·확정불필요
audience_summary고객 N명·동의 분포 즉시 집계 (프로젝트 불필요)불필요
preview_targets조건 프로젝트 대상 인원 미리보기불필요
sync_send_result · sync_all발송 결과 동기화불필요
create_target_snapshot · write_crm_event · send_kakao_message스냅샷·쓰기·발송승인 토큰

에러 코드

코드의미 · 해결
E_PLATFORM_UNREACHABLE플랫폼에 연결 불가 — 방화벽 아웃바운드 443 확인
E_TOKEN_EXPIRED설치 코드 만료/형식 오류 — 콘솔에서 재발급
E_TOKEN_REUSED이미 사용된 코드 — 재설치는 토큰 없이 init (멱등)
E_AUTH_FAILEDDB 인증 실패 — 계정/비밀번호 확인
E_NET_UNREACHABLEDB 호스트 접근 불가 — host/port/방화벽
E_OVERPRIVILEGED쓰기 권한 감지 — 출력된 REVOKE SQL 실행 후 doctor 재실행

부록 — 수동(분리 담당자) 설치 경로

운영자(콘솔 접근)와 전산담당자(DB 접근)가 다른 사람일 때 쓰는 경로예요. 운영자가 설치 토큰을 발급해 담당자에게 전달하면, 담당자는 토큰으로 init만 실행합니다. 보통은 위 절차 A로 충분하니, 조직이 분리된 경우에만 보세요.

1
설치 코드 받기
운영팀이 콘솔에서 발급한 설치 코드(cfit_…)를 전달받으세요. 7일 유효, 1회용입니다 — 만료되면 운영팀에 재발급을 요청하세요. (운영자가 AI에게 “설치 토큰 발급해줘”issue_install_token로 받아 전달할 수도 있어요.)
2
토큰으로 설치 실행
실제 화면 컴포넌트 — 콘솔과 항상 동일
npx @crmforall/connect init --token=<설치토큰> --platform-url=https://crmforall-console.vercel.app
토큰을 명시해 비대화형으로도 가능. 권한 게이트는 동일하게 적용돼요.

<설치토큰> = 1단계의 cfit_…. --platform-url = 콘솔 주소(이 배포: crmforall-console.vercel.app). 과권한이 감지되면 설치가 멈추고 권한 축소 SQL을 출력합니다(그대로 DBA에게 전달). 이후 등록·매핑은 절차 B로.