Agno MCP Search
by kishansri
README.md
# Agno MCP Search
> An **MCP server** that exposes an **Agno agent** with **Google Gemini** reasoning and **Serper** web search — usable from Claude Desktop, Cursor, or any MCP-compatible client, plus a local Streamlit UI for testing.
<p align="left">
<img src="https://img.shields.io/badge/python-3.10%2B-blue" alt="Python 3.10+" />
<img src="https://img.shields.io/badge/license-MIT-green" alt="MIT License" />
<img src="https://img.shields.io/badge/protocol-MCP-purple" alt="Model Context Protocol" />
<img src="https://img.shields.io/badge/agent-Agno-orange" alt="Agno" />
<img src="https://img.shields.io/badge/model-Gemini-red" alt="Gemini" />
<img src="https://img.shields.io/badge/status-alpha-yellow" alt="Alpha" />
</p>
---
## Overview
Modern chat assistants like Claude and ChatGPT are powerful, but their knowledge is frozen at training time. This project bridges that gap by giving them a **fresh, agent-driven search capability** — delivered through the [Model Context Protocol (MCP)](https://modelcontextprotocol.io).
The MCP server exposes a single tool, `search(query)`. Behind the tool sits an [Agno](https://github.com/agno-agi/agno) agent that:
1. Receives a natural-language query,
2. Uses [Serper](https://serper.dev) to run a Google Search,
3. Reasons over the top results with [Google Gemini](https://ai.google.dev),
4. Returns a markdown-formatted summary to the calling MCP client.
The same server is also drivable from a local [Streamlit](https://streamlit.io) UI, which is handy for demos and debugging without needing an MCP client running.
## Why this project exists
- **Learn MCP by building it.** MCP is quickly becoming the de-facto standard for tool-augmented LLM apps. A small, honest reference server is more useful than a giant framework demo.
- **Prove the agent-in-tool pattern.** Rather than exposing raw search results, the tool exposes an **agent**. The client asks a question; the server does the retrieval-and-reason loop and returns a synthesized answer.
- **Stay swappable.** Gemini, Serper, and Agno are all replaceable by design — the boundary is the `search` MCP tool, not the LLM or search vendor.
## Architecture
```mermaid
flowchart LR
subgraph Client["MCP Client (Claude Desktop / Cursor / Streamlit UI)"]
UI[User query]
end
subgraph Server["FastMCP Server (agentic_mcp.server)"]
TOOL["search(query)"]
AGENT[Agno Agent]
GEMINI[[Gemini LLM]]
SERPER[[Serper Search]]
end
UI -- MCP call --> TOOL
TOOL --> AGENT
AGENT -- reasoning --> GEMINI
AGENT -- tool use --> SERPER
SERPER -- results --> AGENT
GEMINI -- answer --> AGENT
AGENT -- markdown --> TOOL
TOOL -- MCP response --> UI
```
## Technology stack
| Layer | Library / Service | Purpose |
| ------------------ | ----------------- | ---------------------------------------------------- |
| Protocol | **FastMCP** | MCP server framework — exposes tools over stdio |
| Agent framework | **Agno** | Agent loop, tool orchestration, markdown formatting |
| LLM | **Google Gemini** | Reasoning and answer synthesis |
| Search | **Serper** | Google Search API |
| Local UI | **Streamlit** | Browser-based demo client |
| Config | **python-dotenv** | Loads secrets from `.env` |
| Test / lint | **pytest, ruff** | Test runner and linter |
## Folder structure
```
agno-mcp-search/
├── agentic_mcp/ # Application package
│ ├── __init__.py
│ ├── config.py # Env loading & validation
│ ├── agent.py # Agno agent factory
│ ├── server.py # FastMCP server + search tool
│ └── ui/
│ └── streamlit_app.py # Streamlit demo UI
├── tests/ # pytest suite
│ ├── test_config.py
│ └── test_server.py
├── scripts/
│ └── verify_env.py # One-shot health checks
├── docs/
│ ├── Architecture.md
│ ├── MCP.md
│ └── Installation.md
├── screenshots/ # (add your captures here)
├── .github/workflows/ci.yml # Lint + test on every PR
├── .env.example
├── .gitignore
├── LICENSE # MIT
├── README.md
├── CONTRIBUTING.md
├── CODE_OF_CONDUCT.md
├── SECURITY.md
├── CHANGELOG.md
├── pyproject.toml # Modern packaging + tool config
├── requirements.txt
└── requirements-dev.txt
```
## Installation
### Prerequisites
- Python **3.10+**
- A [Google Gemini API key](https://aistudio.google.com/apikey)
- A [Serper API key](https://serper.dev/api-key)
- Optional: [uv](https://docs.astral.sh/uv/) for faster installs
### Setup with `pip`
```bash
# 1. Clone
git clone https://github.com/kishansri/agno-mcp-search.git
cd agno-mcp-search
# 2. Create a venv
python -m venv venv
source venv/bin/activate # macOS/Linux
venv\Scripts\Activate.ps1 # Windows PowerShell
# 3. Install (dev mode)
pip install -e ".[dev]"
# 4. Configure secrets
cp .env.example .env # macOS/Linux
Copy-Item .env.example .env # Windows PowerShell
# then edit .env and paste your keys
```
### Setup with `uv`
```bash
git clone https://github.com/kishansri/agno-mcp-search.git
cd agno-mcp-search
uv venv
uv pip install -e ".[dev]"
cp .env.example .env
```
## Environment variables
| Variable | Required | Default | Purpose |
| ----------------- | -------- | ------------------ | ------------------------------------------ |
| `GOOGLE_API_KEY` | Yes | — | Gemini access |
| `SERPER_API_KEY` | Yes | — | Serper Google Search |
| `GEMINI_MODEL_ID` | No | `gemini-3.1-flash-lite` | Override the default Gemini model |
| `LOG_LEVEL` | No | `INFO` | Log verbosity written to `logs/mcp-server.log` |
## Running
### 1. Verify your setup
```bash
python scripts/verify_env.py all
```
This runs env, Gemini, Serper, and end-to-end Agno checks. It never prints your keys.
### 2. Run the MCP server
```bash
python -m agentic_mcp.server
# or, if installed via pip:
agentic-mcp
```
### 3. Run the Streamlit UI
```bash
streamlit run agentic_mcp/ui/streamlit_app.py
```
Open http://localhost:8501 and enter a query.
### 4. Install into Claude Desktop
```bash
fastmcp install claude-desktop agentic_mcp/server.py \
--with agno --with google-genai --with fastmcp --with python-dotenv \
--env-file .env
```
Restart Claude Desktop. The `search` tool will appear in the tool picker.
## How the agent works
1. **Tool receives a query.** `search(query: str)` is invoked by the MCP client.
2. **Input is validated.** Empty or overly long queries are rejected before spending API credits.
3. **Agent runs the reasoning loop.** Agno decides when to call Serper and how many times.
4. **Gemini synthesizes the answer.** Search snippets are handed to Gemini for summarization.
5. **Result is returned as markdown.** The MCP client renders it as-is.
## Features
- ✅ Single-tool MCP server (`search`)
- ✅ Agno agent with Gemini reasoning + Serper search
- ✅ Streamlit local UI
- ✅ Fail-fast config validation
- ✅ Logging to file (stdout stays clean for MCP protocol)
- ✅ pytest suite with mocked external calls
- ✅ CI-ready (`.github/workflows/ci.yml`)
## Known limitations
- **Single-agent design.** No multi-agent planner/reviewer split (yet — see roadmap).
- **No caching.** Repeated queries re-hit Gemini and Serper.
- **No RAG or memory.** Every query is stateless.
- **No auth on the MCP tool.** Fine for local use; do not expose over the network without adding auth.
- **Preview models may break.** If you set `GEMINI_MODEL_ID` to a preview alias and Google deprecates it, the tool will fail until you change the env var.
## Roadmap
See [`CHANGELOG.md`](CHANGELOG.md) for released versions and [`docs/Architecture.md`](docs/Architecture.md) for planned multi-agent design.
Short version:
- **v0.2** — Response caching, richer tool description, structured JSON output option.
- **v0.3** — Optional Planner + Researcher + Reviewer multi-agent flow.
- **v1.0** — Docker image, CI/CD, guardrails, observability.
## Contributing
Contributions welcome. See [`CONTRIBUTING.md`](CONTRIBUTING.md).
## Security
Please read [`SECURITY.md`](SECURITY.md) before reporting vulnerabilities.
## License
MIT — see [`LICENSE`](LICENSE).
## Screenshots
Screenshots live in [`screenshots/`](screenshots/). Suggested captures:
- Streamlit UI with a sample query and response
- Claude Desktop showing the `search` tool available
- Terminal running `verify_env.py all` with all green checks
---
**Built with FastMCP · Agno · Gemini · Serper.**
TDQS
A4.1/5.0
Scored across 1 tool
Disambiguation5/5
Only one tool exists, so there is zero risk of confusing it with another. Its purpose is clearly distinct by definition.
Naming Consistency5/5
With a single tool named 'search', there is no opportunity for inconsistent naming patterns. The verb form is clear and matches the server's stated purpose.
Tool Count4/5
The server exposes one tool, which is slightly thin but reasonable for a narrowly-scoped search utility. The tool handles both searching and summarizing, so the count is not underserved.
Completeness4/5
The domain is web search and result summarization, and the single tool covers that workflow end-to-end. There may be missing advanced options like pagination or filters, but no obvious critical gaps for the stated purpose.
Maintenance
ActivitySlowing
ResponsivenessNo issues