Skip to content

Add pagination to list_users, list_apps, list_tags, list_versions, get_participants#36

Merged
oleksandr-nc merged 3 commits into
mainfrom
feature/add-remaining-pagination
Mar 31, 2026
Merged

Add pagination to list_users, list_apps, list_tags, list_versions, get_participants#36
oleksandr-nc merged 3 commits into
mainfrom
feature/add-remaining-pagination

Conversation

@bigcat88
Copy link
Copy Markdown
Contributor

@bigcat88 bigcat88 commented Mar 31, 2026

Summary

Add limit/offset pagination to 5 remaining list tools that returned unbounded results:

Tool Default Limit Max Limit Pagination Type
list_users 25 200 Server-side (OCS)
list_apps 50 500 Client-side
list_tags 50 500 Client-side
list_versions 50 200 Client-side
get_participants 50 200 Client-side

All return the standard {"data": [...], "pagination": {"count", "offset", "limit", "has_more"}} format.

list_users also got limit clamping (1-200) — previously passed the limit directly to the OCS API with no validation.

Test plan

  • 79 affected tests pass locally (0 regressions)
  • Lint + pyright clean
  • CI

Summary by CodeRabbit

  • New Features

    • Added pagination parameters (limit/offset) to list operations for apps, system tags, conversation participants, users, and file versions.
    • Updated response format for all paginated list operations to include structured metadata with pagination details (count, offset, limit, has_more) alongside result data.
  • Tests

    • Updated integration tests to exercise and validate the new paginated responses and data shape.
  • Chores

    • Adjusted type-checker configuration for an additional source file.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 31, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: f0a019fa-d3b1-4d1c-b095-34aa28fce67f

📥 Commits

Reviewing files that changed from the base of the PR and between b2d1561 and a389033.

📒 Files selected for processing (2)
  • src/nc_mcp_server/tools/app_management.py
  • src/nc_mcp_server/tools/system_tags.py
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/nc_mcp_server/tools/app_management.py
  • src/nc_mcp_server/tools/system_tags.py

📝 Walkthrough

Walkthrough

Multiple MCP tools were changed to add server-side pagination (limit, offset with clamping) and to return a normalized JSON object with data and pagination; tests and Pyright config were updated accordingly.

Changes

Cohort / File(s) Summary
Configuration
pyproject.toml
Added src/nc_mcp_server/tools/users.py to Pyright executionEnvironments with reportUnknownVariableType=false and reportUnknownArgumentType=false.
Tools — pagination & response shape
src/nc_mcp_server/tools/app_management.py, src/nc_mcp_server/tools/system_tags.py, src/nc_mcp_server/tools/talk.py, src/nc_mcp_server/tools/users.py, src/nc_mcp_server/tools/versions.py
Added limit and offset parameters (tool-specific clamping ranges) where applicable; tools now return {"data": [...], "pagination": {count, offset, limit, has_more}} instead of raw lists. Signatures changed for list_apps, list_tags, get_participants, and list_versions; list_users retained its signature but changed return schema.
Integration tests
tests/integration/test_app_management.py, tests/integration/test_system_tags.py, tests/integration/test_talk.py, tests/integration/test_users.py, tests/integration/test_versions.py
Updated test calls to pass limit (commonly 200 or 500 where used) and to extract results from the returned object's data field; assertions adjusted to the new response shape.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

🐰 I hopped through lists both long and wide,

I trimmed them neat with limit and stride,
Data in baskets, metadata bright,
Pages in order — tidy and light,
A rabbit's cheer for each paged byte! ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 11.76% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and concisely summarizes the main change: adding pagination support to five list endpoints (list_users, list_apps, list_tags, list_versions, get_participants).

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/add-remaining-pagination

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.

@codecov
Copy link
Copy Markdown

codecov Bot commented Mar 31, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 95.97%. Comparing base (0725a60) to head (a389033).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main      #36      +/-   ##
==========================================
+ Coverage   95.92%   95.97%   +0.04%     
==========================================
  Files          24       24              
  Lines        1889     1911      +22     
==========================================
+ Hits         1812     1834      +22     
  Misses         77       77              
Flag Coverage Δ
integration 94.66% <100.00%> (+0.06%) ⬆️
nc32 94.66% <100.00%> (+0.06%) ⬆️
nc33 94.61% <100.00%> (+0.06%) ⬆️
py3.12 9.57% <0.00%> (-0.12%) ⬇️
py3.13 9.57% <0.00%> (-0.12%) ⬇️
py3.14 9.57% <0.00%> (-0.12%) ⬇️
session-cache 25.43% <0.00%> (-0.30%) ⬇️
unit 9.57% <0.00%> (-0.12%) ⬇️
user-permissions 47.77% <23.52%> (-0.35%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@bigcat88 bigcat88 marked this pull request as ready for review March 31, 2026 13:27
@bigcat88
Copy link
Copy Markdown
Contributor Author

(AI) Ready for review. All CI checks green.

Adds pagination to 5 remaining list tools: list_users (server-side, max 200), list_apps (client-side, max 500), list_tags (client-side, max 500), list_versions (client-side, max 200), get_participants (client-side, max 200). All return standard {data, pagination} format. 79 affected tests pass.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
src/nc_mcp_server/tools/app_management.py (1)

51-51: Consider defensive handling for data["apps"] access.

Unlike list_users (which checks isinstance(data, dict) and "users" in data), this directly accesses data["apps"]. If the OCS API returns an unexpected format, this will raise a KeyError.

🛡️ Optional: Add defensive check
-        all_apps = data["apps"]
+        all_apps = data["apps"] if isinstance(data, dict) and "apps" in data else data
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/nc_mcp_server/tools/app_management.py` at line 51, Replace the direct
indexing of data["apps"] with a defensive check similar to list_users: verify
isinstance(data, dict) and "apps" in data before assigning to all_apps (e.g.,
default to an empty list or log/raise a clear error). Update the code around the
all_apps = data["apps"] assignment in app_management.py so it uses the validated
value (or fallback) and ensure any downstream code that iterates over all_apps
still works with the fallback.
tests/integration/test_versions.py (1)

40-45: Consider passing limit for consistency.

This test omits the limit parameter while all other list_versions calls in the file use limit=200. This may be intentional to test default behavior, but it creates inconsistency. If testing defaults is the goal, consider adding a comment to clarify; otherwise, add limit=200 for uniformity.

♻️ Suggested change for consistency
     `@pytest.mark.asyncio`
     async def test_returns_json_list(self, nc_mcp: McpTestHelper) -> None:
         file_id = await _create_versioned_file(nc_mcp, "list-basic")
-        result = await nc_mcp.call("list_versions", file_id=file_id)
+        result = await nc_mcp.call("list_versions", file_id=file_id, limit=200)
         parsed = json.loads(result)
         assert isinstance(parsed["data"], list)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/integration/test_versions.py` around lines 40 - 45, The test
test_returns_json_list calls nc_mcp.call("list_versions", file_id=file_id)
without a limit while other tests pass limit=200; update the call to include
limit=200 for consistency (i.e., nc_mcp.call("list_versions", file_id=file_id,
limit=200)), referencing the list_versions RPC invocation in this test and the
helper _create_versioned_file to locate the test; alternatively, if the intent
is to assert default behavior, add a one-line comment above
test_returns_json_list clarifying that omission is intentional.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/nc_mcp_server/tools/app_management.py`:
- Line 51: Replace the direct indexing of data["apps"] with a defensive check
similar to list_users: verify isinstance(data, dict) and "apps" in data before
assigning to all_apps (e.g., default to an empty list or log/raise a clear
error). Update the code around the all_apps = data["apps"] assignment in
app_management.py so it uses the validated value (or fallback) and ensure any
downstream code that iterates over all_apps still works with the fallback.

In `@tests/integration/test_versions.py`:
- Around line 40-45: The test test_returns_json_list calls
nc_mcp.call("list_versions", file_id=file_id) without a limit while other tests
pass limit=200; update the call to include limit=200 for consistency (i.e.,
nc_mcp.call("list_versions", file_id=file_id, limit=200)), referencing the
list_versions RPC invocation in this test and the helper _create_versioned_file
to locate the test; alternatively, if the intent is to assert default behavior,
add a one-line comment above test_returns_json_list clarifying that omission is
intentional.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 7bbe2aef-a2ed-4a32-a401-7883dc039e78

📥 Commits

Reviewing files that changed from the base of the PR and between 0725a60 and b2d1561.

📒 Files selected for processing (11)
  • pyproject.toml
  • src/nc_mcp_server/tools/app_management.py
  • src/nc_mcp_server/tools/system_tags.py
  • src/nc_mcp_server/tools/talk.py
  • src/nc_mcp_server/tools/users.py
  • src/nc_mcp_server/tools/versions.py
  • tests/integration/test_app_management.py
  • tests/integration/test_system_tags.py
  • tests/integration/test_talk.py
  • tests/integration/test_users.py
  • tests/integration/test_versions.py

@oleksandr-nc oleksandr-nc merged commit 9e7b1a0 into main Mar 31, 2026
12 checks passed
@oleksandr-nc oleksandr-nc deleted the feature/add-remaining-pagination branch March 31, 2026 13:59
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