[{'Text': 'from typing import Callable, List, Tuple, Any\nfrom functools import wraps\nimport os\n\n\n\n\n# DECORATORS\n\n# Store tool requirements for status reporting\n_TOOL_REQUIREMENTS = {}\n\ndef check_env_vars(tool_name: str, env_vars: List[str]) -> bool:\n    """\n    Check if environment variables are available and track for status reporting.\n    \n    Args:\n        tool_name: Name of the tool for tracking\n        env_vars: List of environment variable names that must be set\n        \n    Returns:\n        bool: True if all environment variables are present\n    """\n    # Store tool requirements for status reporting\n    all_present = all(os.getenv(var) for var in env_vars)\n    _TOOL_REQUIREMENTS[tool_name] = {\n        \'env_vars\': env_vars,\n        \'available\': all_present\n    }\n    \n    if not all_present:\n        missing_vars = [var for var in env_vars if not os.getenv(var)]\n        print(f"[MCP] Skipping {tool_name}: missing env vars {missing_vars}")\n    else:\n        print(f"[MCP] Registering {tool_name}: env vars {env_vars} ✓")\n    \n    return all_present\n\n\ndef get_mcp_status_info() -> str:\n    """Generate status information about available and missing tools."""\n    if not _TOOL_REQUIREMENTS:\n        return "All tools available (no conditional tools detected)"\n    \n    available_tools = []\n    missing_tools = []\n    \n    for tool_name, info in _TOOL_REQUIREMENTS.items():\n        if info[\'available\']:\n            available_tools.append(tool_name)\n        else:\n            missing_env_vars = [var for var in info[\'env_vars\'] if not os.getenv(var)]\n            missing_tools.append(f"{tool_name} (needs: {\', \'.join(missing_env_vars)})")\n    \n    status_parts = []\n    \n    if available_tools:\n        status_parts.append(f"✓ Available: {len(available_tools)} conditional tools")\n    \n    if missing_tools:\n        status_parts.append(f"✗ Missing: {len(missing_tools)} tools need env vars")\n        status_parts.append("Missing tools: " + " | ".join(missing_tools))\n    \n    if not missing_tools:\n        status_parts.append("All conditional tools available!")\n    \n    return " | ".join(status_parts)\n\n\ndef dynamic_docstring(replacements: List[Tuple[str, Callable[[], str]]]):\n    """\n    Decorator to dynamically replace placeholders in docstrings.\n    \n    Args:\n        replacements: List of [placeholder, function] pairs\n                     where placeholder is replaced with function\'s return value\n    \n    Example:\n        @dynamic_docstring([("{DATASETS}", list_datasets)])\n        def my_tool():\n            \'\'\'Tool with {DATASETS} placeholder\'\'\'\n            pass\n    """\n    def decorator(func):\n        # Get original docstring\n        original_doc = func.__doc__ or ""\n        \n        # Apply all replacements\n        updated_doc = original_doc\n        for placeholder, replacement_func in replacements:\n            try:\n                replacement_value = replacement_func()\n                updated_doc = updated_doc.replace(placeholder, replacement_value)\n            except Exception as e:\n                print(f"Warning: Failed to replace {placeholder} in {func.__name__}: {e}")\n                # Keep placeholder if replacement fails\n        \n        # Update the docstring\n        func.__doc__ = updated_doc\n        \n        return func\n    \n    return decorator\n'}]