Skip to main content
Glama
jaejin0me

TypeScript MCP Server Boilerplate

by jaejin0me
index.ts9.88 kB
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js' import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js' import { z } from 'zod' // Create server instance const server = new McpServer({ name: 'greeting-mcp-server', version: '1.0.0', capabilities: { tools: {}, resources: {}, prompts: {} } }) // Add greeting tool server.tool('greeting', 'Say hello or goodbye to someone', { name: z.string().describe('The name of the person to greet'), type: z.enum(['hello', 'goodbye']).describe('Type of greeting - hello or goodbye'), language: z.enum(['korean', 'english']).optional().describe('Language for greeting (optional, defaults to korean)') }, async (args) => { const { name, type, language = 'korean' } = args let greeting: string if (language === 'english') { greeting = type === 'hello' ? `Hello, ${name}! Nice to meet you!` : `Goodbye, ${name}! See you later!` } else { greeting = type === 'hello' ? `안녕하세요, ${name}님! 만나서 반갑습니다!` : `안녕히 가세요, ${name}님! 또 만나요!` } return { content: [{ type: 'text', text: greeting }] } }) // Add calculator tool server.tool('calculator', 'Perform basic mathematical calculations', { operation: z.enum(['add', 'subtract', 'multiply', 'divide']).describe('The mathematical operation to perform'), a: z.number().describe('The first number'), b: z.number().describe('The second number') }, async (args) => { const { operation, a, b } = args let result: number let operationSymbol: string switch (operation) { case 'add': result = a + b operationSymbol = '+' break case 'subtract': result = a - b operationSymbol = '-' break case 'multiply': result = a * b operationSymbol = '×' break case 'divide': if (b === 0) { return { content: [{ type: 'text', text: '오류: 0으로 나눌 수 없습니다. (Error: Cannot divide by zero)' }] } } result = a / b operationSymbol = '÷' break default: return { content: [{ type: 'text', text: '오류: 지원되지 않는 연산입니다. (Error: Unsupported operation)' }] } } const calculation = `${a} ${operationSymbol} ${b} = ${result}` return { content: [{ type: 'text', text: calculation }] } }) // Add time tool server.tool('time', 'Get current date and time', { timezone: z.string().optional().describe('Timezone (optional, defaults to Asia/Seoul)'), format: z.enum(['full', 'date', 'time', 'iso']).optional().describe('Time format (optional, defaults to full)') }, async (args) => { const { timezone = 'Asia/Seoul', format = 'full' } = args try { const now = new Date() let timeString: string switch (format) { case 'date': timeString = now.toLocaleDateString('ko-KR', { timeZone: timezone, year: 'numeric', month: 'long', day: 'numeric', weekday: 'long' }) break case 'time': timeString = now.toLocaleTimeString('ko-KR', { timeZone: timezone, hour12: false, hour: '2-digit', minute: '2-digit', second: '2-digit' }) break case 'iso': timeString = now.toISOString() break case 'full': default: const dateStr = now.toLocaleDateString('ko-KR', { timeZone: timezone, year: 'numeric', month: 'long', day: 'numeric', weekday: 'long' }) const timeStr = now.toLocaleTimeString('ko-KR', { timeZone: timezone, hour12: false, hour: '2-digit', minute: '2-digit', second: '2-digit' }) timeString = `${dateStr} ${timeStr} (${timezone})` break } return { content: [{ type: 'text', text: `현재 시간: ${timeString}` }] } } catch (error) { return { content: [{ type: 'text', text: `시간 조회 오류: ${error instanceof Error ? error.message : '알 수 없는 오류'}` }] } } }) // Add code review prompt server.prompt('code-review', 'Code review prompt template', { code: z.string().describe('The code to be reviewed') }, async (args) => { const { code } = args // Auto-detect language let detectedLanguage = '코드' if (code.includes('function') && code.includes('{')) { if (code.includes('const') || code.includes('let') || code.includes('=>')) { detectedLanguage = 'JavaScript/TypeScript' } else { detectedLanguage = 'JavaScript' } } else if (code.includes('def ') && code.includes(':')) { detectedLanguage = 'Python' } else if (code.includes('public class') || code.includes('private ')) { detectedLanguage = 'Java' } else if (code.includes('#include') || code.includes('int main')) { detectedLanguage = 'C/C++' } else if (code.includes('func ') && code.includes('package ')) { detectedLanguage = 'Go' } else if (code.includes('fn ') && code.includes('->')) { detectedLanguage = 'Rust' } const systemPrompt = `당신은 경험이 풍부한 시니어 개발자이자 코드 리뷰어입니다. 다음 코드를 전반적으로 검토해주세요. ## 리뷰 가이드라인 다음 관점에서 코드를 검토해주세요: ### 1. 코드 품질 - 코드 구조와 로직의 명확성 - 변수 및 함수명의 적절성 - 가독성과 유지보수성 ### 2. 기능적 측면 - 오류 처리 및 예외 상황 대응 - 성능 최적화 가능성 - 보안 고려사항 ### 3. 모범 사례 - 디자인 패턴 및 코딩 컨벤션 - 업계 표준 준수 - 테스트 가능성 ### 4. 개선 사항 - 구체적인 문제점과 개선 방안 - 더 나은 구현 방법 제안 - 코드 예시 (필요시) ### 5. 긍정적 요소 - 잘 작성된 부분 - 좋은 접근 방식 ### 6. 종합 평가 - 전체적인 코드 품질 점수 (1-10점) - 우선순위별 개선 권장사항 한국어로 상세하고 건설적인 피드백을 제공해주세요.` const userMessage = `다음 ${detectedLanguage} 코드를 리뷰해주세요: \`\`\` ${code} \`\`\`` return { messages: [ { role: 'user', content: { type: 'text', text: `${systemPrompt} ${userMessage}` } } ] } }) // Add server info resource server.resource('server-info', 'server://info', { name: 'Server Information', description: 'Server information and status', mimeType: 'application/json' }, async () => { const serverInfo = { name: 'greeting-mcp-server', version: '1.0.0', description: 'TypeScript MCP 서버 - 인사, 계산기, 시간 도구를 제공합니다', capabilities: { tools: ['greeting', 'calculator', 'time'], resources: ['server://info', 'server://stats'], prompts: ['code-review'] }, status: 'running', uptime: process.uptime(), memory: process.memoryUsage(), platform: process.platform, nodeVersion: process.version, timestamp: new Date().toISOString(), timezone: 'Asia/Seoul' } return { contents: [{ uri: 'server://info', text: JSON.stringify(serverInfo, null, 2), mimeType: 'application/json' }] } }) // Add server stats resource server.resource('server-stats', 'server://stats', { name: 'Server Statistics', description: 'Server runtime statistics', mimeType: 'application/json' }, async () => { const stats = { uptime: { seconds: Math.floor(process.uptime()), formatted: `${Math.floor(process.uptime() / 3600)}시간 ${Math.floor((process.uptime() % 3600) / 60)}분 ${Math.floor(process.uptime() % 60)}초` }, memory: { used: Math.round(process.memoryUsage().heapUsed / 1024 / 1024 * 100) / 100, total: Math.round(process.memoryUsage().heapTotal / 1024 / 1024 * 100) / 100, external: Math.round(process.memoryUsage().external / 1024 / 1024 * 100) / 100, unit: 'MB' }, system: { platform: process.platform, arch: process.arch, nodeVersion: process.version, pid: process.pid }, timestamp: new Date().toISOString() } return { contents: [{ uri: 'server://stats', text: JSON.stringify(stats, null, 2), mimeType: 'application/json' }] } }) // Start the server async function main() { const transport = new StdioServerTransport() await server.connect(transport) } main().catch((error) => { console.error('Server error:', error) process.exit(1) })

Implementation Reference

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/jaejin0me/mcpServer_test'

If you have feedback or need assistance with the MCP directory API, please join our Discord server