Skip to main content
Glama

MCP Gemini API Server

by techkwon
index.ts12.8 kB
import { McpServer, ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { z } from "zod"; import { generateContent, generateImage, editImage, geminiClient } from './api/gemini'; import { getVideoInfo, analyzeVideo } from './api/youtube'; import fs from 'fs'; import path from 'path'; // 디버그 로그 활성화 console.error('MCP 서버 시작 중...'); // MCP 서버 인스턴스 생성 const server = new McpServer({ name: "gemini-mcp", version: "1.0.0" }); // ========================================= // 도구(Tool) 기능 구현 // ========================================= // 도구 등록: 텍스트 생성 server.tool( "gem-generate", { input: z.string().describe("생성할 텍스트 입력"), options: z.object({ temperature: z.number().min(0).max(1).default(0.7).optional().describe("생성 온도(0-1)"), maxTokens: z.number().min(1).max(2048).optional().describe("최대 토큰 수") }).optional() }, async ({ input, options }) => { console.error('텍스트 생성 시작:', input, '옵션:', options); try { const result = await generateContent(input, options); console.error('텍스트 생성 완료'); return { content: [{ type: "text", text: result }] }; } catch (error: unknown) { console.error('텍스트 생성 오류:', error); const errorMessage = error instanceof Error ? error.message : '알 수 없는 오류'; return { content: [{ type: "text", text: `오류: ${errorMessage}` }], isError: true }; } } ); // 도구 등록: 비디오 분석 server.tool( "gem-analyze-video", { videoUrl: z.string().describe("분석할 YouTube 비디오 URL"), query: z.string().optional().describe("분석을 위한 특정 질문(선택사항)") }, async ({ videoUrl, query }) => { console.error('비디오 분석 시작:', videoUrl, '질문:', query); try { const videoInfo = await getVideoInfo(videoUrl); const result = await analyzeVideo(videoInfo, query || ''); console.error('비디오 분석 완료'); return { content: [{ type: "text", text: result }] }; } catch (error: unknown) { console.error('비디오 분석 오류:', error); const errorMessage = error instanceof Error ? error.message : '알 수 없는 오류'; return { content: [{ type: "text", text: `오류: ${errorMessage}` }], isError: true }; } } ); // 도구 등록: 웹 검색 server.tool( "gem-search", { query: z.string().describe("검색 쿼리"), limit: z.number().min(1).max(10).default(5).optional().describe("결과 수 제한") }, async ({ query, limit }) => { console.error('웹 검색 시작:', query, '결과 제한:', limit); try { const result = await geminiClient.searchWeb(query, { limit }); console.error('웹 검색 완료'); return { content: [{ type: "text", text: result }] }; } catch (error: unknown) { console.error('웹 검색 오류:', error); const errorMessage = error instanceof Error ? error.message : '알 수 없는 오류'; return { content: [{ type: "text", text: `오류: ${errorMessage}` }], isError: true }; } } ); // 도구 등록: 이미지 생성 server.tool( "gem-generate-image", { prompt: z.string().describe("이미지 생성 프롬프트"), options: z.object({ style: z.string().optional().describe("이미지 스타일 (예: '사실적', '만화', '유화', '수채화', '픽셀아트' 등)"), resolution: z.string().optional().describe("이미지 해상도 (예: '1024x1024', '512x512' 등)"), quality: z.enum(['standard', 'hd']).optional().describe("이미지 품질 (standard 또는 hd)"), negative_prompt: z.string().optional().describe("이미지에 포함하지 않을 요소"), temperature: z.number().optional().describe("생성 온도 (0.0-1.0)") }).optional() }, async ({ prompt, options }) => { console.error('이미지 생성 시작:', prompt, '옵션:', options); try { const result = await generateImage(prompt, options); console.error('이미지 생성 완료', typeof result, result); // 이미지 데이터가 있는 경우 if (result.imageBase64) { return { content: [ { type: "text", text: result.text || '이미지가 생성되었습니다.' }, { type: "image", data: result.imageBase64, mimeType: "image/png" } ] }; } // 텍스트만 있는 경우 else { return { content: [{ type: "text", text: result.text || '이미지를 생성할 수 없습니다.' }] }; } } catch (error: unknown) { console.error('이미지 생성 오류:', error); const errorMessage = error instanceof Error ? error.message : '알 수 없는 오류'; return { content: [{ type: "text", text: `오류: ${errorMessage}` }], isError: true }; } } ); // 도구 등록: 이미지 편집 server.tool( "gem-edit-image", { imageBase64: z.string().describe("편집할 이미지의 Base64 인코딩 데이터"), prompt: z.string().describe("이미지 편집 지시사항"), options: z.object({ style: z.string().optional().describe("편집 스타일 (예: '사실적', '만화', '유화', '수채화' 등)"), save_path: z.string().optional().describe("이미지 저장 경로") }).optional() }, async ({ imageBase64, prompt, options }) => { console.error('이미지 편집 시작:', prompt, '옵션:', options); try { const result = await editImage(imageBase64, prompt, options); console.error('이미지 편집 완료', typeof result, result); // 이미지 데이터가 있는 경우 if (result.imageBase64) { return { content: [ { type: "text", text: result.text || '이미지가 편집되었습니다.' }, { type: "image", data: result.imageBase64, mimeType: "image/png" } ] }; } // 텍스트만 있는 경우 else { return { content: [{ type: "text", text: result.text || '이미지를 편집할 수 없습니다.' }] }; } } catch (error: unknown) { console.error('이미지 편집 오류:', error); const errorMessage = error instanceof Error ? error.message : '알 수 없는 오류'; return { content: [{ type: "text", text: `오류: ${errorMessage}` }], isError: true }; } } ); // ========================================= // 리소스(Resource) 기능 구현 // ========================================= // 리소스 등록: 도움말 server.resource( "help", "help://main", async (uri) => { console.error('도움말 리소스 요청:', uri.href); return { contents: [{ uri: uri.href, text: `# Gemini MCP 도움말 ## 사용 가능한 도구 - \`gem-generate\`: Gemini를 사용한 텍스트 생성 - \`gem-analyze-video\`: YouTube 비디오 분석 - \`gem-search\`: 웹 검색 - \`gem-generate-image\`: 이미지 생성 - \`gem-edit-image\`: 이미지 편집 ## 사용 가능한 리소스 - \`help://main\`: 이 도움말 - \`examples://tools\`: 도구 사용 예제 - \`docs://{topic}\`: 특정 주제에 대한 문서` }] }; } ); // 리소스 등록: 도구 예제 server.resource( "examples", "examples://tools", async (uri) => { console.error('예제 리소스 요청:', uri.href); return { contents: [{ uri: uri.href, text: `# 도구 사용 예제 ## 텍스트 생성 예제 \`\`\`json { "name": "gem-generate", "arguments": { "input": "한국의 역사에 대해 요약해 주세요", "options": { "temperature": 0.5, "maxTokens": 1000 } } } \`\`\` ## 비디오 분석 예제 \`\`\`json { "name": "gem-analyze-video", "arguments": { "videoUrl": "https://www.youtube.com/watch?v=dQw4w9WgXcQ", "query": "이 비디오의 주요 내용은 무엇인가요?" } } \`\`\` ## 웹 검색 예제 \`\`\`json { "name": "gem-search", "arguments": { "query": "최신 인공지능 기술 트렌드", "limit": 3 } } \`\`\` ## 이미지 생성 예제 \`\`\`json { "name": "gem-generate-image", "arguments": { "prompt": "한국의 전통 한옥과 벚꽃이 있는 풍경", "options": { "style": "수채화", "resolution": "1024x1024", "quality": "hd", "temperature": 0.8 } } } \`\`\` ## 이미지 편집 예제 \`\`\`json { "name": "gem-edit-image", "arguments": { "imageBase64": "[base64 인코딩된 이미지 데이터]", "prompt": "이미지에 눈 내리는 효과를 추가해주세요", "options": { "style": "사실적" } } } \`\`\` ` }] }; } ); // 리소스 등록: 문서 server.resource( "docs", new ResourceTemplate("docs://{topic}", { list: undefined }), async (uri, { topic }) => { console.error('문서 리소스 요청:', uri.href, '주제:', topic); let docText: string; switch (topic) { case 'gemini': docText = `# Gemini API 사용 가이드 Gemini는 Google의 최신 대규모 언어 모델로, 다양한 텍스트 생성 및 처리 작업을 수행할 수 있습니다. ## 주요 기능 - 텍스트 생성 및 완성 - 대화형 상호작용 - 코드 생성 및 분석 - 다양한 언어 지원 ## 매개변수 - temperature: 생성의 무작위성 제어 (0.0-1.0) - maxTokens: 생성할 최대 토큰 수 - topP: 확률 분포의 상위 p% 중에서 토큰 선택 - topK: 확률 분포의 상위 K개 토큰 중에서 선택`; break; case 'youtube': docText = `# YouTube 분석 API 가이드 YouTube 비디오를 분석하여 내용, 주제, 요약 등의 정보를 추출합니다. ## 지원 기능 - 비디오 메타데이터 추출 - 자막 기반 내용 분석 - 주요 주제 추출 - 질문에 대한 답변 생성 ## 사용 방법 1. 유효한 YouTube URL 제공 2. 필요한 경우 특정 질문 추가 3. 결과 확인`; break; case 'search': docText = `# 웹 검색 API 가이드 Google 검색 엔진을 통해 웹 검색을 수행하고 결과를 반환합니다. ## 주요 기능 - 다양한 주제에 대한 검색 - 최신 정보 검색 - 여러 소스의 정보 통합 ## 매개변수 - query: 검색할 쿼리 - limit: 반환할 결과 수 (기본값: 5)`; break; case 'image': docText = `# 이미지 생성 및 편집 API 가이드 ## 이미지 생성 API 텍스트 프롬프트를 기반으로 이미지를 생성합니다. ### 주요 기능 - 텍스트 프롬프트 기반 이미지 생성 - 다양한 스타일 및 해상도 지원 - 실제 이미지 생성 및 Base64 인코딩 데이터 제공 ### 매개변수 - prompt: 이미지를 설명하는 텍스트 프롬프트 - style: 이미지 스타일 (사실적, 만화, 유화 등) - resolution: 이미지 해상도 - quality: 이미지 품질 (standard 또는 hd) - temperature: 생성 온도 (0.0-1.0) ## 이미지 편집 API 기존 이미지를 텍스트 프롬프트에 따라 편집합니다. ### 주요 기능 - 기존 이미지 수정 및 변환 - 텍스트 프롬프트를 통한 편집 지시 - 다양한 편집 스타일 지원 ### 매개변수 - imageBase64: 편집할 Base64 인코딩 이미지 데이터 - prompt: 편집 지시사항 - style: 편집 스타일`; break; default: docText = `# 문서를 찾을 수 없음 요청하신 주제 '${topic}'에 대한 문서를 찾을 수 없습니다. 사용 가능한 문서 주제: - gemini - youtube - search - image`; } return { contents: [{ uri: uri.href, text: docText }] }; } ); // 에러 처리 설정 process.on('uncaughtException', (error: Error) => { console.error('처리되지 않은 예외:', error); }); process.on('unhandledRejection', (reason: unknown) => { console.error('처리되지 않은 Promise 거부:', reason); }); // 서버 실행 async function main() { try { // stdio 트랜스포트 생성 및 연결 const transport = new StdioServerTransport(); console.error('MCP 서버가 준비되었습니다. 메시지 수신 대기 중...'); await server.connect(transport); } catch (error) { console.error('MCP 서버 실행 중 오류:', error); process.exit(1); } } // 메인 함수 실행 main().catch(error => { console.error('치명적인 오류:', error); process.exit(1); });

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/techkwon/mcp-gemini'

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