Provides web search capabilities through Google Custom Search API with language, safe search, and result filtering options.
Enables searching for academic papers and articles with filtering by author, year range, and retrieval of author information from Google Scholar.
Allows searching for YouTube videos with filters for duration, upload date, and sorting options like view count or relevance.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Unified Search MCP Serversearch for recent machine learning papers by Yann LeCun"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Unified Search MCP Server ๐
ํ๋ก๋์ ๋ ๋ฒจ MCP (Model Context Protocol) ์๋ฒ๋ก Google Scholar, Google Web Search, YouTube๋ฅผ ํตํฉ ๊ฒ์ํ ์ ์์ต๋๋ค.
๐ ์ฃผ์ ๊ธฐ๋ฅ
ํต์ฌ ๊ฒ์ ๊ธฐ๋ฅ
๐ 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 ํ๋ซํผ์ ํตํด ์ง์ ๋ฐฐํฌํ๋ฉด ์๋์ผ๋ก ์ค์ ๋ฉ๋๋ค.
์๋ ์ค์น
์ ์ฅ์ ํด๋ก :
git clone https://github.com/JDeun/unified-search-mcp-server.git
cd unified-search-mcp-server๊ฐ์ ํ๊ฒฝ ์์ฑ:
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate์์กด์ฑ ์ค์น:
pip install -r requirements.txtํ๊ฒฝ ์ค์ :
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=3600API ํค ๋ฐ๊ธ ๋ฐฉ๋ฒ
Google Custom Search API:
Google Cloud Console ์ ์
"Custom Search API" ํ์ฑํ
์ธ์ฆ ์ ๋ณด ์์ฑ (API ํค)
cse.google.com์์ Custom Search Engine ์์ฑ
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-httpDocker ๋ฐฐํฌ
# ์ด๋ฏธ์ง ๋น๋
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-mcpClaude 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๐ค ๊ธฐ์ฌ
์ ์ฅ์ ํฌํฌ
๊ธฐ๋ฅ ๋ธ๋์น ์์ฑ (
git checkout -b feature/amazing)๋ณ๊ฒฝ ์ฌํญ ์ปค๋ฐ (
git commit -m 'Add feature')๋ธ๋์น์ ํธ์ (
git push origin feature/amazing)Pull Request ์ด๊ธฐ
๐ ๋ผ์ด์ ์ค
MIT ๋ผ์ด์ ์ค - ์์ธํ ๋ด์ฉ์ LICENSE ํ์ผ ์ฐธ์กฐ
๐ ๊ฐ์ฌ์ ๋ง
โ ๏ธ ์ค์ ์ฌํญ
API ์ ํ
Google Web Search: 100 ์ฟผ๋ฆฌ/์ผ (๋ฌด๋ฃ ํฐ์ด)
YouTube API: 10,000 ์ ๋/์ผ (์ฝ 100 ๊ฒ์)
Google Scholar: ๊ณต์ API ์์, rate ์ ํ ์์
ํ๋ก๋์ ๊ณ ๋ ค์ฌํญ
๋ถ์ฐ ๋ฐฐํฌ๋ฅผ ์ํด Redis ์ฌ์ฉ
์ ์ ํ API ํค ๋กํ ์ด์ ์ค์
Rate limit ๋ฐ ํ ๋น๋ ๋ชจ๋ํฐ๋ง
API ์ค๋ฅ์ ๋ํ ์๋ฆผ ์ค์
์ ๊ธฐ์ ์ธ ์ค์ ๋ฐฑ์
๐ ์ง์
๋ฌธ์ ๋ฐ ์ง๋ฌธ:
GitHub Issues: ์ด์ ์์ฑ
Smithery ์ง์: ๋ฐฐํฌ ๊ด๋ จ ๋ฌธ์
MCP ์ปค๋ฎค๋ํฐ๋ฅผ ์ํด โค๏ธ๋ก ์ ์