Skip to main content
Glama
googleSandy

Google Threat Intelligence MCP Server

by googleSandy

get_threat_profile_associations_timeline

Retrieve timeline associations for threat profiles to analyze relationships with malware, actors, campaigns, and other threat intelligence data over time.

Instructions

Retrieves the associations timeline for the given Threat Profile.

Some important response attributes:

  • event_type (str): the type of the timeline association such as Alias, Motivation, Malware, Actor, Toolkit, Report, Campaign, etc.

  • event_entity (str): The name or value of the timeline association.

  • first_seen (int): Unix epoch UTC time (seconds) when the association between the object and the threat profile was made.

  • last_seen (int): Unix epoch UTC time (seconds) of most recent observed relationship between the object and the threat profile.

  • name (str): name of the object directly associated with the threat profile.

  • link (str): URL of the object directly associated with the threat profile

Returns: List of dictionaries containing timeline associations.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
profile_idYes
limitNo
api_keyNo

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultYes

Implementation Reference

  • The main handler and registration for get_threat_profile_associations_timeline tool. This async function takes profile_id, ctx, limit, and optional api_key parameters, and retrieves timeline associations from the VirusTotal API endpoint /threat_profiles/{profile_id}/timeline/associations. It uses the @server.tool() decorator for registration.
    @server.tool()
    async def get_threat_profile_associations_timeline(
        profile_id: str, ctx: Context, limit: int = 10, api_key: str = None
    ) -> typing.List[typing.Dict[str, typing.Any]]:
      """Retrieves the associations timeline for the given Threat Profile.
    
      Some important response attributes:
        - event_type (str): the type of the timeline association such as Alias, Motivation,
                            Malware, Actor, Toolkit, Report, Campaign, etc.
        - event_entity (str): The name or value of the timeline association.
        - first_seen (int): Unix epoch UTC time (seconds) when the association
                            between the object and the threat profile was made.
        - last_seen (int): Unix epoch UTC time (seconds) of most recent observed
                            relationship between the object and the threat profile.
        - name (str): name of the object directly associated with the threat profile.
        - link (str): URL of the object directly associated with the threat profile
    
      Returns:
        List of dictionaries containing timeline associations.
      """
      async with vt_client(ctx, api_key=api_key) as client:
        res = await utils.consume_vt_iterator(
            client,
            f"/threat_profiles/{profile_id}/timeline/associations",
            limit=limit,
        )
      return utils.sanitize_response([o.to_dict() for o in res])
  • Helper function consume_vt_iterator that consumes a VirusTotal API iterator and returns a list of objects. Used by the handler to fetch timeline associations from the API.
    async def consume_vt_iterator(
        vt_client: vt.Client, endpoint: str, params: dict | None = None, limit: int = 10):
      """Consumes a vt.Iterator iterator and return the list of objects."""
      res = []
      async for obj in vt_client.iterator(endpoint, params=params, limit=limit):
        res.append(obj)
      return res
  • Helper function sanitize_response that recursively removes empty dictionaries and lists from API responses. Used to clean up the timeline associations response before returning.
    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
Behavior3/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 describes the response format in detail, including key attributes like event_type and timestamps, which helps the agent understand the output. However, it lacks information on error handling, rate limits, authentication needs (though api_key is in the schema), or whether the operation is read-only (implied by 'retrieves' but not explicit).

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, with a clear opening sentence followed by bullet points for response attributes and a returns statement. Every sentence adds value, such as detailing response attributes, though it could be more front-loaded by integrating key usage details earlier.

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

Completeness3/5

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

Given the complexity (a timeline retrieval tool with 3 parameters and no annotations) and the presence of an output schema (implied by 'Returns' details), the description is moderately complete. It thoroughly explains the response format, which compensates for the lack of output schema, but gaps remain in parameter explanations and usage context, making it adequate but not fully comprehensive.

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

Parameters2/5

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

The schema description coverage is 0%, so the description must compensate for undocumented parameters. It does not explain any parameters—profile_id, limit, or api_key—leaving their purposes unclear. For example, it does not clarify what profile_id refers to, how limit affects results, or that api_key might be optional with a default. This fails to add meaning beyond the bare schema.

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

Purpose4/5

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

The description clearly states the tool 'retrieves the associations timeline for the given Threat Profile,' specifying the verb (retrieves) and resource (associations timeline for Threat Profile). It distinguishes from sibling tools like 'get_threat_profile' (which likely retrieves profile details) and 'list_threat_profiles' (which lists profiles), but does not explicitly differentiate them by name.

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

Usage Guidelines2/5

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

The description provides no guidance on when to use this tool versus alternatives. It does not mention prerequisites, such as needing a valid profile_id, or compare it to related tools like 'get_threat_profile' or 'get_collection_timeline_events' for context-specific usage.

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