agy-search
by mrbruce516
README.md
# agy-search
把本机 `agy`(antigravity-cli,后端 Gemini,能真实联网搜索)包装成一个 **stdio MCP server**,向 Claude Code 暴露 `web_search` 工具。
## 为什么需要这个
Claude Code 接本地模型时,内置的 `WebSearch` 是 Anthropic **服务端工具**,搜索由官方 API 后端执行——本地模型/代理不实现该工具,所以 `WebSearch` 会返回空结果(`Did 0 searches`),联网搜索能力缺失。
本项目通过 MCP 工具补齐这个缺口:Claude Code 调用 `mcp__agy__web_search` → server 内部 spawn `agy` 子进程 → agy 经 Gemini/Google 联网搜索 → 返回结果。
```
Claude Code ──(stdio JSON-RPC)──► MCP server(长驻)──(tools/call)──► spawn: agy --prompt ... --output-format json ──► Gemini/Google 搜索 ──► 解析 response 回传
```
## 前置要求
- **agy(antigravity-cli)** 已安装并在 `PATH` 中,版本 ≥ 1.1.8
- **uv**(Python 包管理器)
- Python 3.14+
## 安装
```bash
git clone <repo-url> && cd agy-search
uv sync # 安装依赖(fastmcp)
```
## 注册到 Claude Code
推荐**全局注册**(任意目录都可用),用项目 venv 的绝对路径:
```bash
claude mcp add agy -s user -- /<绝对路径>/agy-search/.venv/bin/agy-search
```
验证:
```bash
claude mcp list # 应列出 agy 且 ✔ Connected
claude mcp get agy # Scope 应为 User config
```
注册后,Claude Code 内会出现工具 `mcp__agy__web_search`。
## 使用
在 Claude Code 里直接问需要联网的问题即可,模型会自动调用 `mcp__agy__web_search`:
> 今天有什么科技新闻?
工具签名:
```python
web_search(query: str) -> str
```
- `query`:搜索查询词(自然语言即可,agy 会自行联网检索)
- 返回:agy 的答案文本(通常含来源)
## 可选:禁用不可用的内置 WebSearch
接本地模型时,内置 `WebSearch` 不可用却仍会被调用(白白浪费调用次数)。可在 `~/.claude/settings.json` 加 `permissions.deny` 堵掉它,让搜索统一走 agy:
```json
{
"permissions": {
"deny": ["WebSearch"]
}
}
```
(`WebFetch` 仍可用,用于抓取已知 URL,不必禁用。)
## 本地开发
```bash
# 跑 server(fastmcp CLI,file:object 格式导入 server 对象,默认 stdio)
uv run fastmcp run src/agy_search/__init__.py:mcp
# 或经 entry point
uv run agy-search
# 单独验证 agy 契约(不经 MCP)
agy --prompt "测试查询" --output-format json --print-timeout 90s
```
## agy 调用契约(关键,有坑)
命令:`agy --prompt "<查询>" --output-format json --print-timeout 90s`
- **一律用 `--prompt` 长选项**,不用 `-p`(实测 `-p` 会返回 flag 解释而非执行任务)。
- `--print-timeout` 默认 5m 太长,用 90s。
- 返回 JSON 主用字段:`response`(答案文本)、`status`(SUCCESS/ERROR)、`error`。
- **成败判定不能只看 `status`**:实测 `status:"ERROR"` 时 `response` 仍可能含完整正确答案。判定逻辑——`response` 非空(trim 后)即成功并返回(忽略 status);`response` 空且 `error` 非空才算失败。
- 失败时**重试 1 次**(应对 `Eligibility check failed: EOF`、SSE 断连等瞬时错误),仍失败则 `raise ToolError`(MCP 回 `isError=True`),server 不崩溃。
## 项目结构
```
src/agy_search/__init__.py # 全部实现:FastMCP server + web_search 工具 + agy 调用 + 重试
pyproject.toml # 依赖 fastmcp,entry point: agy-search = "agy_search:main"
```
逻辑内聚在单文件,无额外模块。待加第二个工具时再把 agy 调用逻辑抽成独立模块复用。
TDQS
A4/5.0
Scored across 1 tool
Disambiguation5/5
Only one tool exists, so there is no ambiguity between tools.
Naming Consistency5/5
The single tool 'web_search' follows a clear verb_noun pattern and is self-consistent.
Tool Count2/5
With only one tool, the server feels too thin for a typical search service, which usually requires multiple query types or filters.
Completeness2/5
The server provides only a basic web search with no additional features like filtering, image search, or search history, leaving significant gaps for common search workflows.
Maintenance
ActivityStale
ResponsivenessNo issues