Add outlier filtering metadata to get_valuation_comparables response

The MCP now includes detailed outlier filtering information in the response,
allowing LLMs and bots to inform users about data quality improvements.

Changes to nadlan_mcp/fastmcp_server.py:
- Updated get_valuation_comparables to include outlier filtering metadata
- deal_breakdown now includes when filtering is applied:
  - total_deals: Count after filtering (final result)
  - total_deals_before_filtering: Original count before filtering
  - outliers_removed: Number of deals filtered out
  - filtering_method: Method used ("iqr", "percent", or "none")
  - iqr_multiplier: IQR multiplier when using IQR method (e.g., 1.5)
- Updated docstring to clarify that outlier filtering is automatic
  and metadata is included in response

Changes to tests/e2e/test_mcp_tools_comprehensive.py:
- Added assertions to verify outlier filtering metadata fields
- Test now validates the structure and types of filtering information

Example response:
{
  "market_statistics": {
    "deal_breakdown": {
      "total_deals": 15,
      "total_deals_before_filtering": 17,
      "outliers_removed": 2,
      "filtering_method": "iqr",
      "iqr_multiplier": 1.5
    }
  }
}

This allows bots like nadlan-bot to properly inform users:
"Found 17 comparable deals, filtered 2 outliers using IQR method (k=1.5),
 showing 15 deals."

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Nitzan P
2025-11-26 23:45:56 +02:00
parent 623d79947b
commit 6882d7ab71
2 changed files with 42 additions and 11 deletions
+16 -4
View File
@@ -92,12 +92,24 @@ class TestMCPToolsE2E:
# Normalized structure: total_comparables -> market_statistics.deal_breakdown.total_deals
assert "market_statistics" in data
assert "deal_breakdown" in data["market_statistics"]
assert "total_deals" in data["market_statistics"]["deal_breakdown"]
assert isinstance(data["market_statistics"]["deal_breakdown"]["total_deals"], int)
assert data["market_statistics"]["deal_breakdown"]["total_deals"] >= 0
deal_breakdown = data["market_statistics"]["deal_breakdown"]
assert "total_deals" in deal_breakdown
assert isinstance(deal_breakdown["total_deals"], int)
assert deal_breakdown["total_deals"] >= 0
# Verify outlier filtering metadata is included when filtering is applied
if "outliers_removed" in deal_breakdown:
assert isinstance(deal_breakdown["outliers_removed"], int)
assert deal_breakdown["outliers_removed"] >= 0
assert "total_deals_before_filtering" in deal_breakdown
assert "filtering_method" in deal_breakdown
assert deal_breakdown["filtering_method"] in ["iqr", "percent", "none"]
if deal_breakdown["filtering_method"] == "iqr":
assert "iqr_multiplier" in deal_breakdown
assert isinstance(deal_breakdown["iqr_multiplier"], (int, float))
# Normalized structure: comparables -> deals
if data["market_statistics"]["deal_breakdown"]["total_deals"] > 0:
if deal_breakdown["total_deals"] > 0:
assert "deals" in data
comp = data["deals"][0]
assert "deal_amount" in comp