Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/data-profiler/.python-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3.10
116 changes: 116 additions & 0 deletions src/data-profiler/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
# 🔬 MCP Advanced Data Profiler Server

> An MCP server that empowers AI agents with advanced data profiling, data quality analysis, and statistical outlier detection capabilities for CSV datasets.

---

## 📌 Overview

**MCP Advanced Data Profiler Server** is a data analysis server built on the [Model Context Protocol (MCP)](https://modelcontextprotocol.io) standard. It connects to AI clients such as Claude Desktop and integrates CSV analysis workflows — including missing value detection, column type inspection, and IQR-based outlier detection — directly into AI agent pipelines.

---

## 🛠️ Tools

### 1. `analyze_data_quality`

Analyzes a CSV file and produces a comprehensive data quality report.

| Output | Description |
|---|---|
| Total rows & columns | Overall dataset dimensions |
| Column data types | `int`, `float`, `object`, etc. |
| Missing value count & percentage | Reported per column |

**Example prompt:**
```
"Generate a quality report for sales_data.csv"
```

---

### 2. `find_outliers_iqr`

Detects statistical outliers in a specified numerical column using the **Interquartile Range (IQR)** method.

| Output | Description |
|---|---|
| Lower & upper bounds | `Q1 - 1.5×IQR` and `Q3 + 1.5×IQR` |
| Outlier count & percentage | Share of outliers within total data |
| Sample outlier values | Preview of the first few detected values |

**Example prompt:**
```
"Find outliers in the revenue column using the IQR method"
```

---

## 🚀 Installation

### Requirements

- Python 3.10+
- `mcp` library

```bash
pip install mcp
```

### Running the Server

```bash
python -m mcp run src/benim-mcp-sunucum/server.py
```

---

## ⚙️ Configuration

To use this server with Claude Desktop or any MCP-compatible client, add the following to your `claude_desktop_config.json`:

```json
{
"mcpServers": {
"data-profiler": {
"command": "python",
"args": [
"-m",
"mcp",
"run",
"src/benim-mcp-sunucum/server.py"
]
}
}
}
```

> 💡 Config file location:
> - **macOS / Linux:** `~/.config/claude/claude_desktop_config.json`
> - **Windows:** `%APPDATA%\Claude\claude_desktop_config.json`

---

## 📁 Project Structure

```
benim-mcp-sunucum/
├── src/
│ └── benim-mcp-sunucum/
│ └── server.py # MCP tool definitions and business logic
├── claude_desktop_config.json # Example client configuration
├── requirements.txt
└── README.md
```

---

## 📄 License

MIT License — See `LICENSE` for details.

---

<div align="center">
<sub>Built with Model Context Protocol · Python · Claude Desktop</sub>
</div>
23 changes: 23 additions & 0 deletions src/data-profiler/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
[project]
name = "mcp-data-profiler"
version = "0.1.0"
description = "AI ajanları için gelişmiş veri analizi ve kalite kontrol sunucusu"
readme = "README.md"
requires-python = ">=3.10"
dependencies = [
"mcp[cli]>=1.2.0",
"pandas>=2.0.0",
"numpy>=1.24.0",
]

[dependency-groups]
dev = [
"pyright>=1.1.300",
]

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[tool.hatch.build.targets.wheel]
packages = ["server.py"]
119 changes: 119 additions & 0 deletions src/data-profiler/server.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import os
import pandas as pd
import numpy as np
from mcp.server.fastmcp import FastMCP

# Sunucumuzu tanımlıyoruz
mcp = FastMCP("Advanced Data Profiler")

@mcp.tool()
def analyze_data_quality(file_path: str) -> str:
"""
Verilen bir CSV dosyasının kalitesini, eksik verilerini,
veri tiplerini ve satır/sütun özetlerini analiz eder.
"""
if not os.path.exists(file_path):
return f"Hata: '{file_path}' yolunda bir dosya bulunamadı."

try:
df = pd.read_csv(file_path)
total_rows = len(df)
total_cols = len(df.columns)

# Eksik veri analizi
missing_counts = df.isnull().sum()
missing_summary = []
for col, count in missing_counts.items():
if int(count) > 0:
percentage = (int(count) / total_rows) * 100
missing_summary.append(f" - {col}: {count} eksik değer (%{percentage:.2f})")

missing_text = "\n".join(missing_summary) if missing_summary else " - Eksik veya kayıp değer bulunamadı."
dtypes_summary = [f" - {col}: {dtype}" for col, dtype in df.dtypes.items()]
dtypes_text = "\n".join(dtypes_summary)

report = (
f"📊 **Veri Seti Kalite Raporu** 📊\n"
f"---------------------------------\n"
f"🔹 **Genel Bilgiler:**\n"
f" - Toplam Satır Sayısı: {total_rows}\n"
f" - Toplam Sütun Sayısı: {total_cols}\n\n"
f"🔹 **Veri Tipleri:**\n{dtypes_text}\n\n"
f"🔹 **Eksik/Kayıp Değer Analizi:**\n{missing_text}\n"
f"---------------------------------"
)
return report
except Exception as e:
return f"Dosya okunurken bir hata oluştu: {str(e)}"


@mcp.tool()
def find_outliers_iqr(file_path: str, column_name: str) -> str:
"""
Belirtilen sayısal sütundaki aykırı (outlier) değerleri
IQR (Interquartile Range) yöntemiyle tespit eder ve özetler.
"""
if not os.path.exists(file_path):
return f"Hata: '{file_path}' yolunda bir dosya bulunamadı."

try:
df = pd.read_csv(file_path)

if column_name not in df.columns:
return f"Hata: Sütun '{column_name}' veri setinde bulunamadı. Mevcut sütunlar: {list(df.columns)}"

# Sayısal sütun kontrolünü normal if yapısına çevirdik
is_numeric = pd.api.types.is_numeric_dtype(df[column_name])
if not is_numeric:
return f"Hata: '{column_name}' sütunu sayısal bir veri tipine sahip değil. Aykırı değer analizi yapılamaz."

# Pyright'ı ikna etmek için ham sütun verisini çekiyoruz
raw_series = df[column_name]
if not isinstance(raw_series, pd.Series):
return f"Hata: Sütun verisi okunamadı."

series = raw_series.dropna()
if not isinstance(series, pd.Series) or series.empty:
return f"Hata: '{column_name}' sütununda analiz edilecek geçerli (sayısal) veri bulunamadı."

# IQR Hesaplama
q1 = float(series.quantile(0.25))
q3 = float(series.quantile(0.75))
iqr = q3 - q1

lower_bound = q1 - 1.5 * iqr
upper_bound = q3 + 1.5 * iqr

# Filtreleme yapıp dönen verinin kesinlikle Series olduğunu doğruluyoruz
filtered_outliers = series[(series < lower_bound) | (series > upper_bound)]
if not isinstance(filtered_outliers, pd.Series):
return f"Hata: Aykırı değerler hesaplanırken veri yapısı uyuşmazlığı oluştu."

outliers = filtered_outliers
outlier_count = len(outliers)
outlier_ratio = (outlier_count / len(series)) * 100

report = (
f"🚨 **Aykırı Değer (Outlier) Analiz Raporu** 🚨\n"
f"---------------------------------\n"
f"🔹 **Sütun:** {column_name}\n"
f"🔹 **İstatistiksel Eşikler:**\n"
f" - Alt Sınır (Lower Bound): {lower_bound:.2f}\n"
f" - Üst Sınır (Upper Bound): {upper_bound:.2f}\n\n"
f"🔹 **Tespit Edilen Sonuçlar:**\n"
f" - Toplam Aykırı Değer Sayısı: {outlier_count}\n"
f" - Aykırı Değerlerin Oranı: %{outlier_ratio:.2f}\n"
)

if outlier_count > 0:
sample_list = outliers.head(5).tolist()
report += f" - Bazı Örnek Aykırı Değerler: {sample_list}\n"

report += "---------------------------------"
return report

except Exception as e:
return f"Aykırı değer analizi yapılırken hata oluştu: {str(e)}"

if __name__ == "__main__":
mcp.run()
Loading
Loading