Skip to content

fix(querier): let the MCP query_logs tool run count aggregations - #607

Merged
jensholdgaard merged 3 commits into
mainfrom
fix-mcp-count-aggregation
Jul 23, 2026
Merged

fix(querier): let the MCP query_logs tool run count aggregations#607
jensholdgaard merged 3 commits into
mainfrom
fix-mcp-count-aggregation

Conversation

@jensholdgaard

@jensholdgaard jensholdgaard commented Jul 23, 2026

Copy link
Copy Markdown
Owner

Let the MCP query_logs tool run count aggregations

The MCP query_logs handler unconditionally injected its row-cap limit stage (mcp.rs), but count [by …] and limit are mutually exclusive (compile::validate, RFC 0002 amendment 2026-07-15). So every aggregation submitted through the MCP surface was rejected with "a query with a count stage does not support limit" — an agent could page raw rows but couldn't ask count by attr.model about its own data.

The JSON /v1/query path already handles this correctly: handle_query computes is_aggregation and skips apply_limit for count queries (querier.rs:481). This mirrors that guard into the MCP handler, so the two surfaces behave identically.

Change

  • mcp.rs: skip the injected limit cap when the statement carries a Stage::Count — same guard as the JSON API, referenced in the comment.

Test (RFC 0027 §5, regression)

  • rfc0027_3_query_logs_count_aggregation: runs template_id == 1 | count by template_id through the full MCP protocol with a non-null limit argument set — proving the cap is ignored for aggregations rather than injected — and asserts the tool's answer is byte-identical to the JSON API's for the same statement.

Invariants

No hazard/pillar surface touched — this is a query-surface parity fix (hazard #6: the DSL layer must behave the same across surfaces). No schema, WAL, or miner change.

Verification

  • cargo clippy -p ourios-server --all-targets --all-features -- -D warnings → clean
  • cargo test -p ourios-server --test it rfc0027 → 8 passed, 0 failed (incl. the new regression)
  • cargo fmt --all --check → clean

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Fixed log queries using count by aggregations with a specified limit.
    • Aggregated queries now return grouped results instead of being rejected due to the limit setting.
    • Ensured results remain consistent between MCP and JSON API responses.

The MCP query_logs handler unconditionally injected its row-cap limit
stage, but `count [by …]` and `limit` are mutually exclusive
(compile::validate) — so every aggregation through the MCP surface was
rejected with "does not support limit". The JSON /v1/query path already
guards this behind an is_aggregation check (handle_query); mirror it in
the MCP handler so an agent can aggregate its own telemetry (e.g.
`count by attr.model`), not just page raw rows.

Adds rfc0027_3_query_logs_count_aggregation: runs a count-by through the
full MCP protocol with a limit argument set (proving it is ignored for
aggregations) and asserts byte-equivalence with the JSON API.

Signed-off-by: Jens Holdgaard Pedersen <Jens@holdgaard.org>
@jensholdgaard
jensholdgaard requested a review from Copilot July 23, 2026 15:25
@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@jensholdgaard, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 38 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: a7d5346f-6db8-40ac-84d6-99a79e6f4a45

📥 Commits

Reviewing files that changed from the base of the PR and between c9c3fee and 6a89141.

📒 Files selected for processing (2)
  • crates/ourios-server/src/mcp.rs
  • crates/ourios-server/tests/it/rfc0027_mcp.rs
📝 Walkthrough

Walkthrough

The MCP query_logs tool now avoids applying its hard row limit to queries containing count aggregations. A regression test verifies grouped results and equivalence with the JSON API when a limit is supplied.

Changes

Count aggregation limit handling

Layer / File(s) Summary
Skip row caps for count queries and validate the MCP response
crates/ourios-server/src/mcp.rs, crates/ourios-server/tests/it/rfc0027_mcp.rs
query_logs detects Stage::Count before applying the limit cap, and the RFC0027.3 test verifies grouped aggregation output and JSON API equivalence.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly states the main change: allowing MCP query_logs to run count aggregations.
Description check ✅ Passed The description covers the summary, rationale, change, regression test, invariants, and verification, with only minor template deviations.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix-mcp-count-aggregation

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request fixes a parity bug in the Ourios querier’s MCP query_logs tool: MCP previously always injected a row-cap limit, which made count [by …] aggregations fail validation because count and limit are mutually exclusive. The change mirrors the JSON API behavior by skipping apply_limit when the parsed statement includes a Stage::Count, and adds an integration regression test that exercises the full MCP protocol and asserts MCP/JSON output equivalence.

Changes:

  • Update the MCP query_logs handler to detect Stage::Count and avoid injecting the row-cap limit for aggregations.
  • Add an integration test that runs count by through MCP with a non-null limit argument and asserts the response matches the JSON API byte-for-byte.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
crates/ourios-server/src/mcp.rs Skip MCP-injected limit when the query includes Stage::Count, matching the JSON API guard.
crates/ourios-server/tests/it/rfc0027_mcp.rs Add regression test proving query_logs count aggregations work over MCP and match JSON API output.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@crates/ourios-server/src/mcp.rs`:
- Around line 303-310: Add colocated unit tests in mcp.rs for the query-building
logic around is_aggregation and apply_limit, covering a normal row query, count,
and count by. Assert that limits are applied to row queries but omitted for both
aggregation forms, while preserving the existing integration regression test.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 9154a956-c27e-43a2-8231-7b8ea14a40bf

📥 Commits

Reviewing files that changed from the base of the PR and between c411840 and c9c3fee.

📒 Files selected for processing (2)
  • crates/ourios-server/src/mcp.rs
  • crates/ourios-server/tests/it/rfc0027_mcp.rs

Comment thread crates/ourios-server/src/mcp.rs Outdated
Extract the count-vs-limit guard into cap_rows_unless_aggregation and
unit-test it next to the code (per §6.2): a row query gets the cap
injected as a limit stage; both `count` and `count by` are left
uncapped. Complements the RFC 0027 integration regression.

Signed-off-by: Jens Holdgaard Pedersen <Jens@holdgaard.org>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

Comment thread crates/ourios-server/tests/it/rfc0027_mcp.rs Outdated
Both query_logs equivalence tests now share the identical scenario
heading, so the scenario→test grep stays unambiguous; the
regression-specific wording moves below the heading.

Signed-off-by: Jens Holdgaard Pedersen <Jens@holdgaard.org>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.

@jensholdgaard
jensholdgaard merged commit e7d941f into main Jul 23, 2026
27 checks passed
@jensholdgaard
jensholdgaard deleted the fix-mcp-count-aggregation branch July 23, 2026 15:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants