MCP 서버에 서드파티 AI 에이전트 접근 허용
Logto의 AI 솔루션 을 살펴보세요: MCP 서버, AI 에이전트, 앱을 위한 인증 (Authentication) 및 인가 (Authorization).
이 가이드에서는 mcp-auth 및 MCP 공식 SDK v2를 사용하여 Logto를 MCP 서버와 통합하는 방법을 안내합니다. 이를 통해 서드파티 AI 에이전트가 사용자의 동의 하에 인증을 받고, 안전하게 MCP 서버에 접근할 수 있습니다.
다음 내용을 학습하게 됩니다:
- MCP 서버의 인가 (Authorization) 서버로 Logto를 구성하는 방법
- 서드파티 AI 에이전트 온보딩: 서드파티 앱을 등록하거나, 동적 앱을 활성화하여 사전 등록 없이 어떤 에이전트도 연결할 수 있도록 설정
- MCP 서버에 “whoami” 도구를 설정하여 현재 사용자의 아이덴티티 클레임 (Claim)을 반환
- 서드파티 AI 에이전트 (MCP 클라이언트)로 플로우 테스트
이 튜토리얼을 마치면, MCP 서버는 다음과 같이 동작합니다:
- Logto 테넌트에서 사용자를 인증 (Authentication)하며, 서드파티 AI 에이전트에 대한 사용자 동의를 받음
- Logto가 발급한 JWT 액세스 토큰 (Access token)의 서명, 발급자 (Issuer), 대상 (Audience), 만료를 검증
- "whoami" 도구 호출 시 검증된 아이덴티티 클레임 (
sub,iss,aud등)을 반환
이 가이드의 완전하고 실행 가능한 샘플 코드는 mcp-auth/js 저장소에서 확인할 수 있습니다:
whoami-express: 이 가이드에서 사용하는 "whoami" 서버로, Node.js와 Express 기반입니다.whoami: fetch-native(웹 표준Request/Response및 Hono)로 구축된 동일한 서버로, Cloudflare Workers에 배포할 수 있습니다.
서드파티 AI 에이전트 (MCP 클라이언트)와 자체 MCP 클라이언트의 차이점
예시를 통해 살펴보겠습니다. 여러분이 이메일 접근 및 자동화를 관리하는 MCP 서버를 운영하는 개발자라고 가정해봅시다.
공식 이메일 앱 (자체 MCP 클라이언트)
- 사용자가 이메일을 읽고 관리할 수 있도록 공식 이메일 앱을 제공합니다.
- 동작 방식: 공식 이메일 앱은 Logto를 통해 사용자를 인증 (Authentication)하여 MCP 서버에 연결합니다. Alice가 로그인하면, 신뢰된 앱이므로 별도의 권한 (Permission) 화면 없이 자동으로 이메일에 접근할 수 있습니다.
서드파티 AI 에이전트 (서드파티 MCP 클라이언트)
- MCP 서버를 중심으로 생태계를 구축하고자, 다른 개발자가 “SmartMail AI” (이메일 요약 및 미팅 자동 예약이 가능한 AI 어시스턴트)를 서드파티 클라이언트로 통합합니다.
- 동작 방식: SmartMail AI (서드파티 MCP 클라이언트)는 사용자 이메일에 접근하고자 합니다. Alice가 자신의 계정으로 SmartMail AI에 로그인하면:
- SmartMail AI가 이메일 및 캘린더 접근 권한을 요청하는 동의 화면 (Consent screen)이 표시됩니다.
- Alice는 이 접근을 허용하거나 거부할 수 있습니다.
- Alice가 동의한 데이터만 SmartMail AI에 공유되며, 추가 데이터 접근은 명시적 재동의 없이는 불가합니다.
이러한 접근 (Permission) 제어는 사용자 데이터의 안전을 보장합니다. MCP 서버가 모든 데이터를 관리하더라도, SmartMail AI와 같은 서드파티 앱은 사용자가 명시적으로 허용한 데이터에만 접근할 수 있습니다. 이 과정은 MCP 서버의 접근 제어 구현에 의해 강제되므로 우회할 수 없습니다.
요약
| 클라이언트 유형 | 예시 | 동의 필요 여부 | 제어 주체 |
|---|---|---|---|
| 공식 이메일 앱 | 자체 이메일 애플리케이션 | 아니오 | 여러분 (개발자) |
| 서드파티 AI 에이전트 | SmartMail AI 어시스턴트 | 예 | 다른 개발자 |
자체 AI 에이전트 또는 앱과 MCP 서버를 통합하고 싶다면, Logto로 MCP 기반 앱에 인증 (Authentication) 활성화 가이드를 참고하세요.
사전 준비 사항
- Logto Cloud (또는 자체 호스팅) 테넌트
- Node.js >= 20 환경
아키텍처 이해하기
- MCP 서버: MCP 클라이언트에게 도구와 리소스를 제공하는 서버입니다. 최신 MCP 명세에 따라, Logto에서 발급한 액세스 토큰 (Access token)을 검증하는 OAuth 2.0 리소스 서버 역할을 합니다.
- MCP 클라이언트: 인증 (Authentication) 플로우를 시작하고 통합을 테스트하는 데 사용되는 클라이언트입니다. 이 가이드에서는 서드파티 AI 에이전트를 클라이언트로 사용합니다.
- Logto: OpenID Connect 제공자 (인가 (Authorization) 서버)로서, 사용자 아이덴티티를 관리하고 MCP 서버를 위한 대상 (Audience) 바인딩된 JWT 액세스 토큰 (Access token)을 발급합니다.
비공식 시퀀스 다이어그램은 전체 프로세스의 흐름을 보여줍니다:
MCP가 빠르게 발전하고 있기 때문에, 위 다이어그램이 완전히 최신이 아닐 수 있습니다. 최신 정보는 mcp-auth 문서를 참고하세요.
Logto에서 서드파티 AI 에이전트 구성하기
서드파티 AI 에이전트가 MCP 서버에 접근할 수 있도록 하려면, Logto에서 서드파티 앱을 설정해야 합니다. 이 앱은 AI 에이전트를 대표하며, 인증 (Authentication) 및 인가 (Authorization)에 필요한 자격 증명을 획득하는 데 사용됩니다.
서드파티 앱은 외부 개발자(리소스 소유자가 아님)가 만든 애플리케이션으로, 보호된 리소스에 접근하기 위해 사용자 동의가 필요합니다. 퍼스트파티 앱(자체 애플리케이션)과 달리, 서드파티 앱은 사용자의 데이터에 접근하기 전에 특정 권한을 승인하도록 요청하는 동의 화면을 표시합니다. 이를 통해 사용자는 외부 서비스와 어떤 데이터를 공유할지 직접 제어할 수 있습니다.
자세한 내용은 서드파티 애플리케이션을 참고하세요.
AI 에이전트를 온보딩하는 방법은 세 가지가 있습니다:
- 콘솔에서 수동으로 앱 생성: 테스트 또는 소수의 알려진 에이전트용.
- Management API로 등록 서비스 구축: 자격 증명 발급 대상을 직접 제어하고 싶을 때.
- 동적 앱 활성화: 사전 등록 없이 어떤 에이전트든 연결할 수 있도록 할 때.
개발자가 Logto에서 서드파티 앱을 생성할 수 있도록 허용하기
마켓플레이스를 구축하거나 개발자가 Logto에서 서드파티 앱을 생성할 수 있도록 하려면, Logto Management API를 활용하여 프로그래밍 방식으로 서드파티 앱을 생성할 수 있습니다. 이를 통해 개발자는 자신의 애플리케이션을 등록하고 인증 (Authentication)에 필요한 자격 증명을 획득할 수 있습니다.
클라이언트 등록 프로세스를 처리할 자체 서비스를 호스팅해야 합니다. 이 서비스는 Logto Management API와 상호작용하여 개발자를 대신해 서드파티 앱을 생성합니다.
또는, Logto 콘솔에서 직접 서드파티 앱을 수동으로 생성하여 프로세스를 익힐 수도 있습니다.
사전 등록 없이 어떤 AI 에이전트든 연결 허용하기
오픈 MCP 생태계에서는 사전에 에이전트를 알 수 없는 경우가 많습니다. 동적 앱은 등록 단계를 제거합니다: 에이전트는 자신의 클라이언트 메타데이터 문서를 제공하는 공개 HTTPS URL을 client_id로 사용하고, Logto는 인가 (Authorization) 요청이 도착하면 이를 해석합니다.
여전히 동적 앱에 부여된 권한을 통해 에이전트가 요청할 수 있는 범위를 제어할 수 있으며, 모든 인가 (Authorization)는 사용자 동의 화면을 거칩니다.
Logto에서 서드파티 앱을 수동으로 생성하기
테스트 목적이나 임시 통합을 위해 Logto 콘솔에서 서드파티 앱을 수동으로 생성할 수 있습니다. 전체 클라이언트 등록 플로우를 구현하지 않고 빠르게 통합을 테스트하고 싶을 때 유용합니다.
-
Logto 콘솔에 로그인하세요.
-
애플리케이션 → 애플리케이션 생성 → 서드파티 앱 -> OIDC를 선택하세요.
-
앱 이름 및 기타 필수 항목을 입력한 후 애플리케이션 생성을 클릭하세요.
-
권한 탭을 클릭하여 앱에 권한을 부여하세요:
- 사용자 섹션:
profile,email등 기본 아이덴티티 클레임을 위한 사용자 데이터 권한. - API 리소스 섹션: Logto에서 정의한 API 리소스의 권한(스코프), 예: 귀하의 MCP 서버를 대표하는 API 리소스.
- 조직 섹션: Logto 조직을 사용하는 경우 조직 권한.
- 사용자 섹션:
-
서드파티 앱에서 요청할 권한(스코프)을 설정하세요. 예:
openid profile email및 API 리소스 스코프.참고: OIDC를 위해서는
openid가 필수입니다. API 리소스에 바인딩된 액세스 토큰 (Access token)을 받으려면, 인가 (Authorization) 요청에resource파라미터도 포함해야 합니다. 최신 MCP 사양을 따르는 MCP 클라이언트는 보호된 리소스 메타데이터에 따라 이를 자동으로 처리합니다. -
서드파티 애플리케이션의 리디렉션 URI를 적절히 설정하세요. Logto에서도 리디렉션 URI를 반드시 업데이트해야 합니다.
내부적으로, 서드파티 앱은 표준 OAuth 2.0 / OIDC 클라이언트입니다. 이는 여러분(또는 서드파티 개발자)이 어떤 OAuth 2.0 / OIDC 라이브러리나 프레임워크도 사용하여 Logto와 통합할 수 있음을 의미합니다.
유의해야 할 몇 가지 사항:
- 서드파티 앱을 생성할 때, 앱의 아키텍처에 따라 적절한 애플리케이션 유형을 선택하세요:
- 전통적인 웹: 인증을 위해 클라이언트 시크릿을 사용합니다.
- 싱글 페이지 앱 / 네이티브: 클라이언트 시크릿 없이 PKCE를 사용하여 안전하게 인가합니다.
- 대부분의 빠른 시작 가이드는 퍼스트파티 앱을 대상으로 작성되어 있지만, 서드파티 앱 통합 시에도 참고 자료로 사용할 수 있습니다.
- 주요 차이점은 서드파티 앱에서는 동의 화면 (Consent screen)이 표시되어, 사용자의 데이터 접근에 대해 명시적인 허가를 요청한다는 점입니다.
전체 통합 가이드는 서드파티 애플리케이션에서 확인하세요.
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 서버를 시작합니다.
- 서드파티 AI 에이전트를 MCP 서버에 연결하고
whoami도구를 호출합니다. - 에이전트는 401 Unauthorized 응답을 받고, MCP 서버의 보호된 리소스 메타데이터를 통해 Logto를 발견하여 사용자를 Logto로 리디렉션하여 인증 (Authentication)을 진행합니다.
- 사용자는 로그인 후, 에이전트가 요청한 권한 (Permission)이 나열된 동의 화면 (Consent screen)을 검토하고 접근을 승인 (또는 거부)합니다.
- 에이전트는 대상 (Audience)에 바인딩된 JWT 액세스 토큰 (Access token)을 받아 도구를 다시 호출합니다.
- MCP 서버는 Logto의 JWKS로 액세스 토큰을 검증하고, 검증된 아이덴티티 클레임 (Claim)을 에이전트에 반환합니다.
추가 참고 자료
이제 MCP 서버는 서드파티 AI 에이전트로부터 들어오는 액세스 토큰 (Access token)을 검증합니다. 다음 단계로, 토큰 패스스루 없이 사용자 컨텍스트를 유지하며, 사용자를 대신해 다운스트림 비즈니스 API를 안전하게 호출하는 방법을 알아보세요:
MCP 서버가 사용자를 대신해 API를 호출하는 방법: 프로덕션 토큰 전략