my-mcp-server
TypeScript MCP Server 보일러플레이트 (Vercel 배포용)
Model Context Protocol (MCP) 서버를 TypeScript로 개발하고 Vercel에 배포할 수 있는 보일러플레이트입니다.
Next.js App Router 위에서 mcp-handler로 Streamable HTTP 전송을 제공하며, 로컬 개발용 stdio 진입점도 함께 유지합니다.
📁 프로젝트 구조
typescript-mcp-server-boilerplate/
├── src/
│ ├── mcp/
│ │ └── tools.ts # tool / resource / prompt 등록 (HTTP·stdio 공용)
│ ├── stdio.ts # 로컬 stdio 진입점
│ └── app/
│ ├── api/mcp/route.ts # Streamable HTTP 엔드포인트
│ ├── layout.tsx
│ └── page.tsx # 엔드포인트 안내 랜딩 페이지
├── build/ # stdio 빌드 결과물 (build:stdio 실행 시 생성)
├── next.config.ts
├── tsconfig.json # Next.js용
├── tsconfig.stdio.json # stdio 빌드 전용
└── .env.example🚀 시작하기
1. 의존성 설치
npm install2. 환경변수 설정
cp .env.example .env.local.env.local에 HuggingFace 액세스 토큰을 넣습니다. HTTP로 연결할 때는 클라이언트가 x-hf-token 헤더로 토큰을 보낼 수 있으므로 이 값은 선택 사항(폴백)입니다.
3. 개발 서버 실행
npm run devMCP 엔드포인트: http://localhost:3000/api/mcp
4. MCP Inspector로 테스트
npx @modelcontextprotocol/inspector인스펙터에서 전송 방식을 Streamable HTTP로 선택하고 위 URL을 입력합니다. generate-image를 테스트하려면 Headers에 x-hf-token을 추가하세요.
🔑 HF_TOKEN 주입 방식
generate-image 도구만 HuggingFace 토큰이 필요합니다. 토큰은 다음 우선순위로 결정됩니다.
요청의
x-hf-token헤더 (클라이언트가 자기 토큰을 사용)서버의
HF_TOKEN환경변수 (헤더가 없을 때 폴백)
createMcpHandler는 tool 핸들러에 원본 요청 헤더를 노출하지 않기 때문에, 요청마다 핸들러를 생성해 헤더 값을 등록 클로저로 전달합니다.
// src/app/api/mcp/route.ts
const handler = async (request: Request) => {
const hfToken = request.headers.get('x-hf-token') ?? process.env.HF_TOKEN
return createMcpHandler(
(server) => registerAll(server, { hfToken, transport: 'http' }),
{ serverInfo: SERVER_INFO }
)(request)
}
export { handler as GET, handler as POST }🔧 MCP 클라이언트 연결
로컬 개발 서버
./.cursor/mcp.json:
{
"mcpServers": {
"my-mcp-server": {
"url": "http://localhost:3000/api/mcp",
"headers": {
"x-hf-token": "hf_xxxxxxxxxxxxxxxxxxxx"
}
}
}
}배포된 서버
{
"mcpServers": {
"my-mcp-server": {
"url": "https://<your-app>.vercel.app/api/mcp",
"headers": {
"x-hf-token": "hf_xxxxxxxxxxxxxxxxxxxx"
}
}
}
}주의:
.cursor/mcp.json은 git에 추적되는 파일입니다. 실제 토큰을 커밋하지 않도록 주의하세요.
Streamable HTTP를 지원하지 않는 stdio 전용 클라이언트는 mcp-remote로 연결할 수 있습니다.
{
"mcpServers": {
"my-mcp-server": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"https://<your-app>.vercel.app/api/mcp",
"--header",
"x-hf-token:hf_xxxxxxxxxxxxxxxxxxxx"
]
}
}
}☁️ Vercel 배포
npx vercel또는 GitHub 저장소를 Vercel 프로젝트에 연결하면 됩니다. 추가 설정 없이 /api/mcp 라우트가 Vercel Function으로 배포됩니다.
클라이언트가 항상
x-hf-token을 보낸다면 서버 환경변수는 필요 없습니다.폴백을 두려면 Vercel 프로젝트 Settings → Environment Variables에
HF_TOKEN을 추가하세요.이미지 생성은 시간이 걸리므로 라우트에
maxDuration = 60을 지정해 두었습니다.Vercel Function의 응답 크기 제한(4.5MB)이 있으므로
num_inference_steps를 과도하게 올리지 마세요.
🖥️ stdio로 실행하기
HTTP 없이 기존처럼 로컬 프로세스로 붙이려면:
npm run build:stdio
node build/stdio.js{
"mcpServers": {
"my-mcp-server": {
"command": "node",
"args": ["/ABSOLUTE/PATH/TO/YOUR/PROJECT/build/stdio.js"],
"env": {
"HF_TOKEN": "hf_xxxxxxxxxxxxxxxxxxxx"
}
}
}
}이 경우 헤더를 쓸 수 없으므로 HF_TOKEN 환경변수가 유일한 토큰 출처입니다.
🛠️ 개발 가이드
모든 tool / resource / prompt는 src/mcp/tools.ts의 registerAll() 안에서 등록합니다. HTTP 라우트와 stdio 진입점이 같은 함수를 호출하므로 한 곳만 수정하면 양쪽에 반영됩니다.
Tool 추가하기
inputSchema에는 raw shape이 아니라 z.object()로 감싼 스키마를 넘깁니다 (MCP SDK v2 방식).
server.registerTool(
'reverse-text',
{
description: '입력한 문자열을 뒤집어 반환합니다.',
inputSchema: z.object({
text: z.string().min(1).describe('뒤집을 문자열')
}),
outputSchema: textOutputSchema
},
async ({ text }) => textResult([...text].reverse().join(''))
)외부 비밀값이 필요한 Tool
registerAll(server, options)의 options로 값을 받아 클로저에서 사용하면, HTTP에서는 요청 헤더로 stdio에서는 환경변수로 주입할 수 있습니다.
export type RegisterOptions = {
hfToken?: string
transport?: 'stdio' | 'http'
}Resource 추가하기
server.registerResource(
'app-settings',
'config://settings',
{
title: '애플리케이션 설정',
description: '애플리케이션의 현재 설정 정보',
mimeType: 'application/json'
},
async (uri) => ({
contents: [
{
uri: uri.href,
mimeType: 'application/json',
text: JSON.stringify({ theme: 'dark' }, null, 2)
}
]
})
)🧰 제공 도구
이름 | 설명 |
| 이름과 언어로 인사말 반환 |
| 두 숫자와 연산자로 사칙연산 |
| 타임존별 현재 시간 |
| 도시명을 위도/경도로 변환 (Open-Meteo) |
| 좌표로 현재 날씨 및 예보 (Open-Meteo) |
| 프롬프트로 이미지 생성 (HuggingFace FLUX.1-schnell) |
Resource server://info, Prompt code-review도 함께 제공합니다.
📦 주요 의존성
@modelcontextprotocol/server: MCP TypeScript SDK v2
mcp-handler: MCP 서버를 웹 표준 HTTP 핸들러로 변환
next / react / react-dom: App Router 기반 호스팅
zod: 스키마 검증
@huggingface/inference: HuggingFace Inference API 클라이언트
🔧 스크립트
스크립트 | 설명 |
| Next.js 개발 서버 실행 |
| Next.js 프로덕션 빌드 |
| 프로덕션 서버 실행 |
| stdio 서버를 |
| 컴파일된 stdio 서버 실행 |
| HTTP·stdio 양쪽 타입 검사 |
🔗 참고 자료
📄 라이선스
MIT