Code Review & Utilities
Generate detailed code review prompts tailored to your language and focus. Get the current time in any timezone and perform quick calculations. Create images from text and send greetings in multiple languages.
Ask AI about Code Review & Utilities
Powered by Claude Β· Grounded in docs
I know everything about Code Review & Utilities. Ask me about installation, configuration, usage, or troubleshooting.
0/500
Reviews
Documentation
Multi-Purpose MCP Server
λ€μν κΈ°λ₯μ μ 곡νλ Model Context Protocol (MCP) μλ²μ λλ€. μκ° μ‘°ν, κ³μ°κΈ°, μΈμ¬λ§, μ½λ 리뷰, μ΄λ―Έμ§ μμ± λ±μ κΈ°λ₯μ ν¬ν¨νκ³ μμ΅λλ€.
π μ£Όμ κΈ°λ₯
- νμ¬ μκ° μ‘°ν: μ§μ λ μκ°λμ νμ¬ μκ°μ μ‘°νν©λλ€
- λ€μν μκ°λ μ§μ: Asia/Seoul, America/New_York, Europe/London λ± λͺ¨λ IANA μκ°λ μ§μ
- κ³μ°κΈ°: λ μ«μμ λν μ¬μΉμ°μ°μ μνν©λλ€
- λ€κ΅μ΄ μΈμ¬λ§: λ€μν μΈμ΄λ‘ μΈμ¬λ§μ μ 곡ν©λλ€
- μ½λ 리뷰: μ½λμ λν μμΈν 리뷰 ν둬ννΈλ₯Ό μμ±ν©λλ€
- μ΄λ―Έμ§ μμ±: ν μ€νΈ ν둬ννΈλ₯Ό μ¬μ©νμ¬ AI μ΄λ―Έμ§λ₯Ό μμ±ν©λλ€
π νλ‘μ νΈ κ΅¬μ‘°
time-mcp-server/
βββ src/
β βββ index.ts # MCP μλ² λ©μΈ μ§μ
μ
βββ build/ # μ»΄νμΌλ JavaScript νμΌ (λΉλ ν μμ±)
βββ package.json # νλ‘μ νΈ μμ‘΄μ± λ° μ€ν¬λ¦½νΈ
βββ tsconfig.json # TypeScript μ€μ
βββ README.md # νλ‘μ νΈ λ¬Έμ
π μμνκΈ°
1. μμ‘΄μ± μ€μΉ
npm install
2. νκ²½ λ³μ μ€μ
μ΄λ―Έμ§ μμ± κΈ°λ₯μ μ¬μ©νλ €λ©΄ Hugging Face API ν ν°μ΄ νμν©λλ€.
Hugging Face API ν ν° λ°κΈ
- Hugging Faceμ κ³μ μ μμ±ν©λλ€
- Settings > Access Tokensμμ μ ν ν°μ μμ±ν©λλ€
- ν ν°μ 볡μ¬ν©λλ€
νκ²½ λ³μ μ€μ
Windows (PowerShell):
$env:HF_TOKEN="your_hugging_face_token_here"
Windows (Command Prompt):
set HF_TOKEN=your_hugging_face_token_here
Linux/macOS:
export HF_TOKEN="your_hugging_face_token_here"
λλ .env νμΌμ μμ±νμ¬ μ€μ ν μ μμ΅λλ€:
HF_TOKEN=your_hugging_face_token_here
3. λΉλ
npm run build
4. μ€ν
node build/index.js
λΉλκ° μ±κ³΅νλ©΄ build/ λλ ν 리μ μ»΄νμΌλ JavaScript νμΌμ΄ μμ±λκ³ , μλ²κ° MCP ν΄λΌμ΄μΈνΈμ μ°κ²°μ λκΈ°ν©λλ€.
π οΈ μ¬μ© λ°©λ²
1. μκ° μ‘°ν λꡬ
νμ¬ μκ°μ μ‘°ννλ λꡬμ λλ€:
- λꡬ μ΄λ¦:
current_time - λ§€κ°λ³μ:
timezone(μ νμ¬ν): μκ°λ (μ: Asia/Seoul, America/New_York, Europe/London)- μκ°λλ₯Ό μ§μ νμ§ μμΌλ©΄ νκ΅ μκ°λ(Asia/Seoul)λ₯Ό μ¬μ©ν©λλ€
2. κ³μ°κΈ° λꡬ
λ μ«μμ λν μ¬μΉμ°μ°μ μννλ λꡬμ λλ€:
- λꡬ μ΄λ¦:
calculator - λ§€κ°λ³μ:
num1: 첫 λ²μ§Έ μ«μnum2: λ λ²μ§Έ μ«μoperation: μ°μ°μ (add, subtract, multiply, divide)
3. μΈμ¬λ§ λꡬ
λ€μν μΈμ΄λ‘ μΈμ¬λ§μ μ 곡νλ λꡬμ λλ€:
- λꡬ μ΄λ¦:
greeting - λ§€κ°λ³μ:
name: μ¬μ©μμ μ΄λ¦language: μΈμ¬λ§μ ν μΈμ΄ (korean, english, japanese, chinese, spanish, french, german, italian, portuguese, russian)
4. μ½λ 리뷰 λꡬ
μ½λμ λν μμΈν 리뷰 ν둬ννΈλ₯Ό μμ±νλ λꡬμ λλ€:
- λꡬ μ΄λ¦:
code_review - λ§€κ°λ³μ:
code: 리뷰ν μ½λlanguage(μ νμ¬ν): μ½λ μΈμ΄ (javascript, typescript, python, java, cpp, go, rust)reviewType(μ νμ¬ν): 리뷰 μ ν (comprehensive, security, performance, readability, best_practices)
5. μ΄λ―Έμ§ μμ± λꡬ
ν μ€νΈ ν둬ννΈλ₯Ό μ¬μ©νμ¬ AI μ΄λ―Έμ§λ₯Ό μμ±νλ λꡬμ λλ€:
- λꡬ μ΄λ¦:
generate_image - λ§€κ°λ³μ:
prompt: μ΄λ―Έμ§ μμ±μ μν ν둬ννΈ
- λ°ν νμ: base64-encoded PNG μ΄λ―Έμ§
μ¬μ© μμ
-
νκ΅ μκ° μ‘°ν (κΈ°λ³Έκ°):
νμ¬ μκ°μ μλ €μ€ -
νΉμ μκ°λ μκ° μ‘°ν:
λ΄μ μκ°μ μλ €μ€λλ
Europe/London μκ°λμ νμ¬ μκ°μ μλ €μ€ -
κ³μ°κΈ° μ¬μ©:
5 λνκΈ° 3μ μΌλ§μΌ? 10 λλκΈ° 2λ? -
λ€κ΅μ΄ μΈμ¬λ§:
μλ νμΈμ λΌκ³ μΈμ¬ν΄μ€ HelloλΌκ³ μμ΄λ‘ μΈμ¬ν΄μ€ -
μ½λ 리뷰:
λ€μ μ½λλ₯Ό 리뷰ν΄μ€: function add(a, b) { return a + b; } -
μ΄λ―Έμ§ μμ±:
κ³ μμ΄κ° μ°μ£Όλ₯Ό μ¬ννλ μ΄λ―Έμ§λ₯Ό μμ±ν΄μ€
μ§μνλ μκ°λ μμ
Asia/Seoul- νκ΅ μκ°λ (κΈ°λ³Έκ°)America/New_York- λ΄μ μκ°λAmerica/Los_Angeles- λ‘μ€μ€μ €λ μ€ μκ°λEurope/London- λ°λ μκ°λEurope/Paris- ν리 μκ°λAsia/Tokyo- λμΏ μκ°λAsia/Shanghai- μνμ΄ μκ°λAustralia/Sydney- μλλ μκ°λ
π‘ ν: λͺ¨λ IANA μκ°λλ₯Ό μ§μν©λλ€. IANA Time Zone Databaseμμ μ¬μ© κ°λ₯ν μκ°λ λͺ©λ‘μ νμΈν μ μμ΅λλ€.
π οΈ κ°λ° κ°μ΄λ
MCP λꡬ(Tool) μΆκ°νκΈ°
MCP μλ²μ μλ‘μ΄ λꡬλ₯Ό μΆκ°νλ €λ©΄ server.tool() λ©μλμ Zod μ€ν€λ§λ₯Ό μ§μ μ μνμ¬ λ±λ‘ν©λλ€:
import { z } from 'zod'
// κ³μ°κΈ° λꡬ μΆκ°
server.tool(
'calculator',
{
operation: z
.enum(['add', 'subtract', 'multiply', 'divide'])
.describe('μνν μ°μ° (add, subtract, multiply, divide)'),
a: z.number().describe('첫 λ²μ§Έ μ«μ'),
b: z.number().describe('λ λ²μ§Έ μ«μ')
},
async ({ operation, a, b }) => {
// μ°μ° μν
let result: number
switch (operation) {
case 'add':
result = a + b
break
case 'subtract':
result = a - b
break
case 'multiply':
result = a * b
break
case 'divide':
if (b === 0) throw new Error('0μΌλ‘ λλ μ μμ΅λλ€')
result = a / b
break
default:
throw new Error('μ§μνμ§ μλ μ°μ°μ
λλ€')
}
const operationSymbols = {
add: '+',
subtract: '-',
multiply: 'Γ',
divide: 'Γ·'
} as const
const operationSymbol =
operationSymbols[operation as keyof typeof operationSymbols]
return {
content: [
{
type: 'text',
text: `${a} ${operationSymbol} ${b} = ${result}`
}
]
}
}
)
λ 볡μ‘ν λꡬ μμ
// λ μ¨ μ 보 μ‘°ν λꡬ
server.tool(
'get_weather',
{
city: z.string().describe('λ μ¨λ₯Ό μ‘°νν λμλͺ
'),
unit: z
.enum(['celsius', 'fahrenheit'])
.optional()
.default('celsius')
.describe('μ¨λ λ¨μ (κΈ°λ³Έκ°: celsius)')
},
async ({ city, unit }) => {
try {
// μ€μ λ μ¨ API νΈμΆ λ‘μ§ (μμ)
const weatherData = await fetchWeatherData(city, unit)
return {
content: [
{
type: 'text',
text: `${city}μ νμ¬ λ μ¨:
μ¨λ: ${weatherData.temperature}Β°${unit === 'celsius' ? 'C' : 'F'}
λ μ¨: ${weatherData.condition}
μ΅λ: ${weatherData.humidity}%
νμ: ${weatherData.windSpeed}km/h`
}
]
}
} catch (error) {
throw new Error(
`λ μ¨ μ 보λ₯Ό κ°μ Έμ¬ μ μμ΅λλ€: ${(error as Error).message}`
)
}
}
)
// λμ°λ―Έ ν¨μ
async function fetchWeatherData(city: string, unit: string) {
// μ€μ λ μ¨ API νΈμΆ ꡬν
// μ¬κΈ°μλ μμ λ°μ΄ν° λ°ν
return {
temperature: unit === 'celsius' ? 22 : 72,
condition: 'λ§μ',
humidity: 65,
windSpeed: 12
}
}
리μμ€ μΆκ°νκΈ°
MCP μλ²μ 리μμ€λ₯Ό μΆκ°νμ¬ μΈλΆ λ°μ΄ν°λ νμΌμ λν μ κ·Όμ μ 곡ν μ μμ΅λλ€:
// 리μμ€ λ±λ‘
server.resource(
'example-file',
'file://example.txt',
{
name: 'μμ ν
μ€νΈ νμΌ',
description: 'μμ ν
μ€νΈ νμΌ μ€λͺ
',
mimeType: 'text/plain'
},
async () => {
return {
contents: [
{
uri: 'file://example.txt',
mimeType: 'text/plain',
text: 'μμ νμΌ λ΄μ©μ
λλ€.'
}
]
}
}
)
// λμ 리μμ€ μμ
server.resource(
'app-settings',
'config://settings',
{
name: 'μ ν리μΌμ΄μ
μ€μ ',
description: 'μ ν리μΌμ΄μ
μ νμ¬ μ€μ μ 보',
mimeType: 'application/json'
},
async () => {
const settings = {
theme: 'dark',
language: 'ko-KR',
notifications: true,
lastUpdated: new Date().toISOString()
}
return {
contents: [
{
uri: 'config://settings',
mimeType: 'application/json',
text: JSON.stringify(settings, null, 2)
}
]
}
}
)
π¦ μ£Όμ μμ‘΄μ±
- @modelcontextprotocol/sdk: MCP νλ‘ν μ½ κ΅¬νμ μν 곡μ SDK
- @huggingface/inference: Hugging Face Inference API ν΄λΌμ΄μΈνΈ (μ΄λ―Έμ§ μμ±μ©)
- zod: TypeScript μ°μ μ€ν€λ§ κ²μ¦ λΌμ΄λΈλ¬λ¦¬
- typescript: TypeScript μ»΄νμΌλ¬
π§ μ€ν¬λ¦½νΈ
npm run build: TypeScriptλ₯Ό JavaScriptλ‘ μ»΄νμΌνκ³ μ€ν κΆν μ€μ
π μ¬μ© μμ
μκ° μ‘°ν λꡬ μ¬μ©
// νκ΅ μκ° μ‘°ν (κΈ°λ³Έκ°)
const koreanTime = await getCurrentTime() // "2024-01-15 14:30:25 (Asia/Seoul)"
// λ΄μ μκ° μ‘°ν
const newYorkTime = await getCurrentTime('America/New_York') // "2024-01-15 00:30:25 (America/New_York)"
// λ°λ μκ° μ‘°ν
const londonTime = await getCurrentTime('Europe/London') // "2024-01-15 05:30:25 (Europe/London)"
μμ ν μλ² μμ
import { Server } from '@modelcontextprotocol/sdk/server/index.js'
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js'
import { z } from 'zod'
// μκ° λꡬ μ€ν€λ§
const TimeToolSchema = z.object({
timezone: z.string().optional().describe('μκ°λ (μ: Asia/Seoul, America/New_York)')
})
// νμ¬ μκ° μ‘°ν ν¨μ
const getCurrentTime = (timezone: string = 'Asia/Seoul'): string => {
const now = new Date()
const options: Intl.DateTimeFormatOptions = {
timeZone: timezone,
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: false
}
const formatter = new Intl.DateTimeFormat('ko-KR', options)
const timeString = formatter.format(now)
return `${timeString} (${timezone})`
}
// μλ² μμ±
const server = new Server(
{
name: 'time-mcp-server',
version: '1.0.0',
},
{
capabilities: {
tools: {},
},
}
)
// λꡬ λ±λ‘
server.setRequestHandler(ListToolsRequestSchema, async () => {
return {
tools: [
{
name: 'current_time',
description: 'νμ¬ μκ°μ μ§μ λ μκ°λμμ μ‘°ννλ λꡬ',
inputSchema: {
type: 'object',
properties: {
timezone: {
type: 'string',
description: 'μκ°λ (μ: Asia/Seoul, America/New_York)'
}
},
required: []
}
}
]
}
})
// λꡬ νΈμΆ μ²λ¦¬
server.setRequestHandler(CallToolRequestSchema, async (request) => {
if (request.params.name === 'current_time') {
const { timezone } = TimeToolSchema.parse(request.params.arguments)
const currentTime = getCurrentTime(timezone)
return {
content: [
{
type: 'text',
text: `νμ¬ μκ°: ${currentTime}`
}
]
}
}
throw new Error(`μ μ μλ λꡬ: ${request.params.name}`)
})
// μλ² μμ
async function main() {
const transport = new StdioServerTransport()
await server.connect(transport)
console.error('Time MCP Server started')
}
main().catch(console.error)
π§ Cursor MCP μ°κ²°
κ°λ°ν MCP μλ²λ₯Ό Cursorμμ ν μ€νΈν μ μμ΅λλ€:
μ€μ νμΌ μμ
./.cursor/mcp.json νμΌμ νΈμ§ν©λλ€:
{
"mcpServers": {
"typescript-mcp-server": {
"command": "node",
"args": ["/ABSOLUTE/PATH/TO/YOUR/PROJECT/build/index.js"]
}
}
}
μ£Όμ: μ λ κ²½λ‘λ₯Ό μ¬μ©ν΄μΌ ν©λλ€.
pwdλͺ λ Ήμ΄λ‘ νμ¬ κ²½λ‘λ₯Ό νμΈνμΈμ.
ν μ€νΈ λͺ λ Ήμ΄
Cursor MCPμμ λ€μκ³Ό κ°μ΄ ν μ€νΈν΄λ³Ό μ μμ΅λλ€:
- "νμ¬ μκ°μ μλ €μ€" (νκ΅ μκ° μ‘°ν)
- "λ΄μ μκ°μ μλ €μ€" (λ΄μ μκ° μ‘°ν)
- "Europe/London μκ°λμ νμ¬ μκ°μ μλ €μ€" (λ°λ μκ° μ‘°ν)
- "5 λνκΈ° 3μ μΌλ§μΌ?" (κ³μ°κΈ° λꡬ ν μ€νΈ)
- "μλ νμΈμ λΌκ³ μΈμ¬ν΄μ€" (μΈμ¬ λꡬ ν μ€νΈ)
- "λ€μ μ½λλ₯Ό 리뷰ν΄μ€: function add(a, b) { return a + b; }" (μ½λ 리뷰 ν μ€νΈ)
- "κ³ μμ΄κ° μ°μ£Όλ₯Ό μ¬ννλ μ΄λ―Έμ§λ₯Ό μμ±ν΄μ€" (μ΄λ―Έμ§ μμ± ν μ€νΈ)
π μ°Έκ³ μλ£
- Model Context Protocol 곡μ λ¬Έμ
- MCP TypeScript SDK
- Node.js MCP μλ² κ°λ° κ°μ΄λ
- Zod λ¬Έμ
π λΌμ΄μ μ€
MIT
