web-search-mcp
MCP server cung cấp web search cho Claude Code CLI. Chạy được không cần API key nào.
uvx web-search-mcp-free # hoặc: npx -y @quangnx99/web-search-mcp
Tools
| Tool | Mô tả |
|---|---|
web_search(query, count=5, lang="auto") |
Tìm kiếm web, trả về title/url/snippet |
fetch_page(url, max_chars=20000) |
Lấy nội dung trang dưới dạng markdown |
search_stats() |
Xem thống kê provider: tỷ lệ thành công, latency, lỗi gần nhất |
lang="auto" phát hiện tiếng Việt theo dấu trong truy vấn rồi chuyển sang vi
(dùng region vn-vi). Truy vấn không dấu như "Docker Vietnam" sẽ bị coi là
en — đặt lang="vi" tường minh nếu cần.
Provider chain
Server thử lần lượt cho tới khi có kết quả:
- Serper.dev — Google SERP, nhanh nhất (~0.5s). Chỉ dùng nếu có
SERPER_API_KEY. - Tavily — search tối ưu cho LLM. Chỉ dùng nếu có
TAVILY_API_KEY. free— quaddgs, không cần key. Đây là mặc định.
fetch_page: thử Jina Reader trước, hỏng thì chuyển sang ddgs.extract().
Về tầng free — những gì đã đo được
Mặc định là FREE_BACKENDS=auto, và đây là lựa chọn có cơ sở:
| Cấu hình | Thành công (5 query) | Latency TB |
|---|---|---|
auto |
5/5 | 4.2s |
| danh sách thủ công 6 engine | 0/5 | 3.0s |
auto thắng vì nó đẩy wikipedia + grokipedia lên đầu — hai nguồn gần như
không bao giờ bị rate limit, nên luôn có ít nhất một kết quả.
Ba điều phản trực giác về ddgs, đều đã kiểm chứng:
- Liệt kê nhiều engine KHÔNG tăng khả năng chống rate limit.
ddgsgiới hạn số engine chạy song song bằngmin(số_provider, ceil(max_results/10) + 1). Vớicount=5mặc định thì chỉ 2 engine được dùng, bất kể bạn khai bao nhiêu. - Một engine timeout làm hỏng cả request (
wait(..., FIRST_EXCEPTION)). Vì vậy server retry mặc định 2 lần — engine đượcddgsshuffle mỗi lượt nên lần thử lại thường bốc được tổ hợp khác. bingkhông phải backend hợp lệ. Danh sách thật:brave,duckduckgo,google,grokipedia,mojeek,startpage,wikipedia,yahoo,yandex.bingchỉ là provider nằm dướiduckduckgo/yahoo. Khai tên sai thìddgsâm thầm rơi vềauto— server sẽ cảnh báo ra stderr thay vì để bạn tưởng cấu hình đang có hiệu lực.
Đánh giá thật: tầng free dùng tốt cho tra cứu thường ngày, nhưng latency
3–9s và độ ổn định dao động. Nếu search nhiều, SERPER_API_KEY (2.500 query
miễn phí, không cần thẻ) là nâng cấp đáng giá.
Biến môi trường
Tất cả đều tuỳ chọn.
| Biến | Mặc định | Ghi chú |
|---|---|---|
FREE_BACKENDS |
auto |
Danh sách engine, phân tách bởi dấu phẩy. Tên sai bị lọc kèm cảnh báo |
FREE_SEARCH_RETRIES |
2 |
Số lần thử lại tầng free |
SERPER_API_KEY |
— | https://serper.dev — 2.500 query miễn phí |
TAVILY_API_KEY |
— | https://tavily.com — 1.000 credit/tháng |
JINA_API_KEY |
— | Tăng rate limit fetch_page |
WEB_SEARCH_CACHE_TTL |
3600 |
TTL cache search (giây) |
FETCH_CACHE_TTL |
3600 |
TTL cache fetch (giây) |
MAX_RESULTS_PER_DOMAIN |
2 |
Số URL tối đa giữ lại cho mỗi domain |
WEB_SEARCH_CACHE_DB |
thư mục cache của OS | Đường dẫn file cache.db |
WEB_SEARCH_CACHE_MAX_ENTRIES |
500 |
Số entry cache tối đa giữ trước khi trim |
WEB_SEARCH_STATS_MAX_ROWS |
1000 |
Số bản ghi metrics tối đa (SQLite) |
Cache mặc định nằm trong thư mục cache theo chuẩn OS (
platformdirs.user_cache_dir("web-search-mcp")), không phải cạnh source — quan trọng khi cài quauvx/npx, vì môi trường đó bị xoá sau mỗi lần chạy.
Cài đặt
Cần uv (đi kèm uvx).
uv tự lo Python >= 3.12, không cần cài trước.
uvx web-search-mcp-free # chạy MCP server trên stdio
claude mcp add --scope user web-search -- uvx web-search-mcp-free
claude mcp list # kỳ vọng: web-search ... ✔ Connected
Hoặc qua npm, nếu bạn quen npx (cần Node >= 18):
npx -y @quangnx99/web-search-mcp
claude mcp add --scope user web-search -- npx -y @quangnx99/web-search-mcp
Gói npm là shim: nó gọi uvx (hoặc python -m web_search_mcp nếu bạn đã
pip install web-search-mcp-free) rồi chuyển tiếp stdio nguyên vẹn. Khi máy
chưa có gì chạy được, shim dừng kèm hướng dẫn cài — nó không tự tải và chạy
script lạ.
Thêm API key sau khi đã cài:
claude mcp remove --scope user web-search
claude mcp add --scope user --env SERPER_API_KEY=<key> \
web-search -- uvx web-search-mcp-free
Trên Windows không cần bọc cmd /c: uv/uvx là .exe thật.
Tên gọi: distribution trên PyPI là
web-search-mcp-free— tênweb-search-mcpvàwebsearch-mcp-serverđều đã có dự án khác chiếm (PyPI chặn cả tên chỉ tương tự, không chỉ tên trùng hệt). Package npm là@quangnx99/web-search-mcp, còn lệnh chạy trong mọi trường hợp đều làweb-search-mcp.
CLI dùng tay
Server cũng là một CLI bình thường — tiện thử nhanh mà không cần MCP client:
web-search-mcp search "giá vàng hôm nay" --count 3
web-search-mcp fetch https://example.com --max-chars 4000
web-search-mcp stats --hours 48
web-search-mcp doctor # in đường dẫn cache + biến môi trường đã đặt
web-search-mcp serve # MCP server trên stdio (mặc định khi không tham số)
search/fetch trả exit code 1 khi thất bại nên dùng được trong script. Lệnh
con gọi thẳng hàm mà MCP tool dùng — cache, retry, fallback và metrics đi qua
đúng một đường code.
Chạy từ source
uv sync
uv run web-search-mcp doctor
Test
uv sync # cài pytest ở dependency-group dev
uv run pytest -q # 99 test, không gọi mạng
cd npm && npm test # 5 test cho shim npm (node --test)
Toàn bộ test mock lớp mạng nên chạy offline và deterministic. Trọng tâm phủ:
_valid_backendslọc tên sai (bing) và rơi vềautokhi không còn gì hợp lệ- retry của
free_search, kể cả khi engine timeout _is_binarychặn PDF/ZIP/ảnh màddgs.extract()trả về dạng byte thô — gồm test hồi quy đảm bảo văn bản tiếng Việt không bị nhận nhầm là nhị phân- thứ tự fallback của
fetch_page, và không cache nội dung lỗi - cache: TTL, hết hạn, tách entry theo
lang/count, normalize key (lowercase + strip) - metrics: ghi/đọc, giới hạn dung lượng, windowing theo thời gian
- locale: map
lang→(region, gl, hl)cho DDGS/Serper/Tavily - dedupe domain: giữ tối đa 2 URL/domain, ưu tiên đa dạng
Giới hạn đã biết
cache.dbchỉ trim bản ghi cũ khi vượt ngưỡng, không có vacuum định kỳ.
Release files for web-search-mcp-free 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| web_search_mcp_free-0.1.0.tar.gz | 14.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| web_search_mcp_free-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 33.2 kB
Release files / web_search_mcp_free-0.1.0.tar.gz
| Download URL | web_search_mcp_free-0.1.0.tar.gz |
|---|---|
| Size | 14.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
af4dfd882a7145ead973cbe2e059a2bf095fe48085a130c3fae7978fc4ca0f47
|
|
BLAKE2b-256 checksum How to use checksums |
02e34fab2139f851bb9f2668cca7ab268fe4285ac008fc2cea901340382e25e7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.1 {"installer":{"name":"uv","version":"0.12.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / web_search_mcp_free-0.1.0-py3-none-any.whl
| Download URL | web_search_mcp_free-0.1.0-py3-none-any.whl |
|---|---|
| Size | 18.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
1dba0100a49f599fe5e00df3a558f63ada9cb7b9b590b60ab9e2ed97bf73d39a
|
|
BLAKE2b-256 checksum How to use checksums |
c734bc3624499f575fddf0e02624bac1d3d9c8188208bfdfc5f868c44bddd024
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.1 {"installer":{"name":"uv","version":"0.12.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|