Skip to main content
Glama
panther-labs

Panther MCP Server

Official

list_global_helpers

Read-only

Retrieve shared Python functions for security rules and detections. View descriptions, code, and metadata with pagination and filtering options.

Instructions

List all global helpers from your Panther instance. Global helpers are shared Python functions that can be used across multiple rules, policies, and other detections.

Returns paginated list of global helpers with metadata including descriptions and code.

Permissions:{'all_of': ['View Rules']}

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
cursorNoOptional cursor for pagination from a previous query
limitNoMaximum number of results to return (1-1000)
name_containsNoCase-insensitive substring to search for in the global's name
created_byNoFilter by creator user ID or actor ID
last_modified_byNoFilter by last modifier user ID or actor ID

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault

No arguments

Implementation Reference

  • The core handler function for the 'list_global_helpers' MCP tool. It fetches paginated global helpers from the Panther REST API, applies filters, and returns metadata with pagination info. Includes input schema via Annotated type hints and Pydantic Fields.
    @mcp_tool(
        annotations={
            "permissions": all_perms(Permission.RULE_READ),
            "readOnlyHint": True,
        }
    )
    async def list_global_helpers(
        cursor: Annotated[
            str | None,
            Field(description="Optional cursor for pagination from a previous query"),
        ] = None,
        limit: Annotated[
            int,
            Field(
                description="Maximum number of results to return (1-1000)",
                examples=[100, 25, 50],
                ge=1,
                le=1000,
            ),
        ] = 100,
        name_contains: Annotated[
            str | None,
            Field(
                description="Case-insensitive substring to search for in the global's name",
                examples=["aws", "crowdstrike", "utility"],
            ),
        ] = None,
        created_by: Annotated[
            str | None,
            Field(
                description="Filter by creator user ID or actor ID",
                examples=["user-123", "john.doe@company.com"],
            ),
        ] = None,
        last_modified_by: Annotated[
            str | None,
            Field(
                description="Filter by last modifier user ID or actor ID",
                examples=["user-456", "jane.smith@company.com"],
            ),
        ] = None,
    ) -> dict[str, Any]:
        """List all global helpers from your Panther instance. Global helpers are shared Python functions that can be used across multiple rules, policies, and other detections.
    
        Returns paginated list of global helpers with metadata including descriptions and code.
        """
        logger.info(f"Fetching {limit} global helpers from Panther")
    
        try:
            # Prepare query parameters based on API spec
            params = {"limit": limit}
            if cursor and cursor.lower() != "null":  # Only add cursor if it's not null
                params["cursor"] = cursor
                logger.info(f"Using cursor for pagination: {cursor}")
            if name_contains:
                params["name-contains"] = name_contains
            if created_by:
                params["created-by"] = created_by
            if last_modified_by:
                params["last-modified-by"] = last_modified_by
    
            async with get_rest_client() as client:
                result, _ = await client.get("/globals", params=params)
    
            # Extract globals and pagination info
            globals_list = result.get("results", [])
            next_cursor = result.get("next")
    
            # Keep only specific fields for each global helper to limit the amount of data returned
            filtered_globals_metadata = [
                {
                    "id": global_helper["id"],
                    "description": global_helper.get("description"),
                    "tags": global_helper.get("tags"),
                    "createdAt": global_helper.get("createdAt"),
                    "lastModified": global_helper.get("lastModified"),
                }
                for global_helper in globals_list
            ]
    
            logger.info(
                f"Successfully retrieved {len(filtered_globals_metadata)} global helpers"
            )
    
            return {
                "success": True,
                "global_helpers": filtered_globals_metadata,
                "total_global_helpers": len(filtered_globals_metadata),
                "has_next_page": bool(next_cursor),
                "next_cursor": next_cursor,
            }
        except Exception as e:
            logger.error(f"Failed to list global helpers: {str(e)}")
            return {"success": False, "message": f"Failed to list global helpers: {str(e)}"}
  • Registers all tools (including 'list_global_helpers') with the FastMCP server instance by calling register_all_tools(mcp), which collects and registers functions decorated with @mcp_tool.
    register_all_tools(mcp)
  • The register_all_tools function that iterates over all @mcp_tool decorated functions and registers them with the MCP instance using mcp_instance.tool().
    def register_all_tools(mcp_instance) -> None:
        """
        Register all tools marked with @mcp_tool with the given MCP instance.
    
        Args:
            mcp_instance: The FastMCP instance to register tools with
        """
        logger.info(f"Registering {len(_tool_registry)} tools with MCP")
    
        # Sort tools by name
        sorted_funcs = sorted(_tool_registry, key=lambda f: f.__name__)
        for tool in sorted_funcs:
            logger.debug(f"Registering tool: {tool.__name__}")
    
            # Get tool metadata if it exists
            metadata = getattr(tool, "_mcp_tool_metadata", {})
    
            annotations = metadata.get("annotations", {})
            # Create tool decorator with metadata
            tool_decorator = mcp_instance.tool(
                name=metadata.get("name"),
                description=metadata.get("description"),
                annotations=annotations,
            )
    
            if annotations and annotations.get("permissions"):
                if not tool.__doc__:
                    tool.__doc__ = ""
                tool.__doc__ += f"\n\n Permissions:{annotations.get('permissions')}"
    
            # Register the tool
            tool_decorator(tool)
    
        logger.info("All tools registered successfully")
  • The @mcp_tool decorator that collects tool functions into a registry (_tool_registry) along with their metadata for later registration.
    def mcp_tool(
        func: Optional[Callable] = None,
        *,
        name: Optional[str] = None,
        description: Optional[str] = None,
        annotations: Optional[Dict[str, Any]] = None,
    ) -> Callable:
        """
        Decorator to mark a function as an MCP tool.
    
        Functions decorated with this will be automatically registered
        when register_all_tools() is called.
    
        Can be used in two ways:
        1. Direct decoration:
            @mcp_tool
            def my_tool():
                ...
    
        2. With parameters:
            @mcp_tool(
                name="custom_name",
                description="Custom description",
                annotations={"category": "data_analysis"}
            )
            def my_tool():
                ...
    
        Args:
            func: The function to decorate
            name: Optional custom name for the tool. If not provided, uses the function name.
            description: Optional description of what the tool does. If not provided, uses the function's docstring.
            annotations: Optional dictionary of additional annotations for the tool.
        """
    
        def decorator(func: Callable) -> Callable:
            # Store metadata on the function
            func._mcp_tool_metadata = {
                "name": name,
                "description": description,
                "annotations": annotations,
            }
            _tool_registry.add(func)
    
            @wraps(func)
            def wrapper(*args, **kwargs):
                return func(*args, **kwargs)
    
            return wrapper
    
        # Handle both @mcp_tool and @mcp_tool(...) cases
        if func is None:
            return decorator
        return decorator(func)
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations provide readOnlyHint=true, but the description adds valuable behavioral context: it specifies the return format ('paginated list of global helpers with metadata including descriptions and code') and includes permission requirements ('Permissions:{"all_of": ["View Rules"]}'). This goes beyond what annotations alone provide, though it doesn't mention rate limits or other constraints.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is efficiently structured in three sentences: purpose statement, definition of global helpers, and return format with permissions. Every sentence adds value with zero wasted words, and key information is front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool has annotations (readOnlyHint), 100% schema coverage, and an output schema (implied by context signals), the description provides excellent completeness. It covers purpose, resource definition, return format, pagination behavior, and permissions - everything needed for an agent to use this tool effectively.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 100% schema description coverage, the input schema already fully documents all 5 parameters. The description doesn't add any parameter-specific information beyond what's in the schema, so it meets the baseline of 3 where the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb ('List') and resource ('all global helpers from your Panther instance'), with a helpful definition of what global helpers are ('shared Python functions that can be used across multiple rules, policies, and other detections'). It distinguishes from the sibling tool 'get_global_helper' (singular) by indicating this lists all helpers rather than retrieving a specific one.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context about when to use this tool ('List all global helpers') and implicitly distinguishes it from 'get_global_helper' (singular retrieval). However, it doesn't explicitly state when NOT to use it or mention alternative tools for similar purposes beyond the implicit sibling distinction.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/panther-labs/mcp-panther'

If you have feedback or need assistance with the MCP directory API, please join our Discord server