Query Details
id: 6f1a2b3c-4d5e-4f11-9302-aaaaaaaaaaa2
name: Foundry - MCP / plugin tool description changed
description: |
Detects MCP / plugin tool description poisoning: a tool the agent has
been calling for days suddenly carries a different natural-language
description. Tool description poisoning is the v2.0 taxonomy's primary
agentic supply-chain compromise vector - the binary is unchanged, only
the natural-language instructions the model reads have been swapped.
The rule hashes gen_ai.tool.description (with fallbacks to
microsoft.agent.tool.description and mcp.tool.description) per
(server, tool) and alerts when a hash appears in the last hour that
was not present in the preceding 14-day baseline. Only established
(server, tool) pairs are evaluated (>= 10 baseline calls AND first
seen > 3 days ago) so legitimate onboarding does not fire the rule.
severity: High
requiredDataConnectors:
- connectorId: ApplicationInsights
dataTypes:
- AppDependencies
queryFrequency: PT1H
queryPeriod: P14D
triggerOperator: gt
triggerThreshold: 0
enabled: true
tactics:
- InitialAccess
- DefenseEvasion
- Persistence
relevantTechniques:
- T1195
- T1554
query: |
let baselineWindow = 14d;
let recentWindow = 1h;
let toolDescs =
AppDependencies
| where TimeGenerated > ago(baselineWindow)
| extend
ToolName = tolower(tostring(Properties["gen_ai.tool.name"])),
ToolDesc = tostring(coalesce(
Properties["gen_ai.tool.description"],
Properties["microsoft.agent.tool.description"],
Properties["mcp.tool.description"])),
ToolServer = tolower(tostring(coalesce(
Properties["gen_ai.tool.server"],
Properties["mcp.server.name"],
Properties["microsoft.agent.tool.server"], "unknown")))
| where isnotempty(ToolName) and isnotempty(ToolDesc)
| extend NormDesc = trim(@"\s+", replace_regex(ToolDesc, @"\s+", " "))
| extend DescHash = hash_sha256(NormDesc);
let baseline =
toolDescs
| where TimeGenerated between (ago(baselineWindow) .. ago(recentWindow))
| summarize Calls = count(),
FirstSeen = min(TimeGenerated)
by ToolServer, ToolName, DescHash;
let stable =
baseline
| summarize Calls = sum(Calls), FirstSeen = min(FirstSeen)
by ToolServer, ToolName
| where Calls >= 10 and FirstSeen < ago(3d)
| distinct ToolServer, ToolName;
let recent =
toolDescs
| where TimeGenerated > ago(recentWindow)
| summarize Hits = count(),
Sample = take_any(substring(ToolDesc, 0, 1024)),
AnyAgent = take_any(tostring(Properties["gen_ai.agent.name"])),
AnyConv = take_any(tostring(Properties["gen_ai.conversation.id"])),
FirstSeen = min(TimeGenerated)
by ToolServer, ToolName, DescHash;
recent
| join kind=leftanti baseline on ToolServer, ToolName, DescHash
| join kind=inner stable on ToolServer, ToolName
| where Hits >= 1
| extend AccountName = iff(isempty(AnyAgent), "unknown-agent", AnyAgent)
| project FirstSeen, AccountName, Agent = AnyAgent, ToolServer, ToolName,
DescHash, NewDescriptionSample = Sample, Hits, ConvId = AnyConv
| order by FirstSeen desc
entityMappings:
- entityType: Account
fieldMappings:
- identifier: Name
columnName: AccountName
eventGroupingSettings:
aggregationKind: SingleAlert
incidentConfiguration:
createIncident: true
groupingConfiguration:
enabled: true
reopenClosedIncident: false
lookbackDuration: P1D
matchingMethod: Selected
groupByEntities:
- Account
groupByAlertDetails: []
groupByCustomDetails: []
version: 1.0.0
kind: Scheduled
tags:
- Sentinel-As-Code
- Custom
- Foundry
- AI
- MCP
- SupplyChain
- AIRT-v2
This query is designed to detect suspicious changes in the descriptions of tools used by agents, which could indicate a security threat known as "tool description poisoning." Here's a simplified breakdown of what the query does:
Purpose: The query monitors for changes in the natural-language descriptions of tools that agents have been using consistently. If a tool's description suddenly changes, it could be a sign of a supply-chain compromise, where the tool's functionality remains the same, but the instructions or descriptions read by the model have been altered.
Data Source: It uses data from Application Insights, specifically looking at application dependencies.
Time Frame: The query checks for new tool description hashes that appear within the last hour but were not present in the previous 14 days.
Criteria for Evaluation:
Alerting: If a new description hash is detected for an established tool-server pair, an alert is generated. The alert includes details like the first time the change was seen, the agent name, tool server, tool name, and a sample of the new description.
Severity and Tactics: The rule is marked with high severity and is associated with tactics like Initial Access, Defense Evasion, and Persistence, indicating the potential impact of such changes.
Incident Management: If an alert is triggered, an incident is created. The incidents are grouped by account, and the system is configured to not reopen closed incidents.
Overall, this query helps in identifying potential security threats by monitoring unexpected changes in tool descriptions, which could be a vector for supply-chain attacks.

David Alonso
Released: June 8, 2026
Tables
Keywords
Operators