Logto로 MCP 기반 앱에 인증 (Authentication) 활성화
Logto의 AI 솔루션 을 살펴보세요: MCP 서버, AI 에이전트, 앱을 위한 인증 (Authentication) 및 인가 (Authorization).
이 가이드는 mcp-auth와 MCP 공식 SDK v2를 사용하여 Logto를 MCP 서버와 통합하는 방법을 안내합니다. 이를 통해 사용자를 인증하고 액세스 토큰에서 검증된 아이덴티티를 안전하게 읽을 수 있습니다.
이 가이드에서 배우게 될 내용:
- MCP 서버의 인가 (Authorization) 서버로 Logto를 구성하는 방법
- MCP 서버에 “whoami” 도구를 설정하여 현재 사용자의 클레임 (Claim)을 반환하는 방법
- VS Code (MCP 클라이언트)로 플로우를 테스트하는 방법
이 튜토리얼을 마치면 MCP 서버는 다음과 같은 기능을 갖추게 됩니다:
- Logto 테넌트에서 사용자를 인증 (Authentication)
- Logto에서 발급한 JWT 액세스 토큰 (서명, 발급자, 대상, 만료 등)을 검증
- "whoami" 도구 호출 시 검증된 아이덴티티 클레임 (
sub,iss,aud등) 반환
통합이 완료되면, VS Code 대신 웹 앱 등 자체 MCP 클라이언트로 MCP 서버가 노출하는 도구와 리소스에 접근할 수 있습니다.
이 가이드의 완전하고 실행 가능한 샘플 코드는 mcp-auth/js 저장소에서 확인할 수 있습니다:
whoami-express: 이 가이드에서 사용하는 "whoami" 서버로, Node.js와 Express 기반입니다.whoami: fetch-native(웹 표준Request/Response및 Hono)로 구축된 동일한 서버로, Cloudflare Workers에 배포할 수 있습니다.
사전 준비 사항
- Logto Cloud (또는 자체 호스팅) 테넌트
- Node.js >= 20 환경
아키텍처 이해하기
- MCP 서버: MCP 클라이언트에게 도구와 리소스를 제공하는 서버입니다. 최신 MCP 명세에 따라, Logto에서 발급한 액세스 토큰 (Access token)을 검증하는 OAuth 2.0 리소스 서버 역할을 합니다.
- MCP 클라이언트: 인증 (Authentication) 플로우를 시작하고 통합을 테스트하는 데 사용되는 클라이언트입니다. 이 가이드에서는 VS Code (내장 MCP 지원)를 클라이언트로 사용합니다.
- Logto: OpenID Connect 제공자 (인가 (Authorization) 서버)로서, 사용자 아이덴티티를 관리하고 MCP 서버를 위한 대상 (Audience) 바인딩된 JWT 액세스 토큰 (Access token)을 발급합니다.
비공식 시퀀스 다이어그램은 전체 프로세스의 흐름을 보여줍니다:
MCP가 빠르게 발전하고 있기 때문에, 위 다이어그램이 완전히 최신이 아닐 수 있습니다. 최신 정보는 mcp-auth 문서를 참고하세요.
Logto에서 앱 설정하기
MCP 클라이언트가 인가 플로우를 시작하려면 Logto에 애플리케이션으로 등록되어야 합니다. 이 가이드에서는 VS Code를 클라이언트로 등록합니다:
-
Logto 콘솔에 로그인하세요.
-
애플리케이션 → 애플리케이션 생성 → 프레임워크 없이 앱 생성으로 이동하세요.
-
유형 선택: 네이티브 앱.
-
앱 이름(예: "VS Code") 및 기타 필수 항목을 입력한 후 애플리케이션 생성을 클릭하세요.
-
설정 / 리디렉션 URI 섹션에서 VS Code용으로 아래 리디렉션 URI를 추가한 뒤 변경 사항을 저장하세요:
http://127.0.0.1https://vscode.dev/redirect -
앱 ID와 발급자 (Issuer) 엔드포인트를 저장하고 복사하세요.
MCP 서버 설정하기
MCP 공식 SDK v2와 mcp-auth를 사용하여, 현재 사용자의 아이덴티티 클레임을 반환하는 "whoami" 도구가 포함된 MCP 서버를 만들어보겠습니다.
프로젝트 생성 및 의존성 설치
mkdir mcp-server
cd mcp-server
npm init -y
npm pkg set type="module"
npm pkg set main="whoami.js"
npm pkg set scripts.start="node whoami.js"
npm install @modelcontextprotocol/server @modelcontextprotocol/express @modelcontextprotocol/node express mcp-auth
@modelcontextprotocol/server는 웹 표준Request/Response를 사용하는 MCP SDK v2의 핵심입니다.@modelcontextprotocol/express와@modelcontextprotocol/node는 이를 Node.js의 Express에 맞게 변환해줍니다.mcp-auth는 MCP SDK를 위한 토큰 검증기와 OAuth 디스커버리 메타데이터를 제공합니다.
MCP SDK v2와 mcp-auth는 ESM 전용이며 Node.js >= 20이 필요합니다.
MCP 서버를 API 리소스로 등록하기
최신 MCP 명세는 액세스 토큰이 발급된 리소스에 바인딩되어야 함을 요구합니다 (RFC 8707), 그리고 mcp-auth는 이를 강제합니다: 토큰의 aud 클레임이 MCP 서버의 리소스 식별자와 일치해야 합니다. Logto에서는 MCP 서버의 URL과 일치하는 리소스 지표를 가진 API 리소스를 생성하여 이를 수행합니다:
- Logto 콘솔에 로그인하세요.
- API 리소스 → API 리소스 생성으로 이동하세요.
- 세부 정보를 입력한 후 API 리소스 생성을 클릭하세요:
- API 이름: 예시로 "Who am I"와 같이 입력하세요.
- API 식별자:
http://localhost:3001/을 입력하세요. 이는 MCP 서버에서 설정할 리소스 식별자와 일치해야 합니다.
항상 리소스 지표 끝에 슬래시(/)를 포함하세요. MCP 공식 SDK의 현재 버그로 인해, SDK를 사용하는 클라이언트는 인증 요청을 시작할 때 리소스 식별자에 자동으로 슬래시를 추가합니다. 리소스 지표에 슬래시가 없으면 해당 클라이언트에서 리소스 검증이 실패합니다.
Logto와 함께 MCP Auth 구성하기
MCP 서버를 보호된 리소스로 선언하세요: 리소스 식별자와 신뢰하는 인가 서버를 지정합니다. <your-logto-issuer-endpoint>는 이전에 복사한 발급자 엔드포인트(애플리케이션 상세 페이지의 엔드포인트 & 자격 증명에서 확인, 예: https://my-project.logto.app/oidc)로 교체하세요.
whoami.js에서:
import { MCPAuth } from 'mcp-auth';
const authIssuer = '<your-logto-issuer-endpoint>';
const mcpAuth = new MCPAuth({
protectedResourceMetadata: {
// 리소스 식별자; Logto에 등록한 API 리소스 지표와 일치해야 함
resource: 'http://localhost:3001/',
// 이 MCP 서버가 신뢰하는 인가 서버
authorizationServer: { issuer: authIssuer, type: 'oidc' },
},
});
인가 서버 메타데이터는 처음 필요할 때 지연 로딩되어 이후 캐시됩니다. MCPAuth 인스턴스는 Logto의 JWKS를 통해 JWT 액세스 토큰을 검증합니다 — 서명, 발급자, 대상, 만료 모두 강제됩니다. 별도의 토큰 검증 코드를 작성할 필요가 없습니다.
"whoami" 도구 구현하기
이제, 검증된 액세스 토큰에서 현재 사용자의 아이덴티티 클레임을 반환하는 "whoami" 도구를 구현해봅시다. mcp-auth가 검증한 인증 정보를 툴의 콜백 컨텍스트에서 getAuthInfo로 읽어옵니다.
import { McpServer } from '@modelcontextprotocol/server';
import { getAuthInfo } from 'mcp-auth';
// MCP 서버 인스턴스를 생성하는 팩토리 함수
// 각 요청마다 별도의 서버 인스턴스를 생성하여 요청을 격리함
const createMcpServer = () => {
const mcpServer = new McpServer({
name: 'WhoAmI',
version: '0.0.0',
});
// 현재 사용자 정보를 반환하는 도구를 서버에 추가
mcpServer.registerTool(
'whoami',
{
description: '현재 사용자 정보 가져오기',
},
(context) => {
const { claims } = getAuthInfo(context);
return {
content: [{ type: 'text', text: JSON.stringify(claims) }],
};
}
);
return mcpServer;
};
서버 연결하기
마지막으로, MCP 클라이언트가 인가 서버를 찾을 수 있도록 OAuth 디스커버리 문서(RFC 9728 / RFC 8414)를 제공하고, SDK의 Bearer 인증 미들웨어로 MCP 엔드포인트를 보호하세요.
import {
createMcpExpressApp,
mcpAuthMetadataRouter,
requireBearerAuth,
} from '@modelcontextprotocol/express';
import { toNodeHandler } from '@modelcontextprotocol/node';
import { createMcpHandler } from '@modelcontextprotocol/server';
const PORT = 3001;
// MCP 핸들러는 웹 표준 Request / Response를 사용하며, `toNodeHandler`가 이를 Express에 맞게 변환합니다
const mcpNodeHandler = toNodeHandler(createMcpHandler(createMcpServer));
const app = createMcpExpressApp();
// OAuth 디스커버리 문서(`/.well-known/...`)를 제공하며, 기본적으로 공개되어 있습니다
app.use(mcpAuthMetadataRouter(await mcpAuth.getAuthMetadataOptions()));
app.all(
'/',
// 유효한 Bearer 토큰이 필요합니다; 검증된 인증 정보는 `req.auth`를 통해 핸들러로 전달됩니다
requireBearerAuth(mcpAuth.getBearerAuthOptions()),
// `createMcpExpressApp`은 `express.json()`을 적용하여 요청 스트림을 소진하므로,
// 파싱된 body를 명시적으로 전달합니다
async (request, response) => mcpNodeHandler(request, response, request.body)
);
app.listen(PORT);
서버를 실행하려면:
npm start
통합 테스트하기
-
MCP 서버를 시작하세요:
npm start -
VS Code를 MCP 서버에 연결하세요:
Command + Shift + P(macOS) 또는Ctrl + Shift + P(Windows / Linux)를 눌러 커맨드 팔레트를 엽니다.MCP: Add Server...를 입력하고 선택하세요.- 서버 유형으로
HTTP를 선택하세요. - MCP 서버 URL을 입력하세요:
http://localhost:3001/ - OAuth 플로우가 시작되면, VS Code에서 Client ID를 입력하라는 메시지가 표시됩니다. 앞서 복사한 앱 ID를 붙여넣으세요.
- 앱 시크릿이 없는 공개 클라이언트이므로, 엔터를 눌러 시크릿 입력을 건너뜁니다.
- 브라우저에서 로그인 플로우를 완료하세요.
-
로그인 후, VS Code에서
whoami도구를 실행하세요.
액세스 토큰에서 검증된 클레임 (Claim)이 아래와 같이 표시되어야 합니다:
{
"iss": "https://my-project.logto.app/oidc",
"sub": "user_XXXX",
"aud": "http://localhost:3001/",
"client_id": "<your-app-id>"
}
추가 참고 자료
이제 MCP 서버가 인바운드 액세스 토큰을 검증합니다. 다음 단계로, 토큰 패스스루 없이 사용자 컨텍스트를 유지하며 사용자를 대신해 다운스트림 비즈니스 API를 안전하게 호출하는 방법을 알아보세요:
MCP 서버가 사용자를 대신해 API를 호출하는 방법: 프로덕션 토큰 전략