my-mcp-server
Provides tools for image generation, weather, geocoding, and basic utilities, deployable on Vercel via Streamable HTTP.
README
TypeScript MCP Server 보일러플레이트 (Vercel 배포용)
Model Context Protocol (MCP) 서버를 Streamable HTTP 전송 방식으로 구현하고 Vercel에 배포할 수 있는 보일러플레이트입니다. Next.js App Router와 mcp-handler를 사용합니다.
📁 프로젝트 구조
typescript-mcp-server-boilerplate/
├── app/
│ ├── api/
│ │ └── mcp/
│ │ └── route.ts # MCP HTTP 엔드포인트 (POST /api/mcp)
│ ├── globals.css
│ ├── layout.tsx
│ └── page.tsx # 엔드포인트 안내용 랜딩 페이지
├── src/
│ └── mcp/
│ └── server.ts # 도구·리소스·프롬프트 등록
├── next.config.ts
├── package.json
├── tsconfig.json
└── README.md
🚀 시작하기
1. 의존성 설치
npm install
2. 개발 서버 실행
npm run dev
MCP 엔드포인트가 http://localhost:3000/api/mcp에서 열립니다.
3. 동작 확인
curl -X POST http://localhost:3000/api/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
또는 MCP Inspector로 확인할 수 있습니다:
npx @modelcontextprotocol/inspector
Inspector 화면에서 전송 방식을 Streamable HTTP로, URL을 http://localhost:3000/api/mcp로 설정합니다.
🔑 HF_TOKEN 전달 방식
generate-image 도구는 HuggingFace Inference API를 사용하므로 토큰이 필요합니다. 토큰은 두 가지 경로로 전달할 수 있고, 요청 헤더가 환경변수보다 우선합니다.
x-hf-token요청 헤더 — 클라이언트가 자신의 토큰을 직접 전달합니다. 서버에 토큰을 저장하지 않아도 되고, 사용자별로 다른 토큰을 쓸 수 있습니다.HF_TOKEN환경변수 — 헤더가 없을 때 사용하는 서버 측 폴백입니다.
헤더로 받은 토큰은 해당 요청의 서버 인스턴스에만 주입되며 요청이 끝나면 사라집니다.
// app/api/mcp/route.ts
const hfToken = request.headers.get('x-hf-token')?.trim() || process.env.HF_TOKEN
🔧 MCP 클라이언트 연결
Cursor
.cursor/mcp.json을 다음과 같이 작성합니다. command/args 대신 url과 headers를 사용합니다.
{
"mcpServers": {
"my-mcp-server": {
"url": "http://localhost:3000/api/mcp",
"headers": {
"x-hf-token": "hf_..."
}
}
}
}
배포 후에는 url을 https://<your-deployment>.vercel.app/api/mcp로 바꿉니다.
⚠️
.cursor/mcp.json에는 토큰이 들어가므로.gitignore에 등록되어 있습니다. 커밋하지 마세요.
stdio 전용 클라이언트
HTTP 전송을 지원하지 않는 클라이언트는 mcp-remote를 사용합니다.
{
"mcpServers": {
"my-mcp-server": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"http://localhost:3000/api/mcp",
"--header",
"x-hf-token:hf_..."
]
}
}
}
☁️ Vercel 배포
npx vercel
HF_TOKEN환경변수 설정은 선택입니다. 클라이언트가x-hf-token헤더를 보내면 그 값이 사용됩니다. 헤더 없이 쓰는 클라이언트도 지원하려면 Vercel 프로젝트 환경변수에HF_TOKEN을 추가하세요.- 이미지 생성은 시간이 걸리므로 라우트에
maxDuration = 60이 설정되어 있습니다. 요금제에 따라 상한이 다릅니다. - 이미지는 base64 PNG로 응답에 담깁니다. Vercel 함수 응답 크기 상한(4.5MB)을 넘지 않도록 해상도와 스텝 수를 조절하세요.
🛠️ 개발 가이드
모든 도구·리소스·프롬프트는 src/mcp/server.ts의 registerMcpServer에서 등록합니다. 요청별 값(예: 헤더에서 읽은 토큰)은 deps 인자로 전달됩니다.
export type McpDeps = {
hfToken?: string
}
export function registerMcpServer(server: McpServer, deps: McpDeps): void {
// 여기에 도구를 등록합니다
}
도구(Tool) 추가하기
registerTool에 Zod 스키마를 직접 정의해 등록합니다. outputSchema를 지정하면 structuredContent도 함께 반환해야 합니다.
server.registerTool(
'greet',
{
description: '이름과 언어를 입력하면 인사말을 반환합니다.',
inputSchema: z.object({
name: z.string().describe('인사할 사람의 이름'),
language: z
.enum(['ko', 'en'])
.optional()
.default('en')
.describe('인사 언어 (기본값: en)')
}),
outputSchema: z.object({
content: z.array(
z.object({
type: z.literal('text'),
text: z.string().describe('인사말')
})
)
})
},
async ({ name, language }) => {
const greeting =
language === 'ko' ? `안녕하세요, ${name}님!` : `Hello, ${name}!`
return {
content: [{ type: 'text', text: greeting }],
structuredContent: {
content: [{ type: 'text', text: greeting }]
}
}
}
)
요청 헤더를 사용하는 도구
mcp-handler의 초기화 콜백은 서버 인스턴스만 받으므로, 헤더 값을 쓰려면 라우트에서 읽어 deps로 주입합니다. mcp-handler는 POST 요청마다 새 McpServer를 만들기 때문에 요청마다 핸들러를 생성해도 추가 비용이 없습니다.
// app/api/mcp/route.ts
async function handler(request: Request): Promise<Response> {
const hfToken =
request.headers.get('x-hf-token')?.trim() || process.env.HF_TOKEN
return createMcpHandler(
(server) => registerMcpServer(server, { hfToken }),
{ serverInfo: { ...SERVER_INFO } },
{ basePath: '/api', disableSse: true }
)(request)
}
💡
basePath: '/api'에서 스트리머블 HTTP 엔드포인트/api/mcp가 파생됩니다. 라우트 파일 위치를 옮기면basePath도 함께 맞춰야 합니다.
리소스 추가하기
server.registerResource(
'server-info',
'info://server/info',
{
title: 'Server Info',
description: '서버의 기본 정보를 제공합니다.',
mimeType: 'text/plain'
},
async (uri) => ({
contents: [
{
uri: uri.href,
mimeType: 'text/plain',
text: JSON.stringify({ name: 'my-mcp-server' }, null, 2)
}
]
})
)
📋 제공 도구
| 도구 | 설명 |
|---|---|
greet |
이름과 언어를 입력하면 인사말을 반환 |
calculator |
두 숫자와 연산자로 사칙연산 수행 |
get-time |
타임존 또는 도시명의 현재 시간 조회 |
geocode |
도시명을 위도·경도와 타임존으로 변환 (Open-Meteo) |
get-weather |
좌표로 현재 날씨와 일별 예보 조회 (Open-Meteo) |
generate-image |
프롬프트로 이미지 생성 (HuggingFace FLUX.1-schnell) |
리소스 info://server/info와 프롬프트 code-review도 함께 제공됩니다.
📦 주요 의존성
- next: App Router 기반 HTTP 서버
- mcp-handler: MCP 서버를 웹 표준 요청 핸들러로 변환하는 Vercel 어댑터
- @modelcontextprotocol/sdk: MCP 프로토콜 공식 SDK (
mcp-handler@1.x는1.26.0을 요구) - zod: 도구 입출력 스키마 검증
- @huggingface/inference: 이미지 생성
🔧 스크립트
npm run dev: 개발 서버 실행npm run build: 프로덕션 빌드 및 타입 검사npm start: 프로덕션 서버 실행
🔗 참고 자료
- Model Context Protocol 공식 문서
- Vercel: Deploy MCP servers to Vercel
- vercel/mcp-handler
- MCP TypeScript SDK
- Zod 문서
📄 라이선스
MIT
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。