get_hunting_ruleset
Retrieve a hunting ruleset from Google Threat Intelligence to access YARA rules for threat detection and analysis.
Instructions
Get a Hunting Ruleset object from Google Threat Intelligence.
A Hunting Ruleset object describes a user's hunting ruleset. It may contain multiple Yara rules.
The content of the Yara rules is in the rules attribute.
Some important object attributes:
creation_date: creation date as UTC timestamp.
modification_date (int): last modification date as UTC timestamp.
name (str): ruleset name.
rule_names (list[str]): contains the names of all rules in the ruleset.
number_of_rules (int): number of rules in the ruleset.
rules (str): rule file contents.
tags (list[str]): ruleset's custom tags.
Args: ruleset_id (required): Hunting ruleset identifier.
Returns: Hunting Ruleset object.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| ruleset_id | Yes | ||
| api_key | No |
Implementation Reference
- gti_mcp/tools/intelligence.py:72-103 (handler)The main handler function get_hunting_ruleset decorated with @server.tool(). It takes a ruleset_id parameter, Context, and optional api_key, uses utils.fetch_object to retrieve the hunting ruleset from the VirusTotal API endpoint '/intelligence/hunting_rulesets/{ruleset_id}', and returns the sanitized response.
@server.tool() async def get_hunting_ruleset(ruleset_id: str, ctx: Context, api_key: str = None) -> typing.Dict[str, typing.Any]: """Get a Hunting Ruleset object from Google Threat Intelligence. A Hunting Ruleset object describes a user's hunting ruleset. It may contain multiple Yara rules. The content of the Yara rules is in the `rules` attribute. Some important object attributes: - creation_date: creation date as UTC timestamp. - modification_date (int): last modification date as UTC timestamp. - name (str): ruleset name. - rule_names (list[str]): contains the names of all rules in the ruleset. - number_of_rules (int): number of rules in the ruleset. - rules (str): rule file contents. - tags (list[str]): ruleset's custom tags. Args: ruleset_id (required): Hunting ruleset identifier. Returns: Hunting Ruleset object. """ async with vt_client(ctx, api_key=api_key) as client: res = await utils.fetch_object( client, "intelligence/hunting_rulesets", "hunting_ruleset", ruleset_id, ) return utils.sanitize_response(res) - gti_mcp/utils.py:29-84 (helper)The fetch_object helper function used by get_hunting_ruleset to fetch objects from the Google Threat Intelligence API. It handles API errors, builds the request with optional attributes and relationships, and returns the object as a dictionary.
async def fetch_object( vt_client: vt.Client, resource_collection_type: str, resource_type: str, resource_id: str, attributes: list[str] | None = None, relationships: list[str] | None = None, params: dict[str, typing.Any] | None = None): """Fetches objects from Google Threat Intelligence API.""" logging.info( f"Fetching comprehensive {resource_collection_type} " f"report for id: {resource_id}") params = {k: v for k, v in params.items()} if params else {} # Retrieve a selection of object attributes and/or relationships. if attributes: params["attributes"] = ",".join(attributes) if relationships: params["relationships"] = ",".join(relationships) try: obj = await vt_client.get_object_async( f"/{resource_collection_type}/{resource_id}", params=params) if obj.error: logging.error( f"Error fetching main {resource_type} report for {resource_id}: {obj.error}" ) return { "error": f"Failed to get main {resource_type} report: {obj.error}", # "details": report.get("details"), } except vt.error.APIError as e: logging.warning( f"VirusTotal API Error fetching {resource_type} {resource_id}: {e.code} - {e.message}" ) return { "error": f"VirusTotal API Error: {e.code} - {e.message}", "details": f"The requested {resource_type} '{resource_id}' could not be found or there was an issue with the API request." } except Exception as e: logging.exception( f"Unexpected error fetching {resource_type} {resource_id}: {e}" ) return {"error": "An unexpected internal error occurred."} # Build response. obj_dict = obj.to_dict() obj_dict['id'] = obj.id if 'aggregations' in obj_dict['attributes']: del obj_dict['attributes']['aggregations'] logging.info( f"Successfully generated concise threat summary for id: {resource_id}") return obj_dict - gti_mcp/utils.py:119-138 (helper)The sanitize_response helper function used by get_hunting_ruleset to recursively remove empty dictionaries and lists from the API response.
def sanitize_response(data: typing.Any) -> typing.Any: """Removes empty dictionaries and lists recursively from a response.""" if isinstance(data, dict): sanitized_dict = {} for key, value in data.items(): sanitized_value = sanitize_response(value) if sanitized_value is not None: sanitized_dict[key] = sanitized_value return sanitized_dict elif isinstance(data, list): sanitized_list = [] for item in data: sanitized_item = sanitize_response(item) if sanitized_item is not None: sanitized_list.append(sanitized_item) return sanitized_list elif isinstance(data, str): return data if data else None else: return data - gti_mcp/server.py:67-73 (registration)Creates the FastMCP server instance and imports all tools (including get_hunting_ruleset) via 'from gti_mcp.tools import *', which registers all @server.tool() decorated functions.
server = FastMCP( "Google Threat Intelligence MCP server", dependencies=["vt-py"], stateless_http=stateless) # Load tools. from gti_mcp.tools import * - gti_mcp/tools/__init__.py:14-19 (registration)The tools module init file that imports from all tool modules including 'from .intelligence import *', exposing the get_hunting_ruleset function for registration when the tools package is imported.
from .collections import * from .files import * from .intelligence import * from .netloc import * from .threat_profiles import * from .urls import *