메인 콘텐츠로 건너뛰기

(naptha) OAuth 기반 Streamable HTTP MCP 서버 이해와 활용

요약

MCP 서버란 무엇인가요?

MCP 서버는 AI 에이전트, 앱 등이 통신에 사용할 수 있는 프로토콜 서버로, 기존 HTTP와 서버-센트 이벤트(SSE) 방식 모두를 지원합니다. 특히, OAuth 인증 기능까지 확장된 최신 MCP 명세를 준수하므로 보안성과 확장성이 높습니다.

왜 OAuth 기반 MCP 서버를 개발해야 할까요?

최근 MCP 명세에 OAuth 인증 확장이 공식 추가되어, 안전하게 클라이언트와 통신하려면 OAuth 기반 인증 서버가 필요합니다. TypeScript SDK엔 일부 관련 기능이 있지만, 문서나 예제, 완성된 서버 구현이 부족해 직접 개발할 필요성이 커졌습니다. Python SDK는 아예 Streamable HTTP나 OAuth 기능 구현이 없습니다.

bun 런타임을 사용하는 이유

이 레포지토리는 Bun이라는 빠르고 편리한 JavaScript 런타임을 권장합니다. Bun은 빌드, 패키지 관리, 실행까지 한 번에 지원해 코드 관리가 쉽습니다. npm 및 TypeScript 컴파일러(tsc) 일부 호환성도 확인됐지만, Bun을 이용하는 게 가장 원활합니다.

서버 구성 방식: 무상태와 유상태 서버

  • 무상태(Streamable HTTP만 지원): src/app.stateless.ts 서버리스 등에 적합하지만 SSE 미지원

  • 유상태(Streamable HTTP + SSE 지원): src/app.stateful.ts 인메모리 상태를 유지하며, 수평 확장이나 서버리스와는 맞지 않습니다.

운영 시 명령어 예시는 다음과 같습니다:

bun run src/app.stateless.ts

혹은

bun run src/app.stateful.ts

OAuth 인증 서버 설정: Auth0 활용

클라이언트가 MCP 서버에 자동 등록할 수 있으려면 RFC7591 'Dynamic Client Registration' 지원이 필수입니다. 구글, 깃허브 등은 직접 지원하지 않아 Auth0 같은 전문 서비스가 필요합니다. Auth0에 계정을 만들고, Google/GitHub 등의 IDP를 연결하고, 'Dynamic Application Registration'을 활성화하세요. 다음 정보를 .env 파일에 반드시 입력해야 합니다.

  • Auth0 클라이언트 ID

  • Auth0 클라이언트 비밀키

  • Auth0 테넌트 도메인

.env.template 파일을 복사해 직접 입력합니다.

인증 서버 프록시, 토큰 처리 방법

중간 서버가 Auth0로 인증을 프록시하면서, MCP 클라이언트에 사용자의 원본 OAuth 토큰을 직접 전달하지 않습니다. 대신 자체 토큰을 발행해, 보안 위험(토큰 유출 등)을 줄입니다.

MCP 서버 활용 예시: 클라이언트 연결

기존 MCP 호스트(예: Cursor, Claude 데스크톱)는 Streamable HTTP와 OAuth를 완벽하게 지원하지 않습니다. npm 패키지(mcp-remote)를 활용해 MCP 서버와 통신할 수 있습니다. 커맨드 예시:

bunx mcp-remote --transport http-first https://some-domain.server.com/mcp

옵션:

  • http-first: HTTP 우선, 실패 시 SSE로 대체

  • sse-first: SSE 우선, 실패 시 HTTP로 대체

  • http-only: HTTP만 사용

  • sse-only: SSE만 사용

무상태 서버(src/app.stateless.ts)는 SSE 지원 X → http-only 사용 필수

JavaScript/TypeScript 에이전트에서 직접 연동하는 방법

OAuth 보호 서버와 연동하려면 Authorization 헤더에 유효한 토큰을 포함해야 합니다. 아래는 예시 코드입니다:

import { openai } from '@ai-sdk/openai';
import { experimental_createMCPClient as createMcpClient } from 'ai';
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";

const mcpClient = await createMcpClient({
  transport: new StreamableHTTPClientTransport(
    new URL("http://localhost:5050/mcp"), {
      requestInit: { headers: { Authorization: "Bearer YOUR TOKEN HERE" } },
      authProvider: undefined // 필요 시 구현
    }
  )
});

const tools = await mcpClient.tools();
// 실제 사용 예
await generateText({
  model: openai("gpt-4o"),
  prompt: "Hello, world!",
  tools: { ...(await mcpClient.tools()) }
});

추천 활용법 및 주의점

시연용, PoC, 신규 서비스 개발 시 이 레포를 포크해 바로 자신만의 MCP 서버를 구축할 수 있습니다. 반드시 사설 OAuth 서버(권장: Auth0)와 연동해, 클라이언트 자동 등록(Dynamic Client Registration)까지 챙기세요. 서버 구동, 설정파일(.env 등), 인증 프록시 방식 모두 익숙해지면 다양한 협업 툴, 에이전트, 커스텀 서비스에 쉽게 확장할 수 있습니다.

참고 리소스 및 주요 레이어

  • 레포 코드/문서: TypeScript 위주로 작성

  • 라이선스: MIT (자유로운 재사용 가능)

  • 확장/개발: 서버 구조, 인증 방식, 클라이언트 모델 자유롭게 커스터마이즈

혁신적인 AI 서비스나 기초 인프라 구축에 필요한 핵심 디자인 패턴, 인증/보안 이슈까지 한 번에 배울 수 있는 최신 참고 구현이라 할 수 있습니다.

출처 및 참고 : NapthaAI/http-oauth-mcp-server: Remote MCP server (SEE + Streamable HTTP) implementing the MCP spec's authorization extension. Use directly from your agents, or from Cursor / Claude with mcp-remote