Skip to main content
Glama
googleSandy

Google Threat Intelligence MCP Server

by googleSandy

get_threat_profile_recommendations

Retrieve threat recommendations for a specific profile, including threat actors, malware families, campaigns, and vulnerabilities based on configured interests and regions.

Instructions

Returns the list of objects associated to a given Threat Profile.

Each of these objects has one of the following types:

  • Threat Actors

  • Malware Families

  • Software or Toolkits

  • Campaigns

  • IoC Collections

  • Reports

  • Vulnerabilities

We can distinguish between two other types of objects based on how they were associated with the Threat Profile:

  • Recommended objects are automatically recommended or assigned to a Threat Profile based on our proprietary ML that takes into account the Threat Profile's configured interests such as the targeted industries, target regions, source regions, malware roles and actor motivations to recommend the most relevant threats. These objects are identified by the presence of "source": "SOURCE_RECOMMENDATION" within the "context_attributes" response parameter below.

  • Added objects are assigned or added by users to a Threat Profile, when users find other relevant threats not automatically recommended by our ML module. These objects are identified by the presence of "source": "SOURCE_DIRECT_FOLLOW" within the "context_attributes" response parameter below.

    Args: profile_id (str): Threat Profile identifier at Google Threat Intelligence. limit: Limit the number of objects to retrieve. 10 by default.

    Returns: List of Threat (collection) objects identifiers associated to the Threat Profile. Use get_collection_report to retrieve the full objects.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
profile_idYes
limitNo
api_keyNo

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultYes

Implementation Reference

  • Main handler function that executes the get_threat_profile_recommendations tool. It fetches recommendation relationships for a given threat profile and returns sanitized results.
    @server.tool()
    async def get_threat_profile_recommendations(
        profile_id: str, ctx: Context, limit: int = 10, api_key: str = None
    ) -> typing.List[typing.Dict[str, typing.Any]]:
      """Returns the list of objects associated to a given Threat Profile.
    
      Each of these objects has one of the following types:
      - Threat Actors
      - Malware Families
      - Software or Toolkits
      - Campaigns
      - IoC Collections
      - Reports
      - Vulnerabilities
    
      We can distinguish between two other types of objects based on how
      they were associated with the Threat Profile:
    
      - **Recommended objects** are automatically recommended or assigned to
        a Threat Profile based on our proprietary ML that takes into account
        the Threat Profile's configured interests such as the targeted industries,
        target regions, source regions, malware roles and actor motivations
        to recommend the most relevant threats. These objects are identified
        by the presence of "source": "SOURCE_RECOMMENDATION"
        within the "context_attributes" response parameter below.
      - **Added objects** are assigned or added by users to a Threat Profile,
        when users find other relevant threats not automatically recommended
        by our ML module. These objects are identified by the presence of
        "source": "SOURCE_DIRECT_FOLLOW" within the "context_attributes"
        response parameter below.
    
        Args:
          profile_id (str): Threat Profile identifier at Google Threat Intelligence.
          limit: Limit the number of objects to retrieve. 10 by default.
    
        Returns:
          List of Threat (collection) objects identifiers associated to 
          the Threat Profile. Use `get_collection_report` to retrieve the full objects.
      """
      async with vt_client(ctx, api_key=api_key) as client:
        res = await utils.fetch_object_relationships(
            client, "threat_profiles", profile_id, ['recommendations'], limit=limit)
      return utils.sanitize_response(res.get('recommendations', []))
  • Tool registration through wildcard import of threat_profiles module which contains the get_threat_profile_recommendations function decorated with @server.tool().
    from .collections import *
    from .files import *
    from .intelligence import *
    from .netloc import *
    from .threat_profiles import *
    from .urls import *
  • Helper function that fetches relationship objects from Google Threat Intelligence API. Used by get_threat_profile_recommendations to retrieve the 'recommendations' relationship for threat profiles.
    async def fetch_object_relationships(
        vt_client: vt.Client,
        resource_collection_type: str,
        resource_id: str,
        relationships: typing.List[str],
        params: dict[str, typing.Any] | None = None,
        descriptors_only: bool = True,
        limit: int = 10):
      """Fetches the given relationships descriptors from the given object."""
      rel_futures = {}
      # If true, returns descriptors instead of full objects.
      descriptors = '/relationship' if descriptors_only else ''
      async with asyncio.TaskGroup() as tg:
        for rel_name in relationships:
          rel_futures[rel_name] = tg.create_task(
              consume_vt_iterator(
                  vt_client,
                  f"/{resource_collection_type}/{resource_id}"
                  f"{descriptors}/{rel_name}", params=params, limit=limit))
    
      data = {}
      for name, items in rel_futures.items():
        data[name] = []
        for obj in items.result():
          obj_dict = obj.to_dict()
          if 'aggregations' in obj_dict['attributes']:
            del obj_dict['attributes']['aggregations']
          data[name].append(obj_dict)
    
      return data
  • Helper function that recursively removes empty dictionaries and lists from API responses. Used to clean up the threat profile recommendations response before returning it.
    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
  • Final registration point where all tools including get_threat_profile_recommendations are imported into the MCP server, making them available through the FastMCP framework.
    # Load tools.
    from gti_mcp.tools import *
Behavior4/5

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

With no annotations provided, the description carries the full burden of behavioral disclosure. It does an excellent job explaining the two types of objects returned (Recommended vs. Added) and how to distinguish them via the 'source' field in 'context_attributes'. However, it doesn't mention rate limits, authentication requirements, or error conditions, which keeps it from a perfect score.

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

Conciseness4/5

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

The description is well-structured and appropriately sized. It starts with the core purpose, then details object types and distinctions, and finally covers parameters and returns. While comprehensive, some sections could be more concise (e.g., the bulleted lists are thorough but lengthy). Every sentence adds value, but there's minor room for tightening.

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's complexity (returns multiple object types with different association sources), no annotations, and an output schema that likely covers the response structure, the description is remarkably complete. It explains what the tool returns, how to interpret the results, parameter meanings, and follow-up actions. The presence of an output schema means it doesn't need to detail return values exhaustively.

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

Parameters4/5

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

With 0% schema description coverage, the description must compensate for the lack of parameter documentation in the schema. It successfully explains both parameters: 'profile_id' is described as 'Threat Profile identifier at Google Threat Intelligence' and 'limit' as 'Limit the number of objects to retrieve. 10 by default.' However, it doesn't mention the 'api_key' parameter at all, which is a notable gap.

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 tool's purpose with a specific verb ('Returns') and resource ('list of objects associated to a given Threat Profile'). It distinguishes this tool from siblings like 'get_threat_profile' (which likely returns profile metadata) and 'get_collection_report' (which returns full objects rather than just identifiers).

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

Usage Guidelines5/5

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

The description provides explicit guidance on when to use this tool versus alternatives. It states that this tool returns 'List of Threat (collection) objects identifiers' and directs users to 'Use `get_collection_report` to retrieve the full objects.' This clearly distinguishes between getting identifiers versus full object details.

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/googleSandy/gti-mcp-standalone'

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