Change: Conditional tool registration, disabled tools invisible
Replaced runtime checks with decorator-based registration: - Created conditional_tool() decorator - Disabled tools not registered with FastMCP at all - Client queries won't see disabled tools - Removed "This tool is currently disabled" messages Disabled tools (invisible to clients): - get_deals_by_radius - get_street_deals - get_market_activity_metrics All 311 tests pass, 17 skipped 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -29,6 +29,28 @@ mcp = FastMCP("nadlan-mcp")
|
|||||||
client = GovmapClient()
|
client = GovmapClient()
|
||||||
|
|
||||||
|
|
||||||
|
def conditional_tool(config_flag: str):
|
||||||
|
"""
|
||||||
|
Decorator to conditionally register MCP tools based on config.
|
||||||
|
|
||||||
|
If the config flag is False, the tool won't be registered with FastMCP.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def decorator(func):
|
||||||
|
config = get_config()
|
||||||
|
enabled = getattr(config, config_flag, True)
|
||||||
|
|
||||||
|
if enabled:
|
||||||
|
# Register the tool with FastMCP
|
||||||
|
return mcp.tool()(func)
|
||||||
|
else:
|
||||||
|
# Don't register, just return the function unchanged
|
||||||
|
logger.info(f"Tool {func.__name__} is DISABLED (config: {config_flag})")
|
||||||
|
return func
|
||||||
|
|
||||||
|
return decorator
|
||||||
|
|
||||||
|
|
||||||
def log_mcp_call(func_name: str, **params):
|
def log_mcp_call(func_name: str, **params):
|
||||||
"""
|
"""
|
||||||
Log MCP tool function calls with their parameters for debugging and monitoring.
|
Log MCP tool function calls with their parameters for debugging and monitoring.
|
||||||
@@ -83,7 +105,7 @@ def strip_bloat_fields(deals: List[Deal]) -> List[Dict[str, Any]]:
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
@mcp.tool()
|
@conditional_tool("tool_autocomplete_address_enabled")
|
||||||
def autocomplete_address(search_text: str) -> str:
|
def autocomplete_address(search_text: str) -> str:
|
||||||
"""Search and autocomplete Israeli addresses.
|
"""Search and autocomplete Israeli addresses.
|
||||||
|
|
||||||
@@ -126,7 +148,7 @@ def autocomplete_address(search_text: str) -> str:
|
|||||||
return f"Error searching for address: {str(e)}"
|
return f"Error searching for address: {str(e)}"
|
||||||
|
|
||||||
|
|
||||||
@mcp.tool()
|
@conditional_tool("tool_get_deals_by_radius_enabled")
|
||||||
def get_deals_by_radius(latitude: float, longitude: float, radius_meters: int = 500) -> str:
|
def get_deals_by_radius(latitude: float, longitude: float, radius_meters: int = 500) -> str:
|
||||||
"""Get polygon metadata within a radius of coordinates.
|
"""Get polygon metadata within a radius of coordinates.
|
||||||
|
|
||||||
@@ -141,9 +163,6 @@ def get_deals_by_radius(latitude: float, longitude: float, radius_meters: int =
|
|||||||
Returns:
|
Returns:
|
||||||
JSON string containing polygon metadata (areas with deals nearby)
|
JSON string containing polygon metadata (areas with deals nearby)
|
||||||
"""
|
"""
|
||||||
if not get_config().tool_get_deals_by_radius_enabled:
|
|
||||||
return "This tool is currently disabled"
|
|
||||||
|
|
||||||
log_mcp_call(
|
log_mcp_call(
|
||||||
"get_deals_by_radius", latitude=latitude, longitude=longitude, radius_meters=radius_meters
|
"get_deals_by_radius", latitude=latitude, longitude=longitude, radius_meters=radius_meters
|
||||||
)
|
)
|
||||||
@@ -171,7 +190,7 @@ def get_deals_by_radius(latitude: float, longitude: float, radius_meters: int =
|
|||||||
return f"Error fetching polygons by radius: {str(e)}"
|
return f"Error fetching polygons by radius: {str(e)}"
|
||||||
|
|
||||||
|
|
||||||
@mcp.tool()
|
@conditional_tool("tool_get_street_deals_enabled")
|
||||||
def get_street_deals(polygon_id: str, limit: int = 100, deal_type: int = 2) -> str:
|
def get_street_deals(polygon_id: str, limit: int = 100, deal_type: int = 2) -> str:
|
||||||
"""Get real estate deals for a specific street polygon.
|
"""Get real estate deals for a specific street polygon.
|
||||||
|
|
||||||
@@ -183,9 +202,6 @@ def get_street_deals(polygon_id: str, limit: int = 100, deal_type: int = 2) -> s
|
|||||||
Returns:
|
Returns:
|
||||||
JSON string containing recent real estate deals for the street
|
JSON string containing recent real estate deals for the street
|
||||||
"""
|
"""
|
||||||
if not get_config().tool_get_street_deals_enabled:
|
|
||||||
return "This tool is currently disabled"
|
|
||||||
|
|
||||||
log_mcp_call("get_street_deals", polygon_id=polygon_id, limit=limit, deal_type=deal_type)
|
log_mcp_call("get_street_deals", polygon_id=polygon_id, limit=limit, deal_type=deal_type)
|
||||||
try:
|
try:
|
||||||
deals = client.get_street_deals(polygon_id, limit, deal_type=deal_type)
|
deals = client.get_street_deals(polygon_id, limit, deal_type=deal_type)
|
||||||
@@ -231,7 +247,7 @@ def get_street_deals(polygon_id: str, limit: int = 100, deal_type: int = 2) -> s
|
|||||||
return f"Error fetching street deals: {str(e)}"
|
return f"Error fetching street deals: {str(e)}"
|
||||||
|
|
||||||
|
|
||||||
@mcp.tool()
|
@conditional_tool("tool_find_recent_deals_for_address_enabled")
|
||||||
def find_recent_deals_for_address(
|
def find_recent_deals_for_address(
|
||||||
address: str,
|
address: str,
|
||||||
years_back: int = 2,
|
years_back: int = 2,
|
||||||
@@ -353,7 +369,7 @@ def find_recent_deals_for_address(
|
|||||||
return f"Error analyzing address: {str(e)}"
|
return f"Error analyzing address: {str(e)}"
|
||||||
|
|
||||||
|
|
||||||
@mcp.tool()
|
@conditional_tool("tool_get_neighborhood_deals_enabled")
|
||||||
def get_neighborhood_deals(polygon_id: str, limit: int = 100, deal_type: int = 2) -> str:
|
def get_neighborhood_deals(polygon_id: str, limit: int = 100, deal_type: int = 2) -> str:
|
||||||
"""Get real estate deals for a specific neighborhood polygon.
|
"""Get real estate deals for a specific neighborhood polygon.
|
||||||
|
|
||||||
@@ -410,7 +426,7 @@ def get_neighborhood_deals(polygon_id: str, limit: int = 100, deal_type: int = 2
|
|||||||
return f"Error fetching neighborhood deals: {str(e)}"
|
return f"Error fetching neighborhood deals: {str(e)}"
|
||||||
|
|
||||||
|
|
||||||
@mcp.tool()
|
@conditional_tool("tool_analyze_market_trends_enabled")
|
||||||
def analyze_market_trends(
|
def analyze_market_trends(
|
||||||
address: str,
|
address: str,
|
||||||
years_back: int = 3,
|
years_back: int = 3,
|
||||||
@@ -632,7 +648,7 @@ def analyze_market_trends(
|
|||||||
return f"Error analyzing market trends: {str(e)}"
|
return f"Error analyzing market trends: {str(e)}"
|
||||||
|
|
||||||
|
|
||||||
@mcp.tool()
|
@conditional_tool("tool_compare_addresses_enabled")
|
||||||
def compare_addresses(addresses: List[str]) -> str:
|
def compare_addresses(addresses: List[str]) -> str:
|
||||||
"""Compare real estate markets between multiple addresses.
|
"""Compare real estate markets between multiple addresses.
|
||||||
|
|
||||||
@@ -767,7 +783,7 @@ def compare_addresses(addresses: List[str]) -> str:
|
|||||||
return f"Error comparing addresses: {str(e)}"
|
return f"Error comparing addresses: {str(e)}"
|
||||||
|
|
||||||
|
|
||||||
@mcp.tool()
|
@conditional_tool("tool_get_valuation_comparables_enabled")
|
||||||
def get_valuation_comparables(
|
def get_valuation_comparables(
|
||||||
address: str,
|
address: str,
|
||||||
years_back: int = 2,
|
years_back: int = 2,
|
||||||
@@ -955,7 +971,7 @@ def get_valuation_comparables(
|
|||||||
return f"Error getting valuation comparables: {str(e)}"
|
return f"Error getting valuation comparables: {str(e)}"
|
||||||
|
|
||||||
|
|
||||||
@mcp.tool()
|
@conditional_tool("tool_get_deal_statistics_enabled")
|
||||||
def get_deal_statistics(
|
def get_deal_statistics(
|
||||||
address: str,
|
address: str,
|
||||||
years_back: int = 2,
|
years_back: int = 2,
|
||||||
@@ -1077,7 +1093,7 @@ def _safe_calculate_metric(metric_func, deals):
|
|||||||
return {"error": str(e)}
|
return {"error": str(e)}
|
||||||
|
|
||||||
|
|
||||||
@mcp.tool()
|
@conditional_tool("tool_get_market_activity_metrics_enabled")
|
||||||
def get_market_activity_metrics(address: str, years_back: int = 2, radius_meters: int = 100) -> str:
|
def get_market_activity_metrics(address: str, years_back: int = 2, radius_meters: int = 100) -> str:
|
||||||
"""Get comprehensive market activity and investment potential analysis.
|
"""Get comprehensive market activity and investment potential analysis.
|
||||||
|
|
||||||
@@ -1097,9 +1113,6 @@ def get_market_activity_metrics(address: str, years_back: int = 2, radius_meters
|
|||||||
- Investment potential analysis
|
- Investment potential analysis
|
||||||
- Price appreciation and volatility
|
- Price appreciation and volatility
|
||||||
"""
|
"""
|
||||||
if not get_config().tool_get_market_activity_metrics_enabled:
|
|
||||||
return "This tool is currently disabled"
|
|
||||||
|
|
||||||
log_mcp_call(
|
log_mcp_call(
|
||||||
"get_market_activity_metrics",
|
"get_market_activity_metrics",
|
||||||
address=address,
|
address=address,
|
||||||
|
|||||||
Reference in New Issue
Block a user