Skip to main content
Glama
googleSandy

Google Threat Intelligence MCP Server

by googleSandy

get_threat_profile_associations_timeline

Retrieve a timeline of associations for a threat profile, including events like aliases, malware, and campaigns with first and last seen dates.

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

  • Handler function that executes the get_threat_profile_associations_timeline tool logic. Calls the VT API endpoint /threat_profiles/{profile_id}/timeline/associations using an iterator and returns sanitized results.
    @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])
  • The @server.tool() decorator registers get_threat_profile_associations_timeline as an MCP tool with the FastMCP server instance.
    @server.tool()
    async def get_threat_profile_associations_timeline(
  • Helper utility that consumes a VT API iterator, used by the handler to fetch the paginated /threat_profiles/{profile_id}/timeline/associations endpoint.
    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 utility that recursively removes empty dicts/lists from the response, used by the handler to sanitize the tool output.
    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
Behavior2/5

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

No annotations provided, so the description carries the full burden of behavioral disclosure. It describes the return attributes but does not mention authentication needs (api_key parameter), rate limits, pagination behavior, or whether the operation is read-only or destructive.

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 structured with bullet points for response attributes and is not overly verbose. However, it could be slightly more concise by not repeating 'the object directly associated with the threat profile' multiple times.

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

Completeness2/5

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

Given the tool has 3 input parameters and no annotations, the description should cover input explanations and usage context. It partially covers output but leaves limit and api_key unexplained. This is incomplete for a tool with moderate complexity.

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?

Schema description coverage is 0%, so the description must explain parameters. The description implicitly mentions profile_id by referencing the Threat Profile, but it does not explain the limit or api_key parameters. The return format is described, but input semantics are lacking.

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 that the tool retrieves the associations timeline for a given Threat Profile. It lists important response attributes, which adds clarity. However, it does not differentiate itself from sibling tools like get_threat_profile or get_collection_timeline_events.

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?

No explicit guidance on when to use this tool versus alternatives. It does not mention prerequisites, such as requiring a valid profile_id, nor does it provide any exclusions or usage context.

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