인가
인가 (Authorization)
원격 MCP 서버는 보통 인가를 요구해요. Inspector는 세 클라이언트 모두에서 전체 인가 흐름을 구현하고, 결과 토큰을 디스크에 공유해서 한 번 한 로그인이 어디서든 쓸 수 있게 해줘요.
흐름 전체
- 연결, 그리고 거부당하기 — Inspector가 서버 URL에 연결. 서버가
401로 응답. 응답이WWW-Authenticate헤더를 지니면 protected-resource 메타데이터 URL(resource_metadata)과, 선택적으로 요청이 필요로 하는 스코프를 가리켜요. - 인가 서버 발견 — Inspector가 서버의 protected-resource 및 authorization-server 메타데이터를 가져와 엔드포인트와 지원되는 그랜트를 알아내요.
- 클라이언트 등록 또는 식별 — Inspector가 설정된 메커니즘으로 인가 서버에 자신을 식별해요. 동적 클라이언트 등록, 사전 등록된 정적 클라이언트(
--client-id/--client-secret), Client ID Metadata Document(--client-metadata-url), 또는 엔터프라이즈 관리 IdP. - 브라우저에서 인가 — Inspector가 인가 URL을 열고, 여러분이 로그인하고 동의해요.
- 콜백 수신 — 인가 서버가 인가 코드를 달고 Inspector의 콜백 URL로 리다이렉트해요.
- 교환 후 재시도 — 코드가 토큰으로 교환되고, 토큰이 저장되며, 원래 연결(또는 세션 중 도전의 경우 거부당했던 요청)이 자동으로 재시도돼요.
콜백 URL
웹 앱은 OAuth 콜백을 자기 URL에서 듣는 반면, CLI와 TUI는 의도적으로 두 번째 URL을 공유해요.
| 표면 | 기본 콜백 | 이유 |
|---|---|---|
| 웹 | http://localhost:6274/oauth/callback |
메인 앱 서버에 이미 HTTP 리스너가 있음. |
| CLI | http://127.0.0.1:6276/oauth/callback |
전용 루프백 리스너라 실행 중인 웹 Inspector와 충돌하지 않음. |
| TUI | http://127.0.0.1:6276/oauth/callback |
CLI와 같은 리스너. |
CLI나 TUI를 쓰기 전에 사전 등록된 리다이렉트 URI를 요구하는 IdP에는 http://127.0.0.1:6276/oauth/callback을 등록하세요. 예측 가능한 기본값이 핵심이에요. 한 번 등록하면 재사용하니까요.
--callback-url 또는 MCP_OAUTH_CALLBACK_URL로 덮어쓸 수 있어요.
콜백 URL은 루프백 호스트에 바인딩돼야 해요.
localhost,127.0.0.0/8, 또는[::1]. 리스너는 평문http로 인가 코드를 받으므로 비-루프백 호스트는 오류로 거부되고, 이를 덮어쓸 플래그는 없어요. 브라우저가 다른 머신에 있다면 콜백 포트를 그쪽으로 포워딩하세요.--print-handoff(아래)가 준비된portForwardCmd를 출력해줘요.
리다이렉트 URI는 등록과 정확히 일치해야 해요.
http://localhost:6276/...와http://127.0.0.1:6276/...는 같은 리스너에 닿아도 인가 서버에겐 다른 URI예요.한 번에 한 프로세스만 기본 포트를 점유할 수 있어요. 두 번째 동시 흐름은
EADDRINUSE로 실패해요. 인스턴스마다 다른 고정 포트를 쓰거나, 인가 서버가 동적 리다이렉트 URI 등록을 지원하면http://127.0.0.1:0/oauth/callback으로 OS 배정 임시 포트를 쓰세요.
자격 증명이 사는 곳
| 파일 | 내용 |
|---|---|
~/.mcp-inspector/storage/oauth.json |
정규화된 서버 URL 기준으로 키가 정해진 토큰·클라이언트 정보. 소유자만 쓰도록 기록. |
~/.mcp-inspector/storage/client.json |
설치 수준 클라이언트 설정(클라이언트 메타데이터 URL, 엔터프라이즈 IdP). 웹 클라이언트 Client Settings 대화상자가 쓰는 같은 파일. |
카탈로그 파일 안의 서버 oauth 블록 |
서버별 클라이언트 id/secret, 스코프, 엔터프라이즈 관리 플래그, step-up 정책. |
oauth.json의 경로는 순서대로 해석돼요. MCP_INSPECTOR_OAUTH_STATE_PATH, 그다음 <MCP_STORAGE_DIR>/oauth.json(환경 변수 참고), 마지막으로 위 기본값. 세 클라이언트가 똑같이 해석해요. 명령줄 --client-id / --client-secret / --client-metadata-url은 client.json을 덮어써요.
세션 중 재인가
서버가 세션 중 하나의 요청을 401 또는 403 insufficient_scope로 거부할 수 있고, Inspector는 연결을 끊지 않고 둘 다 처리해요.
- 재인가: 토큰이 만료됐거나 취소됨. Inspector가
WWW-Authenticate도전을 파싱하고 흐름을 다시 돌린 뒤 실패한 요청을 재시도해요. - Step-up: 요청이 현재 토큰에 없는 스코프를 필요로 함. Inspector가 보유 스코프와 필요 스코프의 합집합으로 재인가해서, 새 토큰이 기존 것에 새로 요구된 스코프까지 포함하게 해요.
웹 클라이언트에서는 재인가 배너로 나타나고, CLI에서는 stderr에 프롬프트가 떠요.
Proceed with step-up authorization? [y/N]
y로 계속해요. 파이프 입력(echo y | ...)도, 개행으로 끝나거나 stdin이 닫히면 동작해요. N, 또는 답 없이 EOF는 거절이에요. 5초 안에 아무것도 안 보내는 비-TTY stdin은 명시적 거절과 구별되는 auth_required로 실패해요. 엔터프라이즈 관리 step-up은 프롬프트 없이 조용히 재발행해요.
비대화형 및 CI 실행
대화형 OAuth는 stdin 또는 stderr의 TTY가 필요하거나, MCP_AUTO_OPEN_ENABLED=true가 필요해요. 2>&1 | tee처럼 stderr를 파이프로 리다이렉트해도 stdin이 TTY로 남으므로 동작해요. 둘 다 아니면—보통 CI 모양—CLI는 아무도 완료하지 않을 콜백을 최대 15분 기다리는 대신 auth_required로 빠르게 실패해요.
CI에서는 명시적으로 하세요.
mcp-inspector --cli "$URL" --transport http --stored-auth-only --method tools/list
--stored-auth-only는 대화형 OAuth나 step-up을 절대 시작하지 않고, 브라우저를 열지 않으며, 토큰이 저장소에 있으면 쓰고 없으면 즉시 실패해요.
웹 클라이언트에서 CLI로 핸드오프
흔한 사례: 사람이 이 머신의 웹 Inspector에서 OAuth를 완료했고, 이제 스크립트가 그 토큰을 쓰려고 해요.
| 플래그 | 동작 |
|---|---|
--use-stored-auth |
--server-url의 저장된 인증을 읽고 Authorization: ***를 주입. 리프레시 토큰이 저장돼 있으면 먼저 리프레시 그랜트를 실행하고 새 토큰을 주입해 교체를 유지. 매칭되는 게 없으면 3으로 종료(저장된 서버 URL 나열). |
--wait-for-auth <sec> |
상태 파일을 폴링해서 --server-url의 토큰이 나타나면 주입. <sec>에 타임아웃되며 3으로 종료. 로그인을 사람에게 넘긴 뒤에 사용. |
--list-stored-auth |
{ oauthStatePath, storedServerUrls }를 출력하고 연결 없이 종료. |
--print-handoff |
--server-url에 대한 JSON 블록(deepLink, portForwardCmd, oauthStatePath, apiToken)을 출력하고 종료. 브라우저 쪽을 구동할 원격 스크립트가 필요한 전부예요. |
--relogin |
연결 전에 이 서버 URL의 저장된 OAuth를 삭제. HTTP/SSE만. |
전형적인 원격 VM 시퀀스:
# VM에서: 사람이 브라우저에서 OAuth를 완료하는 데 필요한 것을 출력
mcp-inspector --cli --server-url https://api.example/mcp --print-handoff
# 그런 다음 토큰이 도착할 때까지 블록, 그 토큰으로 호출 실행
mcp-inspector --cli --transport http --server-url https://api.example/mcp \
--wait-for-auth 120 --method tools/list
핸드오프 블록의 deepLink는 브라우저를 연결된 Inspector로 곧장 이동시켜요. Deep links 참고.
저장된 항목은 만료를 기록하지 않으므로, 저장된 리프레시 토큰은
--use-stored-auth실행마다 매번 사용돼요. 회전하는(일회용) 리프레시 토큰에서는 두 가지 좁은 실패 창이 생겨요. 같은 상태 파일에 대한 두 동시 호출이 토큰을 두고 경쟁할 수 있고, 성공적인 리프레시와 쓰기-백 사이의 충돌로 회전된 토큰이 저장되지 않을 수 있어요. 둘 다 드물고, 웹 클라이언트에서 재인가하면 복구돼요.
인증 상태 검사
- 웹: Connection Info 패널이 발견 결과, 등록된 클라이언트, 부여된 스코프, 토큰 상태를 보여주고 활성 서버에 대해 Clear OAuth state를 제공해요.
- TUI: Auth 탭(
a)이 같은 필드를 보여주고 같은 방식으로 상태를 지워요. - CLI:
--list-stored-auth가 디스크에 뭐가 있는지 보여주고,--relogin이 버리고 다시 시작해요.
더 알아보기 (Learn more)
- MCP 공식 문서 — Authorization
- MCP 공식 문서 — OAuth Client Credentials
- MCP 공식 문서 — Enterprise-Managed Authorization