MCP(Model Context Protocol)에서 Authorization은 MCP 서버가 노출하는 민감한 리소스와 작업에 대한 접근을 보호합니다. 서버가 사용자 데이터나 관리 작업을 다룬다면, 어떤 사용자가 어떤 엔드포인트에 접근할 수 있는지 명확히 통제해야 합니다. MCP는 특정 인증 체계에 종속되지 않고 OAuth 2.1 관례를 따르는 표준적인 흐름을 사용합니다.
Authorization은 선택 사항이지만, 다음과 같은 경우에는 강하게 권장됩니다.
STDIO 전송을 사용하는 로컬 MCP 서버는 브라우저 기반 OAuth 흐름 대신 환경 변수 기반 자격 증명이나 서버 내부 라이브러리를 통한 인증 정보를 사용할 수 있습니다. 반대로 HTTP 기반 원격 서버는 OAuth 흐름을 사용하는 것이 일반적입니다.
클라이언트가 보호된 MCP 서버에 처음 접속하면 서버는 401 Unauthorized와 함께
인증 정보를 찾을 위치를 WWW-Authenticate 헤더로 알려줍니다.
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer realm="mcp",
resource_metadata="https://your-server.com/.well-known/oauth-protected-resource"
클라이언트는 PRM 문서를 가져와 어떤 Authorization Server를 써야 하는지, 어떤 scope를 지원하는지 확인합니다.
{
"resource": "https://your-server.com/mcp",
"authorization_servers": ["https://auth.your-server.com"],
"scopes_supported": ["mcp:tools", "mcp:resources"]
}
다음으로 클라이언트는 Authorization Server의 메타데이터를 조회해
authorization_endpoint, token_endpoint,
registration_endpoint 같은 실제 엔드포인트를 파악합니다.
{
"issuer": "https://auth.your-server.com",
"authorization_endpoint": "https://auth.your-server.com/authorize",
"token_endpoint": "https://auth.your-server.com/token",
"registration_endpoint": "https://auth.your-server.com/register"
}
클라이언트가 이미 사전 등록되어 있지 않다면 Dynamic Client Registration(DCR)로 자신을 등록할 수 있습니다. DCR을 지원하지 않고 사전 등록도 없다면, 사용자가 필요한 클라이언트 정보를 직접 입력할 수 있어야 합니다.
{
"client_name": "My MCP Client",
"redirect_uris": ["http://localhost:3000/callback"],
"grant_types": ["authorization_code", "refresh_token"],
"response_types": ["code"]
}
클라이언트는 브라우저를 열어 /authorize 엔드포인트로 보냅니다.
사용자가 로그인하고 권한을 승인하면 authorization code가 발급되고,
클라이언트는 이를 access token과 refresh token으로 교환합니다.
{
"access_token": "eyJhbGciOiJSUzI1NiIs...",
"refresh_token": "def502...",
"token_type": "Bearer",
"expires_in": 3600
}
이후 클라이언트는 Authorization: Bearer ... 헤더를 사용해
MCP 서버에 요청합니다. 서버는 토큰이 유효하고 필요한 권한을 만족하는지 검증해야 합니다.
GET /mcp HTTP/1.1
Host: your-server.com
Authorization: Bearer eyJhbGciOiJSUzI1NiIs...
원문은 로컬 개발 환경에서 Docker로 Keycloak을 띄워 MCP 서버의 Authorization Server로 사용하는 예시를 보여줍니다. 테스트용으로는 다음 명령으로 Keycloak을 시작할 수 있습니다.
docker run -p 127.0.0.1:8080:8080 -e KC_BOOTSTRAP_ADMIN_USERNAME=admin -e KC_BOOTSTRAP_ADMIN_PASSWORD=admin quay.io/keycloak/keycloak start-dev
Keycloak에서는 다음 사항을 추가로 설정합니다.
mcp:tools 같은 scope 생성원문 예시는 TypeScript, Python, C# SDK 중 하나를 사용해 간단한 MCP 서버를 만들고, Keycloak이 발급한 토큰을 검증해 두 개의 도구에 대한 접근을 보호하는 방식으로 설명합니다. 중요한 점은 MCP Authorization 규격을 따르는 것만으로 끝나지 않고, 서버가 실제로 토큰 유효성 검증과 scope 검사를 수행해야 한다는 것입니다.
Authorization 헤더, 토큰, code, secret을 로그에 남기지 말 것WWW-Authenticate 챌린지를 반환할 것Mcp-Session-Id를 인증 근거로 사용하지 말 것