Skip to content

Enhance SeqSearch with date range, signals and pagination#3

Merged
willibrandon merged 9 commits into
willibrandon:mainfrom
matt-richardson:improve-seq-search
May 26, 2026
Merged

Enhance SeqSearch with date range, signals and pagination#3
willibrandon merged 9 commits into
willibrandon:mainfrom
matt-richardson:improve-seq-search

Conversation

@matt-richardson

Copy link
Copy Markdown
Contributor

Add enhancements to SeqSearch tool:

New parameters:

  • signalId: Filter by saved signal/search
  • fromDateUtc/toDateUtc: Date range filtering (more efficient than @timestamp in filter)
  • afterId: Pagination support for fetching more than 1000 events
  • timeoutSeconds: Configurable timeout (1-300 seconds)

Improvements:

  • Filter normalization: Accepts "*" as alias for "all events" (empty string)
  • Catches SeqApiException for filter syntax errors and provides guidance
  • Date validation
  • Signal validation

Includes tests:

  • Date range filtering
  • Timeout handling
  • Invalid input validation (dates, signals, filter syntax)
  • Pagination support
  • Filter normalization

Add enhancements to SeqSearch tool:

New parameters:
- signalId: Filter by saved signal/search
- fromDateUtc/toDateUtc: Date range filtering (more efficient than @timestamp in filter)
- afterId: Pagination support for fetching more than 1000 events
- timeoutSeconds: Configurable timeout (1-300 seconds)

Improvements:
- Filter normalization: Accepts "*" as alias for "all events" (empty string)
- Catches SeqApiException for filter syntax errors  and provides guidance
- Date validation
- Signal validation

Includes tests:
- Date range filtering
- Timeout handling
- Invalid input validation (dates, signals, filter syntax)
- Pagination support
- Filter normalization
@matt-richardson

Copy link
Copy Markdown
Contributor Author

@willibrandon - I've also merged main into this PR to

@willibrandon willibrandon left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Caught up on main, the feature additions look solid. A few notes on the test side, pick what you want to address.

Comment thread tests/SeqMcpServer.Tests/McpToolsIntegrationTests.cs Outdated
Comment thread tests/SeqMcpServer.Tests/McpToolsIntegrationTests.cs Outdated
Comment thread src/SeqMcpServer/Mcp/SeqTools.cs Outdated
matt-richardson and others added 7 commits May 23, 2026 07:14
The README documents passing "" to return all events, but the
[Required] attribute on a non-nullable string is ambiguous: depending
on whether the MCP runtime runs DataAnnotations validation, the
documented all-events path is either unreachable or the attribute is
misleading. Removing it and defaulting filter to "" makes the rule
explicit and keeps the documented behavior intact.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The previous test only asserted Content was non-null; it would have
passed even if fromDateUtc/toDateUtc were ignored entirely. Now it
seeds a uniquely-tagged event, queries a bracketing range and asserts
the event comes back, then queries a future range and asserts nothing
matches the marker.

Adds shared JSON helpers (GetInnerText, GetEventCount, GetEventIds)
on the test base for inspecting tool call results.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The previous test passed whether or not "*" was normalized: the
if (IsError) branch accepted both "Syntax error" and "Invalid filter"
substrings, so a Seq syntax error from a non-normalized "*" would have
counted as success. Now the test seeds a uniquely-tagged event, calls
SeqSearch with filter="*", and asserts no error plus the seeded
marker appearing in the result content.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The previous test passed a hardcoded "event-test-id" that did not exist
in Seq, so it only verified that an unknown afterId did not throw.
Now the test seeds 10 uniquely-tagged events, fetches the first page,
takes the last (oldest) event ID as the cursor, fetches the next page,
and asserts the second page is non-empty and shares no IDs with the
first.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The strict pageSize equality on firstIds.Count would flake if Seq's
indexing ever lagged behind the seed loop; the inline note tells a
future debugger what to soften it to. The cursor-direction note warns
that switching to .First() would silently re-include page 1 events,
since afterId is exclusive and Seq returns newest-first.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Both tests only asserted that result and result.Content were non-null
when timeoutSeconds was set, which passes whether or not the timeout
logic actually works. Meaningfully testing the CTS + cancellation
plumbing requires a behaviour-injection seam (TimeProvider plus a
mockable event source), which is more invasive than the five-line
feature warrants. The non-timeout SeqSearch tests already exercise
the same code path with timeoutSeconds = null, so deletion doesn't
open a real coverage gap.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@willibrandon willibrandon merged commit 3cb8d1a into willibrandon:main May 26, 2026
1 check passed
@willibrandon

Copy link
Copy Markdown
Owner

Merged, thanks for the iteration on the test rewrites.

@matt-richardson

Copy link
Copy Markdown
Contributor Author

Thanks for merging!

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