TypeScript MCP Server Boilerplate
by kimhailey
README.md
# my-mcp-server (Vercel · Streamable HTTP)
Next.js App Router 와 [`mcp-handler`](https://github.com/vercel/mcp-handler) 위에서
동작하는 **Vercel 배포형 MCP 서버**입니다. 기존 `StdioServerTransport` 기반 로컬
서버를 Streamable HTTP 트랜스포트로 이전하여 임의의 MCP 클라이언트(Cursor,
Claude Desktop, MCP Inspector 등) 에서 원격으로 호출할 수 있습니다.
## 아키텍처
```
MCP Client (Cursor / Inspector)
│ Streamable HTTP
│ + x-hf-token header (선택)
▼
Next.js App Router (on Vercel)
app/api/[transport]/route.ts
│
▼
createMcpHandler ─► McpServer
├─ tools: greet / calculate / time / geocode / weather / generate-image
├─ prompts: code-review
└─ resources: server-info
```
`[transport]` 동적 세그먼트를 사용해 매 요청마다 핸들러를 새로 만들고, 요청 헤더
(`x-hf-token`) 와 환경변수(`HF_TOKEN`) 를 클로저로 캡처해 `generate-image` 도구에
전달합니다.
## 프로젝트 구조
```
.
├── app/
│ ├── api/
│ │ └── [transport]/
│ │ └── route.ts # MCP HTTP 엔드포인트
│ ├── layout.tsx
│ └── page.tsx # 안내용 정적 페이지
├── next.config.mjs
├── next-env.d.ts
├── package.json
├── tsconfig.json
└── .env.example
```
## 빠른 시작
### 1. 의존성 설치
```bash
npm install
```
### 2. 환경변수 설정 (선택)
`generate-image` 도구를 사용할 계획이라면 `.env.example` 을 `.env.local` 로 복사한
뒤 HuggingFace 토큰을 채워 넣습니다.
```bash
cp .env.example .env.local
# 그리고 HF_TOKEN=hf_xxx... 로 수정
```
> 환경변수가 없어도 클라이언트가 매 요청마다 `x-hf-token` 헤더를 보내면 동작합니다.
### 3. 로컬 실행
```bash
npm run dev
```
기본 엔드포인트:
- 안내 페이지: <http://localhost:3000>
- MCP Streamable HTTP: <http://localhost:3000/api/mcp>
### 4. MCP Inspector 로 검증
```bash
npx @modelcontextprotocol/inspector@latest
```
Inspector UI 에서:
1. Transport: **Streamable HTTP**
2. URL: `http://localhost:3000/api/mcp`
3. (선택) Custom Headers 에 `x-hf-token: hf_xxx...` 추가
4. **Connect** → **List Tools** → 각 도구 호출 테스트
## 클라이언트 연결
### Cursor (`./.cursor/mcp.json`)
```json
{
"mcpServers": {
"my-mcp-server": {
"url": "https://<your-app>.vercel.app/api/mcp",
"headers": {
"x-hf-token": "hf_xxx..."
}
}
}
}
```
`url` 만 있으면 5개 도구(`greet`/`calculate`/`time`/`geocode`/`weather`)는 정상
동작합니다. `generate-image` 를 사용하려면 `headers.x-hf-token` 또는 서버측
`HF_TOKEN` 환경변수 중 하나가 반드시 필요합니다.
### Streamable HTTP 미지원 클라이언트 (`mcp-remote` 브릿지)
```json
{
"mcpServers": {
"my-mcp-server": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"https://<your-app>.vercel.app/api/mcp",
"--header",
"x-hf-token:hf_xxx..."
]
}
}
}
```
## Vercel 배포
### 방법 1: Vercel CLI
```bash
npm i -g vercel
vercel
```
### 방법 2: GitHub 연동
1. GitHub 저장소에 푸시
2. <https://vercel.com/new> 에서 저장소 선택
3. Framework Preset: **Next.js** (자동 감지)
4. **Environment Variables** 에서 (선택) `HF_TOKEN` 추가
5. **Deploy**
배포가 완료되면 `https://<your-app>.vercel.app/api/mcp` 가 MCP 엔드포인트입니다.
## 등록된 도구
| 이름 | 설명 |
| ---------------- | --------------------------------------------------------------------- |
| `greet` | 이름과 언어(ko/en)로 인사말 생성 |
| `calculate` | 두 숫자 사칙연산 (add/subtract/multiply/divide) |
| `time` | 타임존별 현재 시간 |
| `geocode` | Open-Meteo 로 도시명 → 위경도 조회 |
| `weather` | Open-Meteo 로 위경도 → 현재 날씨 조회 |
| `generate-image` | HuggingFace FLUX.1-schnell 이미지 생성 (`x-hf-token` 또는 `HF_TOKEN`) |
## 프롬프트 / 리소스
- 프롬프트 `code-review`: 코드를 입력받아 시니어 엔지니어 관점의 체계적 리뷰 메시지 생성
- 리소스 `server-info` (`mcp://my-mcp-server/info`): 서버 메타데이터(JSON)
## HF_TOKEN 처리 정책
```
x-hf-token 헤더 ──(있으면 사용)──► HuggingFace Inference
│ (없음)
▼
HF_TOKEN 환경변수 ──(있으면 사용)──► HuggingFace Inference
│ (없음)
▼
generate-image 도구가 명확한 에러 메시지 반환
```
헤더가 우선이므로 동일 배포 인스턴스를 여러 사용자가 각자의 토큰으로 사용할 수
있습니다.
## 스크립트
- `npm run dev`: 로컬 개발 서버
- `npm run build`: 프로덕션 빌드
- `npm run start`: 빌드 결과 실행
- `npm run lint`: Next.js lint
## 참고 자료
- [Deploy MCP servers to Vercel](https://vercel.com/docs/mcp/deploy-mcp-servers-to-vercel)
- [vercel/mcp-handler](https://github.com/vercel/mcp-handler)
- [Model Context Protocol 공식 문서](https://modelcontextprotocol.io/)
- [MCP TypeScript SDK](https://github.com/modelcontextprotocol/typescript-sdk)
## 라이선스
MIT
TDQS
A3.6/5.0
Scored across 6 tools
Disambiguation5/5
Each tool has a clearly distinct purpose (arithmetic, image generation, geocoding, greeting, time, weather), with no overlap or ambiguity in their intended use.
Naming Consistency4/5
Most tool names are single-word verbs (calculate, geocode, greet, time, weather), with one hyphenated compound (generate-image). This is mostly consistent but the hyphenated name is a minor deviation.
Tool Count4/5
With 6 tools, the count is reasonable for a boilerplate example server. It is neither too sparse nor overly heavy for illustrating various capabilities.
Completeness3/5
As a boilerplate, the tool set does not target a specific domain, so completeness is inherently neutral. The tools cover basic utility examples but lack any overarching purpose or desired workflow.
Maintenance
ActivityInactive
ResponsivenessNo issues