VayuChat MCP
The VayuChat MCP server enables natural language analysis of air quality and other datasets through predefined functions without requiring code for common tasks.
Data Management: Load CSV files into named DataFrames, list/unload datasets, inspect structure and details, query with pandas syntax, and sample rows.
Statistical Analysis: Generate statistical summaries, compare groups (e.g., cities), analyze weekday vs weekend patterns, examine hourly and temporal trends, perform correlation analysis, and identify top/bottom records.
Visualization: Create comparison charts (bar, box plots), time series plots, distribution histograms, hourly pattern plots, and weekday/weekend comparisons—all returned as base64-encoded PNG images.
Advanced Customization: Execute arbitrary Python code for complex analyses with access to pandas, numpy, matplotlib, and all loaded DataFrames.
Pre-loaded Datasets: Air quality data (PM2.5, PM10, NO2, SO2, CO, O3), government funding data, and city metadata for immediate analysis.
Hybrid Architecture: Combines natural language understanding with reliable predefined functions for consistent, user-friendly data exploration.
Provides access to numerical computing and array manipulation capabilities within the code execution environment for data analysis.
Enables loading CSV files into DataFrames, performing statistical summaries, querying datasets, and managing data structures through natural language.
Allows for the execution of Python code to perform complex data analysis and generate visualizations using pandas, numpy, and matplotlib.
Click on "Deploy 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., "@VayuChat MCP Load sales.csv and plot a bar chart of total revenue by region."
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.
VayuChat MCP
Natural language data analysis for air quality data using MCP (Model Context Protocol).
Features
Pre-loaded Datasets
air_quality: Hourly PM2.5, PM10, NO2, SO2, CO, O3 readings for Delhi & Bangalore
funding: Government air quality funding by city/year (2020-2024)
city_info: City metadata - population, vehicles, industries, green cover
Analysis Tools (No Code Required!)
Function | Description |
| Show available tables |
| Display table data |
| Detailed statistics |
| Filter with pandas query |
| Weekday vs weekend analysis |
| Compare metrics across cities |
| Correlation analysis |
| Funding breakdown |
| Comprehensive city profile |
Visualization Tools
Function | Description |
| Bar/box charts |
| Time series charts |
| Weekday vs weekend bars |
| Funding over years |
| Hourly patterns |
Related MCP server: mcp-csv-analyst
Installation
# Using uv
uv pip install -e .
# Or with pip
pip install -e .Usage
As MCP Server (with Claude Code)
Add to your Claude Code MCP configuration:
{
"mcpServers": {
"vayuchat": {
"command": "uv",
"args": ["run", "--directory", "/path/to/vayuchat-mcp", "vayuchat-mcp"]
}
}
}As Gradio App (HF Spaces)
# Run locally
python app.py
# Or with gradio
gradio app.pyThen open http://localhost:7860
Deploy to Hugging Face Spaces
Create a new Space on HF (Gradio SDK)
Upload these files:
app.pyrequirements.txtsrc/folderdata/folder
Or connect your GitHub repo directly to HF Spaces.
Example Queries
# Data exploration
"What tables are available?"
"Show me the funding table"
"Describe the air quality data"
# Analysis
"Compare weekday vs weekend PM2.5"
"Compare cities by PM10 levels"
"Get Delhi city profile"
"Show correlation with PM2.5"
# Funding
"Show funding for Delhi"
"What's the funding trend?"
# Visualizations
"Plot weekday vs weekend PM2.5"
"Show hourly pattern for NO2"
"Plot funding trend chart"Architecture
NLQ (User Question)
↓
Gradio Chat UI
↓
Query Router (keyword-based / LLM)
↓
MCP Tool Call
↓
Response (Markdown + Base64 Plot)
↓
Rendered in UIWhy Predefined Functions vs LLM-Generated Code?
This project uses predefined MCP functions instead of letting the LLM generate arbitrary pandas/matplotlib code. Here's why:
Comparison Table
Aspect | Predefined Functions (This Approach) | LLM-Generated Code | Function-Calling LLM |
Reliability | ✅ Deterministic, always works | ❌ May hallucinate syntax | ⚠️ Better but can miss params |
Speed | ✅ Instant (no code generation) | ❌ Slow (generate → parse → execute) | ⚠️ Moderate |
Cost | ✅ Minimal tokens | ❌ Long prompts with schema | ⚠️ Moderate |
Security | ✅ No arbitrary code execution | ❌ Code injection risk | ✅ Safe |
Consistency | ✅ Same visualization style | ❌ Random styling each time | ✅ Consistent |
Model Size | ✅ Works with small/cheap models | ❌ Needs capable coder model | ⚠️ Needs fine-tuned model |
Flexibility | ❌ Limited to predefined queries | ✅ Infinite flexibility | ⚠️ Limited to defined functions |
Error Handling | ✅ Graceful, predictable | ❌ May crash, retry loops | ✅ Structured errors |
When to Use Each Approach
Use Predefined Functions (this approach) when:
You have a known, bounded set of analysis patterns
Users are non-technical (need consistent UX)
Cost/latency matters (production deployment)
You want guaranteed correct outputs
Using smaller/cheaper models (Haiku, GPT-3.5)
Use LLM-Generated Code when:
Exploratory data analysis with unknown patterns
Power users who can debug code
One-off analyses
Prototype/research phase
Use Function-Calling LLM when:
You have predefined functions BUT need better intent parsing
Using OpenAI/Claude with native function calling
Queries are ambiguous and need sophisticated NLU
The Hybrid Approach (Best of Both)
User Query
↓
┌─────────────────────────────────────┐
│ LLM with Function Calling │ ← Parses intent, extracts params
│ (Claude, GPT-4, etc.) │
└─────────────────────────────────────┘
↓
┌─────────────────────────────────────┐
│ MCP Predefined Functions │ ← Executes reliably
│ (compare_cities, plot_trend, etc.) │
└─────────────────────────────────────┘
↓
Structured Response + PlotThis gives you:
LLM's NLU capabilities for parsing complex queries
Predefined functions' reliability for execution
No code hallucination risk
Consistent outputs every time
Example: Same Query, Different Approaches
Query: "Compare PM2.5 on weekdays vs weekends for Delhi and Bangalore"
LLM-Generated Code (risky):
# LLM might generate:
df['is_weekend'] = df['day'].isin(['Sat', 'Sun']) # Wrong column name!
df.groupby(['city', 'is_weekend'])['pm25'].mean() # Wrong column name!
# ... errors, retries, inconsistent outputPredefined Function (reliable):
# MCP calls:
compare_weekday_weekend(value_column="PM2.5", group_by="city")
# Always works, consistent format, proper column namesCost Comparison (Approximate)
Approach | Tokens per Query | Cost (GPT-4) | Latency |
Predefined + Keyword Router | ~100 | $0.001 | <100ms |
Predefined + LLM Router | ~500 | $0.005 | ~500ms |
LLM-Generated Code | ~2000+ | $0.02+ | 2-5s |
For 1000 queries/day:
Predefined: ~$1-5/day
LLM Code Gen: ~$20+/day
Data Sources
Air quality data: Simulated based on real patterns from Indian cities
Funding data: Mock data representing typical government allocations
City info: Approximate real statistics
License
MIT
Available Tools
15 toolsanalyze_correlationC
Analyze correlations between numeric columns.
Args: columns: Optional list of columns to analyze target: Optional target column to show correlations with table: Table name (default: air_quality)
Returns: Correlation analysis.
Inputs: columns, target, table. Returns: result
analyze_fundingC
Analyze air quality funding data.
Args: city: Optional city to filter by year: Optional year to filter by
Returns: Funding analysis.
Inputs: city, year. Returns: result
compare_citiesC
Compare a metric across cities.
Args: value_column: Column to compare (e.g., 'PM2.5') cities: Optional list of cities to compare table: Table name (default: air_quality)
Returns: City comparison statistics.
Inputs: value_column (required), cities, table. Returns: result
compare_weekday_weekendC
Compare weekday vs weekend values for a metric.
Args: value_column: Column to compare (e.g., 'PM2.5', 'PM10') group_by: Optional grouping column (e.g., 'city') table: Table name (default: air_quality)
Returns: Comparison statistics.
Inputs: value_column (required), group_by, table. Returns: result
describe_tableC
Get detailed statistics for a table.
Args: name: Table name
Returns: Statistical summary and column info.
Inputs: name (required). Returns: result
execute_codeC
Execute custom Python code for advanced analysis.
Available variables:
air_quality, funding, city_info: DataFrames
pd, np, plt: Libraries
Args: code: Python code to execute
Returns: Output from code execution.
Inputs: code (required). Returns: result
get_city_profileB
Get comprehensive profile for a city including all available data.
Args: city: City name (Delhi, Bangalore, Mumbai, etc.)
Returns: City profile with air quality, funding, and metadata.
Inputs: city (required). Returns: result
list_tablesB
List all available tables/dataframes with their descriptions.
Returns: Summary of all available tables.
Inputs: no named parameters. Returns: result
plot_comparisonC
Create a comparison chart.
Args: value_column: Column to plot (e.g., 'PM2.5') group_column: Grouping column (default: 'city') chart_type: 'bar', 'horizontal_bar', or 'box' table: Table name title: Optional title
Returns: Base64 encoded plot.
Inputs: value_column (required), group_column, chart_type, table, +1 more. Returns: result
plot_funding_trendB
Plot funding trends over years by city.
Args: cities: Optional list of cities to include title: Optional title
Returns: Base64 encoded plot.
Inputs: cities, title. Returns: result
plot_hourly_patternC
Plot hourly patterns.
Args: value_column: Column to plot group_by: Optional grouping column table: Table name title: Optional title
Returns: Base64 encoded plot.
Inputs: value_column (required), group_by, table, title. Returns: result
plot_time_seriesC
Create a time series plot.
Args: value_column: Column to plot group_by: Optional column for separate lines (e.g., 'city') table: Table name title: Optional title
Returns: Base64 encoded plot.
Inputs: value_column (required), group_by, table, title. Returns: result
plot_weekday_weekendC
Create weekday vs weekend comparison chart.
Args: value_column: Column to compare group_by: Grouping column (default: 'city') table: Table name title: Optional title
Returns: Base64 encoded plot.
Inputs: value_column (required), group_by, table, title. Returns: result
query_tableB
Filter a table using pandas query syntax.
Args: name: Table name query: Pandas query (e.g., "city == 'Delhi' and PM2.5 > 200")
Returns: Filtered results.
Inputs: name (required), query (required). Returns: result
show_tableC
Display rows from a table.
Args: name: Table name (air_quality, funding, city_info) rows: Number of rows to show (default: 10) columns: Optional list of columns to display
Returns: Formatted table data.
Inputs: name (required), rows, columns. Returns: result
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 15 tools
Most tools have distinct purposes focused on air quality data analysis, but some overlap exists between plot tools (e.g., plot_time_series and plot_hourly_pattern could be confused for time-based visualizations) and between describe_table and show_table for data inspection. The descriptions help differentiate them, but careful reading is needed.
All tool names follow a consistent verb_noun pattern with snake_case (e.g., analyze_correlation, compare_cities, plot_time_series). The naming is predictable and readable throughout the set, with no deviations in style.
15 tools are well-scoped for an air quality data analysis server, covering data querying, statistical analysis, visualization, and custom code execution. Each tool earns its place without feeling excessive or insufficient for the domain.
The toolset provides comprehensive coverage for air quality analysis, including data inspection, filtering, statistical comparisons, and various visualizations. A minor gap is the lack of tools for data modification (e.g., update or delete operations), but this is reasonable for an analysis-focused server, and agents can work around it with execute_code if needed.
Maintenance
Related MCP Connectors
MCP server for querying and analyzing data from ad platforms, analytics tools, and spreadsheets
Query, join, profile, clean and convert CSV/JSON/Parquet with server-side DuckDB over MCP.
Ask questions about a CSV in plain English and get answers, charts and cleaned data back.
Related MCP Servers
- AlicenseBqualityDmaintenanceAn MCP server that enables advanced CSV analysis and data visualization using Google's Gemini AI and Plotly. It allows users to perform exploratory data analysis, generate interactive charts, and conduct complex reasoning on tabular data.32MIT
- AlicenseAqualityNot gradedmaintenanceAn MCP server that enables AI assistants to load, query, and analyze local CSV files using tools for filtering, aggregation, and grouping. It provides capabilities to describe schemas, calculate statistics, and sample data directly from CSV files.6-
- FlicenseNot gradedqualityDmaintenanceAn MCP server for data analysis and visualization supporting CSV and Excel files. It enables users to generate statistical summaries and create multi-dimensional charts like heatmaps and bar plots through natural language.-
- FlicenseNot gradedqualityDmaintenanceAn MCP server that enables the analysis of CSV and Parquet files by providing tools for statistical summaries, data previews, and structure exploration. It allows users to query local datasets and create sample data using natural language.-