인가

인가 (Authorization)

출처: MCP 공식 문서 — Authorization

원격 MCP 서버는 보통 인가를 요구해요. Inspector는 세 클라이언트 모두에서 전체 인가 흐름을 구현하고, 결과 토큰을 디스크에 공유해서 한 번 한 로그인이 어디서든 쓸 수 있게 해줘요.

흐름 전체

  1. 연결, 그리고 거부당하기 — Inspector가 서버 URL에 연결. 서버가 401로 응답. 응답이 WWW-Authenticate 헤더를 지니면 protected-resource 메타데이터 URL(resource_metadata)과, 선택적으로 요청이 필요로 하는 스코프를 가리켜요.
  2. 인가 서버 발견 — Inspector가 서버의 protected-resource 및 authorization-server 메타데이터를 가져와 엔드포인트와 지원되는 그랜트를 알아내요.
  3. 클라이언트 등록 또는 식별 — Inspector가 설정된 메커니즘으로 인가 서버에 자신을 식별해요. 동적 클라이언트 등록, 사전 등록된 정적 클라이언트(--client-id / --client-secret), Client ID Metadata Document(--client-metadata-url), 또는 엔터프라이즈 관리 IdP.
  4. 브라우저에서 인가 — Inspector가 인가 URL을 열고, 여러분이 로그인하고 동의해요.
  5. 콜백 수신 — 인가 서버가 인가 코드를 달고 Inspector의 콜백 URL로 리다이렉트해요.
  6. 교환 후 재시도 — 코드가 토큰으로 교환되고, 토큰이 저장되며, 원래 연결(또는 세션 중 도전의 경우 거부당했던 요청)이 자동으로 재시도돼요.

콜백 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-urlclient.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)