OmniRoute란?(OmniRoute 사용법) - 무료 AI 티어를 모아 Claude Code·VS Code에 연결하기
- -
안녕하세요! 갓대희 입니다.
이번 포스팅은 여러 무료 AI 티어를 한데 모아 Claude Code와 VS Code에서 쓰는 OmniRoute 입니다. : )
이번글은 작성하나보니 처음 의도에 너무 많이 벗어 나기도하고, 조금 정리가 안된 느낌이 있어... 미리 말씀드리자면 정말 죄송합니다. ㅠㅠ

OmniRoute가 개발자 커뮤니티에서 눈길을 끈 이유는 단순하다.
Gemini·Groq·Mistral처럼 각기 다른 무료 티어와 이미 보유한 유료 API 키를 한 게이트웨이에 연결해 두면, Claude Code나 Cline 같은 개발 도구는 제공업체가 아니라 OmniRoute 주소 하나만 바라보면 된다.
한 모델의 무료 한도가 끝나거나 장애가 생겼을 때 다음 후보로 넘기는 대체 전환(Fallback)도 같은 곳에서 구성할 수 있다.
즉 ‘무료 모델 목록을 구경하는 프로젝트’가 아니라 흩어진 무료 한도를 실제 개발 흐름에 연결하는 로컬 AI API 게이트웨이에 가깝다.
계정 연결, 요청 형식 변환, 모델 선택, 대체 전환, 사용 한도(Quota)와 사용량(Usage), 코딩 도구 설정을 하나의 관리 화면(Dashboard)에서 다룬다. 다만 이것이 ‘가입 없이 무제한 AI’라는 뜻은 아니다. 제공업체별 가입·API 키·지역·속도·일일 한도·데이터 정책은 그대로 적용되고, 프롬프트와 코드는 선택된 상위 제공업체(Upstream Provider)로 전달된다.
CLI-INTEGRATIONS.md·CLAUDE-CODE-CONFIGURATION.md·ENVIRONMENT.md, 문서 갱신일 2026-08-18)에 대조해 고정했고, 무료 티어 수치는 9월 3일 재감사된 공식 개발 문서까지 반영했다. npm의 latest는 아직 v3.8.50이며 v3.8.51은 정식 릴리스 전이다. 실제 반응은 Reddit·GitHub Issues·X·Threads·GeekNews와 국내 소개 글을 함께 살폈다.- OmniRoute는 AI를 직접 실행하는 엔진이 아니라 여러 제공업체 앞에 두는 다중 규격 게이트웨이다. OpenAI 규격은
/v1, Anthropic 규격은 루트(root), Gemini 규격은/v1beta에 각각 열려 있다. - 핵심 활용법은 무료 티어·유료 API를 한곳에 연결하고 Claude Code·Cline·OpenCode가 게이트웨이 하나만 보게 하는 것이다.
- 처음에는 무료 제공업체 하나 + 고정 모델 + 압축(Compression) 끄기로 확인한 뒤 auto와 대체 전환을 붙이는 것이 좋다.
- 이 글에는 macOS M2 Max·v3.8.50에서 확인한 무인증 auto HTTP 200, z.ai GLM API Key 등록, Google 계열 OAuth와 Playground 응답 화면을 포함했다. 다만 OAuth 성공은 약관상 권장 경로라는 뜻이 아니다.
- 실제 API 키를 넣기 전에 STORAGE_ENCRYPTION_KEY를 준비하고 원격 설정 동기화(Remote Settings Sync)는 일단 끈다.
- 공식 추정치는 반복 무료 약 14.7억 토큰/월, 첫 달 가입 크레디트 포함 약 21억이지만 개인별 보장량이 아니다.
- 커뮤니티는 편의성을 높게 보지만 업데이트, 추론(Reasoning), 특정 제공업체와의 호환 문제도 보고했다.
| 무료 경로 | 어떻게 이해할까 | 실전 주의점 |
|---|---|---|
| 반복 무료 할당량 | 일·월 단위로 다시 생기는 문서화된 무료 풀 | 공유 풀은 모델 수만큼 중복 계산하지 않는다. |
| 가입 크레디트 | 첫 가입·첫 달에만 제공되는 일회성 금액 또는 토큰 | 다음 달 예산으로 반복 계산하면 안 된다. |
| 무료·상한 미공개 | 무료 접근은 있지만 월 토큰 상한이 공개되지 않은 경로 | ‘무제한’이 아니라 속도·동시성·정책 제한이 있는 미계량 항목이다. |
| 구독·OAuth | 이미 결제한 코딩 구독의 사용 한도를 연결하는 방식 | 무료 티어가 아니며 제3자 라우터 사용 허용 범위를 약관에서 확인한다. |

① 무료 API 키 한두 개를 OmniRoute에 등록하고
② 코딩용 조합을 만든 뒤
③ Claude Code·Cline에는 OmniRoute 키 하나만 넣는다.
이후 무료 한도가 남아 있는 동안 그 경로를 쓰고, 한도 소진·429·장애 때는 미리 정한 다음 모델로 넘긴다.
이때 자동 결제 가능성이 싫다면 과금 차단이 공식 확인된 후보만 남기는 freeAccessPolicy=strict를 검토한다. 다만 STRICT는 확인 근거가 부족한 무료 제공업체도 제외하므로 사용 가능한 모델 수가 크게 줄 수 있다.
목차
1. 무료 티어를 모으는 게이트웨이란
OmniRoute는 여러 AI 제공업체를 localhost의 API 하나로 정리하는 자체 호스팅(Self-hosted) AI 게이트웨이다.

AI 코딩 도구나 직접 만든 애플리케이션은 http://localhost:20128/v1만 호출한다. 어느 제공업체와 모델로 보낼지, 실패하면 무엇으로 넘길지는 OmniRoute가 처리한다.
| 구분 | OmniRoute가 하는 일 | 오해하기 쉬운 부분 |
|---|---|---|
| 엔드포인트(Endpoint) | 여러 제공업체를 하나의 기본 주소(Base URL)로 제공 | 새 AI 모델을 만드는 것은 아님 |
| 라우팅(Routing) | 조건에 맞는 모델·계정 선택과 대체 전환 | 항상 가장 좋은 답을 보장하지는 않음 |
| 로컬 우선(Local-first) | 설정·키·로그·게이트웨이를 내 환경에서 관리 | 프롬프트가 반드시 기기 안에만 남는다는 뜻은 아님 |
| 무료 티어(Free tier) | 여러 무료·저가 티어를 목록과 조합(Combo)으로 관리 | 무료 이용량이나 계정 안전을 보장하지 않음 |
v3.8.50 저장소 설명 기준으로 등록된 제공업체는 352개(무료 티어 150개 이상), 모델은 1,200개 이상이다.
기능 문서에는 우선순위(Priority), 가중치(Weighted), 순환 배분(Round-robin), 비용 최적화(Cost-optimized), 한도 초기화 기준(Reset-aware), 여유 한도(Headroom), 다중 모델 종합(Fusion), 단계 연결(Pipeline) 등을 포함한 19개 공개 전략이 정리돼 있다.
이 수치는 릴리스마다 빠르게 바뀌므로, 뒤에 나올 다른 숫자들과 헷갈리지 않게 어디서 읽은 숫자인지를 계속 붙여 두려 한다.
한 줄 정리: AI 앱마다 제공업체를 따로 연결하는 대신, OmniRoute 한 곳에 모으고 앱은 OmniRoute만 바라보게 만든다.
2. 요청은 내부에서 어떻게 움직일까
클라이언트(Client)가 /v1/chat/completions로 요청을 보내면 OmniRoute는 모델 또는 조합을 해석하고, 사용할 수 있는 인증 정보(Credential)를 고른 뒤 제공업체 형식에 맞게 요청을 변환한다.

상위 제공업체의 응답도 다시 클라이언트가 이해하는 형식으로 바꿔 돌려준다. 401·403처럼 인증 갱신이 필요한 상황에서는 토큰 갱신을 시도할 수 있고, 요청 결과와 사용량은 로컬 저장소에 기록된다.

입구가 하나가 아니다: /v1, 루트, /v1beta
여기서 나중에 Claude Code를 붙일 때 반드시 필요한 사실을 하나 먼저 짚어 둔다.
OmniRoute를 ‘OpenAI 호환 게이트웨이’라고만 부르면 절반만 맞다. 공식 CLI 통합 문서는 OpenAI 규격을 /v1, Anthropic 규격을 루트(root), Gemini 규격을 /v1beta에 각각 열어 둔다고 설명한다.
도구마다 Base URL에 /v1을 붙이라고 하기도 하고 붙이지 말라고 하기도 하는 이유가 바로 이것이다. 5장에서 이 표를 다시 쓴다.
auto는 고정된 model 이름이 아니다

model: "auto"를 보내면 현재 활성화된 연결, 유효한 인증 정보, 모델 후보를 확인해 요청 시점에 가상 조합(Virtual Combo)을 만든다. 저장된 고정 모델 하나를 부르는 방식과 다르다.
그래서 같은 요청이라도 남은 사용 한도, 재시도 대기 상태(Cooldown), 연결 상태에 따라 실제 상위 제공업체가 달라질 수 있다.
| 모델 값 | 의도 | 어울리는 실험 |
|---|---|---|
auto |
균형형 기본 라우팅 | 첫 연결과 일반 채팅 |
auto/coding |
코딩 품질 우선 | 도구 호출·저장소 작업 |
auto/fast |
응답 속도 우선 | 짧은 분류·자동완성 |
auto/cheap |
비용 우선 | 대량 작업 전 작은 표본 |
auto/offline |
남은 사용 한도가 많은 후보에 초점 | 한도 소진을 피할 때 |
auto/smart |
탐색을 포함한 선택 | 후보 비교 실험 |
위 표는 대표적인 6개만 정리한 것이고, 실제로 선택 가능한 auto 계열 항목은 연결한 제공업체와 버전에 따라 더 많다. 이번 실습 환경에서는 VS Code 모델 선택기에서 auto/best-coding을 포함해 17개가 보였다(5장 C절).
그리고 이름만 보고 동작을 단정하지 않는 편이 좋다. 예를 들어 auto/offline은 ‘로컬 오프라인 모델만 쓴다’는 뜻으로 읽히기 쉬운데, 실제 기준은 남은 한도 쪽에 가깝다. 각 프로필의 정확한 규칙은 공식 자동 라우팅 모드 설정 소스에서 확인하는 것이 가장 정확하다.
3. 설치 전에 먼저 정할 보안 경계
하기 내용은 이해 되지 않으면 빠르게 쭉 ~ 넘어가고 실제 실습하는 부분을 집중적으로 보고 이해하는것도 괜찮을 것 같다.

게이트웨이에는 제공업체의 접근 토큰(Access Token)과 API 키가 모인다. 기능을 둘러보기 전에 저장소와 네트워크 경계부터 정해야 하는 이유다.
2026년 9월 3일 OmniRoute에 ACP Custom-Agent 원격 코드 실행 취약점 GHSA-hf57-cqmx-p4gr(CVE-2026-88062, 심각도 Critical)이 공개됐다. 영향 버전은 3.8.49 미만, 수정 버전은 3.8.49다.
공식 권고문에 따르면 requireLogin=false이거나 아직 관리 비밀번호를 설정하지 않은 초기 상태에서, 조작된 ACP Agent 설정으로 인증 없이 명령 실행이 가능했다.
반대로 기본값인 requireLogin=true이고 비밀번호가 설정된 상태라면 관리 세션이나 관리 권한 API 키가 필요하다. 즉 ‘무인증 RCE’가 아니라 ‘인증된 RCE’가 된다. 그래도 위험이 사라지는 것은 아니다.
기존 설치를 그대로 쓰는 분들은 omniroute --version부터 확인해야 한다.
이름이 비슷해서 뒤에서 꼭 한 번 헷갈린다. 역할이 완전히 다르다.
requireLogin은 관리 화면(Dashboard) 로그인을 요구할지 결정한다. 위 취약점의 전제 조건이 바로 이 값을 꺼 둔 상태다.
REQUIRE_API_KEY는 /v1/* 프록시 요청에 API 키를 요구할지 결정하는 환경변수이며, 공식 문서 기준 기본값은 false다.
1) 첫번째로는 기본 비밀번호부터 바꾸자
환경설정 문서에서 초기 관리자 비밀번호 INITIAL_PASSWORD의 기본값은 말 그대로 CHANGEME다. 문서에도 “일부러 안전하지 않게 둬서 변경을 강제한다”고 적혀 있고, 첫 사용 전에 바꾸라고 명시한다.
참고로 공식 문서가 ‘반드시 설정’으로 분류한 필수 비밀값은 JWT_SECRET, API_KEY_SECRET, INITIAL_PASSWORD, 그리고 운영 환경의 OMNIROUTE_WS_BRIDGE_SECRET까지 네 개다.
하기 실습에서는 이미 미리 비밀번호를 변경해 놓고 시작 할 예정이다.
2) 저장소 암호화 키를 잃어버리면 기존 인증 정보도 읽지 못한다
공식 환경변수 문서에 따르면 STORAGE_ENCRYPTION_KEY는 SQLite 데이터베이스를 통째로 암호화하는 키이고, 비워 두면 암호화가 비활성화된다.
같은 문서의 배포 시나리오 표에는 “키를 백업해 둬라. 잃어버리면 데이터를 잃는다”고 아주 직설적으로 적혀 있다.
기존 DB와 다른 키로 바꾸면 저장된 인증 정보를 복호화하지 못할 수도 있다. 깨끗한 첫 설치에서 생성하고, 비밀번호 관리자처럼 애플리케이션과 분리된 안전한 위치에 백업해 둔다.
3) 로컬 우선과 로컬 전용(Local-only)은 다르다
관리 화면과 SQLite가 내 컴퓨터에 있어도 실제 추론(Inference)은 상위 제공업체에서 일어난다.
회사 소스 코드, 고객 정보, 운영 로그를 무료 제공업체로 그대로 보내면 안 된다.
제공업체의 데이터 정책과 요금제를 확인하고, 첫 실습은 공개해도 문제없는 짧은 프롬프트로 진행한다.
4) 원격 설정 동기화(Remote Settings Sync)는 필요할 때만 켠다
클라우드 동기화(Cloud Sync)는 기본적으로 꺼져 있고 사용자가 직접 켜야 한다.
다만 동기화 묶음은 제공업체 접근 토큰, 갱신 토큰, API Key와 엔드포인트 키 같은 인증 정보 항목을 다룬다.
클라우드에서 내려온 인증 정보로 로컬 값을 덮어쓰는 기능은 별도 환경변수(OMNIROUTE_CLOUD_SYNC_SECRETS, 기본 false)로 켜야 하지만, HMAC 서명 검증도 비밀값 설정 여부에 따라 달라진다.
개인 PC 한 대에서 시작한다면 원격 설정 동기화는 끄고 로컬 백업부터 익히는 쪽이 단순하다.
5) 포트 20128을 인터넷에 그대로 열지 않는다
공식 문서 기준으로 PORT의 기본값은 20128이고 관리 화면과 API가 같은 포트를 쓴다. 그리고 OMNIROUTE_SERVER_HOST의 기본 바인드 주소는 0.0.0.0이다.
기본값 그대로 두면 같은 네트워크의 다른 기기에서도 접근할 수 있다는 뜻이다.
9월 11일 개발 브랜치에서는 기본 게시 주소를 127.0.0.1로 변경하고, Dashboard 세션 JWT·Telegram Webhook·SSRF·CORS·VNC/CDP 인증 경계를 함께 강화했다.
그러나 아직 v3.8.51 정식판이 아니므로 v3.8.50 사용자는 직접 방어해야 한다.
ports:
- "127.0.0.1:20128:20128"
- "127.0.0.1:20129:20129"
- "127.0.0.1:20132:20132"
게시 포트 구성은 버전에 따라 달라질 수 있으므로, 위 예시를 그대로 쓰기보다 내가 받은 docker-compose.yml의 ports 항목을 열어 보고 거기에 맞춰 앞에 127.0.0.1:만 붙이는 편이 안전하다.
원격 접속이 꼭 필요하면 API Key 인증과 신뢰할 수 있는 리버스 프록시·방화벽을 먼저 구성한다. X-Forwarded-For: 127.0.0.1처럼 외부 요청을 로컬 요청으로 속여서는 안 된다. 이번 초급 실습에서는 서버 바인딩 변수 OMNIROUTE_SERVER_HOST=127.0.0.1로 묶고 터널·포트 포워딩은 사용하지 않는다. Docker라면 위처럼 게시 주소까지 127.0.0.1로 제한한다.
OmniRoute에 계정 풀링(Account Pooling)이나 지문(Fingerprint) 관련 기능이 있어도 제공업체의 이용 제한을 우회해도 된다는 뜻은 아니다.
이 글에서는 한 계정·한 제공업체로 기능을 확인한다. 자동 회전이나 무료 티어 풀링은 각 제공업체 약관을 확인한 뒤 별도로 판단해야 한다.
| Provider | 기본 권장 경로 | 피하거나 확인할 경로 |
|---|---|---|
| OpenAI | 공식 OpenAI API Key | ChatGPT Web Session·Cookie 자동화는 개인용 약관의 자동 추출·자격증명 공유·제한 우회 조항과 충돌할 위험이 있다. |
| Anthropic | 공식 Anthropic API Key | Claude 구독 OAuth의 제3자 라우터 재사용은 API 또는 명시적 허용 경로보다 약관 해석이 불확실하다. |
| 공식 Gemini API Key | 무료 Gemini API 입력·응답은 제품 개선과 사람의 검토에 사용될 수 있으므로 민감 코드·개인정보를 보내지 않는다. |
| 항목 | 첫 실습 권장값 | 이유 |
|---|---|---|
| 관리자 비밀번호 | CHANGEME를 강한 값으로 교체 | 기본 비밀번호 사용 방지 |
| 바인드 주소(Bind address) | 127.0.0.1 | 기본값이 0.0.0.0이라 그대로 두면 외부 노출 |
| 저장소 암호화 | 키 생성 후 별도 백업 | 인증 정보 평문 저장·키 유실 방지 |
| 원격 설정 동기화 | 끄기(OFF) | 첫 실습의 데이터 경계 단순화 |
| 제공업체 | 하나만 연결 | 실패 원인 분리 |
| 프롬프트 | 공개 가능한 짧은 문장 | 민감 정보 유출 방지 |
4. 실제로 따라 해보기: 무료 모델부터 API Gateway까지
다음 장표들을 간단히만 눈으로 익히고 넘어가자. 실습을 다 끝낸 뒤에는 이해가 될 것 이다.



아래 화면은 macOS M2 Max와 OmniRoute v3.8.50에서 직접 설치하고 호출하며 캡처한 결과다.
비밀번호와 API Key 같은 비밀값은 가렸다.
무료 제공업체의 가용성과 모델 목록은 지역·시점·계정에 따라 달라질 수 있으므로, 화면과 같은 결과가 영구적으로 보장된다는 뜻은 아니다.
실습 순서
- 관리자 비밀번호·암호화 키·환경 파일 준비
- 안정판 설치·로그인
- localhost에서 키 없는 무료 요청을 한 번만 확인
- GLM 같은 공식 API Key와 필요한 Provider 연결
- OmniRoute 엔드포인트 키를 만들고 API 보호 활성화
- 모델 목록을 읽기 전용으로 확인
- 고정 모델 → auto 순서로 호출, 그 뒤 키 권한 좁히기
- TypeScript 애플리케이션에 연결
- 압축 기능은 마지막에 비교
Claude Code·VS Code 같은 개발 도구 연결은 분량이 커서 5장에서 따로 다룬다.
1단계. 관리자 비밀번호와 환경 파일 준비
CLI는 ~/.omniroute/.env 또는 현재 디렉터리의 .env를 읽는다. 먼저 기존 데이터베이스가 있는지 확인한다.
공식 환경변수 문서 기준으로 데이터 디렉터리 DATA_DIR의 기본값은 ~/.omniroute/이고, DB 파일은 ~/.omniroute/omniroute.db에 생긴다.
ls -al "${DATA_DIR:-$HOME/.omniroute}"/*.db 2>/dev/null \
&& echo "기존 DB 발견: 새 키를 만들지 말고 기존 .env를 먼저 복구하세요." \
|| echo "새 설치 상태"
ex) 이 실습 장비에는 기존 DB가 없어 새 설치 상태로 진행했다.

기존 DB와 다른 STORAGE_ENCRYPTION_KEY를 만들면 저장된 인증 정보를 읽지 못할 수 있다. 아래 생성 명령은 깨끗한 첫 설치에서만 실행한다.
umask 077
mkdir -p "$HOME/.omniroute"
chmod 700 "$HOME/.omniroute"
omniroute_env_file="$HOME/.omniroute/.env"
omniroute_admin_password="$(openssl rand -base64 24)"
printf '%s\n' \
'OMNIROUTE_SERVER_HOST=127.0.0.1' \
"INITIAL_PASSWORD=$omniroute_admin_password" \
"JWT_SECRET=$(openssl rand -base64 48)" \
"API_KEY_SECRET=$(openssl rand -hex 32)" \
"OMNIROUTE_WS_BRIDGE_SECRET=$(openssl rand -base64 32)" \
"STORAGE_ENCRYPTION_KEY=$(openssl rand -hex 32)" \
'REQUIRE_API_KEY=false' \
> "$omniroute_env_file"
chmod 600 "$omniroute_env_file"
printf '관리자 비밀번호: %s\n' "$omniroute_admin_password"
sed -E 's/=.*/=<REDACTED>/' "$omniroute_env_file"
원래 쓰던 순서에서 umask 077을 mkdir보다 앞으로 옮겼다. 반대로 두면 디렉터리 권한에는 umask가 적용되지 않는다.
OMNIROUTE_WS_BRIDGE_SECRET은 내부 Codex 응답 WebSocket 브리지용 비밀값인데, 공식 문서가 운영 환경 필수로 분류하고 미설정 시 브리지 요청을 전부 거부한다고 적어 두었다. 미리 만들어 두는 편이 낫다.
ex) 아래 캡처처럼 변수 이름만 확인하고 값은 모두 가렸다.

화면에 한 번 표시된 관리자 비밀번호와 환경 파일의 비밀값은 비밀번호 관리자에 보관한다.
캡처하기 전에는 터미널을 지우고, .env를 Git에 올리지 않는다. 로컬 실습에서는 OMNIROUTE_SERVER_HOST=127.0.0.1을 유지한다.
운영체제가 자동으로 정하는 HOSTNAME은 Playwright 테스트용 변수이므로 서버 바인딩에 사용하지 않는다. 공식 문서에도 omniroute serve에는 쓰지 말라고 못 박혀 있다.
그리고 첫 로그인 뒤 관리 화면(Settings → Security)에서 비밀번호를 바꾸고 나면, .env에 남은 INITIAL_PASSWORD 줄은 지워 두는 편이 깔끔하다.
REQUIRE_API_KEY=false는 필요하면 잠깐만 사용한다
다음 단계의 무인증 무료 요청을 확인하기 위한 임시 값이다. 앞서 3장에서 정리했듯 관리 화면 로그인을 끄는 requireLogin과는 다른 값이다. 반드시 127.0.0.1에만 바인딩된 개인 PC에서 사용하고, 외부·사내 LAN·공유 서버에는 적용하지 않는다. Provider 연결과 엔드포인트 키 생성이 끝나면 즉시 true로 바꾼다.
2단계. 안정판 설치하고 실행
공식 문서의 설치 명령은 버전을 고정하지 않지만, 이 글에서는 나중에 따라 하실 분들의 재현성을 위해 v3.8.50으로 고정해 적는다.
글을 쓰는 시점의 latest도 v3.8.50이라 결과는 같다. (나의 경우는 버전을 명시하지 않고 latest로 설치 하긴 하였다.)
node -v
npm install -g omniroute@3.8.50
omniroute --version
omniroute doctor
omniroute
node -v를 먼저 넣은 이유가 있다. 이 프로젝트는 네이티브 모듈(better-sqlite3)을 쓰기 때문에 지원 범위를 벗어난 Node에서는 설치 직후가 아니라 실행할 때 깨진다. 6장에서 볼 GitHub 이슈들도 대부분 이 계열이다.
실행 뒤 브라우저에서 http://localhost:20128을 열고, 앞에서 저장한 관리자 비밀번호로 로그인한다.
API 기본 주소는 http://localhost:20128/v1이다.
ex) 실행 뒤 로그인 페이지로 이동했고, 저장해 둔 관리자 비밀번호로 로그인하면 Dashboard가 열렸다.



3단계. 키 없이 첫 무료 요청 보내기
별도 Provider Key 없이 auto를 호출했을 때 OpenCode Free·Felo 계열 경로가 선택되며 HTTP 200 응답을 확인할 수 있었다.
아직 아무 Provider도 연결하지 않았는데 응답이 오는 이유가 있다. 공식 VS Code 연동 문서 설명에 따르면 모델 목록에는 연결이 활성화된 제공업체 + 키가 필요 없는(noAuth) 제공업체 전부가 들어간다. 무료 티어의 상당수가 이 키 없는 쪽이다.
원래는 고정 모델부터 부르는 게 순서지만, 이 시점에는 내가 등록한 모델이 하나도 없다. 그래서 여기서만 예외적으로 auto로 시작한다.
다음 요청은 REQUIRE_API_KEY=false인 localhost 첫 점검에서 한 번만 사용해보려 한다.
curl -sS -i http://localhost:20128/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "auto",
"messages": [
{"role": "user", "content": "HTTP 429를 초보자에게 한 문장으로 설명해줘."}
],
"temperature": 0
}'
ex) HTTP 200과 텍스트 응답을 확인했다.


응답만 보고 끝내지 말고 요청 기록(Request Logs)에서 실제 선택 모델, 상태 코드, 재시도 여부와 응답 시간을 확인한다.
목록·상세·모바일 화면에서도 같은 기록을 볼 수 있었다.



4단계. GLM·Gemini 등 Provider를 한 곳씩 연결
제공업체(Providers) → 제공업체 추가(Add Provider)로 이동한다. 화면에는 API Key, OAuth, IDE 구독, Web Cookie, Local Provider 등 다양한 방식이 보이지만, 처음에는 공식 API Key 하나만 추가하는 것이 실패 원인을 찾기 쉽다.
참고로 여기서부터는 실제 키가 저장되기 시작한다. 마음이 불편하면 REQUIRE_API_KEY를 먼저 true로 돌려놓고 진행해도 된다. 이 글에서는 흐름 설명을 위해 5단계에서 전환한다.


A. z.ai GLM API Key: 직접 등록해 본 경로
실습에서는 잔액이 남아 있는 z.ai의 GLM API Key를 등록했다.
키를 입력하고 모델을 별도로 고정하지 않자 사용 가능한 모델을 자동으로 가져왔고, 연결 상태와 모델 목록이 Provider 화면에 표시됐다.



B. Gemini 무료 API Key: 권장 경로지만 이번 실습에서는 등록하지 않았다
먼저 분명히 해두면, 이번 실습에서 실제로 연결한 Google 계열은 바로 아래 작성하는 C절의 OAuth 쪽이고 Gemini API Key는 등록하지 않았다. 그래서 뒤의 단계들도 z.ai GLM과 Antigravity(agy/) 기준으로 진행한다.
그럼에도 이 경로를 먼저 적어 두는 이유는, 장기 사용이라면 이쪽이 권장 경로이기 때문이다.
Gemini를 무료 구간에서 쓰려면 Google AI Studio에서 본인 프로젝트의 API Key를 발급받아 Google·Gemini 계열의 API Key Provider로 등록한다. 연결 뒤에는 모델 목록에서 Gemini 모델 하나를 골라 고정 ID로 먼저 호출한다.
무료 할당량, 지원 지역과 데이터 처리 조건은 계정·모델별로 다르며 바뀔 수 있으므로 Google의 최신 Rate Limit 문서를 확인한다.
GLM·Gemini API Key는 OmniRoute가 상위 모델 서비스에 접속할 때 쓴다. 다음 단계에서 만드는 OmniRoute 엔드포인트 키는 Claude Code·VS Code 같은 내 도구가 로컬 Gateway에 접속할 때 쓴다. 개발 도구에는 GLM·Gemini의 원본 키가 아니라 OmniRoute 키 하나만 넣는다.
C. Google 계열 OAuth: 동작 확인과 권장 여부는 별개
첨부한 Google 계열 화면은 Gemini API Key 등록이 아니라 Antigravity CLI OAuth 연결이다. 인증 후 연결 상태와 사용 가능 모델이 나타났고, Playground에서도 실제 응답을 확인했다.






나의 경우 과거 Gemini CLI를 OpenCode에 연결해 사용하다 계정이 영구 차단된 경험이 있다.
이번에는 기능 확인 차원에서 연결했지만, 동작했다는 사실이 제3자 Router 사용을 Google이 승인했다는 뜻은 아니다.
장기 사용과 중요한 계정에는 공식 Gemini API Key 방식을 우선하고, OAuth는 최신 약관과 허용 범위를 직접 확인한 뒤 판단한다.
D. 이번 실습에서 사용하지 않은 연결
Cursor 구독이 없어 IDE Provider는 건너뛰었다.
Web Cookie Provider는 Hugging Face Chat 연결을 시험했지만 실패했고, 웹 세션·쿠키 재사용의 안정성·약관 위험도 있어 더 진행하지 않았다.
Ollama·LM Studio 같은 Local Provider도 이번 실습 범위에서는 제외했다.



홈 화면으로 돌아오면 이번에 연결한 두 Provider(z.ai GLM API Key, Antigravity OAuth)의 토폴로지가 한눈에 보인다. 이것이 “여러 원본 키를 Gateway 한 곳으로 모은다”는 의미다.


- 회사 계정이나 운영용 키로 첫 실습을 하지 않는다.
- Provider별 이용약관·무료 한도·데이터 정책을 확인한다.
- 연결 직후에는
auto보다 해당 Provider의 고정 모델 ID를 먼저 호출한다. - 이메일, 토큰, 조직·계정 ID는 캡처에서 가린다.
5단계. 엔드포인트 API Key를 만들고 API 보호하기
관리 화면의 API 키(API Keys) → API 키 생성에서 튜토리얼 전용 키를 만든다.
이 키는 GLM·Gemini의 원본 API Key가 아니라,
Claude Code·VS Code 같은 개발 도구가 OmniRoute에 접속할 때 사용하는 Gateway용 키다.
- 모델 권한: 현재 제한(Restrict) + 선택 모델 0개다. 그대로 저장하면 목록에 뜬 모델을 하나도 호출할 수 없다. 첫 실습에서는 모두 허용으로 되돌린다.
- Prompt Compression: 현재 활성화 상태다. 첫 연결 검증에서는 변수를 줄이기 위해 비활성화하고, 정상 응답을 확인한 뒤 별도로 비교한다.
그 밖의 항목은 아래 권장값처럼 대부분 기본 상태를 유지하면 된다.
키 이름은 for_tutorial도 사용할 수 있다.
다만 claude-code-local, cline-local처럼 사용 도구와 환경이 드러나는 이름을 쓰면 나중에 사용 중지하거나 삭제할 키를 찾기 쉽다. (난 바로 삭제할 예정이어서 for_tutorial이라고 명시했다.)
전체 비밀값은 생성 직후 한 번만 표시될 수 있으므로 즉시 복사해 비밀번호 관리자에 저장하고, 캡처나 블로그에는 넣지 않는다.
실제로 확인한 API Key 생성 화면



초보자용 권장 설정: 먼저 성공시키고, 그다음 줄인다
권한 편집(Edit Permissions) 팝업은 항목이 많지만, 첫 실습에서 전부 설정할 필요는 없다.
다음 표의 첫 연결 권장값만 맞추면 된다.
ex) 생성 된 key 우측 하단에 보면 권한 편집 버튼이 있다. 여기서 모델 권한만 ‘모두 허용’으로 바꾸고 저장했다. 나머지 항목은 기본 상태로 둬도 무방한데, 어떤 스위치들인지 간단히만 설명하고 넘어 가려 한다.

| 화면 영역 | 첫 연결 권장값 | 왜 이렇게 두나 |
|---|---|---|
| Reasoning routing | 규칙을 만들지 않음 | 모델명과 Reasoning Effort를 자동 변경하는 고급 기능이다. 첫 연결에는 필요하지 않다. |
| 모델 접근 | 모두 허용 | 캡처의 제한 0개 상태는 모든 요청을 차단한다. 먼저 고정 모델 호출을 성공시킨다. |
| Key Active | 활성화 | 꺼진 키는 즉시 403으로 거부된다. |
| 최대 활성 세션 | 0 | 0은 무제한이다. 개인 로컬 테스트에서는 그대로 둔다. |
| 스로틀 지연 | 0ms | 일부러 응답을 늦출 이유가 없다. |
| 사용자 정의 속도 제한 | 추가하지 않음 | 먼저 Provider 자체 한도로 동작을 확인한다. 공유 환경에서만 별도 제한을 검토한다. |
| Access Schedule | 비활성화 | 요일·시간대별 사용 제한이 필요할 때만 켠다. |
| 로그 없는 페이로드 개인정보 보호 | 첫 디버깅은 비활성화 | 처음에는 Request Logs로 오류를 확인한다. 정상 연결 뒤 민감한 코드를 다룰 때 활성화한다. |
| Auto-Resolve | 비활성화 | 모호한 모델명을 자동 해석하지 않고 정확한 Provider/Model ID를 사용한다. |
| 스트림 기본 호환성 | 레거시 | Claude Code·Cline 같은 기존 클라이언트 호환성을 먼저 확인한다. |
| Prompt Compression | 비활성화 | 첫 응답의 기준선(Baseline)을 만든 뒤 같은 요청으로 켜기·끄기를 비교한다. |
| 금지 상태 | Active 그대로 | 이 표시는 현재 키가 차단되지 않았다는 뜻이다. 키가 유출됐을 때만 접근을 즉시 취소한다. |
| 만료 날짜 | 선택 사항 | 일회성 실습 키라면 7일 또는 30일 뒤로 지정해도 된다. |
이제 API 보호를 켠다
export OMNIROUTE_BASE_URL="http://localhost:20128/v1"
read -rs -p "OmniRoute API Key: " OMNIROUTE_API_KEY && export OMNIROUTE_API_KEY && echo
키를 export OMNIROUTE_API_KEY="값"으로 바로 적으면 셸 히스토리 파일에 그대로 남는다. 위처럼 read -rs로 받으면 화면에도 히스토리에도 남지 않는다.
이 환경변수는 현재 셸 세션에서만 사용한다. 실제 키가 들어간 명령은 캡처하지 않는다.
이제 ~/.omniroute/.env의 임시 설정을 REQUIRE_API_KEY=true로 바꾸고 OmniRoute를 다시 시작한다.
이후 모든 /v1 요청에는 위에서 만든 OmniRoute 엔드포인트 키를 사용한다.
ex) vi ~/.omniroute/.env
- 난 직접 REQUIRE_API_KEY=true로 직접 변경하였는데 하기 스크립트를 통해 한번에 변경해도 된다.

sed -i.bak 's/^REQUIRE_API_KEY=false$/REQUIRE_API_KEY=true/' "$HOME/.omniroute/.env"
rm -f "$HOME/.omniroute/.env.bak" # 백업본에도 비밀값이 그대로 들어 있다
# 실행 중인 OmniRoute를 종료한 뒤 다시 실행
omniroute
sed -i.bak은 .env.bak을 만드는데, 그 안에도 JWT·암호화 키가 평문으로 들어간다. 원본 백업이 필요하면 지우지 말고 .env와 같은 600 권한으로 따로 옮겨 둔다.
재시작 뒤 키 없이 같은 요청을 보내 401이 나오는지 본다. 3단계에서 200이 나왔던 요청이 이제 거부되어야 정상이다.
curl -sS -o /dev/null -w '%{http_code}\n' \
http://localhost:20128/v1/models
6단계. 모델 목록을 읽기 전용으로 확인
curl -sS -i "$OMNIROUTE_BASE_URL/models" \
-H "Authorization: Bearer $OMNIROUTE_API_KEY"
HTTP 200과 모델 목록이 보이면 클라이언트에서 게이트웨이까지의 가장 단순한 연결은 확인된 셈이다.
ex) 지금 설정에서는 너무 많은 모델이 노출되어 전체를 캡처하지는 않았다. 대신 아래처럼 잘라서 형태만 확인하면 캡처하기도 편하다.
# 전체 개수와 앞의 다섯 개 ID만 확인
curl -sS "$OMNIROUTE_BASE_URL/models" \
-H "Authorization: Bearer $OMNIROUTE_API_KEY" \
| jq '{count: (.data | length), sample: [.data[:5][].id]}'
# 내가 연결한 Provider의 모델만 골라 보기
curl -sS "$OMNIROUTE_BASE_URL/models" \
-H "Authorization: Bearer $OMNIROUTE_API_KEY" \
| jq -r '.data[].id' | grep -E '^(glm|zai|agy)/'
ex)

7단계. 고정 모델을 확인한 뒤 auto 호출
먼저 /v1/models에 표시된 정확한 모델 ID로 같은 요청을 한 번 보낸다.
고정 모델이 성공해야 Provider Key와 모델 연결이 정상이라는 뜻이다.
curl -sS -i "$OMNIROUTE_BASE_URL/chat/completions" \
-H "Authorization: Bearer $OMNIROUTE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "<6단계에서 확인한 glm/... 또는 agy/... ID>",
"messages": [
{"role": "user", "content": "HTTP 429와 503의 차이를 한국어 두 문장으로 설명해줘."}
],
"temperature": 0
}'
ex) 고정 모델 호출의 HTTP 200과 Request Logs 화면
그 다음에만 아래처럼 auto를 호출한다.
curl -sS -i "$OMNIROUTE_BASE_URL/chat/completions" \
-H "Authorization: Bearer $OMNIROUTE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "auto",
"messages": [
{"role": "user", "content": "HTTP 429와 503의 차이를 한국어 두 문장으로 설명해줘."}
],
"temperature": 0
}'
응답 본문만 보지 말고 요청 로그(Request Logs)에서 실제 제공업체, 모델, 상태 코드, 응답 시간을 함께 본다. 응답에 X-OmniRoute-Decision 같은 라우팅 정보가 있다면 같이 기록한다.
ex) GUI 로그로 편하게 살펴보자.
- 내가 등록한 for_tutorial 이라는 OmniRoute API Key를 사용한 것을 볼 수 있다.
- 모델은 opencode/big-pickle이라는 모델을 사용한 것을 볼 수 있다.

응답은 200이지만, 선택된 모델은 내가 등록한 z.ai GLM도 Antigravity도 아니었다. 3단계에서 봤던 키 없는 무료 경로로 나갔다.
즉 이 요청 하나로는 게이트웨이가 동작한다는 것만 확인되고, 내가 등록한 Provider 키가 쓸 만한지는 확인되지 않는다. 그래서 앞의 고정 모델 호출이 필요하다.
동시에 이 화면은 2장에서 말한 “auto는 요청 시점에 후보를 고른다”의 실물 증거이기도 하다. 같은 요청이라도 무엇이 선택될지 내가 통제하지 못한다는 점이 로그에 그대로 남았다.
- 좀더 살펴보자면 기존 로그는 요청 > 응답의 단순한 구조였을 것이다.
하지만 이번 실습을 잘 살펴보면 클라이언트 > 제공자(Provider) > 실제 모델로 한 단계가 더 들어간다.

- 제공자가 그 요청을 다시 특정 모델로 넘기고 응답을 돌려주기 때문에, 기존보다 한 단계가 더 추가된 것을 볼 수 있다.

여기까지 성공했으면, 이제 키 권한을 좁힌다

5단계에서 넓게 열어 둔 권한을 이제 줄인다. 순서를 반대로 하면 ‘설치가 잘못된 건지, 권한이 막은 건지’ 구분이 안 된다.
- 모델 권한을 제한으로 바꾸고, 방금 실제로 성공한 모델만 선택한다.
- 허용된 연결은 사용 중인 z.ai·Antigravity 연결만 남긴다.
- Allowed Endpoints는 텍스트 코딩 용도라면 Chat / Messages와 모델 목록용 Models만 허용한다. Messages는 5장의 Claude Code 연결에 반드시 필요하다.
auto나 사용자 조합(Combo)을 쓸 계획이면 Dashboard에 표시된 정확한 조합 ID도 허용한다.- 좁힌 뒤 같은 고정 모델 호출을 다시 한 번 보내 여전히 200인지 확인한다.
캡처처럼 제한을 선택하고 모델을 하나도 고르지 않으면 설치나 Provider 연결이 정상이어도 요청이 차단된다.
먼저 넓은 범위에서 연결을 한 번 확인하고, 성공한 모델·연결·Endpoint만 남기는 편이 초보자에게 원인을 찾기 쉽다.
단, 이 과정은 127.0.0.1에만 바인딩된 개인 PC에서 진행한다.
8단계. TypeScript 애플리케이션에 연결
OpenAI SDK를 쓰는 애플리케이션은 baseURL과 apiKey만 바꿔 연결할 수 있다.
import OpenAI from "openai";
const client = new OpenAI({
baseURL: process.env.OMNIROUTE_BASE_URL, // http://localhost:20128/v1
apiKey: process.env.OMNIROUTE_API_KEY,
});
const response = await client.chat.completions.create({
// 7단계에서 성공을 확인한 고정 ID를 그대로 쓴다.
// auto/coding 같은 조합으로 바꾸려면 API Key 권한에서 그 ID를 먼저 허용해야 한다.
model: "<glm/... 또는 agy/... ID>",
temperature: 0,
messages: [
{
role: "user",
content: "TypeScript에서 unknown과 any의 차이를 예시와 함께 설명해줘.",
},
],
});
console.log(response.choices[0]?.message?.content);
9단계. 압축 기능은 마지막에 A/B 비교
공식 문서는 RTK와 Caveman을 겹쳐 적용한 압축에서 압축 가능한 문맥 기준으로 높은 절감률을 제시하고 있다.
첫 연결을 확인할 때는 압축을 끄고, 이후 같은 긴 입력으로 끄기와 켜기를 나눠 비교한다.
( 나는 이 부분은 일단 빠르게 넘어 가도록 하겠다ㅠ 갈길이 멀다. 빨리 코딩 에이전트에 붙여 봐야지 않겠나... )
그래서 이 글에서 압축 비교는 다루지 않는다. 아래는 나중에 내가 직접 해볼 때 쓰려고 정리해 둔 체크리스트이고, 수치 비교는 별도 글로 따로 다루려 한다.
- 같은 모델과 temperature 값을 사용한다.
- 원본 입력과 출력을 저장한다.
- 답의 정확도와 누락 여부를 사람이 읽어 본다.
- 도구 호출 인자, 코드 블록, URL, JSON이 유지됐는지 확인한다.
- 토큰, 응답 시간, 오류를 함께 기록한다.
5. Claude Code·VS Code 연결
A. Claude Code를 OmniRoute에 연결

Cline과 Cursor는 OpenAI 형식(/v1/chat/completions)으로 통한다.
반면 Claude Code는 Anthropic Messages 형식으로 말하고, Base URL 뒤에 /v1/messages를 스스로 붙인다.
공식 문서에도 Claude Code에는 --base-url 같은 옵션이 아예 없고 환경변수로만 방향을 바꾼다고 적혀 있다.
그리고 2장에서 정리했듯 OmniRoute는 OpenAI 규격을 /v1, Anthropic 규격을 루트(root)에 열어 둔다.
이 두 사실이 합쳐져서 아래 두 가지가 결정된다.
ANTHROPIC_BASE_URL에는/v1을 붙이지 않는다. 붙이면 실제 요청이/v1/v1/messages가 된다.- 7단계에서 API Key의 Allowed Endpoints에 Messages를 포함시켜야 한다. 빼면 Cline은 되는데 Claude Code만 막히는, 원인 찾기 아주 귀찮은 상태가 된다.
연결 전에 기존 설정부터 확인하고 백업한다
claude --version
env | grep -i ANTHROPIC # 기존에 export 해 둔 값이 있는지 확인
cp ~/.claude/settings.json ~/.claude/settings.json.bak # 파일이 있다면 백업
공식 문서 기준으로 ANTHROPIC_AUTH_TOKEN은 Authorization: Bearer로, ANTHROPIC_API_KEY는 x-api-key로 전달되며 둘 다 설정되면 ANTHROPIC_AUTH_TOKEN이 우선권을 가져간다.
그래도 셸에 예전 값이 남아 있으면 나중에 원인 찾기가 번거로우니 먼저 확인해 두는 편이 낫다.
방법 1. 설정 파일을 건드리지 않고 한 번 띄워 보기
가장 안전한 첫 시도다. 아무 파일도 쓰지 않고 환경변수만 주입해서 claude를 실행한다.
# 앞 5단계에서 export 해 둔 OMNIROUTE_API_KEY를 그대로 사용한다.
omniroute launch
# 3.8.50에는 도구 공통 런처도 있다. 모델을 바로 지정할 수 있어 편하다.
omniroute run claude --model "<glm/... 또는 agy/... ID>"
omniroute launch는 활성 컨텍스트에서 Base URL과 토큰을 꺼내 넣고, 서버 상태를 확인한 뒤 claude를 실행한다. --api-key를 따로 주지 않으면 OMNIROUTE_API_KEY 환경변수를 기본값으로 쓴다.
ex) omniroute run claude --model "auto/best-coding"

- 요청을 보내보고 응답을 받았고, 실제 로그로 확인해도 정상동작한것을 볼 수 있다.

- 어떤 모델을 사용 했는지 확인해보니 opus4.6이었따. 해외에서는 아직도 opus4.6에 대한 애정이 끊이지 않고 있는데, 간만에 opus4.6을 보니 반가웠다.


방법 2. 모델별 프로필 만들기
# 무엇이 만들어질지 먼저 본다 (파일을 쓰지 않는다)
omniroute setup-claude --dry-run
# 실제로 연결한 Provider만 걸러서 생성
omniroute setup-claude --only glm
# 출력된 프로필 이름으로 실행
omniroute launch --profile <생성된_프로필_이름>
Claude Code에는 Codex 같은 프로필 파일 규격이 없어서, setup-claude는 ~/.claude/profiles/<이름>/settings.json에 모델별 설정을 만들고 CLAUDE_CONFIG_DIR로 분리해 쓰는 방식을 택했다.
그래서 내 기본 ~/.claude/settings.json은 건드리지 않는다. 주력 환경을 망칠 걱정 없이 시험해 보기에는 이쪽이 제일 낫다.
--only는 모델 ID에 들어간 문자열로 거르는 옵션이라(공식 예시는 --only glm,kimi), 6단계에서 확인한 실제 ID의 앞부분을 넣어야 한다. 아무것도 안 만들어졌다면 대개 여기가 틀린 것이다.
한 가지 더. 토큰은 프로필 파일에 쓰이지 않는다.
omniroute launch --profile로 실행하면 그때 주입되고, 직접 실행하려면 ANTHROPIC_AUTH_TOKEN을 export 한 뒤 CLAUDE_CONFIG_DIR=~/.claude/profiles/<이름> claude로 띄운다.
방법 3. settings.json에 직접 넣기
{
"env": {
"ANTHROPIC_BASE_URL": "http://localhost:20128",
"ANTHROPIC_AUTH_TOKEN": "발급받은_엔드포인트_키",
"ANTHROPIC_MODEL": "<provider/model>",
"CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY": "1"
}
}
관리 화면의 Dashboard → CLI Code에 있는 Claude 카드가 내 인스턴스 기준으로 이 조각을 그대로 만들어 주고 복사 버튼도 제공한다. 키는 자리표시자로 나오니 캡처해도 유출되지 않는다.
| 환경변수 | 역할 | 자주 틀리는 부분 |
|---|---|---|
ANTHROPIC_BASE_URL |
게이트웨이 루트 주소 | /v1을 붙이지 않는다. 끝에 슬래시도 넣지 않는다. |
ANTHROPIC_AUTH_TOKEN |
OmniRoute 엔드포인트 키(Bearer) | z.ai·Gemini 원본 키도, Anthropic API Key도 아니다. |
ANTHROPIC_MODEL |
사용할 모델 고정 | Claude 계열이 아닌 모델은 /model 목록에 안 뜨므로 여기서 고정하는 편이 확실하다. |
CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY |
게이트웨이 모델 목록 사용 | 공식 문서 기준 Claude Code v2.1.219 이상이 필요하다. |
CLAUDE_CODE_AUTO_COMPACT_WINDOW |
자동 압축 시점 조정 | 아래 ‘컨텍스트 창’ 항목 참고. 프로필을 쓰면 자동으로 들어간다. |
환경변수는 시작할 때 한 번만 읽힌다. 값을 바꿨으면 claude 프로세스를 반드시 다시 띄운다.
컨텍스트 창이 어긋나면 대화가 엉뚱한 지점에서 잘린다
Claude Code는 자기가 모르는 모델 ID를 만나면 컨텍스트 창을 200K로 가정한다. /v1/models에서 실제 창 크기를 읽어 오지 못하기 때문이다.
그래서 실제 창이 더 큰 모델을 붙이면 자동 압축(auto-compaction)이 너무 일찍 돌고, 반대 경우에는 늦게 돈다. 모델의 실제 창보다 조금 낮은 값을 CLAUDE_CODE_AUTO_COMPACT_WINDOW에 넣어 주면 된다.
이것도 setup-claude가 만든 프로필에는 모델별로 이미 들어가 있다. 직접 설정보다 프로필을 권하는 이유 중 하나다.
연결됐는지 확인하는 3단계
- Claude Code를 새로 띄우고
/status로 현재 Base URL과 모델을 확인한다. - 결과를 눈으로 확인하기 쉬운 작업을 하나 시켜 본다. 파일을 건드리지 않는 쪽이 안전하다.
현재 폴더의 파일 목록을 확인하고 프로젝트 구조만 설명해 줘. 파일은 수정하지 마.- OmniRoute Dashboard의 Request Logs에서 Endpoint가 Messages인지, Provider와 Model이 의도한 값인지 확인한다.
Cline 절에서 한 것과 똑같은 양방향 대조다. 응답이 왔다는 것만으로는 어디를 거쳐 왔는지 알 수 없다.
증상별로 어디를 볼까
| 증상 | 확인할 것 |
|---|---|
| 게이트웨이를 아예 안 거치는 것 같다 | ANTHROPIC_BASE_URL에 /v1이 붙지 않았는지, 그리고 프로세스를 다시 띄웠는지 확인한다. |
| 401 / 403 | 엔드포인트 키와 Allowed Endpoints의 Messages 허용, 모델 권한이 ‘제한 + 0개’가 아닌지 본다. |
/model 목록이 비어 있다 |
Claude Code v2.1.219 이상인지, CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY=1인지 확인한다. 안 되면 ANTHROPIC_MODEL로 고정한다. |
400 Ambiguous model 'claude-…' |
Claude Code는 접두사 없는 모델 ID를 보내는데, Claude Code 계열(cc/)과 Claude 계열(claude/) 연결이 둘 다 있으면 후보가 겹쳐 OmniRoute가 판단을 거부한다. ANTHROPIC_MODEL에 접두사를 붙여 고정한다. |
| 인증 오류인데 프로필을 쓰고 있다 | 프로필에는 토큰이 없다. omniroute launch --profile로 실행하거나 ANTHROPIC_AUTH_TOKEN을 직접 export 한다. |
| 긴 대화에서 이상한 시점에 압축된다 | 200K 가정 문제다. CLAUDE_CODE_AUTO_COMPACT_WINDOW를 조정하거나 setup-claude 프로필을 쓴다. |
그리고 프로필을 지웠는데도 계속 게이트웨이로 붙는다면 echo $CLAUDE_CONFIG_DIR을 확인해 본다. 이 값이 프로필 폴더를 가리키고 있으면 그쪽 설정이 계속 적용된다.
- Claude 구독 OAuth를 제3자 라우터에서 재사용하는 것보다 공식 API Key 기반 Provider를 우선한다. Anthropic Consumer Terms는 API 또는 명시적으로 허용된 경우가 아닌 자동 접근을 제한한다.
원격 OmniRoute라면 포트를 인터넷에 직접 열지 말고 VPN·Tailnet 또는 인증된 Reverse Proxy를 구성한 뒤, 공식 원격 컨텍스트 기능을 사용한다.
omniroute connect <안전하게_접근_가능한_호스트>
omniroute launch
omniroute connect로 컨텍스트를 한 번 만들어 두면 이후 setup-claude와 launch가 자동으로 그 원격 서버를 바라본다. 매번 --remote와 --api-key를 붙이지 않아도 된다.

B. VS Code의 Cline 확장에 연결
Cline과 OmniCopilot은 서로 다른 확장 프로그램이다.
Cline은 독립적인 코딩 에이전트 UI를 제공하고, OmniCopilot은 OmniRoute 모델을 VS Code의 Copilot Chat 모델 선택기에 넣는다. 따라서 Cline을 쓰려면 먼저 Cline 확장을 설치한다.
ex) 상기 링크를 통해서도 가능 하고

ex) 다음과 같이 플러그인을 직접 검색 설치 해도 된다.

Cline을 연 뒤 Settings → API Provider → OpenAI Compatible을 선택하고 다음 값을 입력한다.
또는 처음 설치하는 분들의 경우 다음과 같은 화면에서 Bring my own API key를 선택하면 된다.
ex) Cline 기본 설정

- 나의 경우는 당장은 블로그 작성을 위해 간단한 테스트만 진행할 것이므로 모델 ID는 auto로 진행하였다.

버전에 따라 메뉴 이름은 조금 다를 수 있지만 입력값의 역할은 같다.
| Cline 항목 | 입력값 | 주의점 |
|---|---|---|
| API Provider | OpenAI Compatible | OpenAI 계정을 연결한다는 뜻이 아니라 호환 규격을 선택하는 것이다. |
| Base URL | http://localhost:20128 |
/v1을 붙이지 않는다. Cline이 /v1/chat/completions를 덧붙인다. |
| API Key | 앞에서 만든 OmniRoute 엔드포인트 키 | GLM·Gemini의 원본 Provider Key를 넣지 않는다. |
| Model ID | <provider/model> |
/v1/models에 나온 glm/...·zai/... 또는 agy/... 항목 하나를 그대로 복사한다. |
처음에는 auto나 여러 모델 조합보다, Playground에서 이미 성공한 고정 모델 하나를 넣는 편이 좋다. 나는 테스트 목적이라 auto로 넘어갔지만, 원인 추적이 필요한 상황이라면 고정 모델이 훨씬 편하다.
연결이 되면 Cline에서 현재 작업 폴더의 파일 하나를 읽고 요약하도록 요청한 뒤 OmniRoute의 Request Logs에서 실제 Provider와 Model이 맞는지 확인한다.
ex) 인사부터..

- 파일 하나를 읽기보다 가장 내가 많이 사용하던 예시인, 프로젝트 분석을 한번 시켜 보았다.
> 결과는 생각보다 빠르고, 퀄리티도 나쁘지 않았다.

정확한 입력값을 터미널에서 먼저 확인하고 싶다면 아래처럼 실행한다.
--dry-run은 실제 설정을 덮어쓰지 않고 Cline에 붙여 넣을 값과 변경 예정 내용을 보여 준다.
omniroute setup-cline --model "<provider/model>" --dry-run
Cline은 모델 자동 탐색이 없어서 --model이 필수다. 비대화형으로 돌릴 때는 --yes도 함께 붙인다.
별도의 Antigravity 확장을 설치할 필요가 없다. 이미 OmniRoute Provider 화면에서 Antigravity OAuth 연결을 완료했다면, Cline의 Model ID에 모델 목록의 agy/... ID를 넣으면 된다. 다만 이 OAuth 경로의 약관·계정 위험은 그대로이므로 장기 사용과 중요한 계정에는 공식 Gemini API Key 경로를 우선한다.
C. VS Code Copilot Chat에는 OmniCopilot로 연결
내가 캡처한 아래 실습 화면은 Cline이 아니라 OmniCopilot 설치 과정이다.
이 방법은 새 채팅 사이드바를 하나 더 만드는 대신, OmniRoute가 제공하는 모델을 VS Code의 기존 Copilot Chat 모델 선택기에 등록한다. Copilot의 에이전트 모드, 도구 호출, MCP 서버 설정이 그대로 유지된 채 모델만 바뀌는 방식이다.
EXTENSIONS 에서 다음 2개를 검색하여 설치해주자.

공식 문서 기준 요구 버전은 VS Code 1.104 이상이다.
VS Code 1.122 이상에서는 언어 모델 제공자(Language Model Provider)를 쓰는 데 GitHub 로그인이나 Copilot 구독이 필요하지 않다. 다만 인라인 자동완성과 Embedding 기반 기능은 이 제공자 API 밖이어서 여전히 Copilot이 필요하다.
- VS Code 확장 화면에서 OmniRoute를 검색해
diegosouzapw.omnicopilot을 설치한다. - OmniRoute가 기본 주소
http://localhost:20128에서 실행 중이면 별도 설정 없이 연결을 시도한다. - 연결 패널이 열리면 Server URL에는
http://localhost:20128을 입력한다. 여기에도/v1을 붙이지 않는다. 확장이 알아서 붙인다. - API Key에는 앞에서 만든 OmniRoute 엔드포인트 키를 입력하고 Save & Test를 누른다. 이 값은
settings.json이 아니라 VS Code SecretStorage를 통해 OS 키체인에 저장된다. - Copilot Chat의 모델 선택기에서 Manage Models… → OmniRoute로 들어가 실제로 쓸 모델만 체크한다.

Save & Test에 성공하면 현재 엔드포인트 키가 접근할 수 있는 채팅 모델 수가 갱신된다. 여기서 보이는 숫자는 OmniRoute 전체 Catalog 수와 같지 않은데, 공식 문서가 그 이유를 두 가지로 설명한다.
- 중복 제거: OmniRoute는 기본적으로 모델 하나를 짧은 별칭 접두사와 정식 제공업체 접두사 두 벌로 광고한다. 확장은
?prefix=alias로 한 벌만 요청해서 중복을 없앤다. 문서의 기준 인스턴스에서는 2345개가 1396개로 줄었고 사라진 모델은 없었다고 적혀 있다. - 채팅 불가 모델 제외: 이미지·영상·음성·rerank·Embedding·moderation 모델은 어차피 채팅 요청에서 400으로 거부되므로 선택기에서 걸러 낸다.
그리고 내가 연결한 적 없는 제공업체가 목록에 보이는 것도 정상이다. 목록에는 활성 연결 + 키가 필요 없는(noAuth) 제공업체 전부가 들어가고, 무료 티어의 상당수가 바로 이 키 없는 쪽이다. 보기 싫으면 Dashboard 설정의 blockedProviders에 넣으면 된다.


그리고 이번엔 '콤보(Combo)' 기능, 간단하게 설명하자면 여러 AI 모델을 하나의 가상 엔드포인트로 묶어 관리하는 지능형 모델 라우터(Intelligent Model Router)?? 기능을 사용해볼 예정이다.

코파일럿을 사용하면 기본적으로 동작한다고 하는데 바로 밑에 옵션을 한번 사용해보려 한다.
- 우측 하단의 기본 VSCode의 챗 UI에서 > Auto > Manage Models... 를 클릭하자.


- Default가 auto여서, 변경 가능한 다른 모델 중 auto로 검색해 보았는데 위에서 캡처해둔 것처럼 auto/best-coding, 그 외에도 총 17개의 모델을 확인할 수 있었다. 더블 클릭 하면 활성화되는 모습.

이 선택은 Provider 권한을 새로 부여하는 작업이 아니라 VS Code 모델 선택기에 노출할 항목을 고르는 작업이다.
모델이 나타나지 않으면 Command Palette에서 OmniRoute: Check Connection과 OmniRoute: Refresh Models를 차례로 실행한다.
Activity Bar에 아이콘이 없으면 왼쪽 아이콘 영역을 우클릭해 OmniRoute를 다시 표시하거나 OmniRoute: Manage Connection을 실행한다.
그런 다음 해당 콤보 모델을 선택 한 후 대화를 해보자.

- 정상적으로 응답오는것을 양방향(VSCode, OmniRoute 대시보드)에서 확인하자.
ex) VSCode 정상 응답.

ex) OmniRoute에서 확인
- 시스템 프롬프트에서 부터 코딩관련하여 페르소나를 기본적으로 입히는것을 볼 수 있다.

D. Cursor에서 쓰는 두 가지 방법
Cursor에서는 목적에 따라 방법이 달라진다.
OmniCopilot을 설치하는 방법과 Cursor 기본 Chat을 OmniRoute 주소로 바꾸는 방법을 섞지 않는 것이 중요하다.
방법 1. Open VSX에서 OmniCopilot 설치
OmniRoute 공식 문서는 Cursor·Windsurf·VSCodium·Antigravity 같은 VS Code 계열 Editor에서 Open VSX의 OmniCopilot을 설치할 수 있다고 안내한다. 설치 후 Server URL과 OmniRoute 키는 위 C절과 똑같이 입력한다.
다만 OmniCopilot은 호환되는 VS Code Copilot Chat 모델 선택기에 모델을 등록하는 확장이다. Cursor 고유의 Composer·Tab 자동완성 전체를 OmniRoute로 바꾼다는 뜻은 아니다.
방법 2. Cursor 기본 Chat에 직접 연결
이 방법은 별도의 확장이 필요 없다. 먼저 다음 명령으로 현재 버전에 맞는 Cursor 입력값을 출력한다.
omniroute setup-cursor --only glm,agy
참고로 setup-cursor는 파일을 전혀 쓰지 않는다. Cursor 설정이 불투명한 내부 SQLite에 저장되기 때문에, 이 명령은 화면에 붙여 넣을 값만 출력한다. 그래서 다른 setup-* 명령과 달리 --dry-run 옵션도 없다.
- Cursor → Settings → Models로 이동한다.
- Override OpenAI Base URL을 켜고
http://localhost:20128/v1을 입력한다. Cursor에서는/v1이 필요하다. - OpenAI API Key 입력란에는 OpenAI 원본 키가 아니라 OmniRoute 엔드포인트 키를 넣는다.
- Models에
/v1/models에서 확인한 정확한glm/...·zai/...또는agy/...모델 이름을 직접 추가한다. - Chat 패널에서 짧은 질문을 보내고 OmniRoute Request Logs를 확인한다.
공식 v3.8.50 구현 설명상 Custom Base URL은 Cursor의 Chat 패널에만 적용된다. Composer, Cmd/Ctrl+K 인라인 편집, Tab 자동완성은 Cursor 자체 백엔드를 계속 사용한다. 설정 메뉴나 Override 항목이 보이지 않으면 현재 Cursor 버전·플랜·조직 정책에서 이 기능이 제공되는지 확인하고, 실습은 Cline 또는 OmniCopilot 방식으로 진행한다.
E. Antigravity는 ‘Provider’와 ‘Editor’를 구분한다
이 글에서 Antigravity라는 이름은 두 위치에 등장할 수 있어 특히 헷갈린다.
- OmniRoute의 Antigravity Provider: Google 계정 OAuth로 모델을 공급하는 상류 연결이다. 이미 연결했다면 Cline·OmniCopilot·Cursor에서
agy/...모델 ID를 선택하면 된다. 추가 확장은 필요 없다. - Antigravity Editor: VS Code 계열 Editor 안에서 OmniRoute 모델 선택기를 쓰려는 경우다. 공식 안내에 따라 Open VSX에서 같은 OmniCopilot 확장을 설치하고 Server URL과 OmniRoute 키를 입력한다.
후자의 확장을 설치했다고 해서 Antigravity Editor의 고유 Agent 트래픽이나 Google OAuth가 자동으로 OmniRoute를 거치는 것은 아니다. 확장이 연결하는 범위는 호환되는 Copilot Chat Provider 화면이다. 그리고 전자의 OAuth Provider는 기술적으로 동작하더라도 서비스 약관과 계정 정지 위험이 사라지지 않는다.
| 사용 화면 | 추가 설치 | Base URL | Model | 실제 적용 범위 |
|---|---|---|---|---|
| Claude Code | 없음 | http://localhost:20128 (/v1 없음) |
ANTHROPIC_MODEL로 고정 |
Messages 엔드포인트, 환경변수로만 제어 |
| VS Code Cline | Cline | http://localhost:20128 |
정확한 고정 ID | Cline의 채팅·Agent |
| VS Code Copilot Chat | OmniCopilot | http://localhost:20128 |
Manage Models에서 선택 | Copilot Chat Provider |
| Cursor 기본 Chat | 없음 | http://localhost:20128/v1 |
Models에 직접 추가 | Chat만, Composer·Tab 제외 |
| Cursor·Antigravity의 OmniCopilot | Open VSX의 OmniCopilot | http://localhost:20128 |
호환 모델 선택기에서 선택 | Editor 고유 Agent 전체가 아님 |
모든 방법에서 입력하는 API Key는 동일한 OmniRoute 엔드포인트 키다. GLM·Gemini·Antigravity 자격 증명을 Editor마다 다시 복사하지 않는 것이 이 Gateway 구성의 핵심이다.
F. 연결 뒤 반드시 확인할 세 가지
- 정말 어느 모델이 답했나: Dashboard의 Request Logs에서 실제 Provider·Model·Status를 확인한다.
- 도구 호출이 유지되나: 단순 채팅뿐 아니라 파일 읽기·수정 제안처럼 작은 Tool Call을 시험한다.
- 무료 한도가 끝나면 어떻게 되나: 조합의 첫 후보를 잠시 비활성화해 둘째 후보로 넘어가는지 확인한다. 실제 한도를 소진시키는 테스트는 하지 않는다.
G. 실습이 끝났으면 정리한다
나는 for_tutorial 키를 바로 지울 예정이라고 했으니, 정리 순서도 같이 적어 둔다.
- Dashboard에서
for_tutorialAPI 키를 삭제한다. - 더 쓰지 않을 Provider 연결을 해제한다. 특히 OAuth 연결.
~/.omniroute/.env에서INITIAL_PASSWORD줄을 지우고,.env.bak이 남아 있으면 삭제한다.- Claude Code 설정을 원복한다(위 A절 마지막).
- Cline·OmniCopilot에 넣은 키를 지운다.
- 당분간 쓰지 않을 거라면
npm uninstall -g omniroute. 데이터는~/.omniroute/에 남으므로 필요 없으면 같이 정리한다.
6. 실제 사용자와 커뮤니티의 반응
반응을 살필 때는 플랫폼 성격을 나눠 봐야 한다.
X와 Threads는 프로젝트를 발견하고 공유하는 반응이 많았고, Reddit과 GitHub Issues에는 실제로 며칠 써 본 경험과 실패 조건이 더 구체적으로 남아 있었다.
Reddit: 효율적이지만 손이 전혀 안 가는 도구는 아니다
r/opencodeCLI의 한 사용자는 약 일주일 동안 많이 사용해 봤고, 조합 설정에는 시간이 들며 일부 앱이 OmniRoute를 거친 추론 모델의 능력을 제대로 이해하지 못했다고 적었다. 그럼에도 대부분의 상황에서는 효율적이어서 계속 쓰고 있다고 평가했다.
업데이트 뒤 암호화 문제로 인증 정보를 지우고 다시 연결한 경험, curl과 키 문서가 더 명확했으면 좋겠다는 의견도 함께 남겼다.
다른 Reddit 글에서는 Hermes 연결이 동작했다는 확인과, Antigravity의 특정 Gemini 모델만 동작하지 않았다는 보고가 함께 있었다. 따라서 ‘OmniRoute가 된다/안 된다’로만 나누기는 어렵다. 클라이언트 × 제공업체 × 모델 × 스트리밍·추론 방식의 조합마다 결과가 달라질 수 있다.
GitHub 이슈: 버전과 실행 환경을 함께 봐야 한다
- #9927: 반복적인 복호화 오류가 보고됐다. 모든 연결이 중단된 것은 아니었고 Kiro는 계속 동작했다는 설명이 있어, 오래된 암호화 키 또는 연결별 저장 상태를 확인할 필요가 있다.
- #3476: Node 업데이트 뒤 네이티브
better-sqlite3바이너리 호환 문제가 보고됐다. 모듈 다시 빌드(Rebuild) 또는 대체 구현 사용 여부를 확인해야 한다. - #8091: Windows에서 Bun으로 실행했을 때 발생한 시작 실패(Startup failure)는 지원되는 Node 실행 환경을 사용하라는 방향으로 닫혔다.
- #1628: 도구 호출 뒤 추론 내용을 다시 전달하는 과정의 호환 문제 보고가 있다.
Issue는 위험 신호이면서 동시에 범위가 좁은 증거다. 오래된 버전의 한 사례를 현재 안정판의 보편적인 결함으로 확대하면 안 된다. 반대로 닫힌 Issue라고 현재 환경에서 무조건 해결됐다고 봐도 안 된다.
제3자 검증 글: 설치 성공과 운영 적합성은 다른 문제
Pinggy는 v3.8.48 Docker 환경에서 실제 설치, 모델 목록 조회, 채팅 요청, 관리 API 인증을 확인했다. 동시에 기본 관리자 비밀번호 변경과 무인증 무료 제공업체의 낮은 성공률을 지적했다. Wavect의 운영 체크리스트는 한 모델과 검증된 대체 후보 하나부터 시작하고, 응답 품질·도구 호출·지연 시간·비용을 직접 비교하라고 권한다. 두 글 모두 프로젝트 소개문보다 실제 도입 판단에 가까운 자료다.
다만 Pinggy는 원격 터널 서비스 업체이고 Wavect도 관련 시장의 사업자다. 독립적인 제3자 자료이기는 하지만 상업적 이해관계가 전혀 없는 자료로 볼 수는 없다. 실제 수치는 참고하되, 최종 판단은 공식 문서와 자신의 실행 결과를 기준으로 해야 한다.
X·Threads: 단일 엔드포인트와 설치 편의성에 관심
X에서는 5분 안에 설정할 수 있다는 소개와 여러 AI 모델을 한 엔드포인트로 묶는다는 요약이 확산됐다.
Threads의 한국어 게시물도 제공업체 수와 무료 티어 통합을 핵심으로 소개했다.
다만 여러 게시물이 유지관리자의 홍보 문구와 비슷한 표현을 반복하고, 게시 시점에 따라 제공업체·모델·별 개수도 서로 달랐다. 튜토리얼 실행 로그나 장기 사용 기록이 없는 글은 관심도를 보여 주는 자료로만 보고 실제 안정성 근거로 쓰지 않았다.
국내 소개 글: 왜 ‘무료 티어 통합’이 주목받았는지 잘 보여 준다
2026년 7월 12일 게시된 ‘월 0원으로 237개 AI 프로바이더’ 소개 글은 무료 티어를 모아 Claude Code·Cursor·Cline에 연결한다는 효용을 전면에 내세웠다. OmniRoute가 왜 화제가 됐는지를 이해하기에는 좋은 자료다.
다만 제목의 ‘무제한’, 237개 Provider, 약 16억 토큰, 17개 전략 같은 수치는 당시 스냅샷 또는 홍보 표현이다. 현재 공식 문서와는 다르고, 가입·할당량·약관 제한도 생략돼 있다. Docker의 단순 포트 공개 예시와 Claude Code·Cline의 Base URL 역시 현재 공식 v3.8.50 규칙과 함께 다시 확인해야 한다. 따라서 이 글에서는 문제의식과 활용 장면은 받아들이되 숫자와 명령은 공식 저장소 기준으로 다시 작성했다.
한국 커뮤니티: 기대와 코드 노출 우려가 같이 나왔다
하나는 무료 모델에 코드를 잘못 보내면 코드가 노출될 수 있다는 우려, 다른 하나는 비용 최적화 도구라는 반응이었다.
댓글 수가 적어 한국 사용자 전체 반응을 대표할 수는 없지만, 장점과 위험을 아주 짧게 보여 준다.
GeekNews에 적힌 제공업체 271개, 모델 500개 이상, 전략 18개는 글이 올라온 당시 수치다.
현재 안정판 v3.8.50 저장소 설명의 제공업체 352개, 모델 1,200개 이상, 공개 전략 19개와 다르다.
이 프로젝트는 릴리스가 빠르므로 커뮤니티 요약의 숫자는 날짜를 붙여 읽어야 한다. 이번 조사에서는 요즘IT가 OmniRoute를 직접 다룬 글은 찾지 못했다.
| 반응 | 근거가 된 경험 | 글에서의 판단 |
|---|---|---|
| 편리하다 | 엔드포인트 통합, 대부분의 상황에서 효율적 | 개인 코딩 환경에서 설득력 있음 |
| 설정이 필요하다 | 조합 조정, 키와 curl 문서 요구 | 설치 후 전혀 손댈 필요가 없는 도구는 아님 |
| 호환성이 흔들린다 | 추론·도구 호출·특정 모델 사례 | 클라이언트별 동작 확인 필요 |
| 보안이 걱정된다 | 클라우드 동기화, 코드 노출, 계정 사용 방식 | localhost 유지·동기화 끄기·약관 확인 필요 |
7. LiteLLM·OpenRouter·Portkey와 비교
어느 것이 더 좋으냐보다 누가 게이트웨이를 운영하고 무엇을 관리하려는가로 나누는 편이 정확하다.
| 선택지 | 운영 방식 | 강점이 드러나는 상황 | 먼저 볼 것 |
|---|---|---|---|
| OmniRoute | 로컬·자체 호스팅, 관리 화면 중심 | 개인 AI 코딩 도구, 여러 계정·조합 실험 | 빠른 릴리스, 인증 정보·약관 경계 |
| LiteLLM | 자체 호스팅 프록시, Python·플랫폼 중심 | 가상 키, 예산, 로그, 팀 게이트웨이 | DB·프록시 운영 복잡도 |
| OpenRouter | 호스팅형 단일 엔드포인트 | 직접 서버를 운영하지 않고 여러 모델을 빠르게 사용 | 제3자 게이트웨이를 지나는 데이터 경계와 비용 |
| Portkey | 관리형·오픈소스 게이트웨이 | 관찰 가능성(Observability), 정책 관리, 라우팅 통합 | 요금제와 배포 방식 |
개인 Mac에서 Cursor와 OpenCode의 제공업체 설정을 통합하려는 목적이면 OmniRoute가 자연스럽다. 반대로 회사 플랫폼 팀이 가상 키, 예산, 감사, SSO와 중앙 운영을 우선한다면 LiteLLM이나 Portkey의 운영 방식을 함께 검토해야 한다. 서버를 관리하고 싶지 않다면 OpenRouter가 더 단순할 수 있다.
8. 문제가 생겼을 때 확인할 순서

| 증상 | 먼저 확인 | 다음 조치 |
|---|---|---|
| 관리 화면이 안 열림 | Node 버전, 20128 포트, 시작 로그 | omniroute doctor |
| 네이티브 모듈 오류 | Node 업데이트 여부, better-sqlite3 ABI | 지원 Node로 재설치. 공식 omniroute update는 --include=optional을 항상 붙여 better-sqlite3 같은 선택적 네이티브 의존성이 사라지지 않게 한다. |
| 복호화 오류 | 기존 STORAGE_ENCRYPTION_KEY와 DB 조합 | 원래 키 복구, 새 키로 덮어쓰지 않기 |
| 모델 목록 401/403 | 엔드포인트 키, Bearer 헤더, 권한 범위 | 튜토리얼 키 재발급·최소 권한 확인 |
| Claude Code만 401/404 | Base URL의 /v1 유무, Allowed Endpoints의 Messages |
5장 A절 증상 표로 이동 |
| 고정 모델은 되지만 조합 실패 | 각 대상 단독 호출, 전략, 로그 | 대상을 하나씩 추가 |
| 추론·도구 호출 이상 | 클라이언트 API 방식, 모델 기능, 스트리밍 여부 | 직접 연결 기준선과 원본 응답 비교 |
가장 중요한 원칙은 확인 범위를 한 단계씩 줄이는 것이다.
auto가 실패하면 고정 모델, 조합이 실패하면 대상 하나, 개발 도구에서 실패하면 curl 요청으로 내려간다. 이 순서를 지키면 OmniRoute 자체 문제인지, 클라이언트 설정 문제인지, 제공업체 응답 문제인지 구분할 수 있다.
9. 누구에게 맞고, 누구에게는 과할까

여러 AI 코딩 도구와 제공업체를 직접 써 보고 있고, 엔드포인트와 대체 전환을 내 컴퓨터에서 통제하고 싶다면 OmniRoute는 꽤 매력적이다. 특히 한 도구의 한도가 끝날 때마다 설정 파일을 다시 편집하는 일이 반복된다면 체감이 크다.
반대로 제공업체 하나만 쓰고 대체 전환이 필요하지 않다면 게이트웨이 한 층을 더 두는 것이 오히려 복잡하다.
보안 검토 없이 회사 코드에 붙이거나, 무료 계정을 무제한으로 순회하는 도구로 접근하는 것도 맞지 않는다.
운영용 플랫폼이라면 개인 관리 화면의 편리함보다 인증, 감사, 데이터 보존, SSO, 고가용성(HA), 장애 대응을 먼저 비교해야 한다.
잘 맞는 경우
AI 코딩 도구와 제공업체를 여러 개 쓰고, 로컬 관리 화면에서 라우팅·대체 전환을 실험하려는 개인 개발자
신중해야 할 경우
회사 민감 코드, 계정 약관이 엄격한 환경, 운영 게이트웨이에 고가용성·SSO·감사가 필요한 팀
결론: OmniRoute의 매력은 흩어진 무료 티어를 실제 Claude Code·VS Code 작업에 연결하고, 한도가 끝났을 때 도구 설정을 다시 고치지 않아도 된다는 데 있다. 다만 ‘무료 모델을 무제한 사용’하게 해 주는 도구가 아니라, 내가 합법적으로 확보한 무료·유료 경로를 한곳에서 관찰하고 전환하는 게이트웨이다. 암호화 키, Provider 약관·데이터 정책, 고정 모델 기준선까지 함께 관리해야 이 장점을 안전하게 누릴 수 있다.
참고 자료
- OmniRoute v3.8.50 안내문(README)
- OmniRoute v3.8.50 릴리스(Release)
- 공식 아키텍처 문서
- 공식 보안 문서
- OmniRoute ACP Custom-Agent RCE 보안 권고(CVE-2026-88062)
- 환경변수·필수 비밀값 문서
- 자동 라우팅 모드 설정 소스
- 로컬 전용 API 보호 문서
- 9월 3일 재감사된 무료 티어 산정 방법
- v3.8.50 STRICT_ZERO_COST 무료 라우팅 문서
- v3.8.50 CLI 통합 명령·Base URL 규칙
- v3.8.50 Claude Code 연결 문서
- v3.8.50 Remote Mode 문서
- v3.8.50 VS Code Copilot Chat·OmniCopilot 연결 문서
- OmniCopilot — VS Code Marketplace
- OmniCopilot — Open VSX(Cursor·Antigravity 등)
- Cline — VS Code Marketplace
- OpenAI 개인용 이용약관
- Anthropic Consumer Terms
- Gemini API Additional Terms
- Reddit opencodeCLI 사용 경험
- Reddit coolgithubprojects 토론
- GitHub 이슈 #9927 — 복호화 오류 보고
- GitHub 이슈 #1628 — 추론·도구 호출 호환 보고
- X — 빠른 설치를 강조한 소개 게시물
- Threads — 한국어 OmniRoute 소개 게시물
- GeekNews 한국 커뮤니티 반응
- 국내 OmniRoute 소개 글 — 무료 티어·개발 도구 활용 관점 참고
- Pinggy v3.8.48 Docker 실행 검증
- Wavect OmniRoute 운영 체크리스트
- LiteLLM 공식 문서
- OpenRouter 빠른 시작(Quickstart)
- Portkey AI 게이트웨이 공식 문서
'AI > DevTools for AI' 카테고리의 다른 글
| cmux란? cmux 설치 및 사용해보기 - AI 에이전트를 위해 설계된 터미널(cmux vs tmux 비교) (6) | 2026.03.23 |
|---|---|
| [Python] 파이썬 로컬 개발 환경 설정 : AI 관련 코딩 실습 준비 (1) | 2025.11.30 |
| [Python 웹 환경] Google Colab 활용 가이드 : AI 관련 코딩 실습 준비 (0) | 2025.11.18 |
소중한 공감 감사합니다