my-mcp-server

my-mcp-server

Provides tools for image generation, weather, geocoding, and basic utilities, deployable on Vercel via Streamable HTTP.

Category
Visit Server

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를 사용하므로 토큰이 필요합니다. 토큰은 두 가지 경로로 전달할 수 있고, 요청 헤더가 환경변수보다 우선합니다.

  1. x-hf-token 요청 헤더 — 클라이언트가 자신의 토큰을 직접 전달합니다. 서버에 토큰을 저장하지 않아도 되고, 사용자별로 다른 토큰을 쓸 수 있습니다.
  2. 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: 프로덕션 서버 실행

🔗 참고 자료

📄 라이선스

MIT

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured