Query Details

Foundry - MCP server and tool inventory

Foundry Mcp Inventory

Query

AppDependencies
| where isnotempty(tostring(Properties["gen_ai.tool.name"]))
| extend
    Agent = tostring(Properties["gen_ai.agent.name"]),
    Model = tostring(Properties["gen_ai.request.model"]),
    ConvId = tostring(Properties["gen_ai.conversation.id"]),
    ToolName = tostring(Properties["gen_ai.tool.name"]),
    ToolType = tostring(Properties["gen_ai.tool.type"]),
    ToolDescription = tostring(Properties["gen_ai.tool.description"]),
    ServerLabel = coalesce(tostring(Properties["gen_ai.tool.server_label"]), tostring(Properties["mcp.server.label"]), tostring(Properties["server_label"])),
    ServerUrl = coalesce(tostring(Properties["gen_ai.tool.server_url"]), tostring(Properties["mcp.server.url"]), tostring(Properties["server_url"])),
    Operation = tostring(Properties["gen_ai.operation.name"])
| extend McpServer = coalesce(ServerUrl, ServerLabel, tostring(Target))
| where ToolType has "mcp" or Operation has "mcp" or ToolName has "mcp" or ToolDescription has "mcp" or McpServer has "mcp"
| extend McpServer = iff(isempty(McpServer), "(server metadata not emitted)", McpServer)
| summarize Calls = count(), Failures = countif(Success == false),
    Conversations = dcountif(ConvId, isnotempty(ConvId)),
    AvgMs = round(avg(DurationMs), 0), P95Ms = round(percentile(DurationMs, 95), 0),
    FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated)
    by McpServer, ToolName, ToolType, Agent, Model
| extend FailurePct = round(100.0 * Failures / Calls, 2)
| order by Calls desc

Explanation

This query is designed to analyze and inventory the execution of Foundry MCP tools by examining data from a source called AppDependencies. Here's a simplified breakdown of what the query does:

  1. Filter Data: It starts by filtering records where the property gen_ai.tool.name is not empty, indicating the presence of tool execution data.

  2. Extract Information: It extracts various properties related to the tool execution, such as:

    • Agent: The name of the agent executing the tool.
    • Model: The model used in the request.
    • ConvId: The conversation ID.
    • ToolName: The name of the tool.
    • ToolType: The type of the tool.
    • ToolDescription: A description of the tool.
    • ServerLabel and ServerUrl: Information about the server from which the tool was executed.
    • Operation: The name of the operation being performed.
  3. Identify MCP Tools: It identifies records related to MCP (Managed Control Plane) by checking if any of the extracted fields contain the term "mcp".

  4. Handle Missing Server Information: If server information is missing, it labels it as "(server metadata not emitted)".

  5. Summarize Data: It summarizes the data by counting the number of calls, failures, unique conversations, and calculating average and 95th percentile durations. It also notes the first and last time the tool was seen.

  6. Calculate Failure Rate: It calculates the percentage of failed calls.

  7. Order Results: Finally, it orders the results by the number of calls in descending order.

The query is used for discovery purposes, specifically to populate an approved-server watchlist and identify telemetry that lacks a stable server identity. It is tagged with various identifiers like Sentinel-As-Code, Custom, Foundry, AI, and MCP, and is associated with the MITRE ATT&CK technique T1580 (Discovery).