seunghui-mcp-server
README.md
# TypeScript MCP Server (Vercel 배포용)
Model Context Protocol (MCP) 서버 보일러플레이트입니다. Next.js App Router 위에서
[`mcp-handler`](https://github.com/vercel/mcp-handler)로 **Streamable HTTP** 엔드포인트를
제공하며, 같은 도구 정의를 재사용하는 **stdio** 진입점도 함께 유지합니다.
- HTTP 엔드포인트: `POST /api/mcp`
- stdio 진입점: `src/mcp/stdio.ts`
- 이미지 생성 토큰: `x-hf-token` 요청 헤더 우선, 없으면 `HF_TOKEN` 환경변수로 폴백
## 📁 프로젝트 구조
```
├── app/
│ ├── api/mcp/route.ts # Streamable HTTP 엔드포인트
│ ├── layout.tsx # 루트 레이아웃
│ ├── page.tsx # 서버 안내 페이지
│ └── globals.css
├── src/mcp/
│ ├── metadata.ts # 서버 이름/버전, 헤더 이름, 기능 목록 (단일 출처)
│ ├── server.ts # registerAll() - 도구/리소스/프롬프트 등록
│ └── stdio.ts # stdio 진입점
├── next.config.ts
├── tsconfig.json
└── .env.example
```
`app/api/mcp/route.ts`와 `src/mcp/stdio.ts`는 둘 다 `registerAll()`을 호출하므로
도구를 한 번만 정의하면 두 트랜스포트가 함께 갱신됩니다.
## 🚀 시작하기
```bash
npm install
npm run dev
```
`http://localhost:3000`에서 안내 페이지를, `http://localhost:3000/api/mcp`에서
MCP 엔드포인트를 확인할 수 있습니다.
### 스크립트
| 명령 | 설명 |
| ------------------- | ------------------------------------------ |
| `npm run dev` | Next.js 개발 서버 |
| `npm run build` | 프로덕션 빌드 |
| `npm run start` | 빌드 결과 실행 |
| `npm run stdio` | stdio 트랜스포트로 MCP 서버 실행 (tsx) |
| `npm run typecheck` | 타입 검사 |
## 🔑 HF_TOKEN 전달 방식
`generate-image` 도구는 HuggingFace Inference API를 사용합니다. 토큰은 다음 순서로 찾습니다.
1. 요청의 `x-hf-token` 헤더 (HTTP 트랜스포트)
2. 서버의 `HF_TOKEN` 환경변수
헤더를 쓰면 클라이언트마다 자기 토큰을 사용할 수 있어 서버에 비밀값을 두지 않아도 됩니다.
stdio로 실행할 때는 HTTP 요청이 없으므로 항상 `HF_TOKEN` 환경변수를 사용합니다.
구현은 `src/mcp/server.ts`의 `resolveHfToken()`에 있으며, MCP SDK v2가 도구 콜백의
두 번째 인자로 넘겨주는 컨텍스트에서 원본 `Request`를 꺼내 씁니다.
```ts
const resolveHfToken = (ctx: ServerContext): string | undefined =>
ctx.http?.req?.headers.get(HF_TOKEN_HEADER)?.trim() || process.env.HF_TOKEN
```
로컬에서 환경변수를 쓰려면 `.env.example`을 `.env.local`로 복사한 뒤 값을 채우세요.
## ▲ Vercel 배포
1. 저장소를 Vercel에 연결하면 Next.js 프로젝트로 자동 인식됩니다.
2. (선택) 서버 기본 토큰을 두려면 프로젝트 설정 → Environment Variables에 `HF_TOKEN`을 추가합니다.
클라이언트가 항상 `x-hf-token` 헤더를 보낸다면 설정하지 않아도 됩니다.
3. 배포 후 엔드포인트는 `https://seunghui-mcp-server.vercel.app/api/mcp` 입니다.
`app/api/mcp/route.ts`는 Node 런타임과 `maxDuration = 60`을 지정합니다. 이미지 생성처럼
오래 걸리는 도구가 있다면 플랜에 맞춰 값을 조정하세요.
> `mcp-handler` 2.x는 stateless로 동작하므로 Redis가 필요 없고, 레거시 HTTP+SSE
> 트랜스포트는 제공하지 않습니다. 엔드포인트 경로는 라우트 파일 위치로 결정됩니다.
## 🔧 MCP 클라이언트 연결
### HTTP (배포 후 또는 로컬 개발 서버)
`.cursor/mcp.json`:
```json
{
"mcpServers": {
"typescript-mcp-server": {
"url": "https://seunghui-mcp-server.vercel.app/api/mcp",
"headers": {
"x-hf-token": "hf_xxxxxxxxxxxxxxxx"
}
}
}
}
```
Streamable HTTP를 지원하지 않는 stdio 전용 클라이언트는
[`mcp-remote`](https://www.npmjs.com/package/mcp-remote)를 경유할 수 있습니다.
```json
{
"mcpServers": {
"typescript-mcp-server": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"https://seunghui-mcp-server.vercel.app/api/mcp",
"--header",
"x-hf-token:hf_xxxxxxxxxxxxxxxx"
]
}
}
}
```
### stdio (로컬)
```json
{
"mcpServers": {
"typescript-mcp-server": {
"command": "npx",
"args": ["tsx", "src/mcp/stdio.ts"],
"cwd": "/ABSOLUTE/PATH/TO/YOUR/PROJECT",
"env": { "HF_TOKEN": "hf_xxxxxxxxxxxxxxxx" }
}
}
}
```
> `.cursor/mcp.json`은 토큰을 담을 수 있어 `.gitignore`에 포함되어 있습니다.
## 🧪 MCP Inspector로 테스트
```bash
npm run dev
npx @modelcontextprotocol/inspector
```
1. `http://127.0.0.1:6274` 접속
2. 왼쪽 드롭다운에서 **Streamable HTTP** 선택
3. URL에 `http://localhost:3000/api/mcp` 입력
4. Configuration에서 커스텀 헤더 `x-hf-token`을 추가하면 `generate-image` 테스트 가능
5. **Connect** → **List Tools**
## 🛠️ 도구 추가하기
`src/mcp/server.ts`의 `registerAll()` 안에 등록하면 HTTP와 stdio 양쪽에 동시에 반영됩니다.
MCP SDK v2는 `inputSchema`/`outputSchema`에 Zod 객체 스키마를 그대로 받습니다.
```ts
server.registerTool(
'roll-dice',
{
description: 'N면체 주사위를 굴립니다.',
inputSchema: z.object({
sides: z.number().int().min(2).describe('주사위 면 수')
})
},
async ({ sides }) => {
const value = 1 + Math.floor(Math.random() * sides)
return { content: [{ type: 'text', text: `🎲 ${value}` }] }
}
)
```
HTTP 요청 정보가 필요하면 두 번째 인자 `ctx`에서 `ctx.http?.req`로 접근합니다.
stdio 실행 시에는 `ctx.http`가 `undefined`이므로 항상 옵셔널 체이닝으로 다루세요.
새 도구를 추가하면 `src/mcp/metadata.ts`의 `TOOLS` 목록에도 넣어 주세요.
`server-info` 리소스 텍스트와 안내 페이지가 이 목록을 함께 사용합니다.
## 📦 주요 의존성
- **mcp-handler**: MCP 서버를 Web 표준 `Request` 핸들러로 변환 (Vercel 어댑터)
- **@modelcontextprotocol/server**: MCP TypeScript SDK v2 서버 패키지
- **next / react**: HTTP 라우트 호스팅
- **zod**: 도구 입출력 스키마
- **@huggingface/inference**: 이미지 생성
- **tsx**: stdio 진입점 실행
## 🔗 참고 자료
- [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)
- [Zod 문서](https://zod.dev/)
## 📄 라이선스
MIT
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessSyncing