Skip to content

feat(clp-mcp-server): Add search_by_kql_with_timestamp_range MCP tool call.#1457

Merged
20001020ycx merged 52 commits into
y-scope:mainfrom
20001020ycx:10-20-substring-search-with-ts
Oct 23, 2025
Merged

feat(clp-mcp-server): Add search_by_kql_with_timestamp_range MCP tool call.#1457
20001020ycx merged 52 commits into
y-scope:mainfrom
20001020ycx:10-20-substring-search-with-ts

Conversation

@20001020ycx

@20001020ycx 20001020ycx commented Oct 20, 2025

Copy link
Copy Markdown
Contributor

Description

This PR implements search API for MCP server: search_by_kql_with_timestamp_range.
The documentation of search_by_kql_with_timestamp_range is listed below:

search_by_kql_with_timestamp_range

Description:
Runs a search query that returns the 10 newest log messages that satisfy this KQL query and fall under the specified timestamp with pagination support for up to 1000 log messages.

Inputs:

  • kql-query: The query LLM wants to search for.
  • start-timestamp to end-timestamp: Only log messages whose timestamp falls within this timestamp range will be returned. Timestamp will be in ISO 8601 (YYYY-MM-DDTHH:mm:ssZ) format.

Outputs:

  • The 10 newest log messages that satisfy the search query with their timestamp in datestring format.
  • The pagination metadata for the query response.

Errors:

  • Error: The query was CANCELLED
  • Error: The query FAILED
  • Error: The query was KILLED
  • Error: The query job TIMED OUT
  • Error: Begin timestamp cannot be greater than end timestamp

Checklist

  • The PR satisfies the contribution guidelines.
  • This is a breaking change and that has been indicated in the PR title, OR this isn't a
    breaking change.
  • Necessary docs have been updated, OR no docs need to be updated.

Validation performed

  1. Unit Tests: uv run --group dev pytest tests/server/test-utils.py -v.
  2. Lint Tests: uv run ruff check clp/components/clp-mcp-server && task lint:check-py.
  3. Manual Integration Tests: Built usingtask docker-images:package with docker compose. Connected Claude Desktop agent to the running MCP server service in docker compose. Manually instructed LLM to perform a search_kql_query_with_timestamp in a bounded time range where only one log message satisfies the kql query. The retruned result is consistent with the log message we selected. You can see the end-to-end result using this link
Screenshot 2025-10-20 at 7 05 23 PM Note: AI team is actively working on the automated integration test.

Summary by CodeRabbit

  • New Features

    • Added timestamp-range log search accepting explicit begin/end ISO 8601 UTC timestamps with session-aware first-page caching and paged results.
  • Improvements

    • Millisecond-precision timestamp parsing, validation and formatting.
    • Results consistently sorted by timestamp for easier review.
    • Session synchronization notes updated for the new search flow.
  • Tests

    • Expanded tests for timestamp conversion, validation, sorting and error handling.
  • Documentation

    • Guidance clarified to require ISO 8601 UTC timestamps ending with Z.

@coderabbitai

coderabbitai Bot commented Oct 20, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

Adds ISO‑8601 ↔ epoch utilities and tests; updates SYSTEM_PROMPT guidance to require ISO‑8601(Z) timestamps; and adds server helpers _execute_kql_query and search_by_kql_with_timestamp_range to run a KQL query over an explicit timestamp range, sort/format results, and cache the first page.

Changes

Cohort / File(s) Summary
Timestamp utilities
components/clp-mcp-server/clp_mcp_server/server/utils.py
Adds convert_date_string_to_epoch, parse_timestamp_range, and convert_epoch_to_date_string to validate ISO‑8601(Z) strings, convert to/from epoch milliseconds, and enforce begin ≤ end; raise ValueError on invalid input.
KQL execution helpers
components/clp-mcp-server/clp_mcp_server/server/server.py
Imports parse_timestamp_range; adds `async def _execute_kql_query(session_id: str, kql_query: str, begin_ts: int
Session docstring
components/clp-mcp-server/clp_mcp_server/server/session_manager.py
Updates SessionState.get_page_data docstring to reference synchronization with MCP tool calls including get_nth_page, search_by_kql, and search_by_kql_with_timestamp_range; no behavioral changes.
Unit tests
components/clp-mcp-server/tests/server/test_utils.py
Adds tests for convert_date_string_to_epoch and parse_timestamp_range (valid and invalid cases), defines error-message constants, and extends existing tests for formatting/sorting and invalid timestamp handling.
System prompt text
components/clp-mcp-server/clp_mcp_server/server/constants.py
Updates guidance to require calling search_by_kql_with_timestamp_range with explicit ISO‑8601 UTC timestamps ending with Z (instead of embedding a time range in the KQL), clarifies format and examples.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant Server as server.py
    participant Utils as utils.py
    participant Query as QueryEngine
    participant Cache as SessionManager

    Client->>Server: search_by_kql_with_timestamp_range(kql, begin_iso, end_iso)
    Server->>Utils: parse_timestamp_range(begin_iso, end_iso)
    Utils-->>Server: (begin_epoch_ms, end_epoch_ms)
    Server->>Server: _execute_kql_query(session_id, kql, begin_epoch_ms, end_epoch_ms)
    Server->>Query: submit_timed_query(kql, begin_epoch_ms, end_epoch_ms)
    Query-->>Server: query_id
    Server->>Query: wait_for_completion(query_id)
    Query-->>Server: query_results
    Server->>Utils: sort_by_timestamp(query_results)
    Utils-->>Server: sorted_results
    Server->>Utils: format_query_results(sorted_results)
    Utils-->>Server: formatted_results
    Server->>Cache: cache_first_page(session_id, formatted_results)
    Cache-->>Server: ack
    Server-->>Client: response { results } or { "Error": "..." }
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The pull request title "feat(clp-mcp-server): Add search_by_kql_with_timestamp_range MCP tool call" directly and accurately describes the main objective of the changeset. The PR implements a new MCP server search API that enables querying with both KQL search criteria and explicit ISO 8601 timestamp range bounds, which is precisely what the title conveys. The title is concise, specific, and uses clear language that would allow teammates reviewing the repository history to quickly understand the primary change without requiring additional context. The use of standard commit convention (feat:) with scope further enhances clarity.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 94893e0 and d2dc639.

📒 Files selected for processing (2)
  • components/clp-mcp-server/clp_mcp_server/server/server.py (3 hunks)
  • components/clp-mcp-server/clp_mcp_server/server/session_manager.py (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
components/clp-mcp-server/clp_mcp_server/server/server.py (3)
components/clp-mcp-server/clp_mcp_server/server/utils.py (3)
  • format_query_results (80-110)
  • parse_timestamp_range (31-62)
  • sort_by_timestamp (113-133)
components/clp-mcp-server/clp_mcp_server/clp_connector.py (3)
  • submit_query (43-99)
  • wait_query_completion (121-155)
  • read_results (157-177)
components/clp-mcp-server/clp_mcp_server/server/session_manager.py (3)
  • cache_query_result_and_get_first_page (79-96)
  • cache_query_result_and_get_first_page (195-205)
  • start (177-180)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: package-image
  • GitHub Check: lint-check (ubuntu-24.04)
  • GitHub Check: lint-check (macos-15)
🔇 Additional comments (4)
components/clp-mcp-server/clp_mcp_server/server/session_manager.py (1)

112-113: Docstring correctly synchronized with MCP tool calls.

The NOTE now properly lists all three MCP tools (get_nth_page, search_by_kql, and search_by_kql_with_timestamp_range) that must remain synchronized with this docstring. This resolves the previous coordination issue and ensures maintainers have an accurate reference point.

components/clp-mcp-server/clp_mcp_server/server/server.py (3)

12-12: LGTM!

The import statement correctly brings in the utility functions needed for timestamp parsing, result sorting, and formatting.


127-127: LGTM!

The refactoring correctly delegates to the shared _execute_kql_query helper without a timestamp range, maintaining the original behaviour while reducing code duplication.


155-162: LGTM!

The error handling correctly catches ValueError from parse_timestamp_range, and the delegation to _execute_kql_query properly passes the parsed epoch timestamps.


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 and usage tips.

@junhaoliao

Copy link
Copy Markdown
Member

@20001020ycx let's merge main into this branch

@20001020ycx 20001020ycx changed the title feat(clp-mcp-server): Implement search_kql_query_with_timestamp tool call in MCP Server feat(clp-mcp-server): Add search_kql_query_with_timestamp MCP tool call. Oct 22, 2025
@20001020ycx 20001020ycx marked this pull request as ready for review October 22, 2025 21:14
@20001020ycx 20001020ycx requested a review from a team as a code owner October 22, 2025 21:14
@20001020ycx 20001020ycx changed the title feat(clp-mcp-server): Add search_kql_query_with_timestamp MCP tool call. feat(clp-mcp-server): Add search_by_kql_with_timestamp MCP tool call. Oct 22, 2025
@20001020ycx 20001020ycx changed the title feat(clp-mcp-server): Add search_by_kql_with_timestamp MCP tool call. feat(clp-mcp-server): Add search_by_kql_with_timestamp_range MCP tool call. Oct 22, 2025

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 19

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
components/clp-mcp-server/clp_mcp_server/clp_mcp_server.py (1)

42-85: Use Click exceptions for error handling
Replace the manual exit_code tracking and sys.exit(main(standalone_mode=False)) hack with idiomatic Click errors—raise click.BadParameter for invalid host/port and click.ClickException or click.Exit(code) on config‐load failures—so Click’s normal exit behavior produces the right exit code and user messaging. Also update your --config-path option to use click.Path(exists=True, path_type=Path) to validate the file up front.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8e77a81 and 85d4a19.

📒 Files selected for processing (8)
  • components/clp-mcp-server/clp_mcp_server/clp_connector.py (2 hunks)
  • components/clp-mcp-server/clp_mcp_server/clp_mcp_server.py (3 hunks)
  • components/clp-mcp-server/clp_mcp_server/server/constants.py (1 hunks)
  • components/clp-mcp-server/clp_mcp_server/server/server.py (3 hunks)
  • components/clp-mcp-server/clp_mcp_server/server/session_manager.py (1 hunks)
  • components/clp-mcp-server/clp_mcp_server/server/utils.py (1 hunks)
  • components/clp-mcp-server/tests/server/__init__.py (1 hunks)
  • components/clp-mcp-server/tests/server/test_utils.py (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-10-20T20:19:40.504Z
Learnt from: 20001020ycx
PR: y-scope/clp#1436
File: components/clp-mcp-server/clp_mcp_server/clp_mcp_server.py:22-27
Timestamp: 2025-10-20T20:19:40.504Z
Learning: In the clp-mcp-server project (components/clp-mcp-server/clp_mcp_server/clp_mcp_server.py), the --config Click option should use exists=True to validate the configuration file path at option processing time, even though this requires the default path to exist on all machines.

Applied to files:

  • components/clp-mcp-server/clp_mcp_server/clp_mcp_server.py
🧬 Code graph analysis (3)
components/clp-mcp-server/clp_mcp_server/clp_mcp_server.py (3)
components/clp-py-utils/clp_py_utils/clp_config.py (1)
  • CLPConfig (557-739)
components/clp-py-utils/clp_py_utils/core.py (1)
  • read_yaml_config_file (56-62)
components/clp-mcp-server/clp_mcp_server/server/server.py (1)
  • create_mcp_server (15-151)
components/clp-mcp-server/tests/server/test_utils.py (1)
components/clp-mcp-server/clp_mcp_server/server/utils.py (4)
  • convert_date_string_to_epoch (12-31)
  • format_query_results (78-108)
  • parse_timestamp_range (34-60)
  • sort_by_timestamp (111-131)
components/clp-mcp-server/clp_mcp_server/server/server.py (4)
components/clp-py-utils/clp_py_utils/clp_config.py (1)
  • CLPConfig (557-739)
components/clp-mcp-server/clp_mcp_server/clp_connector.py (4)
  • ClpConnector (23-177)
  • submit_query (43-99)
  • wait_query_completion (121-155)
  • read_results (157-177)
components/clp-mcp-server/clp_mcp_server/server/session_manager.py (4)
  • SessionManager (157-237)
  • start (176-179)
  • cache_query_result_and_get_first_page (79-96)
  • cache_query_result_and_get_first_page (194-204)
components/clp-mcp-server/clp_mcp_server/server/utils.py (3)
  • format_query_results (78-108)
  • parse_timestamp_range (34-60)
  • sort_by_timestamp (111-131)
🪛 Ruff (0.14.1)
components/clp-mcp-server/tests/server/test_utils.py

21-34: Mutable class attributes should be annotated with typing.ClassVar

(RUF012)


35-39: Mutable class attributes should be annotated with typing.ClassVar

(RUF012)


42-51: Mutable class attributes should be annotated with typing.ClassVar

(RUF012)


52-55: Mutable class attributes should be annotated with typing.ClassVar

(RUF012)


58-70: Mutable class attributes should be annotated with typing.ClassVar

(RUF012)


71-73: Mutable class attributes should be annotated with typing.ClassVar

(RUF012)


76-115: Mutable class attributes should be annotated with typing.ClassVar

(RUF012)


117-138: Mutable class attributes should be annotated with typing.ClassVar

(RUF012)


143-143: Magic value used in comparison, consider replacing 1729267200123 with a constant variable

(PLR2004)


146-146: Magic value used in comparison, consider replacing 1729267200123 with a constant variable

(PLR2004)


149-149: Magic value used in comparison, consider replacing 1729267200000 with a constant variable

(PLR2004)


152-152: Magic value used in comparison, consider replacing 1729267200000 with a constant variable

(PLR2004)


155-155: Magic value used in comparison, consider replacing 1729267200000 with a constant variable

(PLR2004)


160-160: pytest.raises(ValueError) is too broad, set the match parameter or use a more specific exception

(PT011)


164-164: pytest.raises(ValueError) is too broad, set the match parameter or use a more specific exception

(PT011)


168-168: pytest.raises(ValueError) is too broad, set the match parameter or use a more specific exception

(PT011)


172-172: pytest.raises(ValueError) is too broad, set the match parameter or use a more specific exception

(PT011)


173-173: print found

Remove print

(T201)


176-176: pytest.raises(ValueError) is too broad, set the match parameter or use a more specific exception

(PT011)


177-177: print found

Remove print

(T201)


191-191: pytest.raises(ValueError) is too broad, set the match parameter or use a more specific exception

(PT011)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: package-image
  • GitHub Check: lint-check (ubuntu-24.04)
  • GitHub Check: lint-check (macos-15)
🔇 Additional comments (7)
components/clp-mcp-server/clp_mcp_server/server/session_manager.py (1)

112-114: Docstring sync note looks good.

Clear cross-reference to MCP tools; no action needed.

components/clp-mcp-server/tests/server/__init__.py (1)

1-1: OK to keep.

Package initialiser is fine.

components/clp-mcp-server/tests/server/test_utils.py (1)

214-219: Be aware: sort_by_timestamp mutates the input list.

No change required, but future tests shouldn’t rely on RAW_LOG_ENTRIES remaining unsorted after this call.

If that’s a concern, copy before sorting:

sorted_result = sort_by_timestamp(self.RAW_LOG_ENTRIES.copy())
components/clp-mcp-server/clp_mcp_server/server/server.py (2)

15-23: create_mcp_server signature and wiring look good.

Constructor injection via CLPConfig is clean.


77-110: I’ve requested the full SYSTEM_PROMPT to verify whether it indeed instructs hyperlink wrapping. Awaiting those results.

components/clp-mcp-server/clp_mcp_server/server/utils.py (2)

63-76: Confirm Python version for timespec="milliseconds"; provide fallback if needed.

Some older environments don’t support the "milliseconds" timespec. If you support such runtimes, fall back to rounding microseconds.

# Fallback pattern if needed:
dt = datetime.fromtimestamp(epoch_seconds, tz=timezone.utc)
try:
    return dt.isoformat(timespec="milliseconds").replace("+00:00", "Z")
except TypeError:
    # Older Python: emulate milliseconds
    ms = int(dt.microsecond / 1000)
    base = dt.replace(microsecond=0).isoformat().replace("+00:00", "Z")
    return f"{base[:-1]}.{ms:03d}Z"

111-131: Sorting helper looks good.

Stable, simple key; treats invalid/missing timestamps as oldest. No issues.

Comment thread components/clp-mcp-server/clp_mcp_server/clp_connector.py
Comment thread components/clp-mcp-server/clp_mcp_server/clp_connector.py
Comment thread components/clp-mcp-server/clp_mcp_server/clp_mcp_server.py
Comment thread components/clp-mcp-server/clp_mcp_server/server/constants.py
Comment thread components/clp-mcp-server/clp_mcp_server/server/server.py Outdated
Comment thread components/clp-mcp-server/tests/server/test_utils.py
Comment thread components/clp-mcp-server/tests/server/test_utils.py
Comment on lines +117 to +138
EXPECTED_RESULTS = [
(
'timestamp: 2024-10-18T16:00:00.123Z, message: '
'{"ts":1729267200123,"pid":1234,"tid":5678,'
'"message":"Log with millisecond precision"}\n'
),
(
'timestamp: 2024-10-18T16:00:00.000Z, message: '
'{"ts":1729267200000,"pid":1234,"tid":5678,'
'"message":"Log with zero milliseconds"}\n'
),
(
'timestamp: 1970-01-01T00:00:00.000Z, message: '
'{"ts":0,"pid":null,"tid":null,'
'"message":"Log at epoch zero"}\n'
),
(
'timestamp: N/A, message: '
'{"pid":null,"tid":null,'
'"message":"Log at epoch none"}\n'
),
]

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.

🧹 Nitpick | 🔵 Trivial

EXPECTED_RESULTS: keep as-is or switch to constants for clarity (optional).

No functional issue; optional to reference the named epoch constants for symmetry.

🧰 Tools
🪛 Ruff (0.14.1)

117-138: Mutable class attributes should be annotated with typing.ClassVar

(RUF012)

🤖 Prompt for AI Agents
components/clp-mcp-server/tests/server/test_utils.py around lines 117 to 138:
the EXPECTED_RESULTS block currently uses hard-coded timestamp strings; either
leave it unchanged or refactor to reference named constants for clarity — if you
choose refactor, add descriptive constants (e.g., TS_MILLI=
"2024-10-18T16:00:00.123Z", TS_ZERO="1970-01-01T00:00:00.000Z", TS_NA="N/A") (or
reuse existing epoch constants if present), then replace the literal timestamp
substrings in each tuple with those constants so the expected values remain
identical but are clearer and easier to maintain.

Comment thread components/clp-mcp-server/tests/server/test_utils.py
Comment thread components/clp-mcp-server/tests/server/test_utils.py Outdated
@20001020ycx

20001020ycx commented Oct 23, 2025

Copy link
Copy Markdown
Contributor Author

@coderabbitai, review my recent change, make sure I didn't make any stupid mistakes

@coderabbitai

coderabbitai Bot commented Oct 23, 2025

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain



🏁 Script executed:

#!/bin/bash
# Let's examine the new tool implementation in server.py
echo "=== Examining search_by_kql_with_timestamp_range in server.py ==="
ast-grep --pattern $'async def search_by_kql_with_timestamp_range($$$) {
  $$$
}'

echo -e "\n=== Examining timestamp utility functions in utils.py ==="
ast-grep --pattern $'def convert_date_string_to_epoch($$$) {
  $$$
}'

ast-grep --pattern $'def parse_timestamp_range($$$) {
  $$$
}'

ast-grep --pattern $'def convert_epoch_to_date_string($$$) {
  $$$
}'

echo -e "\n=== Let's look at the actual files to get full context ==="
cat components/clp-mcp-server/clp_mcp_server/server/server.py

Length of output: 6985


🏁 Script executed:

#!/bin/bash
# Examine the utils.py file for the timestamp functions
echo "=== Full utils.py content ==="
cat components/clp-mcp-server/clp_mcp_server/server/utils.py

Length of output: 4955


🏁 Script executed:

#!/bin/bash
# Examine the test file to understand test coverage
echo "=== Test file content ==="
cat components/clp-mcp-server/tests/server/test_utils.py

Length of output: 7648


🏁 Script executed:

#!/bin/bash
# Check the constants file to see the updated guidance
echo "=== Constants file ==="
cat components/clp-mcp-server/clp_mcp_server/server/constants.py

Length of output: 1612


@20001020ycx, I found several issues in your changes that need fixing:

Critical Issues

1. Misleading Parameter Names in _execute_kql_query

The parameters formatted_begin_timestamp and formatted_end_timestamp are actually epoch integers (milliseconds), not formatted strings. This is confusing:

async def _execute_kql_query(
    session_id: str,
    kql_query: str,
    formatted_begin_timestamp: int | None = None,  # ❌ Misleading name - these are epochs
    formatted_end_timestamp: int | None = None,     # ❌ Not formatted strings
) -> dict[str, Any]:

Fix: Rename them to clearly indicate they're epoch timestamps:

async def _execute_kql_query(
    session_id: str,
    kql_query: str,
    begin_timestamp_epoch: int | None = None,
    end_timestamp_epoch: int | None = None,
) -> dict[str, Any]:

Then update the call in connector.submit_query accordingly.

2. Missing Space in Error Message

In utils.py, line in parse_timestamp_range:

err_msg = (
    f"Timestamp must end with 'Z' to indicate UTC. Got: {formatted_begin_timestamp} and"
    f"{formatted_end_timestamp} instead."  # ❌ Missing space after "and"
)

Fix:

err_msg = (
    f"Timestamp must end with 'Z' to indicate UTC. Got: {formatted_begin_timestamp} and "
    f"{formatted_end_timestamp} instead."
)

3. Incorrect Docstring Parameter Names

In parse_timestamp_range, the docstring uses begin_timestamp and end_timestamp, but the actual parameters are formatted_begin_timestamp and formatted_end_timestamp:

def parse_timestamp_range(
    formatted_begin_timestamp: str, formatted_end_timestamp: str
) -> tuple[int, int]:
    """
    :param begin_timestamp:  # ❌ Wrong name
    :param end_timestamp:    # ❌ Wrong name

Fix:

    """
    :param formatted_begin_timestamp:
    :param formatted_end_timestamp:

4. Incorrect Docstring in _execute_kql_query

The docstring mentions a ctx parameter that doesn't exist in the function signature:

:param ctx: The `FastMCP` context containing the metadata of the underlying MCP session.

Fix: Remove this line from the docstring since ctx is not a parameter of this function.

Minor Style Issue

5. Missing Space Before = in Test File

In test_utils.py:

INVALID_DATE_STRING_VALUE= "is earlier than `begin_timestamp`"  # ❌ Missing space

Fix:

INVALID_DATE_STRING_VALUE = "is earlier than `begin_timestamp`"

Summary

The logic and error handling look good overall, but the parameter naming in _execute_kql_query is particularly problematic because it suggests the function accepts formatted strings when it actually expects epoch integers. This could cause confusion for future maintainers.

🐰✍️

@coderabbitai

coderabbitai Bot commented Oct 23, 2025

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Fetch the main changed files to review
echo "=== server/server.py ==="
cat components/clp-mcp-server/clp_mcp_server/server/server.py

echo -e "\n=== server/utils.py ==="
cat components/clp-mcp-server/clp_mcp_server/server/utils.py

echo -e "\n=== tests/server/test_utils.py ==="
cat components/clp-mcp-server/clp_mcp_server/tests/server/test_utils.py

echo -e "\n=== server/constants.py ==="
cat components/clp-mcp-server/clp_mcp_server/server/constants.py

Length of output: 13531


🏁 Script executed:

#!/bin/bash
# Find the correct test file path
fd -t f test_utils.py components/clp-mcp-server/

# Read the test file
cat components/clp-mcp-server/tests/server/test_utils.py

Length of output: 7675


@20001020ycx, I've reviewed your changes and found a few issues to fix:

Issues Found

1. Misleading Parameter Names in _execute_kql_query (server.py)

The parameters are named formatted_begin_timestamp and formatted_end_timestamp, but they're actually epoch integers (milliseconds), not formatted strings. This is confusing.

Lines 29-30:

formatted_begin_timestamp: int | None = None,
formatted_end_timestamp: int | None = None,

Recommendation: Rename to begin_timestamp_epoch and end_timestamp_epoch, or simply begin_timestamp and end_timestamp since the context makes it clear they're epoch values:

begin_timestamp: int | None = None,
end_timestamp: int | None = None,

2. Docstring Parameter Name Mismatch in parse_timestamp_range (utils.py)

The docstring refers to begin_timestamp and end_timestamp, but the actual parameters are formatted_begin_timestamp and formatted_end_timestamp.

Lines 32-33:

"""
:param begin_timestamp:
:param end_timestamp:

Fix: Update the docstring to match the actual parameter names:

"""
:param formatted_begin_timestamp:
:param formatted_end_timestamp:

3. Missing Space in Error Message (utils.py)

Line 49:

err_msg = (
    f"Timestamp must end with 'Z' to indicate UTC. Got: {formatted_begin_timestamp} and"
    f"{formatted_end_timestamp} instead."
)

There's a missing space between "and" and the second timestamp. Should be:

err_msg = (
    f"Timestamp must end with 'Z' to indicate UTC. Got: {formatted_begin_timestamp} and "
    f"{formatted_end_timestamp} instead."
)

4. Minor Style Issue in Test File (test_utils.py)

Line 19:

INVALID_DATE_STRING_VALUE= "is earlier than `begin_timestamp`"

Missing space after =. Should be:

INVALID_DATE_STRING_VALUE = "is earlier than `begin_timestamp`"

Positive Notes

✅ Logic is correct - timestamp validation and error handling look good
✅ Good test coverage for edge cases
✅ Proper error propagation with try/except blocks
✅ Consistent use of ISO 8601 format validation

The issues are all minor quality/clarity improvements. Once these are fixed, the implementation looks solid!

@20001020ycx

Copy link
Copy Markdown
Contributor Author

@coderabbitai, great catches on point 2,3,4, do it again to make sure I didn't commit similar mistakes

@coderabbitai

coderabbitai Bot commented Oct 23, 2025

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Examine all changed files carefully for similar issues

echo "=== Checking server.py for docstring/parameter mismatches and spacing issues ==="
cat components/clp-mcp-server/clp_mcp_server/server/server.py

echo -e "\n=== Checking utils.py for docstring/parameter mismatches and spacing issues ==="
cat components/clp-mcp-server/clp_mcp_server/server/utils.py

echo -e "\n=== Checking test_utils.py for spacing issues around operators ==="
cat components/clp-mcp-server/tests/server/test_utils.py

echo -e "\n=== Checking constants.py for any issues ==="
cat components/clp-mcp-server/clp_mcp_server/server/constants.py

echo -e "\n=== Checking session_manager.py for any issues ==="
cat components/clp-mcp-server/clp_mcp_server/server/session_manager.py

echo -e "\n=== Check for other potential spacing issues in f-strings ==="
rg -n 'f".*\band"$' components/clp-mcp-server/
rg -n "f'.*\band'$" components/clp-mcp-server/

echo -e "\n=== Check for missing spaces around = in assignments ==="
rg -n '\w+= ' components/clp-mcp-server/ --type py | head -20

Length of output: 30982


@20001020ycx, I found one additional issue similar to the ones I caught before:

New Issue Found

Docstring Parameter Mismatch in _execute_kql_query (server.py)

Line 40: The docstring mentions a ctx parameter that doesn't exist in the function signature:

async def _execute_kql_query(
    session_id: str,
    kql_query: str,
    formatted_begin_timestamp: int | None = None,
    formatted_end_timestamp: int | None = None,  # ❌ No ctx parameter
) -> dict[str, Any]:
    """
    ...
    :param formatted_begin_timestamp: The beginning of the time range (inclusive).
    :param formatted_end_timestamp: The end of the time range (inclusive).
    :param ctx: The `FastMCP` context containing the metadata of the underlying MCP session.  # ❌ This parameter doesn't exist!
    ...
    """

Fix: Remove the :param ctx: line from the docstring since this function doesn't have a ctx parameter.


Previously Reported Issues (Still Present)

Just to confirm, these three issues from before are still in the code:

  1. utils.py line 32-33: Docstring parameter names (begin_timestamp, end_timestamp) don't match actual parameter names (formatted_begin_timestamp, formatted_end_timestamp)

  2. utils.py line 47: Missing space after "and" in the f-string:

    f"Timestamp must end with 'Z' to indicate UTC. Got: {formatted_begin_timestamp} and"
  3. test_utils.py line 19: Missing space before =:

    INVALID_DATE_STRING_VALUE= "is earlier than `begin_timestamp`"

Everything else looks clean! No other docstring mismatches, spacing issues, or style problems found. 🎯

@20001020ycx

Copy link
Copy Markdown
Contributor Author

@coderabbitai, I forgot to push, do it again

@coderabbitai

coderabbitai Bot commented Oct 23, 2025

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Fetch the files to verify fixes

echo "=== Checking server.py for the ctx parameter docstring issue ==="
cat components/clp-mcp-server/clp_mcp_server/server/server.py

echo -e "\n=== Checking utils.py for docstring parameter names and f-string spacing ==="
cat components/clp-mcp-server/clp_mcp_server/server/utils.py

echo -e "\n=== Checking test_utils.py for spacing around = ==="
cat components/clp-mcp-server/tests/server/test_utils.py

Length of output: 19556


@20001020ycx, great progress! You fixed 3 out of 4 issues. Here's the status:

✅ Fixed Issues

  1. server.py: Removed the incorrect :param ctx: from _execute_kql_query docstring - Perfect! ✓
  2. utils.py lines 32-33: Updated docstring parameter names to match actual parameters (formatted_begin_timestamp, formatted_end_timestamp) - Perfect! ✓
  3. utils.py line 47: Added space after "and" in the f-string error message - Perfect! ✓

❌ Remaining Issue

test_utils.py line 19: Still missing space before =

INVALID_DATE_STRING_VALUE= "is earlier than `begin_timestamp`"

Should be:

INVALID_DATE_STRING_VALUE = "is earlier than `begin_timestamp`"

Once you fix this last spacing issue, all the previously identified problems will be resolved! 🎯

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 2

♻️ Duplicate comments (3)
components/clp-mcp-server/clp_mcp_server/server/utils.py (2)

35-36: Complete the parameter documentation.

The docstring is missing descriptions for formatted_begin_timestamp and formatted_end_timestamp. These should document that both parameters accept ISO 8601 UTC date strings (with second or millisecond precision) ending with 'Z'.


14-15: Docstring overly restrictive on accepted timestamp formats.

The docstring states "millisecond precision (YYYY-MM-DDTHH:mm:ss.fffZ)" but datetime.fromisoformat on line 21 also accepts second precision (e.g., YYYY-MM-DDTHH:mm:ssZ). Update the docstring to reflect both accepted formats for accuracy.

components/clp-mcp-server/clp_mcp_server/server/server.py (1)

134-136: Broaden docstring to accept both second and millisecond precision.

The docstring specifies YYYY-MM-DDTHH:mm:ss.fffZ (millisecond precision) but the implementation via parse_timestamp_rangeconvert_date_string_to_epoch also accepts second precision (e.g., YYYY-MM-DDTHH:mm:ssZ). Update to document both accepted formats.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6b45f59 and 77890b1.

📒 Files selected for processing (3)
  • components/clp-mcp-server/clp_mcp_server/server/server.py (3 hunks)
  • components/clp-mcp-server/clp_mcp_server/server/session_manager.py (1 hunks)
  • components/clp-mcp-server/clp_mcp_server/server/utils.py (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
components/clp-mcp-server/clp_mcp_server/server/server.py (3)
components/clp-mcp-server/clp_mcp_server/server/utils.py (3)
  • format_query_results (80-110)
  • parse_timestamp_range (31-62)
  • sort_by_timestamp (113-133)
components/clp-mcp-server/clp_mcp_server/clp_connector.py (3)
  • submit_query (43-99)
  • wait_query_completion (121-155)
  • read_results (157-177)
components/clp-mcp-server/clp_mcp_server/server/session_manager.py (3)
  • cache_query_result_and_get_first_page (79-96)
  • cache_query_result_and_get_first_page (195-205)
  • start (177-180)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: package-image
  • GitHub Check: lint-check (macos-15)
  • GitHub Check: lint-check (ubuntu-24.04)

Comment thread components/clp-mcp-server/clp_mcp_server/server/server.py Outdated
Comment thread components/clp-mcp-server/clp_mcp_server/server/session_manager.py Outdated
Comment thread components/clp-mcp-server/clp_mcp_server/server/server.py Outdated
Comment thread components/clp-mcp-server/clp_mcp_server/server/server.py Outdated
- "has_previous": Whether a page exists before the returned one.
:return: A dictionary with the following key-value pair on failures:
- "Error": An error message describing the failure.
:return: Forwards `_execute_kql_query`'s return values.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Are u sure this is OK? I thought the purpose was not to confuse AI...

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

damn, was thinking about code formatting. I dont think AI would read this...

But, this makes Docstring very repetitive, shall we revert to the earlier version?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Considering the future release, we may have more metadata queries being made, so I guess this helper function would be useful in the future. The only problem is having repetitive docstring..., that's a trade off we must make I guess.

I will add back the full return type then.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think we can add them back for now.
But in the meanwhile, is there any documentation we can find or an experiment we can do, for us to test whether AI will read the Forwards... docstrings?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I asked AI, it doesn't read private functions

@LinZhihao-723 LinZhihao-723 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Left one comment in the test cases.

Comment thread components/clp-mcp-server/tests/server/test_utils.py Outdated

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 3

♻️ Duplicate comments (3)
components/clp-mcp-server/tests/server/test_utils.py (1)

154-175: Remove print statements and use pytest.raises match parameter.

Lines 169 and 173 contain print() statements that serve no purpose in tests. Additionally, all pytest.raises blocks should use the match parameter to validate exception messages more precisely.

Apply this diff to improve the test:

     def test_convert_date_string_to_epoch_invalid_date_string(self):
         """Validates the handling of invalid date string."""
-        with pytest.raises(ValueError) as exc_info:
+        with pytest.raises(ValueError, match=self.INVALID_DATE_STRING_ERROR):
             convert_date_string_to_epoch("not-a-date")
-        assert self.INVALID_DATE_STRING_ERROR in str(exc_info.value)
 
-        with pytest.raises(ValueError) as exc_info:
+        with pytest.raises(ValueError, match=self.INVALID_DATE_STRING_ERROR):
             convert_date_string_to_epoch("2024-13-45T25:99:99Z")
-        assert self.INVALID_DATE_STRING_ERROR in str(exc_info.value)
 
-        with pytest.raises(ValueError) as exc_info:
+        with pytest.raises(ValueError, match=self.INVALID_DATE_STRING_ERROR):
             convert_date_string_to_epoch("")
-        assert self.INVALID_DATE_STRING_ERROR in str(exc_info.value)
 
-        with pytest.raises(ValueError) as exc_info:
-            print(convert_date_string_to_epoch("2024.10.18T16:00:00.123"))
-        assert self.INVALID_DATE_STRING_ERROR in str(exc_info.value)
+        with pytest.raises(ValueError, match=self.INVALID_DATE_STRING_ERROR):
+            convert_date_string_to_epoch("2024.10.18T16:00:00.123")
 
-        with pytest.raises(ValueError) as exc_info:
-            print(convert_date_string_to_epoch("2024-10-18T16-00-00-123"))
-        assert self.INVALID_DATE_STRING_ERROR in str(exc_info.value)
+        with pytest.raises(ValueError, match=self.INVALID_DATE_STRING_ERROR):
+            convert_date_string_to_epoch("2024-10-18T16-00-00-123")
components/clp-mcp-server/clp_mcp_server/server/server.py (2)

30-64: Clarify timestamp units in the docstring.

The parameters begin_ts and end_ts represent Unix epoch timestamps in milliseconds (as expected by connector.submit_query on line 54), but the docstring on lines 41-42 doesn't specify the units.

Apply this diff to clarify:

-        :param begin_ts: The beginning of the time range (inclusive).
-        :param end_ts: The end of the time range (inclusive).
+        :param begin_ts: The beginning of the time range in Unix epoch milliseconds (inclusive).
+        :param end_ts: The end of the time range in Unix epoch milliseconds (inclusive).

136-169: Update docstring to document both accepted timestamp formats.

The docstring on line 142 specifies only millisecond precision (YYYY-MM-DDTHH:mm:ss.fffZ), but the implementation via parse_timestamp_range and convert_date_string_to_epoch also accepts second precision without milliseconds (e.g., YYYY-MM-DDTHH:mm:ssZ). This discrepancy can mislead callers.

Apply this diff to document both accepted formats:

         Searches log events that match the given Kibana Query Language (KQL) query within the given
-        time range. Timestamps must follow the ISO 8601 UTC format (`YYYY-MM-DDTHH:mm:ss.fffZ`),
-        where the trailing `Z` indicates UTC. Timestamps that do not follow this format will be
-        rejected.
+        time range. Timestamps must follow the ISO 8601 UTC format (e.g., `YYYY-MM-DDTHH:mm:ssZ`
+        or `YYYY-MM-DDTHH:mm:ss.fffZ`), where the trailing `Z` indicates UTC. Timestamps that do
+        not follow this format will be rejected.
📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 77890b1 and 93c90b7.

📒 Files selected for processing (2)
  • components/clp-mcp-server/clp_mcp_server/server/server.py (3 hunks)
  • components/clp-mcp-server/tests/server/test_utils.py (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
components/clp-mcp-server/tests/server/test_utils.py (1)
components/clp-mcp-server/clp_mcp_server/server/utils.py (4)
  • convert_date_string_to_epoch (12-28)
  • format_query_results (80-110)
  • parse_timestamp_range (31-62)
  • sort_by_timestamp (113-133)
components/clp-mcp-server/clp_mcp_server/server/server.py (3)
components/clp-mcp-server/clp_mcp_server/server/utils.py (3)
  • format_query_results (80-110)
  • parse_timestamp_range (31-62)
  • sort_by_timestamp (113-133)
components/clp-mcp-server/clp_mcp_server/clp_connector.py (3)
  • submit_query (43-99)
  • wait_query_completion (121-155)
  • read_results (157-177)
components/clp-mcp-server/clp_mcp_server/server/session_manager.py (3)
  • cache_query_result_and_get_first_page (79-96)
  • cache_query_result_and_get_first_page (195-205)
  • start (177-180)
🪛 Ruff (0.14.1)
components/clp-mcp-server/tests/server/test_utils.py

145-145: Magic value used in comparison, consider replacing 1729267200123 with a constant variable

(PLR2004)


148-148: Magic value used in comparison, consider replacing 1729267200000 with a constant variable

(PLR2004)


151-151: Magic value used in comparison, consider replacing 1729267200000 with a constant variable

(PLR2004)


156-156: pytest.raises(ValueError) is too broad, set the match parameter or use a more specific exception

(PT011)


160-160: pytest.raises(ValueError) is too broad, set the match parameter or use a more specific exception

(PT011)


164-164: pytest.raises(ValueError) is too broad, set the match parameter or use a more specific exception

(PT011)


168-168: pytest.raises(ValueError) is too broad, set the match parameter or use a more specific exception

(PT011)


169-169: print found

Remove print

(T201)


172-172: pytest.raises(ValueError) is too broad, set the match parameter or use a more specific exception

(PT011)


173-173: print found

Remove print

(T201)


179-179: pytest.raises(ValueError) is too broad, set the match parameter or use a more specific exception

(PT011)


184-184: pytest.raises(ValueError) is too broad, set the match parameter or use a more specific exception

(PT011)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: lint-check (ubuntu-24.04)
🔇 Additional comments (3)
components/clp-mcp-server/tests/server/test_utils.py (1)

3-10: LGTM!

The imports are clean and all imported functions are exercised in the test methods below.

components/clp-mcp-server/clp_mcp_server/server/server.py (2)

12-12: LGTM!

The addition of parse_timestamp_range to the imports is necessary for the new timestamp-bounded search functionality and is correctly placed.


134-134: LGTM!

The refactoring to delegate to _execute_kql_query successfully eliminates code duplication and maintains the original functionality. This addresses the refactoring suggestion from previous reviews.

Comment thread components/clp-mcp-server/tests/server/test_utils.py
Comment thread components/clp-mcp-server/tests/server/test_utils.py

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

♻️ Duplicate comments (2)
components/clp-mcp-server/tests/server/test_utils.py (2)

16-20: Fix the spacing before the assignment operator on Line 19.

Line 19 is missing a space before the = operator, which violates PEP 8 style guidelines. This issue was previously flagged but remains unresolved.

Apply this diff to fix the spacing:

-    INVALID_DATE_STRING_VALUE_ERROR= "is earlier than `formatted_begin_timestamp`"
+    INVALID_DATE_STRING_VALUE_ERROR = "is earlier than `formatted_begin_timestamp`"

154-175: Use pytest.raises match parameter and remove print statements.

The test logic is correct, but it violates pytest best practices (PT011) and contains debug print statements (T201) that should be removed. Use the match parameter to validate exception messages inline for consistency with the rest of the test suite.

Apply this diff to address the issues:

-        with pytest.raises(ValueError) as exc_info:
-            convert_date_string_to_epoch("not-a-date")
-        assert self.INVALID_DATE_STRING_ERROR in str(exc_info.value)
+        with pytest.raises(ValueError, match=self.INVALID_DATE_STRING_ERROR):
+            convert_date_string_to_epoch("not-a-date")
 
-        with pytest.raises(ValueError) as exc_info:
-            convert_date_string_to_epoch("2024-13-45T25:99:99Z")
-        assert self.INVALID_DATE_STRING_ERROR in str(exc_info.value)
+        with pytest.raises(ValueError, match=self.INVALID_DATE_STRING_ERROR):
+            convert_date_string_to_epoch("2024-13-45T25:99:99Z")
 
-        with pytest.raises(ValueError) as exc_info:
-            convert_date_string_to_epoch("")
-        assert self.INVALID_DATE_STRING_ERROR in str(exc_info.value)
+        with pytest.raises(ValueError, match=self.INVALID_DATE_STRING_ERROR):
+            convert_date_string_to_epoch("")
 
-        with pytest.raises(ValueError) as exc_info:
-            print(convert_date_string_to_epoch("2024.10.18T16:00:00.123"))
-        assert self.INVALID_DATE_STRING_ERROR in str(exc_info.value)
+        with pytest.raises(ValueError, match=self.INVALID_DATE_STRING_ERROR):
+            convert_date_string_to_epoch("2024.10.18T16:00:00.123")
 
-        with pytest.raises(ValueError) as exc_info:
-            print(convert_date_string_to_epoch("2024-10-18T16-00-00-123"))
-        assert self.INVALID_DATE_STRING_ERROR in str(exc_info.value)
+        with pytest.raises(ValueError, match=self.INVALID_DATE_STRING_ERROR):
+            convert_date_string_to_epoch("2024-10-18T16-00-00-123")
📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a078d87 and 083cc8a.

📒 Files selected for processing (1)
  • components/clp-mcp-server/tests/server/test_utils.py (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
components/clp-mcp-server/tests/server/test_utils.py (1)
components/clp-mcp-server/clp_mcp_server/server/utils.py (4)
  • convert_date_string_to_epoch (12-28)
  • format_query_results (80-110)
  • parse_timestamp_range (31-62)
  • sort_by_timestamp (113-133)
🪛 Ruff (0.14.1)
components/clp-mcp-server/tests/server/test_utils.py

145-145: Magic value used in comparison, consider replacing 1729267200123 with a constant variable

(PLR2004)


148-148: Magic value used in comparison, consider replacing 1729267200000 with a constant variable

(PLR2004)


151-151: Magic value used in comparison, consider replacing 1729267200000 with a constant variable

(PLR2004)


156-156: pytest.raises(ValueError) is too broad, set the match parameter or use a more specific exception

(PT011)


160-160: pytest.raises(ValueError) is too broad, set the match parameter or use a more specific exception

(PT011)


164-164: pytest.raises(ValueError) is too broad, set the match parameter or use a more specific exception

(PT011)


168-168: pytest.raises(ValueError) is too broad, set the match parameter or use a more specific exception

(PT011)


169-169: print found

Remove print

(T201)


172-172: pytest.raises(ValueError) is too broad, set the match parameter or use a more specific exception

(PT011)


173-173: print found

Remove print

(T201)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: package-image
  • GitHub Check: lint-check (macos-15)
🔇 Additional comments (2)
components/clp-mcp-server/tests/server/test_utils.py (2)

3-10: LGTM!

The import statements are clean and all imported functions are properly used in the test suite.


177-184: Excellent use of pytest best practices!

The test correctly uses the match parameter for exception validation, following PT011 guidelines. The test coverage for both format and value errors is comprehensive and well-structured.

Comment on lines +142 to +152
def test_convert_date_string_to_epoch(self):
"""Validates converting ISO 8601 format to a Unix epoch."""
result = convert_date_string_to_epoch("2024-10-18T16:00:00.123Z")
assert result == 1729267200123

result = convert_date_string_to_epoch("2024-10-18T16:00:00Z")
assert result == 1729267200000

result = convert_date_string_to_epoch("2024-10-18T16:00Z")
assert result == 1729267200000

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.

🧹 Nitpick | 🔵 Trivial

Consider using named constants for epoch values (optional).

The test logic is correct and validates the conversion properly. To improve maintainability and reduce duplication, consider extracting the epoch values (1729267200123, 1729267200000) as named constants at the class level, similar to the pattern used in RAW_LOG_ENTRIES.

🧰 Tools
🪛 Ruff (0.14.1)

145-145: Magic value used in comparison, consider replacing 1729267200123 with a constant variable

(PLR2004)


148-148: Magic value used in comparison, consider replacing 1729267200000 with a constant variable

(PLR2004)


151-151: Magic value used in comparison, consider replacing 1729267200000 with a constant variable

(PLR2004)

🤖 Prompt for AI Agents
In components/clp-mcp-server/tests/server/test_utils.py around lines 142 to 152,
the test uses literal epoch numbers (1729267200123, 1729267200000) inline;
extract these magic numbers into named constants at the class/module level
(e.g., EXPECTED_EPOCH_MS_WITH_MS and EXPECTED_EPOCH_MS) and replace the inline
literals in the three assertions to reference those constants to improve
readability and maintainability.

@LinZhihao-723 LinZhihao-723 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Otherwise lgtm.

Comment thread components/clp-mcp-server/clp_mcp_server/server/server.py Outdated
Comment thread components/clp-mcp-server/clp_mcp_server/server/session_manager.py Outdated
@20001020ycx 20001020ycx merged commit 63e9db7 into y-scope:main Oct 23, 2025
20 checks passed
junhaoliao pushed a commit to junhaoliao/clp that referenced this pull request May 17, 2026
…ol call. (y-scope#1457)

Co-authored-by: Lin Zhihao <59785146+LinZhihao-723@users.noreply.github.com>
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.

5 participants