microsoft / microsoft/mcp

Remove KQL management-command blocklist from shared KqlQueryValidator (Kusto + Monitor)

Open
#3,391 2 comments 0 reactions 1 assignee Claimed by @LarryOsterman View on GitHub
enhancement needs-team-attention server-Azure.Mcp tools-Core tools-Kusto tools-Monitor
Dominant language
C#
Stars
3.7k
Forks
624
Avg merge
2d 20h
Merged PRs (30d)
220

Description

## Background

In #3202 the MySQL and PostgreSQL `database query` tools were marked `Destructive = true`, `Idempotent = false`, `ReadOnly = false`, and the keyword/verb blocklists were removed from their validators. The rationale: the signed-in user's permissions are the authority on what a statement may do, and heuristic blocklists produce false positives on legitimate queries while being trivially bypassable.

`KqlQueryValidator` should get the same treatment.

## Current behavior

`core/Microsoft.Mcp.Core/src/Validation/KqlQueryValidator.cs` is shared by two toolsets:

- `kusto query` — `KustoService.cs:254`
- Monitor — `MonitorService.QueryResourceLogs` (:54), `QueryWorkspace` (:113), `QueryWorkspaceLogs` (:247), backing `monitor_workspace_log_query`, `monitor_resource_log_query`, and related commands

It rejects queries based on:

- **`s_dangerousCommands` blocklist** — `.drop`, `.alter`, `.create`, `.delete`, `.set`, `.append`, `.set-or-append`, `.set-or-replace`, `.ingest`, `.purge`, `.execute`, matched at input start or after `|` / `;`. These are Kusto *management/control commands*; whether a caller may run them is already governed by their Kusto RBAC role (Database Admin/Ingestor vs Viewer).
- **Tautology detection** — `s_tautologyPattern` rejects `or 1==1`, `or 1=1`, `or true`, `or 'x'=='x'`. These are legitimate constructs in a query the caller authored themselves; there is no untrusted concatenation happening here. This also false-positives on any `where` clause that happens to match the shape.

## Proposed change

Reduce `KqlQueryValidator` to structural checks only:

- Empty / whitespace-only query
- Max query length (currently 10,000 chars)

Remove `s_dangerousCommands`, `s_managementCommandPattern`, `BuildManagementCommandPattern()`, and `s_tautologyPattern`. At that point the string-literal stripping (`queryWithoutStrings`) has no remaining consumer and can go too.

## Considerations

- This validator lives in `Microsoft.Mcp.Core` and is **shared across two toolsets** — changing it affects Kusto and Monitor together. Decide whether both should be relaxed in one change or whether the validator should become configurable per caller.
- If management commands become reachable through `kusto query`, revisit `QueryCommand`'s metadata (`Destructive` / `ReadOnly`) the way #3202 did for MySQL/PostgreSQL. The Monitor log query commands query Log Analytics rather than ADX and may warrant different treatment.

## Checklist

- [ ] Decide on shared vs. per-caller validation policy for Kusto and Monitor
- [ ] Trim `KqlQueryValidator` to structural checks
- [ ] Update `core/Microsoft.Mcp.Core/tests/Microsoft.Mcp.Core.Tests/Validation/KqlQueryValidatorTests.cs`
- [ ] Update affected command metadata if management commands become reachable
- [ ] Update `servers/Azure.Mcp.Server/docs/azmcp-commands.md` if descriptions or metadata flags change
- [ ] Add a changelog entry under `servers/Azure.Mcp.Server/changelog-entries/` (`.yml`, not `.md` — `Compile-Changelog.ps1` only globs `*.yaml`/`*.yml`)

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.