unified-search-mcp-server

JDeun/unified-search-mcp-server

3.3

If you are the rightful owner of unified-search-mcp-server and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to henry@mcphub.com.

Unified Search MCP Server integrates Google Scholar, Google Web Search, and YouTube into a single search platform.

Unified Search MCP Server ๐Ÿ”

ํ”„๋กœ๋•์…˜ ๋ ˆ๋ฒจ MCP (Model Context Protocol) ์„œ๋ฒ„๋กœ Google Scholar, Google Web Search, YouTube๋ฅผ ํ†ตํ•ฉ ๊ฒ€์ƒ‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

License: MIT Python 3.11+ smithery badge

๐Ÿš€ ์ฃผ์š” ๊ธฐ๋Šฅ

ํ•ต์‹ฌ ๊ฒ€์ƒ‰ ๊ธฐ๋Šฅ

  • ๐ŸŽ“ Google Scholar: ํ•™์ˆ  ๋…ผ๋ฌธ ๊ฒ€์ƒ‰ (์ €์ž, ์—ฐ๋„ ํ•„ํ„ฐ๋ง)
  • ๐ŸŒ Google Web Search: Google Custom Search API๋ฅผ ์‚ฌ์šฉํ•œ ์›น ๊ฒ€์ƒ‰
  • ๐Ÿ“บ YouTube Search: ๋™์˜์ƒ ๊ฒ€์ƒ‰ (๊ธธ์ด, ์—…๋กœ๋“œ ๋‚ ์งœ, ์ •๋ ฌ ์˜ต์…˜)
  • ๐Ÿ”„ ํ†ตํ•ฉ ๊ฒ€์ƒ‰: ๋ชจ๋“  ์†Œ์Šค์—์„œ ๋™์‹œ ๊ฒ€์ƒ‰

์—”ํ„ฐํ”„๋ผ์ด์ฆˆ ๊ธฐ๋Šฅ

  • ๐Ÿ” ๋ณด์•ˆ: API ํ‚ค ์•”ํ˜ธํ™”, ์ž…๋ ฅ๊ฐ’ ๊ฒ€์ฆ, XSS/SQL ์ธ์ ์…˜ ๋ฐฉ์ง€
  • ๐Ÿ’พ ๋ถ„์‚ฐ ์บ์‹ฑ: Redis ๊ธฐ๋ฐ˜ ์บ์‹ฑ ๋ฐ TTL ๊ด€๋ฆฌ
  • โšก Rate Limiting: Redis ๋ฐฑ์—”๋“œ ๊ธฐ๋ฐ˜ ์„ค์ • ๊ฐ€๋Šฅํ•œ rate limit
  • ๐Ÿ“Š ๋ชจ๋‹ˆํ„ฐ๋ง: Prometheus ๋ฉ”ํŠธ๋ฆญ, ํ—ฌ์Šค ์ฒดํฌ, ๊ตฌ์กฐํ™”๋œ ๋กœ๊น…
  • ๐Ÿ”„ ๋ณต์›๋ ฅ: ์žฌ์‹œ๋„ ๋กœ์ง, ์„œํ‚ท ๋ธŒ๋ ˆ์ด์ปค, ์šฐ์•„ํ•œ ์„ฑ๋Šฅ ์ €ํ•˜
  • ๐Ÿ“ ๊ฐ์‚ฌ ๋กœ๊น…: ๊ทœ์ • ์ค€์ˆ˜๋ฅผ ์œ„ํ•œ ํฌ๊ด„์ ์ธ ๊ฐ์‚ฌ ์ถ”์ 

๐Ÿ“‹ ์š”๊ตฌ ์‚ฌํ•ญ

  • Python 3.11+
  • Redis (์„ ํƒ์‚ฌํ•ญ, ๋ถ„์‚ฐ ๊ธฐ๋Šฅ์šฉ)
  • API ํ‚ค:
    • Google Custom Search API (์›น ๊ฒ€์ƒ‰์šฉ)
    • YouTube Data API v3 (YouTube ๊ฒ€์ƒ‰์šฉ)

๐Ÿ› ๏ธ ์„ค์น˜

Smithery๋ฅผ ํ†ตํ•œ ๋น ๋ฅธ ์„ค์น˜

Smithery ํ”Œ๋žซํผ์„ ํ†ตํ•ด ์ง์ ‘ ๋ฐฐํฌํ•˜๋ฉด ์ž๋™์œผ๋กœ ์„ค์ •๋ฉ๋‹ˆ๋‹ค.

์ˆ˜๋™ ์„ค์น˜

  1. ์ €์žฅ์†Œ ํด๋ก :
git clone https://github.com/JDeun/unified-search-mcp-server.git
cd unified-search-mcp-server
  1. ๊ฐ€์ƒ ํ™˜๊ฒฝ ์ƒ์„ฑ:
python -m venv venv
source venv/bin/activate  # Windows: venv\Scripts\activate
  1. ์˜์กด์„ฑ ์„ค์น˜:
pip install -r requirements.txt
  1. ํ™˜๊ฒฝ ์„ค์ •:
cp .env.example .env
# .env ํŒŒ์ผ์„ ํŽธ์ง‘ํ•˜์—ฌ API ํ‚ค์™€ ์„ค์ • ์ž…๋ ฅ

โš™๏ธ ์„ค์ •

ํ™˜๊ฒฝ ๋ณ€์ˆ˜

# API ํ‚ค
GOOGLE_API_KEY=your-google-api-key
GOOGLE_CUSTOM_SEARCH_ENGINE_ID=your-cse-id
YOUTUBE_API_KEY=your-youtube-api-key

# ๋ณด์•ˆ
MCP_ENCRYPTION_KEY=your-256-bit-key
MCP_RATE_LIMIT_SECRET=your-secret

# Redis (์„ ํƒ์‚ฌํ•ญ)
MCP_REDIS_URL=redis://localhost:6379/0

# ์„ค์ •
MCP_ENV=production
MCP_LOG_LEVEL=INFO
MCP_CACHE_TTL=3600

API ํ‚ค ๋ฐœ๊ธ‰ ๋ฐฉ๋ฒ•

  1. Google Custom Search API:

    • Google Cloud Console ์ ‘์†
    • "Custom Search API" ํ™œ์„ฑํ™”
    • ์ธ์ฆ ์ •๋ณด ์ƒ์„ฑ (API ํ‚ค)
    • cse.google.com์—์„œ Custom Search Engine ์ƒ์„ฑ
  2. YouTube Data API v3:

    • ๋™์ผํ•œ Google Cloud Console ํ”„๋กœ์ ํŠธ ์‚ฌ์šฉ
    • "YouTube Data API v3" ํ™œ์„ฑํ™”
    • ๋™์ผํ•œ API ํ‚ค ์‚ฌ์šฉ ๋˜๋Š” ์ƒˆ๋กœ ์ƒ์„ฑ

๐Ÿš€ ์‚ฌ์šฉ๋ฒ•

์„œ๋ฒ„ ์‹คํ–‰

# ๊ฐœ๋ฐœ ๋ชจ๋“œ (stdio)
python unified_search_server.py

# ํ”„๋กœ๋•์…˜ ๋ชจ๋“œ (HTTP)
python unified_search_server.py --transport streamable-http

# ์ปค์Šคํ…€ ํฌํŠธ
MCP_PORT=8080 python unified_search_server.py --transport streamable-http

Docker ๋ฐฐํฌ

# ์ด๋ฏธ์ง€ ๋นŒ๋“œ
docker build -t unified-search-mcp .

# ์ปจํ…Œ์ด๋„ˆ ์‹คํ–‰
docker run -p 8000:8000 \
  -e GOOGLE_API_KEY=your-key \
  -e GOOGLE_CUSTOM_SEARCH_ENGINE_ID=your-cse \
  -e YOUTUBE_API_KEY=your-key \
  unified-search-mcp

Claude Desktop ํ†ตํ•ฉ

claude_desktop_config.json์— ์ถ”๊ฐ€:

{
  "mcpServers": {
    "unified-search": {
      "command": "python",
      "args": ["/path/to/unified_search_server.py"],
      "env": {
        "GOOGLE_API_KEY": "your-key",
        "GOOGLE_CUSTOM_SEARCH_ENGINE_ID": "your-cse",
        "YOUTUBE_API_KEY": "your-key"
      }
    }
  }
}

๐Ÿ“– ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๋„๊ตฌ

unified_search

๋ชจ๋“  ์†Œ์Šค์—์„œ ๋™์‹œ์— ๊ฒ€์ƒ‰ํ•ฉ๋‹ˆ๋‹ค.

results = await unified_search(
    query="์ธ๊ณต์ง€๋Šฅ",
    sources=["scholar", "web", "youtube"],
    num_results=10
)

search_google_scholar

ํ•™์ˆ  ๋…ผ๋ฌธ์„ ๊ฒ€์ƒ‰ํ•ฉ๋‹ˆ๋‹ค.

results = await search_google_scholar(
    query="๋จธ์‹ ๋Ÿฌ๋‹",
    author="Yann LeCun",
    year_start=2020,
    year_end=2024,
    num_results=10
)

search_google_web

์›น์„ ๊ฒ€์ƒ‰ํ•ฉ๋‹ˆ๋‹ค.

results = await search_google_web(
    query="ChatGPT",
    language="ko",
    safe_search="medium",
    num_results=10
)

search_youtube

YouTube ๋™์˜์ƒ์„ ๊ฒ€์ƒ‰ํ•ฉ๋‹ˆ๋‹ค.

results = await search_youtube(
    query="ํŒŒ์ด์ฌ ํŠœํ† ๋ฆฌ์–ผ",
    video_duration="medium",
    upload_date="month",
    order="viewCount",
    num_results=20
)

get_author_info

Google Scholar์—์„œ ์ €์ž ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.

info = await get_author_info("Geoffrey Hinton")

clear_cache

์บ์‹œ๋œ ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ๋ฅผ ์‚ญ์ œํ•ฉ๋‹ˆ๋‹ค.

await clear_cache(source="web")  # ๋˜๋Š” None์œผ๋กœ ์ „์ฒด ์‚ญ์ œ

get_api_usage_stats

API ์‚ฌ์šฉ๋Ÿ‰๊ณผ ์ œํ•œ์„ ๋ชจ๋‹ˆํ„ฐ๋งํ•ฉ๋‹ˆ๋‹ค.

stats = await get_api_usage_stats()

๐Ÿ—๏ธ ์•„ํ‚คํ…์ฒ˜

๋ชจ๋“ˆ์‹ ์„ค๊ณ„

src/
โ”œโ”€โ”€ config/       # ์„ค์ • ๋ฐ ๋ณด์•ˆ
โ”œโ”€โ”€ models/       # ๋ฐ์ดํ„ฐ ๋ชจ๋ธ ๋ฐ ๊ฒ€์ฆ
โ”œโ”€โ”€ services/     # ๊ฒ€์ƒ‰ ์„œ๋น„์Šค ๊ตฌํ˜„
โ”œโ”€โ”€ cache/        # ์บ์‹ฑ ๋ ˆ์ด์–ด
โ”œโ”€โ”€ utils/        # ์œ ํ‹ธ๋ฆฌํ‹ฐ (๋กœ๊น…, rate limiting)
โ”œโ”€โ”€ monitoring/   # ๋ฉ”ํŠธ๋ฆญ ๋ฐ ํ—ฌ์Šค ์ฒดํฌ
โ””โ”€โ”€ mcp_server.py # ๋ฉ”์ธ ์„œ๋ฒ„ ๊ตฌํ˜„

๋ณด์•ˆ ๋ ˆ์ด์–ด

  • ์ž…๋ ฅ๊ฐ’ ๊ฒ€์ฆ ๋ฐ ์‚ด๊ท 
  • API ํ‚ค ์•”ํ˜ธํ™” ์ €์žฅ
  • ํด๋ผ์ด์–ธํŠธ/์—”๋“œํฌ์ธํŠธ๋ณ„ rate limiting
  • ๊ทœ์ • ์ค€์ˆ˜๋ฅผ ์œ„ํ•œ ๊ฐ์‚ฌ ๋กœ๊น…
  • CORS ๋ฐ ์š”์ฒญ ID ์ถ”์ 

์„ฑ๋Šฅ ์ตœ์ ํ™”

  • Redis ๊ธฐ๋ฐ˜ ๋ถ„์‚ฐ ์บ์‹ฑ
  • HTTP ํด๋ผ์ด์–ธํŠธ ์—ฐ๊ฒฐ ํ’€๋ง
  • ๋™์‹œ ๊ฒ€์ƒ‰ ์‹คํ–‰
  • ์ง€์ˆ˜ ๋ฐฑ์˜คํ”„๋ฅผ ํ†ตํ•œ ์Šค๋งˆํŠธ ์žฌ์‹œ๋„
  • ์™ธ๋ถ€ API์šฉ ์„œํ‚ท ๋ธŒ๋ ˆ์ด์ปค

๐Ÿ“Š ๋ชจ๋‹ˆํ„ฐ๋ง

ํ—ฌ์Šค ์ฒดํฌ ์—”๋“œํฌ์ธํŠธ

๋ฆฌ์†Œ์Šค: health://status

๋ฉ”ํŠธ๋ฆญ ์—”๋“œํฌ์ธํŠธ

๋ฆฌ์†Œ์Šค: metrics://stats

์ฃผ์š” ๋ฉ”ํŠธ๋ฆญ

  • ๊ฒ€์ƒ‰ ์š”์ฒญ ์ˆ˜ ๋ฐ ์ง€์—ฐ ์‹œ๊ฐ„
  • ์บ์‹œ ํžˆํŠธ์œจ
  • API ํ• ๋‹น๋Ÿ‰ ์‚ฌ์šฉ๋Ÿ‰
  • ์†Œ์Šค๋ณ„ ์˜ค๋ฅ˜์œจ
  • Rate limit ์œ„๋ฐ˜

๐Ÿ”’ ๋ณด์•ˆ

๋ชจ๋ฒ” ์‚ฌ๋ก€

  • ๋ชจ๋“  API ํ‚ค Fernet์œผ๋กœ ์•”ํ˜ธํ™”
  • XSS/SQL ์ธ์ ์…˜ ๋ฐฉ์ง€๋ฅผ ์œ„ํ•œ ์ž…๋ ฅ ๊ฒ€์ฆ
  • ๋‚จ์šฉ ๋ฐฉ์ง€๋ฅผ ์œ„ํ•œ rate limiting
  • ๋ฏผ๊ฐํ•œ ๋ฐ์ดํ„ฐ ์—†๋Š” ๊ตฌ์กฐํ™”๋œ ๋กœ๊น…
  • ์ •๊ธฐ์ ์ธ ๋ณด์•ˆ ์—…๋ฐ์ดํŠธ

๊ทœ์ • ์ค€์ˆ˜

  • PII ์ €์žฅ ์—†๋Š” GDPR ์ค€๋น„
  • ๋ชจ๋“  ๊ฒ€์ƒ‰์— ๋Œ€ํ•œ ๊ฐ์‚ฌ ์ถ”์ 
  • ์„ค์ • ๊ฐ€๋Šฅํ•œ ๋ฐ์ดํ„ฐ ๋ณด์กด
  • API ์‚ฌ์šฉ๋Ÿ‰ ์ถ”์ 

๐Ÿงช ํ…Œ์ŠคํŠธ

ํ…Œ์ŠคํŠธ ์‹คํ–‰:

pytest tests/ -v --cov=src

๐Ÿค ๊ธฐ์—ฌ

  1. ์ €์žฅ์†Œ ํฌํฌ
  2. ๊ธฐ๋Šฅ ๋ธŒ๋žœ์น˜ ์ƒ์„ฑ (git checkout -b feature/amazing)
  3. ๋ณ€๊ฒฝ ์‚ฌํ•ญ ์ปค๋ฐ‹ (git commit -m 'Add feature')
  4. ๋ธŒ๋žœ์น˜์— ํ‘ธ์‹œ (git push origin feature/amazing)
  5. Pull Request ์—ด๊ธฐ

๐Ÿ“ ๋ผ์ด์„ ์Šค

MIT ๋ผ์ด์„ ์Šค - ์ž์„ธํ•œ ๋‚ด์šฉ์€ ํŒŒ์ผ ์ฐธ์กฐ

๐Ÿ™ ๊ฐ์‚ฌ์˜ ๋ง

  • FastMCP๋กœ ๊ตฌ์ถ•
  • scholarly๋ฅผ ํ†ตํ•œ Google Scholar ๊ฒ€์ƒ‰
  • MCP ์ปค๋ฎค๋‹ˆํ‹ฐ์˜ ์˜๊ฐ

โš ๏ธ ์ค‘์š” ์‚ฌํ•ญ

API ์ œํ•œ

  • Google Web Search: 100 ์ฟผ๋ฆฌ/์ผ (๋ฌด๋ฃŒ ํ‹ฐ์–ด)
  • YouTube API: 10,000 ์œ ๋‹›/์ผ (์•ฝ 100 ๊ฒ€์ƒ‰)
  • Google Scholar: ๊ณต์‹ API ์—†์Œ, rate ์ œํ•œ ์žˆ์Œ

ํ”„๋กœ๋•์…˜ ๊ณ ๋ ค์‚ฌํ•ญ

  • ๋ถ„์‚ฐ ๋ฐฐํฌ๋ฅผ ์œ„ํ•ด Redis ์‚ฌ์šฉ
  • ์ ์ ˆํ•œ API ํ‚ค ๋กœํ…Œ์ด์…˜ ์„ค์ •
  • Rate limit ๋ฐ ํ• ๋‹น๋Ÿ‰ ๋ชจ๋‹ˆํ„ฐ๋ง
  • API ์˜ค๋ฅ˜์— ๋Œ€ํ•œ ์•Œ๋ฆผ ์„ค์ •
  • ์ •๊ธฐ์ ์ธ ์„ค์ • ๋ฐฑ์—…

๐Ÿ“ž ์ง€์›

๋ฌธ์ œ ๋ฐ ์งˆ๋ฌธ:


MCP ์ปค๋ฎค๋‹ˆํ‹ฐ๋ฅผ ์œ„ํ•ด โค๏ธ๋กœ ์ œ์ž‘