Content
# Valencia Smart City Agent
Valencia Smart City Agent is a multi-agent assistant for answering operational questions about Valencia, Spain. It combines Google ADK agents, an MCP tool server, city open-data integrations, user memory, RAG, and web/API frontends.
The assistant is designed for queries such as:
- "What is the traffic like near the city center?"
- "Can I go by bike today, considering weather and air quality?"
- "Find public parking and EV charging points near my destination."
- "How do I get from UPV to the city center?"
- "Where are nearby police districts, kiosks, hydrants, or public city services?"
The user-facing agent answers in Spanish, while this repository documentation is in English.
## Highlights
- Google ADK multi-agent orchestration with specialist agents for mobility, environment, and city services.
- FastMCP server exposing real-time tools over SSE.
- Dynamic orchestration layer with rule-based and optional LLM planning.
- Real-time and near-real-time integrations for Valencia traffic, EMT/GTFS, Valenbisi, FGV/metro-tram data, weather, air quality, routing, geocoding, and city services.
- Persistent user profile memory for recurring needs such as accessibility or travel preferences.
- REST API backend for a React interface.
- Chainlit and terminal chat interfaces for local demos.
- Evaluation harness and regression tests for tools, orchestration, response synthesis, and data quality.
## Architecture
```text
User
|
| CLI / Chainlit / React
v
Google ADK root orchestrator
|
| routes tasks
v
Specialist agents
|-- mobility_specialist
|-- environment_specialist
|-- services_specialist
|
| filtered MCP toolsets
v
FastMCP SSE server
|
| domain modules
v
Valencia Open Data, NAP GTFS, Open-Meteo, OpenRouteService,
DuckDuckGo, Neo4j/RAG, local SQLite memory
```
The MCP server owns the tool registry and exposes category-filtered toolsets. The ADK agents connect to it through SSE, normally at `http://127.0.0.1:8081/sse`.
## Data And Tool Domains
The MCP server registers tools from `src/domains/` and assigns them to agent categories:
- Traffic: congestion summaries, monitored road segments, and traffic-state distributions from Valencia Open Data.
- EMT and public transport: bus lines, stops, arrival-oriented data, and NAP GTFS-backed transport helpers.
- Bikes: Valenbisi station availability and nearby bike searches.
- Mobility: FGV metro/tram stations, public parking, EV charging points, ZBE status, loading zones, bike parking, and related city mobility datasets.
- Routing and geocoding: place search plus pedestrian/car route calculation through OpenRouteService when configured.
- Weather: current weather, daily summaries, and forecasts through Open-Meteo.
- Air quality: pollutant summaries and health-oriented interpretations.
- City services: police districts, kiosks, hydrants, public facilities, tourism, municipal services, and other documentary datasets.
- Web search: recent events, news, and public information lookups.
- Knowledge/RAG: municipal and tourism knowledge backed by the RAG pipeline.
## Repository Layout
```text
.
|-- agent_runner.py # Terminal chat/demo runner
|-- agent_smartcity/ # ADK root and specialist agents
|-- evals/ # ADK evaluation cases and custom metrics
|-- scripts/ # Debug and paper evaluation helpers
|-- smartcity-react/ # React + Vite web client
|-- src/
| |-- api.py # FastAPI backend for the React client
| |-- frontend.py # Chainlit frontend
| |-- mcp_server.py # FastMCP tool server and registry
| |-- domains/ # City data/tool implementations
| |-- memory/ # User profile persistence
| |-- orchestration/ # Planning, execution, evidence, synthesis
| |-- rag/ # Knowledge/RAG ingestion and query code
| `-- utils/ # Shared API, GTFS, logging, model helpers
|-- tests/ # Unit and integration-style regression tests
|-- requirements.txt # Python dependencies
|-- start_server.sh # Starts the MCP SSE server
`-- start_frontend.sh # Starts the Chainlit frontend
```
## Requirements
- Python 3.11 or newer.
- Node.js 20 or newer for the React/Vite client.
- A valid `.env` file for model and external API configuration.
- Optional: Neo4j with APOC if you want to run the graph RAG ingestion pipeline.
The current agent code uses PoliGPT through LiteLLM for the root and specialist agents. The MCP server configuration also validates `GOOGLE_API_KEY`, so local runs should provide both keys unless you adjust that validation in code.
## Installation
```bash
git clone <repository-url>
cd SmartCity
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .env
```
Then edit `.env`. A practical local configuration looks like this:
```ini
# LLM backend used by the ADK agents through LiteLLM.
POLIGPT_API_KEY=your_poligpt_api_key
POLIGPT_API_BASE=https://api.poligpt.upv.es/
# Still validated by src/config.py when the MCP server starts.
GOOGLE_API_KEY=your_google_api_key
AGENT_MODEL=gemini-2.0-flash-exp
AGENT_TEMPERATURE=0.7
# MCP server.
MCP_SERVER_HOST=0.0.0.0
MCP_SERVER_PORT=8081
# Optional but recommended for richer mobility answers.
ORS_API_KEY=your_openrouteservice_key
NAP_API_KEY=your_transportes_nap_key
# Defaults are usually fine.
VALENCIA_API_BASE_URL=https://valencia.opendatasoft.com
VALENCIA_LATITUDE=39.47
VALENCIA_LONGITUDE=-0.38
ENABLE_CACHE=true
CACHE_TTL=600
NAP_GTFS_TTL=43200
# Optional graph/RAG backend.
NEO4J_URI=bolt://localhost:7687
NEO4J_USERNAME=neo4j
NEO4J_PASSWORD=password
NEO4J_DATABASE=neo4j
```
## Running The Project
Start the MCP server first. The ADK specialist agents connect to this SSE service to access tools.
```bash
./start_server.sh
```
The script is idempotent. If an MCP server is already running on the configured port, it reuses it. To deliberately replace the process on that port:
```bash
./start_server.sh --restart
```
### Terminal Chat
```bash
python agent_runner.py
```
This launches a small terminal UI with an interactive mode and a demo mode.
### Chainlit UI
```bash
./start_frontend.sh
```
Equivalent manual command:
```bash
chainlit run src/frontend.py -w
```
### React + FastAPI UI
Run the API backend:
```bash
uvicorn src.api:app --host 0.0.0.0 --port 8000
```
In another terminal, start the React app:
```bash
cd smartcity-react
npm install
npm run dev
```
The Vite dev server proxies `/api` to `http://localhost:8000`. If you deploy the backend elsewhere, set `VITE_API_BASE_URL` for the React client.
### Google ADK Interfaces
```bash
adk web .
```
or:
```bash
adk run agent_smartcity
```
## Optional RAG Services
The services specialist can use a local services agent by default, or a remote A2A RAG service when available on port `8001`.
Start the RAG A2A service:
```bash
python src/rag/rag_a2a_server.py
```
Force local services-agent mode instead of the remote A2A service:
```bash
SMARTCITY_FORCE_LOCAL_SERVICES_AGENT=1 python agent_runner.py
```
Run the web/graph ingestion pipeline:
```bash
python src/rag/ingestion/pipeline.py
```
The ingestion pipeline crawls configured Valencia-related seed URLs, cleans and chunks documents, creates vector data, and writes graph information to Neo4j. It expects the Neo4j settings in `.env` and APOC support for entity-resolution post-processing.
## API Endpoints
The FastAPI backend exposes:
- `POST /api/chat` for chat requests.
- `POST /api/sessions` to create a chat session.
- `GET /api/sessions/{user_id}` to list sessions.
- `GET /api/sessions/{session_id}/messages` to fetch session history.
- `PUT /api/sessions/{session_id}` to update title or pin state.
- `DELETE /api/sessions/{session_id}` to delete a session.
- `GET /api/profile/{user_id}` to inspect persistent user memory.
- `DELETE /api/profile/{user_id}/{category}` to delete a saved preference category.
- `GET /api/data-sources/summary` to inspect verified and inferred data-source coverage.
The backend stores chat sessions in `smartcity_chat.db`. User profile memory uses the database configured by `DATABASE_URL`, defaulting to local SQLite.
## Testing
Run the full configured test suite:
```bash
python -m pytest
```
Useful focused checks:
```bash
python -m pytest tests/test_open_data.py tests/test_adk_patches.py tests/test_response_synthesis.py -q
python -m pytest tests/test_dynamic_orchestrator.py tests/test_orchestration_modules.py -q
python -m pytest evals/evaluate.py::test_mixed_scenarios -vv -s
```
Paper/evaluation helper:
```bash
scripts/run_paper_eval_battery.sh
```
Common evaluation environment variables:
```ini
ADK_EVAL_CONFIG=test_config_paper.json
ADK_EVAL_NUM_RUNS=1
EVAL_TIMEOUT_SECONDS=240
SMARTCITY_EVAL_DIAGNOSTICS_DIR=/tmp/smartcity_eval_diagnostics
```
## Configuration Notes
- `POLIGPT_API_KEY` is required by `agent_smartcity/agent.py` through `validate_poligpt_environment()`.
- `POLIGPT_API_BASE` defaults to `https://api.poligpt.upv.es/`.
- `GOOGLE_API_KEY` is currently required by `src/config.py` validation when starting the MCP server.
- `ORS_API_KEY` enables route calculation through OpenRouteService. Without it, routing answers will be limited.
- `NAP_API_KEY` enables GTFS downloads from the Spanish National Access Point for richer EMT, FGV, and interurban data.
- `MCP_SERVER_PORT` defaults to `8081`. The API backend commonly runs on `8000`; the optional RAG A2A service runs on `8001`.
- `SMARTCITY_PLANNER_MODE` controls root orchestration mode. Supported values include `llm`, `rule_based`, and `env`.
- `SMARTCITY_LLM_PLANNER_ENABLED=1` enables the optional planner when `SMARTCITY_PLANNER_MODE=env`.
- `SMARTCITY_FORCE_LOCAL_SERVICES_AGENT=1` bypasses the remote A2A services agent.
## Development Tips
- Keep the MCP server running while using CLI, Chainlit, ADK, or API flows.
- If tool schemas look stale after code changes, restart the MCP server with `./start_server.sh --restart`.
- Use `GET /api/data-sources/summary` before demos to understand which datasets are verified, inferred, or pending.
- Prefer focused tests when changing one domain module, then run the orchestration and synthesis tests before demos.
## License
See [LICENSE](LICENSE).
MCP Config
Below is the configuration for this MCP Server. You can copy it directly to Cursor or other MCP clients.
mcp.json
Connection Info
You Might Also Like
No recommendations available