-
Notifications
You must be signed in to change notification settings - Fork 1
Add configurable NFT page size and slice responses #126
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add configurable NFT page size and slice responses #126
Conversation
WalkthroughThe codebase introduces a configurable page size for the Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant MCP_Server
participant Blockscout_API
Client->>MCP_Server: Request NFT tokens (with/without cursor)
MCP_Server->>Blockscout_API: Fetch full page (e.g., 50 items)
Blockscout_API-->>MCP_Server: Return items (up to 50)
MCP_Server->>MCP_Server: Slice items to page size (e.g., 10)
MCP_Server->>MCP_Server: Generate cursor from last item in slice
MCP_Server-->>Client: Return sliced items + pagination cursor
Assessment against linked issues
Poem
✨ Finishing Touches
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (2)
SPEC.md (2)
235-235
: Markdown-lint warning: missing fenced-code language
markdownlint
flags this fence (MD040). Although the block starts earlier withjson, the closing fence is indented and the linter treats it as a new fence without a language. Out-dent the closing
or add a dummy language to silence the warning.Example:
- ``` +```
237-244
: New slicing section is clear but missing env-var cross-referenceGood explanation of the slicing logic. Consider explicitly linking the config key (
nft_page_size
) to its environment variable (BLOCKSCOUT_NFT_PAGE_SIZE
) in this paragraph for quicker discoverability.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
.cursor/rules/110-new-mcp-tool.mdc
(1 hunks)SPEC.md
(4 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- .cursor/rules/110-new-mcp-tool.mdc
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.652Z
Learning: Applies to blockscout_mcp_server/tools/*.py : Truncate large data fields in API responses and flag the truncation, providing guidance on how to retrieve the full data.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.652Z
Learning: Applies to blockscout_mcp_server/tools/*.py : For paginated tools, do not expose individual pagination parameters; use a single, opaque cursor string and handle it with apply_cursor_to_params.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.652Z
Learning: Applies to blockscout_mcp_server/tools/*.py : For paginated tools, include the exact notice '**SUPPORTS PAGINATION**: If response includes 'pagination' field, use the provided next_call to get additional pages.' in the docstring.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/220-integration-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:31:56.449Z
Learning: Applies to tests/integration/test_*_integration.py : Integration tests for cursor-based pagination must perform a two-step test: (1) call the tool without a cursor and extract the cursor from the response, (2) call the tool again with the cursor and assert that the second page's data is different from the first.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/220-integration-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:31:56.449Z
Learning: Applies to tests/integration/test_*_integration.py : Integration tests for paginated tools must use a loop with a max_pages_to_check limit to search across pages, and skip the test with a clear message if the target data is not found within the limit.
SPEC.md (13)
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.652Z
Learning: Applies to blockscout_mcp_server/tools/*.py : For paginated tools, do not expose individual pagination parameters; use a single, opaque cursor string and handle it with apply_cursor_to_params.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.652Z
Learning: Applies to blockscout_mcp_server/tools/*.py : For paginated tools, include the exact notice '**SUPPORTS PAGINATION**: If response includes 'pagination' field, use the provided next_call to get additional pages.' in the docstring.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.652Z
Learning: Applies to blockscout_mcp_server/tools/*.py : Truncate large data fields in API responses and flag the truncation, providing guidance on how to retrieve the full data.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/900-rules-maintenance.mdc:0-0
Timestamp: 2025-07-04T20:35:06.699Z
Learning: Applies to .cursor/AGENTS.md : Update the corresponding guidance in the 'Rule Application Guidelines' section of `.cursor/AGENTS.md` to reflect the changes made to the rule file.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/130-version-management.mdc:0-0
Timestamp: 2025-07-04T20:25:11.247Z
Learning: Applies to blockscout_mcp_server/__init__.py : When updating the version of the MCP server, update the `__version__` variable in `blockscout_mcp_server/__init__.py`.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.652Z
Learning: Applies to blockscout_mcp_server/tools/*.py : Simplify address objects in API responses to a single address string to save LLM context.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.652Z
Learning: Applies to blockscout_mcp_server/tools/*.py : Recursively truncate nested data structures in API responses, replacing long strings with a structured object to signal truncation.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/000-role-and-task.mdc:0-0
Timestamp: 2025-07-04T20:18:25.785Z
Learning: Applies to **/*.py : The MCP server must wrap Blockscout APIs and expose blockchain data (balances, tokens, NFTs, contract metadata) via the Model Context Protocol (MCP)
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/130-version-management.mdc:0-0
Timestamp: 2025-07-04T20:25:11.247Z
Learning: Update both `pyproject.toml` and `blockscout_mcp_server/__init__.py` simultaneously to maintain consistency across the codebase.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-07-04T20:16:41.158Z
Learning: Read the project technical description in `SPEC.md` to clearly understand how the MCP server communicates with counterparties and important aspects of the server implementation before responding to a user request
Learnt from: CR
PR: blockscout/mcp-server#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-07-04T20:16:41.158Z
Learning: Read `.cursor/rules/010-implementation-rules.mdc` for general coding instructions before responding to a user request
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/220-integration-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:31:56.449Z
Learning: Applies to tests/integration/test_*_integration.py : Integration tests for cursor-based pagination must perform a two-step test: (1) call the tool without a cursor and extract the cursor from the response, (2) call the tool again with the cursor and assert that the second page's data is different from the first.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.652Z
Learning: Applies to blockscout_mcp_server/tools/*.py : For tools that query Blockscout API, use dynamic chain resolution via get_blockscout_base_url and make_blockscout_request.
🪛 markdownlint-cli2 (0.17.2)
SPEC.md
235-235: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: Docker build and docker push
🔇 Additional comments (2)
SPEC.md (2)
205-206
: Mechanism paragraph – looks goodClear, technically accurate text that matches the implementation (
apply_cursor_to_params
). No action needed.
179-180
: Invalid JSON example – extra brace breaks tooling copy-pasteThe sample JSON now has one closing brace too many. Anyone copying it into a linter / example request will get a parse error.
- } - ``` + } + ```Removing the superfluous brace keeps the example syntactically valid.
Likely an incorrect or invalid review comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR introduces a configurable page size for the nft_tokens_by_address
tool, slices API responses accordingly, and updates all related tests, docs, and environment settings.
- Adds
nft_page_size
to configuration,.env
, and Dockerfile - Implements response slicing and custom cursor generation in
address_tools.py
- Updates unit/integration tests and SPEC.md to reflect the new pagination pattern
Reviewed Changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.
Show a summary per file
File | Description |
---|---|
tests/tools/test_address_tools_2.py | Adjusted unit tests to cover default slicing and custom page sizes |
tests/integration/test_address_tools_integration.py | Tightened integration test to assert slice length ≤ page size |
blockscout_mcp_server/tools/address_tools.py | Added slicing logic based on config.nft_page_size and new cursor logic |
blockscout_mcp_server/config.py | Introduced nft_page_size setting |
SPEC.md | Documented the response slicing and context-aware pagination pattern |
Dockerfile | Exposed BLOCKSCOUT_NFT_PAGE_SIZE environment variable |
.env.example | Added example entry for BLOCKSCOUT_NFT_PAGE_SIZE |
.cursor/rules/110-new-mcp-tool.mdc | Updated example code snippet to illustrate per-tool pagination |
Comments suppressed due to low confidence (2)
tests/tools/test_address_tools_2.py:346
- Add an assertion on
len(result.data)
(e.g.,assert len(result.data) == config.nft_page_size
) to verify that the slicing behavior returns the expected number of items.
result = await nft_tokens_by_address(chain_id=chain_id, address=address, ctx=mock_ctx)
.cursor/rules/110-new-mcp-tool.mdc:400
- The example snippet still uses a hard-coded
PAGE_SIZE
. Consider showing how to read a per-tool page size from your configuration (e.g.,config.nft_page_size
) to align with project conventions.
PAGE_SIZE = 10 # This should be a configurable value per-tool
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🔭 Outside diff range comments (2)
tests/tools/test_transaction_tools_3.py (2)
319-319
: Fix inconsistent variable naming.The variable should be renamed from
hash
totx_hash
to maintain consistency with the rest of the file and avoid shadowing the built-inhash()
function.Apply this diff to fix the inconsistency:
- hash = "0xabc123" + tx_hash = "0xabc123"
327-327
: Update the function call to use the renamed variable.Since the variable should be renamed to
tx_hash
, update the function call accordingly.Apply this diff:
- await get_transaction_logs(chain_id=chain_id, transaction_hash=hash, cursor=invalid_cursor, ctx=mock_ctx) + await get_transaction_logs(chain_id=chain_id, transaction_hash=tx_hash, cursor=invalid_cursor, ctx=mock_ctx)
♻️ Duplicate comments (1)
blockscout_mcp_server/tools/address_tools.py (1)
205-220
: NFT pagination correctly implements configurable page size.The implementation properly slices items based on the configured
nft_page_size
and constructs pagination parameters from the last item in the sliced list.Note: The hard-coded value
50
on line 218 has been previously flagged and will be addressed in a future update.
🧹 Nitpick comments (3)
.cursor/rules/110-new-mcp-tool.mdc (1)
356-397
: Well-designed pagination pattern that balances API efficiency with LLM context constraints.The new context conservation strategy and page size configuration approach is excellent. The separation between API fetch size and LLM response size addresses a real problem.
Consider adding guidance on choosing appropriate page sizes based on typical item complexity (e.g., "For simple items like addresses, 20-30 is reasonable; for complex items with nested data, 5-10 may be better").
blockscout_mcp_server/tools/transaction_tools.py (2)
122-208
: Excellent implementation of smart pagination for sparse filtered data.The function elegantly handles the challenge of accumulating enough filtered items across multiple API pages. The progress reporting integration and the logic for determining
has_more_pages
are well-thought-out.Consider making
max_pages_to_fetch
configurable viaconfig
to allow tuning for different deployment scenarios:+ max_pages_to_fetch: int = config.smart_pagination_max_pages, # Default could be 10 in config - max_pages_to_fetch: int = 10, # Prevent infinite loops
585-602
: Consider simplifying the address extraction logic for better readability.While the current logic is correct, it could be more readable.
- address_value = ( - item.get("address", {}).get("hash") if isinstance(item.get("address"), dict) else item.get("address") - ) + address_obj = item.get("address") + address_value = address_obj.get("hash") if isinstance(address_obj, dict) else address_obj
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (19)
.cursor/rules/110-new-mcp-tool.mdc
(3 hunks).cursor/rules/210-unit-testing-guidelines.mdc
(3 hunks).env.example
(1 hunks)AGENTS.md
(3 hunks)Dockerfile
(1 hunks)SPEC.md
(4 hunks)blockscout_mcp_server/config.py
(1 hunks)blockscout_mcp_server/tools/address_tools.py
(7 hunks)blockscout_mcp_server/tools/common.py
(2 hunks)blockscout_mcp_server/tools/transaction_tools.py
(9 hunks)tests/integration/test_address_tools_integration.py
(2 hunks)tests/integration/test_transaction_tools_integration.py
(4 hunks)tests/tools/test_address_logs.py
(3 hunks)tests/tools/test_common.py
(2 hunks)tests/tools/test_transaction_tools.py
(15 hunks)tests/tools/test_transaction_tools_2.py
(4 hunks)tests/tools/test_transaction_tools_3.py
(19 hunks)tests/tools/test_transaction_tools_helpers.py
(1 hunks)tests/tools/test_transaction_tools_pagination.py
(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- tests/tools/test_transaction_tools_2.py
🚧 Files skipped from review as they are similar to previous changes (3)
- Dockerfile
- blockscout_mcp_server/config.py
- tests/integration/test_address_tools_integration.py
🧰 Additional context used
📓 Path-based instructions (13)
`.env.example`: Add new API environment variables to .env.example when introducing a new endpoint.
.env.example
: Add new API environment variables to .env.example when introducing a new endpoint.
📄 Source: CodeRabbit Inference Engine (.cursor/rules/110-new-mcp-tool.mdc)
List of files the instruction was applied to:
.env.example
`.cursor/rules/*.mdc`: When you create, modify, or delete any `.mdc` file in `.cursor/rules/`, you MUST update `.cursor/AGENTS.md` accordingly.
.cursor/rules/*.mdc
: When you create, modify, or delete any.mdc
file in.cursor/rules/
, you MUST update.cursor/AGENTS.md
accordingly.
📄 Source: CodeRabbit Inference Engine (.cursor/rules/900-rules-maintenance.mdc)
List of files the instruction was applied to:
.cursor/rules/210-unit-testing-guidelines.mdc
.cursor/rules/110-new-mcp-tool.mdc
`**/*.py`: The MCP server must be implemented in Python The MCP server must wrap...
**/*.py
: The MCP server must be implemented in Python
The MCP server must wrap Blockscout APIs and expose blockchain data (balances, tokens, NFTs, contract metadata) via the Model Context Protocol (MCP)
The MCP server must communicate with AI agents or chat applications through stdin
📄 Source: CodeRabbit Inference Engine (.cursor/rules/000-role-and-task.mdc)
List of files the instruction was applied to:
tests/tools/test_transaction_tools_helpers.py
tests/tools/test_common.py
tests/integration/test_transaction_tools_integration.py
tests/tools/test_address_logs.py
blockscout_mcp_server/tools/address_tools.py
tests/tools/test_transaction_tools_3.py
tests/tools/test_transaction_tools_pagination.py
blockscout_mcp_server/tools/common.py
blockscout_mcp_server/tools/transaction_tools.py
tests/tools/test_transaction_tools.py
`**/*.py`: Regular Python modules should generally not exceed 500 lines of code ...
**/*.py
: Regular Python modules should generally not exceed 500 lines of code (LOC). If a module approaches this limit, consider splitting it into multiple focused modules (e.g., address_tools.py and address_tools_advanced.py) to maintain readability and logical organization.
ALL import statements must be placed at the top of the Python module, immediately after the module docstring (if present) and before any other code. Never insert imports inline near where the functionality is used. Follow PEP 8 import order.
ALL linting and formatting issues must be resolved before committing or pushing code. Use the Ruff rules defined in .cursor/rules/300-ruff-lint-and-format.mdc to identify and fix issues.
📄 Source: CodeRabbit Inference Engine (.cursor/rules/010-implementation-rules.mdc)
List of files the instruction was applied to:
tests/tools/test_transaction_tools_helpers.py
tests/tools/test_common.py
tests/integration/test_transaction_tools_integration.py
tests/tools/test_address_logs.py
blockscout_mcp_server/tools/address_tools.py
tests/tools/test_transaction_tools_3.py
tests/tools/test_transaction_tools_pagination.py
blockscout_mcp_server/tools/common.py
blockscout_mcp_server/tools/transaction_tools.py
tests/tools/test_transaction_tools.py
`tests/tools/test_*.py`: Create or update the appropriate unit test file when adding or modifying tool functions: tests/tools/test_{tool_module}.py
tests/tools/test_*.py
: Create or update the appropriate unit test file when adding or modifying tool functions: tests/tools/test_{tool_module}.py
📄 Source: CodeRabbit Inference Engine (.cursor/rules/200-development-testing-workflow.mdc)
List of files the instruction was applied to:
tests/tools/test_transaction_tools_helpers.py
tests/tools/test_common.py
tests/tools/test_address_logs.py
tests/tools/test_transaction_tools_3.py
tests/tools/test_transaction_tools_pagination.py
tests/tools/test_transaction_tools.py
`tests/tools/*.py`: Use the `mock_ctx` pytest fixture from `tests/conftest.py` f...
tests/tools/*.py
: Use themock_ctx
pytest fixture fromtests/conftest.py
for mocking the MCP Context object in tests; do not create a manual MagicMock for the context within your test functions.
For tools returning aToolResponse
object, do not parse JSON from string results in your test; instead, mock the serialization function (json.dumps
) if used internally, and make assertions on the structuredToolResponse
object and its attributes.
When testing tools that transform a list of items, programmatically generate theexpected_result
from themock_api_response
instead of writing out large, repetitive expected results.
Always verify the number of calls tomock_ctx.report_progress
in your assertions to ensure progress tracking is tested.
Assert that mocked API helper functions (such asmake_blockscout_request
) are called exactly once with the correctapi_path
andparams
in your tests.
For tools usingmake_request_with_periodic_progress
, mock the wrapper itself and assert that it was called with the correct arguments (request_function
,request_args
, etc.).
Unit test files must not exceed 500 lines of code (LOC); if a file approaches this limit, split tests into multiple files (e.g.,test_some_tools_1.py
,test_some_tools_2.py
) to maintain readability and focus.
Ensure all external API calls are properly mocked usingunittest.mock.patch
andAsyncMock
.
Group related tests using descriptive class names or clear function naming patterns.
📄 Source: CodeRabbit Inference Engine (.cursor/rules/210-unit-testing-guidelines.mdc)
List of files the instruction was applied to:
tests/tools/test_transaction_tools_helpers.py
tests/tools/test_common.py
tests/tools/test_address_logs.py
tests/tools/test_transaction_tools_3.py
tests/tools/test_transaction_tools_pagination.py
tests/tools/test_transaction_tools.py
`**/*.py`: Always run `ruff check . --fix` and `ruff format .` on generated code...
**/*.py
: Always runruff check . --fix
andruff format .
on generated code before suggesting commits or opening a PR
Avoid using# noqa: E501
for ordinary code lines; split long lines instead. Only use# noqa: E501
for docstrings or string literals that must exceed 120 characters.
Ruff enforces a 120-character line length limit by default (Black-compatible style)
📄 Source: CodeRabbit Inference Engine (.cursor/rules/300-ruff-lint-and-format.mdc)
List of files the instruction was applied to:
tests/tools/test_transaction_tools_helpers.py
tests/tools/test_common.py
tests/integration/test_transaction_tools_integration.py
tests/tools/test_address_logs.py
blockscout_mcp_server/tools/address_tools.py
tests/tools/test_transaction_tools_3.py
tests/tools/test_transaction_tools_pagination.py
blockscout_mcp_server/tools/common.py
blockscout_mcp_server/tools/transaction_tools.py
tests/tools/test_transaction_tools.py
`tests/integration/test_*_integration.py`: Add integration tests in tests/integr...
tests/integration/test_*_integration.py
: Add integration tests in tests/integration/test_{tool_module}_integration.py when adding or modifying tool functions that interact with live APIs
📄 Source: CodeRabbit Inference Engine (.cursor/rules/200-development-testing-workflow.mdc)
List of files the instruction was applied to:
tests/integration/test_transaction_tools_integration.py
`tests/integration/test_*_integration.py`: Tool-level integration tests targetin...
tests/integration/test_*_integration.py
: Tool-level integration tests targeting high-level MCP tool functions (e.g., get_latest_block, get_tokens_by_address) must be located in files matching tests/integration/test_*_integration.py and should validate data extraction and schema against live API responses.
Integration tests for paginated tools must use a loop with a max_pages_to_check limit to search across pages, and skip the test with a clear message if the target data is not found within the limit.
Integration tests for cursor-based pagination must perform a two-step test: (1) call the tool without a cursor and extract the cursor from the response, (2) call the tool again with the cursor and assert that the second page's data is different from the first.
📄 Source: CodeRabbit Inference Engine (.cursor/rules/220-integration-testing-guidelines.mdc)
List of files the instruction was applied to:
tests/integration/test_transaction_tools_integration.py
`tests/integration/*`: Integration tests must use stable, non-volatile data poin...
tests/integration/*
: Integration tests must use stable, non-volatile data points such as historical blocks, famous addresses, or established ENS names to ensure reliability across runs.
Every integration test function must be decorated with @pytest.mark.integration.
Integration tests should be resilient to temporary network issues by implementing retry logic and skipping the test with a clear message if connectivity cannot be established after several attempts.
Do not hardcode environment-specific URLs in integration test assertions; instead, dynamically resolve URLs using the same helper functions as the code under test.
Integration test files must not exceed 500 lines of code (LOC); if a file approaches this limit, split tests into multiple focused files to maintain readability and logical organization.
Group related integration tests using descriptive class names or clear function naming patterns, use descriptive test names indicating the contract/schema being validated, separate helper-level and tool-level tests into different files when appropriate, and include clear comments explaining the choice of test data.
📄 Source: CodeRabbit Inference Engine (.cursor/rules/220-integration-testing-guidelines.mdc)
List of files the instruction was applied to:
tests/integration/test_transaction_tools_integration.py
`blockscout_mcp_server/tools/*.py`: Create or modify a tool module file in block...
blockscout_mcp_server/tools/*.py
: Create or modify a tool module file in blockscout_mcp_server/tools/ for each new tool, choosing an existing module or creating a new one as appropriate.
All tools MUST return a strongly-typed ToolResponse[YourDataModel] instead of generic ToolResponse[dict].
For tools that query Blockscout API, use dynamic chain resolution via get_blockscout_base_url and make_blockscout_request.
For tools that use fixed API endpoints (like BENS), use the appropriate request helper (e.g., make_bens_request).
All tools MUST return a standardized ToolResponse[YourDataModel] object using the build_tool_response helper.
Avoid returning ToolResponse[dict] or ToolResponse[Any]; always prefer specific ToolResponse[YourDataModel].
For paginated tools, do not expose individual pagination parameters; use a single, opaque cursor string and handle it with apply_cursor_to_params.
For paginated tools, include the exact notice 'SUPPORTS PAGINATION: If response includes 'pagination' field, use the provided next_call to get additional pages.' in the docstring.
Simplify address objects in API responses to a single address string to save LLM context.
Truncate large data fields in API responses and flag the truncation, providing guidance on how to retrieve the full data.
Recursively truncate nested data structures in API responses, replacing long strings with a structured object to signal truncation.
Always raise exceptions for error conditions; never return error messages in ToolResponse notes.
Use the report_and_log_progress helper from tools/common.py for all progress reporting instead of calling ctx.report_progress directly.
When making multiple independent API calls, use asyncio.gather with return_exceptions=True and handle exceptions appropriately.
📄 Source: CodeRabbit Inference Engine (.cursor/rules/110-new-mcp-tool.mdc)
List of files the instruction was applied to:
blockscout_mcp_server/tools/address_tools.py
blockscout_mcp_server/tools/common.py
blockscout_mcp_server/tools/transaction_tools.py
`blockscout_mcp_server/tools/common.py`: Create a request helper function for new APIs in blockscout_mcp_server/tools/common.py.
blockscout_mcp_server/tools/common.py
: Create a request helper function for new APIs in blockscout_mcp_server/tools/common.py.
📄 Source: CodeRabbit Inference Engine (.cursor/rules/110-new-mcp-tool.mdc)
List of files the instruction was applied to:
blockscout_mcp_server/tools/common.py
`AGENTS.md`: Update AGENTS.md documentation to reflect new or modified tool modules, including updates to the project structure and examples sections.
AGENTS.md
: Update AGENTS.md documentation to reflect new or modified tool modules, including updates to the project structure and examples sections.
📄 Source: CodeRabbit Inference Engine (.cursor/rules/110-new-mcp-tool.mdc)
List of files the instruction was applied to:
AGENTS.md
🧠 Learnings (16)
📓 Common learnings
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : Truncate large data fields in API responses and flag the truncation, providing guidance on how to retrieve the full data.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : For paginated tools, do not expose individual pagination parameters; use a single, opaque cursor string and handle it with apply_cursor_to_params.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : For paginated tools, include the exact notice '**SUPPORTS PAGINATION**: If response includes 'pagination' field, use the provided next_call to get additional pages.' in the docstring.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/220-integration-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:31:56.480Z
Learning: Applies to tests/integration/test_*_integration.py : Integration tests for cursor-based pagination must perform a two-step test: (1) call the tool without a cursor and extract the cursor from the response, (2) call the tool again with the cursor and assert that the second page's data is different from the first.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/220-integration-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:31:56.480Z
Learning: Applies to tests/integration/test_*_integration.py : Integration tests for paginated tools must use a loop with a max_pages_to_check limit to search across pages, and skip the test with a clear message if the target data is not found within the limit.
.env.example (6)
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to .env.example : Add new API environment variables to .env.example when introducing a new endpoint.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to Dockerfile : Add new API environment variables to the Dockerfile when introducing a new endpoint.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : For paginated tools, include the exact notice '**SUPPORTS PAGINATION**: If response includes 'pagination' field, use the provided next_call to get additional pages.' in the docstring.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : For paginated tools, do not expose individual pagination parameters; use a single, opaque cursor string and handle it with apply_cursor_to_params.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : For tools that query Blockscout API, use dynamic chain resolution via get_blockscout_base_url and make_blockscout_request.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : For tools that use fixed API endpoints (like BENS), use the appropriate request helper (e.g., make_bens_request).
.cursor/rules/210-unit-testing-guidelines.mdc (23)
Learnt from: CR
PR: blockscout/mcp-server#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-07-04T20:16:41.182Z
Learning: Read `.cursor/rules/200-development-testing-workflow.mdc` for instructions related to unit and integration testing applicable when a new helper function or MCP tool function is added or modified
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/220-integration-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:31:56.480Z
Learning: Applies to tests/integration/* : Group related integration tests using descriptive class names or clear function naming patterns, use descriptive test names indicating the contract/schema being validated, separate helper-level and tool-level tests into different files when appropriate, and include clear comments explaining the choice of test data.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/210-unit-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:30:09.292Z
Learning: Applies to tests/tools/*.py : Unit test files must not exceed 500 lines of code (LOC); if a file approaches this limit, split tests into multiple files (e.g., `test_some_tools_1.py`, `test_some_tools_2.py`) to maintain readability and focus.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/210-unit-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:30:09.292Z
Learning: Applies to tests/tools/*.py : Group related tests using descriptive class names or clear function naming patterns.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/900-rules-maintenance.mdc:0-0
Timestamp: 2025-07-04T20:35:06.726Z
Learning: Applies to .cursor/AGENTS.md : Update the corresponding guidance in the 'Rule Application Guidelines' section of `.cursor/AGENTS.md` to reflect the changes made to the rule file.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/220-integration-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:31:56.480Z
Learning: Applies to tests/integration/* : Integration test files must not exceed 500 lines of code (LOC); if a file approaches this limit, split tests into multiple focused files to maintain readability and logical organization.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/200-development-testing-workflow.mdc:0-0
Timestamp: 2025-07-04T20:28:28.716Z
Learning: Applies to tests/test_server.py : Create or update the unit test file tests/test_server.py when adding or modifying server functionality
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/210-unit-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:30:09.292Z
Learning: Applies to tests/tools/*.py : Ensure all external API calls are properly mocked using `unittest.mock.patch` and `AsyncMock`.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/200-development-testing-workflow.mdc:0-0
Timestamp: 2025-07-04T20:28:28.716Z
Learning: Applies to tests/test_common.py : Create or update the unit test file tests/test_common.py when adding or modifying common utilities
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/210-unit-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:30:09.292Z
Learning: Applies to tests/tools/*.py : Always verify the number of calls to `mock_ctx.report_progress` in your assertions to ensure progress tracking is tested.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/210-unit-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:30:09.292Z
Learning: Applies to tests/tools/*.py : Use the `mock_ctx` pytest fixture from `tests/conftest.py` for mocking the MCP Context object in tests; do not create a manual MagicMock for the context within your test functions.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/220-integration-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:31:56.480Z
Learning: Applies to tests/integration/test_*_integration.py : Tool-level integration tests targeting high-level MCP tool functions (e.g., get_latest_block, get_tokens_by_address) must be located in files matching tests/integration/test_*_integration.py and should validate data extraction and schema against live API responses.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/210-unit-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:30:09.292Z
Learning: Write tests covering success scenarios, error cases, and edge cases.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/210-unit-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:30:09.292Z
Learning: Applies to tests/tools/*.py : For tools returning a `ToolResponse` object, do not parse JSON from string results in your test; instead, mock the serialization function (`json.dumps`) if used internally, and make assertions on the structured `ToolResponse` object and its attributes.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/200-development-testing-workflow.mdc:0-0
Timestamp: 2025-07-04T20:28:28.716Z
Learning: Run integration tests (pytest -m integration) when you have added or modified any existing MCP tool function, modified helper functions in tools/common.py, added or changed any integration test, or changed data extraction or transformation logic
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/210-unit-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:30:09.292Z
Learning: Applies to tests/tools/*.py : For tools using `make_request_with_periodic_progress`, mock the wrapper itself and assert that it was called with the correct arguments (`request_function`, `request_args`, etc.).
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/210-unit-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:30:09.292Z
Learning: Applies to tests/tools/*.py : Assert that mocked API helper functions (such as `make_blockscout_request`) are called exactly once with the correct `api_path` and `params` in your tests.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/210-unit-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:30:09.292Z
Learning: Applies to tests/tools/*.py : When testing tools that transform a list of items, programmatically generate the `expected_result` from the `mock_api_response` instead of writing out large, repetitive expected results.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/200-development-testing-workflow.mdc:0-0
Timestamp: 2025-07-04T20:28:28.716Z
Learning: Always run the unit test suite before and after making changes using pytest
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : Avoid returning ToolResponse[dict] or ToolResponse[Any]; always prefer specific ToolResponse[YourDataModel].
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : All tools MUST return a standardized ToolResponse[YourDataModel] object using the build_tool_response helper.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : All tools MUST return a strongly-typed ToolResponse[YourDataModel] instead of generic ToolResponse[dict].
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/200-development-testing-workflow.mdc:0-0
Timestamp: 2025-07-04T20:28:28.716Z
Learning: Applies to tests/integration/test_*_integration.py : Add integration tests in tests/integration/test_{tool_module}_integration.py when adding or modifying tool functions that interact with live APIs
tests/tools/test_transaction_tools_helpers.py (5)
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/200-development-testing-workflow.mdc:0-0
Timestamp: 2025-07-04T20:28:28.716Z
Learning: Applies to tests/integration/test_common_helpers.py : Add integration tests in tests/integration/test_common_helpers.py when modifying helper functions in tools/common.py
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/200-development-testing-workflow.mdc:0-0
Timestamp: 2025-07-04T20:28:28.716Z
Learning: Applies to tests/integration/test_*_integration.py : Add integration tests in tests/integration/test_{tool_module}_integration.py when adding or modifying tool functions that interact with live APIs
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/220-integration-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:31:56.480Z
Learning: Applies to tests/integration/test_*_integration.py : Tool-level integration tests targeting high-level MCP tool functions (e.g., get_latest_block, get_tokens_by_address) must be located in files matching tests/integration/test_*_integration.py and should validate data extraction and schema against live API responses.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/210-unit-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:30:09.292Z
Learning: Applies to tests/tools/*.py : When testing tools that transform a list of items, programmatically generate the `expected_result` from the `mock_api_response` instead of writing out large, repetitive expected results.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/200-development-testing-workflow.mdc:0-0
Timestamp: 2025-07-04T20:28:28.716Z
Learning: Applies to tests/tools/test_*.py : Create or update the appropriate unit test file when adding or modifying tool functions: tests/tools/test_{tool_module}.py
tests/tools/test_common.py (13)
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/220-integration-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:31:56.480Z
Learning: Applies to tests/integration/test_*_integration.py : Integration tests for cursor-based pagination must perform a two-step test: (1) call the tool without a cursor and extract the cursor from the response, (2) call the tool again with the cursor and assert that the second page's data is different from the first.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/200-development-testing-workflow.mdc:0-0
Timestamp: 2025-07-04T20:28:28.716Z
Learning: Applies to tests/integration/test_common_helpers.py : Add integration tests in tests/integration/test_common_helpers.py when modifying helper functions in tools/common.py
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : For paginated tools, do not expose individual pagination parameters; use a single, opaque cursor string and handle it with apply_cursor_to_params.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/220-integration-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:31:56.480Z
Learning: Applies to tests/integration/test_*_integration.py : Integration tests for paginated tools must use a loop with a max_pages_to_check limit to search across pages, and skip the test with a clear message if the target data is not found within the limit.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/200-development-testing-workflow.mdc:0-0
Timestamp: 2025-07-04T20:28:28.716Z
Learning: Applies to tests/integration/test_*_integration.py : Add integration tests in tests/integration/test_{tool_module}_integration.py when adding or modifying tool functions that interact with live APIs
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/210-unit-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:30:09.292Z
Learning: Applies to tests/tools/*.py : When testing tools that transform a list of items, programmatically generate the `expected_result` from the `mock_api_response` instead of writing out large, repetitive expected results.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-07-04T20:16:41.182Z
Learning: Read `.cursor/rules/200-development-testing-workflow.mdc` for instructions related to unit and integration testing applicable when a new helper function or MCP tool function is added or modified
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/210-unit-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:30:09.292Z
Learning: Applies to tests/tools/*.py : Ensure all external API calls are properly mocked using `unittest.mock.patch` and `AsyncMock`.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : For paginated tools, include the exact notice '**SUPPORTS PAGINATION**: If response includes 'pagination' field, use the provided next_call to get additional pages.' in the docstring.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/200-development-testing-workflow.mdc:0-0
Timestamp: 2025-07-04T20:28:28.716Z
Learning: Run integration tests (pytest -m integration) when you have added or modified any existing MCP tool function, modified helper functions in tools/common.py, added or changed any integration test, or changed data extraction or transformation logic
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : Recursively truncate nested data structures in API responses, replacing long strings with a structured object to signal truncation.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : Truncate large data fields in API responses and flag the truncation, providing guidance on how to retrieve the full data.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/210-unit-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:30:09.292Z
Learning: Applies to tests/tools/*.py : Assert that mocked API helper functions (such as `make_blockscout_request`) are called exactly once with the correct `api_path` and `params` in your tests.
tests/integration/test_transaction_tools_integration.py (10)
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/220-integration-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:31:56.480Z
Learning: Applies to tests/integration/test_*_integration.py : Integration tests for paginated tools must use a loop with a max_pages_to_check limit to search across pages, and skip the test with a clear message if the target data is not found within the limit.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/200-development-testing-workflow.mdc:0-0
Timestamp: 2025-07-04T20:28:28.716Z
Learning: Applies to tests/integration/test_*_integration.py : Add integration tests in tests/integration/test_{tool_module}_integration.py when adding or modifying tool functions that interact with live APIs
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/220-integration-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:31:56.480Z
Learning: Applies to tests/integration/test_*_integration.py : Tool-level integration tests targeting high-level MCP tool functions (e.g., get_latest_block, get_tokens_by_address) must be located in files matching tests/integration/test_*_integration.py and should validate data extraction and schema against live API responses.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/220-integration-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:31:56.480Z
Learning: Applies to tests/integration/test_*_integration.py : Integration tests for cursor-based pagination must perform a two-step test: (1) call the tool without a cursor and extract the cursor from the response, (2) call the tool again with the cursor and assert that the second page's data is different from the first.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/200-development-testing-workflow.mdc:0-0
Timestamp: 2025-07-04T20:28:28.716Z
Learning: Applies to tests/integration/test_common_helpers.py : Add integration tests in tests/integration/test_common_helpers.py when modifying helper functions in tools/common.py
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/200-development-testing-workflow.mdc:0-0
Timestamp: 2025-07-04T20:28:28.716Z
Learning: Run integration tests (pytest -m integration) when you have added or modified any existing MCP tool function, modified helper functions in tools/common.py, added or changed any integration test, or changed data extraction or transformation logic
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/210-unit-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:30:09.292Z
Learning: Applies to tests/tools/*.py : When testing tools that transform a list of items, programmatically generate the `expected_result` from the `mock_api_response` instead of writing out large, repetitive expected results.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/210-unit-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:30:09.292Z
Learning: Applies to tests/tools/*.py : Always verify the number of calls to `mock_ctx.report_progress` in your assertions to ensure progress tracking is tested.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/220-integration-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:31:56.480Z
Learning: Applies to tests/integration/* : Group related integration tests using descriptive class names or clear function naming patterns, use descriptive test names indicating the contract/schema being validated, separate helper-level and tool-level tests into different files when appropriate, and include clear comments explaining the choice of test data.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/210-unit-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:30:09.292Z
Learning: Applies to tests/tools/*.py : Ensure all external API calls are properly mocked using `unittest.mock.patch` and `AsyncMock`.
tests/tools/test_address_logs.py (22)
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/210-unit-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:30:09.292Z
Learning: Applies to tests/tools/*.py : Ensure all external API calls are properly mocked using `unittest.mock.patch` and `AsyncMock`.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/220-integration-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:31:56.480Z
Learning: Applies to tests/integration/test_*_integration.py : Integration tests for cursor-based pagination must perform a two-step test: (1) call the tool without a cursor and extract the cursor from the response, (2) call the tool again with the cursor and assert that the second page's data is different from the first.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/210-unit-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:30:09.292Z
Learning: Applies to tests/tools/*.py : When testing tools that transform a list of items, programmatically generate the `expected_result` from the `mock_api_response` instead of writing out large, repetitive expected results.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/200-development-testing-workflow.mdc:0-0
Timestamp: 2025-07-04T20:28:28.716Z
Learning: Applies to tests/integration/test_*_integration.py : Add integration tests in tests/integration/test_{tool_module}_integration.py when adding or modifying tool functions that interact with live APIs
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/210-unit-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:30:09.292Z
Learning: Applies to tests/tools/*.py : Always verify the number of calls to `mock_ctx.report_progress` in your assertions to ensure progress tracking is tested.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/220-integration-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:31:56.480Z
Learning: Applies to tests/integration/test_*_integration.py : Integration tests for paginated tools must use a loop with a max_pages_to_check limit to search across pages, and skip the test with a clear message if the target data is not found within the limit.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/200-development-testing-workflow.mdc:0-0
Timestamp: 2025-07-04T20:28:28.716Z
Learning: Applies to tests/integration/test_common_helpers.py : Add integration tests in tests/integration/test_common_helpers.py when modifying helper functions in tools/common.py
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/210-unit-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:30:09.292Z
Learning: Applies to tests/tools/*.py : Use the `mock_ctx` pytest fixture from `tests/conftest.py` for mocking the MCP Context object in tests; do not create a manual MagicMock for the context within your test functions.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : For paginated tools, include the exact notice '**SUPPORTS PAGINATION**: If response includes 'pagination' field, use the provided next_call to get additional pages.' in the docstring.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/210-unit-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:30:09.292Z
Learning: Applies to tests/tools/*.py : For tools using `make_request_with_periodic_progress`, mock the wrapper itself and assert that it was called with the correct arguments (`request_function`, `request_args`, etc.).
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : For tools that query Blockscout API, use dynamic chain resolution via get_blockscout_base_url and make_blockscout_request.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : For tools that use fixed API endpoints (like BENS), use the appropriate request helper (e.g., make_bens_request).
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : Simplify address objects in API responses to a single address string to save LLM context.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/220-integration-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:31:56.480Z
Learning: Applies to tests/integration/test_*_integration.py : Tool-level integration tests targeting high-level MCP tool functions (e.g., get_latest_block, get_tokens_by_address) must be located in files matching tests/integration/test_*_integration.py and should validate data extraction and schema against live API responses.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : Avoid returning ToolResponse[dict] or ToolResponse[Any]; always prefer specific ToolResponse[YourDataModel].
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/config.py : Add new API endpoint configuration to blockscout_mcp_server/config.py when introducing a new external API endpoint.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : For paginated tools, do not expose individual pagination parameters; use a single, opaque cursor string and handle it with apply_cursor_to_params.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/220-integration-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:31:56.480Z
Learning: Applies to tests/integration/test_common_helpers.py : Helper-level integration tests targeting low-level helper functions in tools/common.py (e.g., make_blockscout_request, get_blockscout_base_url) must be located in tests/integration/test_common_helpers.py and verify basic network connectivity and response structure.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : All tools MUST return a standardized ToolResponse[YourDataModel] object using the build_tool_response helper.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : All tools MUST return a strongly-typed ToolResponse[YourDataModel] instead of generic ToolResponse[dict].
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/210-unit-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:30:09.292Z
Learning: Applies to tests/tools/*.py : Assert that mocked API helper functions (such as `make_blockscout_request`) are called exactly once with the correct `api_path` and `params` in your tests.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/210-unit-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:30:09.292Z
Learning: Applies to tests/tools/*.py : For tools returning a `ToolResponse` object, do not parse JSON from string results in your test; instead, mock the serialization function (`json.dumps`) if used internally, and make assertions on the structured `ToolResponse` object and its attributes.
blockscout_mcp_server/tools/address_tools.py (19)
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : For paginated tools, do not expose individual pagination parameters; use a single, opaque cursor string and handle it with apply_cursor_to_params.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : For paginated tools, include the exact notice '**SUPPORTS PAGINATION**: If response includes 'pagination' field, use the provided next_call to get additional pages.' in the docstring.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : Simplify address objects in API responses to a single address string to save LLM context.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : Truncate large data fields in API responses and flag the truncation, providing guidance on how to retrieve the full data.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/220-integration-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:31:56.480Z
Learning: Applies to tests/integration/test_*_integration.py : Integration tests for cursor-based pagination must perform a two-step test: (1) call the tool without a cursor and extract the cursor from the response, (2) call the tool again with the cursor and assert that the second page's data is different from the first.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : Recursively truncate nested data structures in API responses, replacing long strings with a structured object to signal truncation.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/220-integration-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:31:56.480Z
Learning: Applies to tests/integration/test_*_integration.py : Integration tests for paginated tools must use a loop with a max_pages_to_check limit to search across pages, and skip the test with a clear message if the target data is not found within the limit.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/000-role-and-task.mdc:0-0
Timestamp: 2025-07-04T20:18:25.795Z
Learning: Applies to **/*.py : The MCP server must wrap Blockscout APIs and expose blockchain data (balances, tokens, NFTs, contract metadata) via the Model Context Protocol (MCP)
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/models.py : When defining BaseModel subclasses for external API responses, use ConfigDict(extra="allow").
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/config.py : Add new API endpoint configuration to blockscout_mcp_server/config.py when introducing a new external API endpoint.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/130-version-management.mdc:0-0
Timestamp: 2025-07-04T20:25:11.277Z
Learning: Update both `pyproject.toml` and `blockscout_mcp_server/__init__.py` simultaneously to maintain consistency across the codebase.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/models.py : Create a specific Pydantic data model for each new tool's data payload in blockscout_mcp_server/models.py, using Field(description=...) for every attribute.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/server.py : Register each new tool in blockscout_mcp_server/server.py by importing the tool function and registering it with the @mcp.tool() decorator.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/210-unit-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:30:09.292Z
Learning: Applies to tests/tools/*.py : Use the `mock_ctx` pytest fixture from `tests/conftest.py` for mocking the MCP Context object in tests; do not create a manual MagicMock for the context within your test functions.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : For tools that query Blockscout API, use dynamic chain resolution via get_blockscout_base_url and make_blockscout_request.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : For tools that use fixed API endpoints (like BENS), use the appropriate request helper (e.g., make_bens_request).
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/common.py : Create a request helper function for new APIs in blockscout_mcp_server/tools/common.py.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : When making multiple independent API calls, use asyncio.gather with return_exceptions=True and handle exceptions appropriately.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : Create or modify a tool module file in blockscout_mcp_server/tools/ for each new tool, choosing an existing module or creating a new one as appropriate.
tests/tools/test_transaction_tools_3.py (23)
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/210-unit-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:30:09.292Z
Learning: Applies to tests/tools/*.py : Ensure all external API calls are properly mocked using `unittest.mock.patch` and `AsyncMock`.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/220-integration-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:31:56.480Z
Learning: Applies to tests/integration/test_*_integration.py : Integration tests for cursor-based pagination must perform a two-step test: (1) call the tool without a cursor and extract the cursor from the response, (2) call the tool again with the cursor and assert that the second page's data is different from the first.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/200-development-testing-workflow.mdc:0-0
Timestamp: 2025-07-04T20:28:28.716Z
Learning: Applies to tests/integration/test_*_integration.py : Add integration tests in tests/integration/test_{tool_module}_integration.py when adding or modifying tool functions that interact with live APIs
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/210-unit-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:30:09.292Z
Learning: Applies to tests/tools/*.py : When testing tools that transform a list of items, programmatically generate the `expected_result` from the `mock_api_response` instead of writing out large, repetitive expected results.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/210-unit-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:30:09.292Z
Learning: Applies to tests/tools/*.py : Always verify the number of calls to `mock_ctx.report_progress` in your assertions to ensure progress tracking is tested.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/200-development-testing-workflow.mdc:0-0
Timestamp: 2025-07-04T20:28:28.716Z
Learning: Applies to tests/integration/test_common_helpers.py : Add integration tests in tests/integration/test_common_helpers.py when modifying helper functions in tools/common.py
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/220-integration-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:31:56.480Z
Learning: Applies to tests/integration/test_*_integration.py : Tool-level integration tests targeting high-level MCP tool functions (e.g., get_latest_block, get_tokens_by_address) must be located in files matching tests/integration/test_*_integration.py and should validate data extraction and schema against live API responses.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/210-unit-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:30:09.292Z
Learning: Applies to tests/tools/*.py : Group related tests using descriptive class names or clear function naming patterns.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/220-integration-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:31:56.480Z
Learning: Applies to tests/integration/test_*_integration.py : Integration tests for paginated tools must use a loop with a max_pages_to_check limit to search across pages, and skip the test with a clear message if the target data is not found within the limit.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : For paginated tools, include the exact notice '**SUPPORTS PAGINATION**: If response includes 'pagination' field, use the provided next_call to get additional pages.' in the docstring.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : For tools that query Blockscout API, use dynamic chain resolution via get_blockscout_base_url and make_blockscout_request.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : For tools that use fixed API endpoints (like BENS), use the appropriate request helper (e.g., make_bens_request).
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : For paginated tools, do not expose individual pagination parameters; use a single, opaque cursor string and handle it with apply_cursor_to_params.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : Avoid returning ToolResponse[dict] or ToolResponse[Any]; always prefer specific ToolResponse[YourDataModel].
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : All tools MUST return a strongly-typed ToolResponse[YourDataModel] instead of generic ToolResponse[dict].
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : All tools MUST return a standardized ToolResponse[YourDataModel] object using the build_tool_response helper.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/000-role-and-task.mdc:0-0
Timestamp: 2025-07-04T20:18:25.795Z
Learning: Applies to **/*.py : The MCP server must wrap Blockscout APIs and expose blockchain data (balances, tokens, NFTs, contract metadata) via the Model Context Protocol (MCP)
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : When making multiple independent API calls, use asyncio.gather with return_exceptions=True and handle exceptions appropriately.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : Use the report_and_log_progress helper from tools/common.py for all progress reporting instead of calling ctx.report_progress directly.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/210-unit-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:30:09.292Z
Learning: Applies to tests/tools/*.py : Assert that mocked API helper functions (such as `make_blockscout_request`) are called exactly once with the correct `api_path` and `params` in your tests.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/210-unit-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:30:09.292Z
Learning: Applies to tests/tools/*.py : For tools using `make_request_with_periodic_progress`, mock the wrapper itself and assert that it was called with the correct arguments (`request_function`, `request_args`, etc.).
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/210-unit-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:30:09.292Z
Learning: Applies to tests/tools/*.py : For tools returning a `ToolResponse` object, do not parse JSON from string results in your test; instead, mock the serialization function (`json.dumps`) if used internally, and make assertions on the structured `ToolResponse` object and its attributes.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : Truncate large data fields in API responses and flag the truncation, providing guidance on how to retrieve the full data.
tests/tools/test_transaction_tools_pagination.py (12)
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/220-integration-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:31:56.480Z
Learning: Applies to tests/integration/test_*_integration.py : Integration tests for cursor-based pagination must perform a two-step test: (1) call the tool without a cursor and extract the cursor from the response, (2) call the tool again with the cursor and assert that the second page's data is different from the first.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/200-development-testing-workflow.mdc:0-0
Timestamp: 2025-07-04T20:28:28.716Z
Learning: Applies to tests/integration/test_*_integration.py : Add integration tests in tests/integration/test_{tool_module}_integration.py when adding or modifying tool functions that interact with live APIs
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/210-unit-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:30:09.292Z
Learning: Applies to tests/tools/*.py : Ensure all external API calls are properly mocked using `unittest.mock.patch` and `AsyncMock`.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/220-integration-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:31:56.480Z
Learning: Applies to tests/integration/test_*_integration.py : Integration tests for paginated tools must use a loop with a max_pages_to_check limit to search across pages, and skip the test with a clear message if the target data is not found within the limit.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/220-integration-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:31:56.480Z
Learning: Applies to tests/integration/test_*_integration.py : Tool-level integration tests targeting high-level MCP tool functions (e.g., get_latest_block, get_tokens_by_address) must be located in files matching tests/integration/test_*_integration.py and should validate data extraction and schema against live API responses.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : For paginated tools, include the exact notice '**SUPPORTS PAGINATION**: If response includes 'pagination' field, use the provided next_call to get additional pages.' in the docstring.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/200-development-testing-workflow.mdc:0-0
Timestamp: 2025-07-04T20:28:28.716Z
Learning: Applies to tests/integration/test_common_helpers.py : Add integration tests in tests/integration/test_common_helpers.py when modifying helper functions in tools/common.py
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/210-unit-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:30:09.292Z
Learning: Applies to tests/tools/*.py : Always verify the number of calls to `mock_ctx.report_progress` in your assertions to ensure progress tracking is tested.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/210-unit-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:30:09.292Z
Learning: Applies to tests/tools/*.py : When testing tools that transform a list of items, programmatically generate the `expected_result` from the `mock_api_response` instead of writing out large, repetitive expected results.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : For paginated tools, do not expose individual pagination parameters; use a single, opaque cursor string and handle it with apply_cursor_to_params.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : When making multiple independent API calls, use asyncio.gather with return_exceptions=True and handle exceptions appropriately.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/210-unit-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:30:09.292Z
Learning: Applies to tests/tools/*.py : Assert that mocked API helper functions (such as `make_blockscout_request`) are called exactly once with the correct `api_path` and `params` in your tests.
blockscout_mcp_server/tools/common.py (15)
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : For paginated tools, do not expose individual pagination parameters; use a single, opaque cursor string and handle it with apply_cursor_to_params.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : For paginated tools, include the exact notice '**SUPPORTS PAGINATION**: If response includes 'pagination' field, use the provided next_call to get additional pages.' in the docstring.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : Use the report_and_log_progress helper from tools/common.py for all progress reporting instead of calling ctx.report_progress directly.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/server.py : Register each new tool in blockscout_mcp_server/server.py by importing the tool function and registering it with the @mcp.tool() decorator.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/220-integration-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:31:56.480Z
Learning: Applies to tests/integration/test_*_integration.py : Integration tests for cursor-based pagination must perform a two-step test: (1) call the tool without a cursor and extract the cursor from the response, (2) call the tool again with the cursor and assert that the second page's data is different from the first.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/common.py : Create a request helper function for new APIs in blockscout_mcp_server/tools/common.py.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : Truncate large data fields in API responses and flag the truncation, providing guidance on how to retrieve the full data.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : Create or modify a tool module file in blockscout_mcp_server/tools/ for each new tool, choosing an existing module or creating a new one as appropriate.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : For tools that query Blockscout API, use dynamic chain resolution via get_blockscout_base_url and make_blockscout_request.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : For tools that use fixed API endpoints (like BENS), use the appropriate request helper (e.g., make_bens_request).
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : Always raise exceptions for error conditions; never return error messages in ToolResponse notes.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : Avoid returning ToolResponse[dict] or ToolResponse[Any]; always prefer specific ToolResponse[YourDataModel].
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : All tools MUST return a strongly-typed ToolResponse[YourDataModel] instead of generic ToolResponse[dict].
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : Recursively truncate nested data structures in API responses, replacing long strings with a structured object to signal truncation.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : All tools MUST return a standardized ToolResponse[YourDataModel] object using the build_tool_response helper.
blockscout_mcp_server/tools/transaction_tools.py (17)
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : For paginated tools, do not expose individual pagination parameters; use a single, opaque cursor string and handle it with apply_cursor_to_params.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : For paginated tools, include the exact notice '**SUPPORTS PAGINATION**: If response includes 'pagination' field, use the provided next_call to get additional pages.' in the docstring.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : Use the report_and_log_progress helper from tools/common.py for all progress reporting instead of calling ctx.report_progress directly.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : Truncate large data fields in API responses and flag the truncation, providing guidance on how to retrieve the full data.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : When making multiple independent API calls, use asyncio.gather with return_exceptions=True and handle exceptions appropriately.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : For tools that query Blockscout API, use dynamic chain resolution via get_blockscout_base_url and make_blockscout_request.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : For tools that use fixed API endpoints (like BENS), use the appropriate request helper (e.g., make_bens_request).
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/common.py : Create a request helper function for new APIs in blockscout_mcp_server/tools/common.py.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : Simplify address objects in API responses to a single address string to save LLM context.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/220-integration-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:31:56.480Z
Learning: Applies to tests/integration/test_*_integration.py : Integration tests for cursor-based pagination must perform a two-step test: (1) call the tool without a cursor and extract the cursor from the response, (2) call the tool again with the cursor and assert that the second page's data is different from the first.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : Recursively truncate nested data structures in API responses, replacing long strings with a structured object to signal truncation.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : Avoid returning ToolResponse[dict] or ToolResponse[Any]; always prefer specific ToolResponse[YourDataModel].
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : All tools MUST return a strongly-typed ToolResponse[YourDataModel] instead of generic ToolResponse[dict].
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : All tools MUST return a standardized ToolResponse[YourDataModel] object using the build_tool_response helper.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/000-role-and-task.mdc:0-0
Timestamp: 2025-07-04T20:18:25.795Z
Learning: Applies to **/*.py : The MCP server must wrap Blockscout APIs and expose blockchain data (balances, tokens, NFTs, contract metadata) via the Model Context Protocol (MCP)
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/server.py : Register each new tool in blockscout_mcp_server/server.py by importing the tool function and registering it with the @mcp.tool() decorator.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : Always raise exceptions for error conditions; never return error messages in ToolResponse notes.
tests/tools/test_transaction_tools.py (23)
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/210-unit-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:30:09.292Z
Learning: Applies to tests/tools/*.py : For tools using `make_request_with_periodic_progress`, mock the wrapper itself and assert that it was called with the correct arguments (`request_function`, `request_args`, etc.).
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/220-integration-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:31:56.480Z
Learning: Applies to tests/integration/test_*_integration.py : Integration tests for cursor-based pagination must perform a two-step test: (1) call the tool without a cursor and extract the cursor from the response, (2) call the tool again with the cursor and assert that the second page's data is different from the first.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/210-unit-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:30:09.292Z
Learning: Applies to tests/tools/*.py : Ensure all external API calls are properly mocked using `unittest.mock.patch` and `AsyncMock`.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/200-development-testing-workflow.mdc:0-0
Timestamp: 2025-07-04T20:28:28.716Z
Learning: Applies to tests/integration/test_*_integration.py : Add integration tests in tests/integration/test_{tool_module}_integration.py when adding or modifying tool functions that interact with live APIs
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/220-integration-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:31:56.480Z
Learning: Applies to tests/integration/test_*_integration.py : Tool-level integration tests targeting high-level MCP tool functions (e.g., get_latest_block, get_tokens_by_address) must be located in files matching tests/integration/test_*_integration.py and should validate data extraction and schema against live API responses.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/210-unit-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:30:09.292Z
Learning: Applies to tests/tools/*.py : When testing tools that transform a list of items, programmatically generate the `expected_result` from the `mock_api_response` instead of writing out large, repetitive expected results.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/210-unit-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:30:09.292Z
Learning: Applies to tests/tools/*.py : Always verify the number of calls to `mock_ctx.report_progress` in your assertions to ensure progress tracking is tested.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/220-integration-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:31:56.480Z
Learning: Applies to tests/integration/test_*_integration.py : Integration tests for paginated tools must use a loop with a max_pages_to_check limit to search across pages, and skip the test with a clear message if the target data is not found within the limit.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/200-development-testing-workflow.mdc:0-0
Timestamp: 2025-07-04T20:28:28.716Z
Learning: Applies to tests/integration/test_common_helpers.py : Add integration tests in tests/integration/test_common_helpers.py when modifying helper functions in tools/common.py
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/210-unit-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:30:09.292Z
Learning: Applies to tests/tools/*.py : For tools returning a `ToolResponse` object, do not parse JSON from string results in your test; instead, mock the serialization function (`json.dumps`) if used internally, and make assertions on the structured `ToolResponse` object and its attributes.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/config.py : Add new API endpoint configuration to blockscout_mcp_server/config.py when introducing a new external API endpoint.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : For tools that query Blockscout API, use dynamic chain resolution via get_blockscout_base_url and make_blockscout_request.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/000-role-and-task.mdc:0-0
Timestamp: 2025-07-04T20:18:25.795Z
Learning: Applies to **/*.py : The MCP server must wrap Blockscout APIs and expose blockchain data (balances, tokens, NFTs, contract metadata) via the Model Context Protocol (MCP)
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : For tools that use fixed API endpoints (like BENS), use the appropriate request helper (e.g., make_bens_request).
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : For paginated tools, include the exact notice '**SUPPORTS PAGINATION**: If response includes 'pagination' field, use the provided next_call to get additional pages.' in the docstring.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/common.py : Create a request helper function for new APIs in blockscout_mcp_server/tools/common.py.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/220-integration-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:31:56.480Z
Learning: Applies to tests/integration/test_common_helpers.py : Helper-level integration tests targeting low-level helper functions in tools/common.py (e.g., make_blockscout_request, get_blockscout_base_url) must be located in tests/integration/test_common_helpers.py and verify basic network connectivity and response structure.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : When making multiple independent API calls, use asyncio.gather with return_exceptions=True and handle exceptions appropriately.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : Avoid returning ToolResponse[dict] or ToolResponse[Any]; always prefer specific ToolResponse[YourDataModel].
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/210-unit-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:30:09.292Z
Learning: Applies to tests/tools/*.py : Assert that mocked API helper functions (such as `make_blockscout_request`) are called exactly once with the correct `api_path` and `params` in your tests.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/210-unit-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:30:09.292Z
Learning: Applies to tests/tools/*.py : Use the `mock_ctx` pytest fixture from `tests/conftest.py` for mocking the MCP Context object in tests; do not create a manual MagicMock for the context within your test functions.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : Simplify address objects in API responses to a single address string to save LLM context.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : For paginated tools, do not expose individual pagination parameters; use a single, opaque cursor string and handle it with apply_cursor_to_params.
.cursor/rules/110-new-mcp-tool.mdc (20)
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : For paginated tools, do not expose individual pagination parameters; use a single, opaque cursor string and handle it with apply_cursor_to_params.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-07-04T20:16:41.182Z
Learning: Read `.cursor/rules/110-new-mcp-tool.mdc` for instructions on adding a new MCP tool to the server or modifying an existing one before responding to a user request
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : For paginated tools, include the exact notice '**SUPPORTS PAGINATION**: If response includes 'pagination' field, use the provided next_call to get additional pages.' in the docstring.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-07-04T20:16:41.182Z
Learning: Read `.cursor/rules/200-development-testing-workflow.mdc` for instructions related to unit and integration testing applicable when a new helper function or MCP tool function is added or modified
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/220-integration-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:31:56.480Z
Learning: Applies to tests/integration/test_*_integration.py : Integration tests for cursor-based pagination must perform a two-step test: (1) call the tool without a cursor and extract the cursor from the response, (2) call the tool again with the cursor and assert that the second page's data is different from the first.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/900-rules-maintenance.mdc:0-0
Timestamp: 2025-07-04T20:35:06.726Z
Learning: Applies to .cursor/AGENTS.md : Update the corresponding guidance in the 'Rule Application Guidelines' section of `.cursor/AGENTS.md` to reflect the changes made to the rule file.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : Truncate large data fields in API responses and flag the truncation, providing guidance on how to retrieve the full data.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/900-rules-maintenance.mdc:0-0
Timestamp: 2025-07-04T20:35:06.726Z
Learning: Applies to .cursor/rules/*.mdc : When you create, modify, or delete any `.mdc` file in `.cursor/rules/`, you MUST update `.cursor/AGENTS.md` accordingly.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/140-tool-description.mdc:0-0
Timestamp: 2025-07-04T20:26:50.806Z
Learning: Applies to mcp/tools/**/*.py : The tool description docstring must name the data or system touched and any hard constraints (such as authentication, size, or date limits).
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/140-tool-description.mdc:0-0
Timestamp: 2025-07-04T20:26:50.806Z
Learning: Applies to mcp/tools/**/*.py : If still under the character limit, the tool description docstring may include an ultra-short usage example to clarify intent.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : All tools MUST return a strongly-typed ToolResponse[YourDataModel] instead of generic ToolResponse[dict].
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : All tools MUST return a standardized ToolResponse[YourDataModel] object using the build_tool_response helper.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : Avoid returning ToolResponse[dict] or ToolResponse[Any]; always prefer specific ToolResponse[YourDataModel].
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/220-integration-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:31:56.480Z
Learning: Applies to tests/integration/test_*_integration.py : Integration tests for paginated tools must use a loop with a max_pages_to_check limit to search across pages, and skip the test with a clear message if the target data is not found within the limit.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : For tools that query Blockscout API, use dynamic chain resolution via get_blockscout_base_url and make_blockscout_request.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : For tools that use fixed API endpoints (like BENS), use the appropriate request helper (e.g., make_bens_request).
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : Create or modify a tool module file in blockscout_mcp_server/tools/ for each new tool, choosing an existing module or creating a new one as appropriate.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : Simplify address objects in API responses to a single address string to save LLM context.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : Recursively truncate nested data structures in API responses, replacing long strings with a structured object to signal truncation.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/210-unit-testing-guidelines.mdc:0-0
Timestamp: 2025-07-04T20:30:09.292Z
Learning: Applies to tests/tools/*.py : For tools returning a `ToolResponse` object, do not parse JSON from string results in your test; instead, mock the serialization function (`json.dumps`) if used internally, and make assertions on the structured `ToolResponse` object and its attributes.
AGENTS.md (19)
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to AGENTS.md : Update AGENTS.md documentation to reflect new or modified tool modules, including updates to the project structure and examples sections.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/130-version-management.mdc:0-0
Timestamp: 2025-07-04T20:25:11.277Z
Learning: Applies to blockscout_mcp_server/__init__.py : When updating the version of the MCP server, update the `__version__` variable in `blockscout_mcp_server/__init__.py`.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/130-version-management.mdc:0-0
Timestamp: 2025-07-04T20:25:11.277Z
Learning: Update both `pyproject.toml` and `blockscout_mcp_server/__init__.py` simultaneously to maintain consistency across the codebase.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/140-tool-description.mdc:0-0
Timestamp: 2025-07-04T20:26:50.806Z
Learning: Applies to mcp/tools/**/*.py : The tool description docstring must name the data or system touched and any hard constraints (such as authentication, size, or date limits).
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/140-tool-description.mdc:0-0
Timestamp: 2025-07-04T20:26:50.806Z
Learning: Applies to mcp/tools/**/*.py : The tool description docstring must not include implementation internals such as schemas, parameter lists, versions, or other details.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/900-rules-maintenance.mdc:0-0
Timestamp: 2025-07-04T20:35:06.726Z
Learning: Applies to .cursor/AGENTS.md : Update the corresponding guidance in the 'Rule Application Guidelines' section of `.cursor/AGENTS.md` to reflect the changes made to the rule file.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/130-version-management.mdc:0-0
Timestamp: 2025-07-04T20:25:11.277Z
Learning: Applies to pyproject.toml : When updating the version of the MCP server, update the `version` field in the `[project]` section of `pyproject.toml`.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/000-role-and-task.mdc:0-0
Timestamp: 2025-07-04T20:18:25.795Z
Learning: Applies to **/*.py : The MCP server must wrap Blockscout APIs and expose blockchain data (balances, tokens, NFTs, contract metadata) via the Model Context Protocol (MCP)
Learnt from: CR
PR: blockscout/mcp-server#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-07-04T20:16:41.182Z
Learning: Read the project technical description in `SPEC.md` to clearly understand how the MCP server communicates with counterparties and important aspects of the server implementation before responding to a user request
Learnt from: CR
PR: blockscout/mcp-server#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-07-04T20:16:41.182Z
Learning: Read `.cursor/rules/110-new-mcp-tool.mdc` for instructions on adding a new MCP tool to the server or modifying an existing one before responding to a user request
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : All tools MUST return a standardized ToolResponse[YourDataModel] object using the build_tool_response helper.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : All tools MUST return a strongly-typed ToolResponse[YourDataModel] instead of generic ToolResponse[dict].
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : Create or modify a tool module file in blockscout_mcp_server/tools/ for each new tool, choosing an existing module or creating a new one as appropriate.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : For tools that use fixed API endpoints (like BENS), use the appropriate request helper (e.g., make_bens_request).
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : For tools that query Blockscout API, use dynamic chain resolution via get_blockscout_base_url and make_blockscout_request.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/server.py : Register each new tool in blockscout_mcp_server/server.py by importing the tool function and registering it with the @mcp.tool() decorator.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : For paginated tools, do not expose individual pagination parameters; use a single, opaque cursor string and handle it with apply_cursor_to_params.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : Use the report_and_log_progress helper from tools/common.py for all progress reporting instead of calling ctx.report_progress directly.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : Recursively truncate nested data structures in API responses, replacing long strings with a structured object to signal truncation.
SPEC.md (10)
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : For paginated tools, include the exact notice '**SUPPORTS PAGINATION**: If response includes 'pagination' field, use the provided next_call to get additional pages.' in the docstring.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : For paginated tools, do not expose individual pagination parameters; use a single, opaque cursor string and handle it with apply_cursor_to_params.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/900-rules-maintenance.mdc:0-0
Timestamp: 2025-07-04T20:35:06.726Z
Learning: Applies to .cursor/AGENTS.md : Update the corresponding guidance in the 'Rule Application Guidelines' section of `.cursor/AGENTS.md` to reflect the changes made to the rule file.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : Truncate large data fields in API responses and flag the truncation, providing guidance on how to retrieve the full data.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : Simplify address objects in API responses to a single address string to save LLM context.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-07-04T20:16:41.182Z
Learning: Read `.cursor/rules/010-implementation-rules.mdc` for general coding instructions before responding to a user request
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : Recursively truncate nested data structures in API responses, replacing long strings with a structured object to signal truncation.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : For tools that query Blockscout API, use dynamic chain resolution via get_blockscout_base_url and make_blockscout_request.
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/000-role-and-task.mdc:0-0
Timestamp: 2025-07-04T20:18:25.795Z
Learning: Applies to **/*.py : The MCP server must wrap Blockscout APIs and expose blockchain data (balances, tokens, NFTs, contract metadata) via the Model Context Protocol (MCP)
Learnt from: CR
PR: blockscout/mcp-server#0
File: .cursor/rules/110-new-mcp-tool.mdc:0-0
Timestamp: 2025-07-04T20:22:01.665Z
Learning: Applies to blockscout_mcp_server/tools/*.py : For tools that use fixed API endpoints (like BENS), use the appropriate request helper (e.g., make_bens_request).
🧬 Code Graph Analysis (8)
tests/tools/test_transaction_tools_helpers.py (1)
blockscout_mcp_server/tools/transaction_tools.py (1)
_transform_advanced_filter_item
(32-44)
tests/tools/test_common.py (1)
blockscout_mcp_server/tools/common.py (4)
create_items_pagination
(488-535)decode_cursor
(315-324)extract_log_cursor_params
(538-544)extract_advanced_filters_cursor_params
(547-556)
tests/tools/test_address_logs.py (3)
blockscout_mcp_server/models.py (4)
AddressLogItem
(255-258)NextCallInfo
(12-18)PaginationInfo
(21-24)ToolResponse
(272-297)blockscout_mcp_server/tools/address_tools.py (1)
get_address_logs
(276-381)tests/conftest.py (1)
mock_ctx
(8-13)
blockscout_mcp_server/tools/address_tools.py (2)
blockscout_mcp_server/tools/common.py (4)
create_items_pagination
(488-535)encode_cursor
(307-312)extract_log_cursor_params
(538-544)build_tool_response
(424-465)blockscout_mcp_server/models.py (4)
NftCollectionHolding
(228-235)PaginationInfo
(21-24)NextCallInfo
(12-18)AddressLogItem
(255-258)
tests/tools/test_transaction_tools_pagination.py (2)
blockscout_mcp_server/tools/transaction_tools.py (1)
get_transactions_by_address
(210-320)tests/conftest.py (1)
mock_ctx
(8-13)
blockscout_mcp_server/tools/common.py (1)
blockscout_mcp_server/models.py (3)
NextCallInfo
(12-18)PaginationInfo
(21-24)ToolResponse
(272-297)
blockscout_mcp_server/tools/transaction_tools.py (2)
blockscout_mcp_server/tools/common.py (7)
create_items_pagination
(488-535)extract_advanced_filters_cursor_params
(547-556)extract_log_cursor_params
(538-544)make_request_with_periodic_progress
(193-298)make_blockscout_request
(99-124)report_and_log_progress
(412-421)build_tool_response
(424-465)blockscout_mcp_server/models.py (2)
AdvancedFilterItem
(165-179)TransactionLogItem
(262-268)
tests/tools/test_transaction_tools.py (3)
blockscout_mcp_server/models.py (3)
AdvancedFilterItem
(165-179)NextCallInfo
(12-18)PaginationInfo
(21-24)tests/conftest.py (1)
mock_ctx
(8-13)blockscout_mcp_server/tools/transaction_tools.py (2)
get_transactions_by_address
(210-320)get_token_transfers_by_address
(323-435)
🪛 LanguageTool
AGENTS.md
[uncategorized] ~111-~111: Loose punctuation mark.
Context: ... * BLOCKSCOUT_NFT_PAGE_SIZE
: Page size for NFT token queries (defaul...
(UNLIKELY_OPENING_PUNCTUATION)
[uncategorized] ~112-~112: Loose punctuation mark.
Context: ... * BLOCKSCOUT_LOGS_PAGE_SIZE
: Page size for address logs queries (def...
(UNLIKELY_OPENING_PUNCTUATION)
[uncategorized] ~113-~113: Loose punctuation mark.
Context: ... BLOCKSCOUT_ADVANCED_FILTERS_PAGE_SIZE
: Page size for advanced filter queries (...
(UNLIKELY_OPENING_PUNCTUATION)
SPEC.md
[misspelling] ~259-~259: This word is normally spelled as one.
Context: ..., the server implements a sophisticated multi-page fetching strategy to handle cases where...
(EN_COMPOUNDS_MULTI_PAGE)
⏰ 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: Docker build and docker push
🔇 Additional comments (38)
blockscout_mcp_server/tools/common.py (3)
16-16
: LGTM: Import addition aligns with new pagination functionality.The import of
NextCallInfo
is correctly added to support the new pagination utilities.
488-536
: Excellent pagination utility implementation.The
create_items_pagination
function provides a well-designed, reusable approach to pagination with:
- Clear handling of both normal and forced pagination scenarios
- Proper edge case management (empty items, cursor generation)
- Clean separation of concerns using the cursor_extractor pattern
- Standardized response format using
NextCallInfo
andPaginationInfo
The logic correctly slices items and generates appropriate pagination metadata. The force_pagination parameter is particularly useful for scenarios where the caller knows more pages exist despite having fewer items than the page size.
538-556
: Well-designed cursor extractor functions.Both
extract_log_cursor_params
andextract_advanced_filters_cursor_params
provide clean, focused implementations for their specific use cases:
extract_log_cursor_params
: Appropriately extracts block_number and index for log paginationextract_advanced_filters_cursor_params
: Comprehensively extracts all relevant indices for advanced filter paginationThe functions return properly structured dictionaries suitable for cursor encoding, maintaining consistency with the pagination pattern.
.env.example (1)
13-21
: LGTM: Environment variables properly configured for pagination.The three new environment variables are well-designed:
- Clear, descriptive naming that indicates their specific use cases
- Comprehensive comments explaining which tools use each variable
- Reasonable default value of 10 that balances API efficiency with response size
- Consistent with the existing environment variable pattern
These variables provide the necessary configuration flexibility for the new pagination functionality.
tests/tools/test_transaction_tools_helpers.py (1)
157-192
: Excellent test implementation following best practices.This test function demonstrates several strengths:
- Comprehensive coverage: Tests address transformation, field removal, and preservation of unknown fields
- Clear structure: Uses proper ARRANGE/ACT/ASSERT pattern with descriptive comments
- Focused scope: Tests one specific behavior (transformation preserves unknown fields)
- Thorough assertions: Verifies both expected transformations and field preservation
- Good test data: Uses realistic input with both standard and custom fields
The test aligns well with the new unit testing guidelines about keeping tests simple and focused.
AGENTS.md (2)
16-16
: Good documentation update for common.py.The updated description appropriately reflects the expanded role of
common.py
with the new pagination utilities, emphasizing its function as a shared utilities module.
111-113
: LGTM: Environment variables properly documented.The three new pagination-related environment variables are clearly documented with:
- Descriptive names indicating their specific purposes
- Consistent formatting with existing variables
- Appropriate default values mentioned
This maintains the documentation's completeness and helps users understand the configuration options.
.cursor/rules/210-unit-testing-guidelines.mdc (1)
10-40
: Excellent addition of focused testing guidelines.The new "Keep Unit Tests Simple and Focused" section provides valuable guidance that will improve test quality:
- Clear principles: Emphasizes one test per behavior/scenario
- Practical benefits: Lists concrete advantages of simple tests (easier maintenance, faster debugging, better failure diagnosis)
- Actionable examples: Shows clear bad vs. good patterns for splitting complex tests
- High priority placement: Appropriately positioned at the top to emphasize importance
This addition aligns well with the improved test practices seen throughout the codebase and will help maintain test quality as the project grows.
tests/integration/test_transaction_tools_integration.py (4)
61-61
: LGTM! Correctly enforces page size limits.The test now properly validates that results don't exceed the configured page size limit (10 items), which aligns with the new pagination approach.
245-247
: LGTM! Proper pagination validation added.The test correctly asserts that pagination metadata is present when exactly 10 items are returned, ensuring the pagination mechanism works as expected for full pages.
283-285
: LGTM! Consistent pagination validation.The same pagination validation pattern is correctly applied to token transfers, maintaining consistency across different transaction tools.
370-370
: LGTM! Increased search range for better test coverage.Increasing
MAX_PAGES_TO_CHECK
from 5 to 20 allows the test to search across more pages for truncated logs, improving the robustness of the pagination test.tests/tools/test_address_logs.py (4)
6-12
: LGTM! Appropriate imports for new pagination functionality.The added imports for
config
,NextCallInfo
, andPaginationInfo
are necessary for the updated pagination testing approach.
107-120
: LGTM! Correctly updated to use new pagination helper.The test properly migrates from mocking
encode_cursor
to mockingcreate_items_pagination
, reflecting the new pagination implementation. The mock return value correctly provides both sliced items and pagination info.
124-124
: LGTM! Updated assertion for new pagination approach.The assertion correctly validates that
create_items_pagination
is called once, aligning with the new pagination implementation.
140-170
: LGTM! Excellent test for configurable page size.This new test properly verifies that the
get_address_logs
function respects custom page size configuration by:
- Mocking
config.logs_page_size
to 5- Verifying
create_items_pagination
is called with the correct page size- Using appropriate test data (10 items) to validate the slicing behavior
The test follows the established patterns and provides good coverage for the new configuration feature.
tests/tools/test_common.py (3)
335-434
: LGTM! Comprehensive test coverage for pagination helper.These tests provide excellent coverage for the
create_items_pagination
function, validating:
- Normal pagination behavior when items exceed page size
- No pagination when items are below page size
- Force pagination functionality with various scenarios
- Proper cursor generation and parameter preservation
The tests are well-structured and cover important edge cases like empty item lists and different pagination modes.
476-498
: LGTM! Proper validation of parameter preservation.This test correctly verifies that base parameters are preserved in pagination info while adding the cursor, ensuring the pagination mechanism maintains all necessary context for subsequent calls.
501-548
: LGTM! Thorough testing of cursor extractor functions.The tests for
extract_log_cursor_params
andextract_advanced_filters_cursor_params
properly validate:
- Extraction of correct fields from complete items
- Handling of missing fields (returning
None
)- Proper behavior with empty dictionaries
These tests ensure the cursor extraction functions are robust and handle edge cases appropriately.
SPEC.md (3)
179-180
: LGTM! Fixed formatting consistency.The JSON code block delimiter is now properly closed, maintaining consistent formatting throughout the documentation.
239-268
: LGTM! Excellent documentation of pagination strategy.This section provides a comprehensive and clear explanation of the response slicing and multi-page fetching mechanisms. The documentation accurately describes:
- The basic slicing mechanism that fetches full pages but returns smaller slices
- The advanced multi-page fetching strategy for heavily filtered queries
- The smart pagination logic that handles sparse data scenarios
- The efficiency balance between network and context optimization
This documentation will be valuable for understanding the sophisticated pagination approach implemented in the codebase.
259-259
: Address the static analysis hint about compound word.The static analysis tool suggests "multipage" instead of "multi-page", but "multi-page" is widely accepted and more readable. No action needed as this is a style preference rather than an error.
tests/tools/test_transaction_tools_3.py (3)
7-13
: LGTM! Imports properly organized.The new imports for
config
,NextCallInfo
, andPaginationInfo
are correctly added and follow the established import order.
222-246
: Pagination test correctly updated to use new helper.The test now properly mocks
create_items_pagination
and constructs the expected return value with curated dictionaries andPaginationInfo
, aligning with the new pagination pattern.
446-476
: Well-structured test for custom page size configuration.The test properly mocks the configuration, verifies that
create_items_pagination
is called with the correct page size parameter, and follows the established testing patterns.blockscout_mcp_server/tools/address_tools.py (1)
366-375
: Address logs pagination correctly uses the unified helper.The migration to
create_items_pagination
withextract_log_cursor_params
follows the new pagination pattern and properly handles the conversion between dictionaries andAddressLogItem
objects.tests/tools/test_transaction_tools.py (4)
24-93
: Excellent refactoring to use smart pagination.The test correctly verifies that
_fetch_filtered_transactions_with_smart_pagination
is called with the proper parameters including progress tracking steps (2.0 to 11.0 out of 12.0 total).
249-279
: Good test coverage for custom page size configuration.The test properly mocks the configuration and verifies that
create_items_pagination
is called with the configured page size.
641-749
: Comprehensive test for sparse data multi-page fetching.This test excellently simulates a realistic scenario where most transactions are filtered out, requiring multiple page fetches. The test data is well-structured with clear documentation of the expected behavior.
751-846
: Thorough verification of multi-page progress reporting.The test meticulously verifies each progress report at the correct steps (0, 1, and 12) with appropriate messages, ensuring the enhanced progress tracking works correctly throughout the multi-page fetching operation.
tests/tools/test_transaction_tools_pagination.py (5)
1-15
: Well-documented test module with clear purpose.The module docstring clearly explains the multi-page fetching strategy being tested, and imports are minimal and appropriate.
16-106
: Excellent test for multi-page fetching with mixed transaction types.The test clearly simulates sparse data requiring multiple page fetches, with detailed mock data showing filtered and valid transactions. The assertions verify correct accumulation, filtering, slicing, and pagination.
107-171
: Important test for preventing excessive API calls.This test ensures the 10-page maximum limit is enforced, preventing potential infinite loops or API abuse. The mock setup and assertions are thorough.
172-233
: Good coverage of the optimized single-page scenario.The test verifies that when sufficient data is available on the first page, no additional API calls are made, demonstrating the efficiency of the implementation.
234-294
: Proper handling of API responses without next page.The test correctly verifies that when the API indicates no more pages are available, the pagination metadata is not included in the response.
blockscout_mcp_server/tools/transaction_tools.py (3)
249-320
: Proper integration of smart pagination with accurate progress reporting.The function correctly uses the new pagination pattern, properly calculates progress steps to account for multiple page fetches, and appropriately uses the
force_pagination
parameter based on thehas_more_pages
indicator from the smart pagination helper.
419-435
: Clean implementation of the standardized pagination pattern.The replacement of manual cursor encoding with
create_items_pagination
simplifies the code and ensures consistency across all paginated tools.
559-559
: Correct implementation of pagination with required documentation.The function properly includes the exact pagination notice in the docstring and correctly uses
create_items_pagination
with the appropriate cursor extractor.Also applies to: 636-644
Summary
nft_page_size
to configuration and environment filesnft_tokens_by_address
using the new configCloses #124
https://chatgpt.com/codex/tasks/task_b_6868533fa4688323b3b5260a94066d97
Summary by CodeRabbit
New Features
Bug Fixes
Documentation
Tests