get_token_transfers_by_address
Retrieve ERC-20 token transfers for a blockchain address within specified time ranges. Filter by token or date to analyze transaction history and track token movements.
Instructions
Get ERC-20 token transfers for an address within a specific time range.
Use cases:
- `get_token_transfers_by_address(address, age_from)` - get all transfers of any ERC-20 token to/from the address since the given date up to the current time
- `get_token_transfers_by_address(address, age_from, age_to)` - get all transfers of any ERC-20 token to/from the address between the given dates
- `get_token_transfers_by_address(address, age_from, age_to, token)` - get all transfers of the given ERC-20 token to/from the address between the given dates
**SUPPORTS PAGINATION**: If response includes 'pagination' field, use the provided next_call to get additional pages.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| chain_id | Yes | The ID of the blockchain | |
| address | Yes | Address which either transfer initiator or transfer receiver | |
| age_from | No | Start date and time (e.g 2025-05-22T23:00:00.00Z). This parameter should be provided in most cases to limit transfers and avoid heavy database queries. Omit only if you absolutely need the full history. | |
| age_to | No | End date and time (e.g 2025-05-22T22:30:00.00Z). Can be omitted to get all transfers up to the current time. | |
| token | No | An ERC-20 token contract address to filter transfers by a specific token. If omitted, returns transfers of all tokens. | |
| cursor | No | The pagination cursor from a previous response to get the next page of results. |
Implementation Reference
- Main handler function implementing the get_token_transfers_by_address tool. Fetches ERC-20 token transfers using Blockscout API, handles pagination, transforms data with AdvancedFilterItem models, and reports progress.@log_tool_invocation async def get_token_transfers_by_address( chain_id: Annotated[str, Field(description="The ID of the blockchain")], address: Annotated[str, Field(description="Address which either transfer initiator or transfer receiver")], ctx: Context, age_from: Annotated[ str | None, Field( description="Start date and time (e.g 2025-05-22T23:00:00.00Z). This parameter should be provided in most cases to limit transfers and avoid heavy database queries. Omit only if you absolutely need the full history." # noqa: E501 ), ] = None, age_to: Annotated[ str | None, Field( description="End date and time (e.g 2025-05-22T22:30:00.00Z). Can be omitted to get all transfers up to the current time." # noqa: E501 ), ] = None, token: Annotated[ str | None, Field( description="An ERC-20 token contract address to filter transfers by a specific token. If omitted, returns transfers of all tokens." # noqa: E501 ), ] = None, cursor: Annotated[ str | None, Field(description="The pagination cursor from a previous response to get the next page of results."), ] = None, ) -> ToolResponse[list[AdvancedFilterItem]]: """ Get ERC-20 token transfers for an address within a specific time range. Use cases: - `get_token_transfers_by_address(address, age_from)` - get all transfers of any ERC-20 token to/from the address since the given date up to the current time - `get_token_transfers_by_address(address, age_from, age_to)` - get all transfers of any ERC-20 token to/from the address between the given dates - `get_token_transfers_by_address(address, age_from, age_to, token)` - get all transfers of the given ERC-20 token to/from the address between the given dates **SUPPORTS PAGINATION**: If response includes 'pagination' field, use the provided next_call to get additional pages. """ # noqa: E501 api_path = "/api/v2/advanced-filters" query_params = { "transaction_types": "ERC-20", "to_address_hashes_to_include": address, "from_address_hashes_to_include": address, } if age_from: query_params["age_from"] = age_from if age_to: query_params["age_to"] = age_to if token: query_params["token_contract_address_hashes_to_include"] = token apply_cursor_to_params(cursor, query_params) tool_overall_total_steps = 2.0 await report_and_log_progress( ctx, progress=0.0, total=tool_overall_total_steps, message=f"Starting to fetch token transfers for {address} on chain {chain_id}...", ) base_url = await get_blockscout_base_url(chain_id) await report_and_log_progress( ctx, progress=1.0, total=tool_overall_total_steps, message="Resolved Blockscout instance URL. Now fetching token transfers...", ) response_data = await make_request_with_periodic_progress( ctx=ctx, request_function=make_blockscout_request, request_args={"base_url": base_url, "api_path": api_path, "params": query_params}, total_duration_hint=config.bs_timeout, progress_interval_seconds=config.progress_interval_seconds, in_progress_message_template="Query in progress... ({elapsed_seconds:.0f}s / {total_hint:.0f}s hint)", tool_overall_total_steps=tool_overall_total_steps, current_step_number=2.0, current_step_message_prefix="Fetching token transfers", ) original_items = response_data.get("items", []) fields_to_remove = ["value", "internal_transaction_index", "created_contract"] sliced_items, pagination = create_items_pagination( items=original_items, page_size=config.advanced_filters_page_size, tool_name="get_token_transfers_by_address", next_call_base_params={ "chain_id": chain_id, "address": address, "age_from": age_from, "age_to": age_to, "token": token, }, cursor_extractor=extract_advanced_filters_cursor_params, ) transformed_items = [ AdvancedFilterItem.model_validate(_transform_advanced_filter_item(item, fields_to_remove)) for item in sliced_items ] return build_tool_response(data=transformed_items, pagination=pagination)
- blockscout_mcp_server/server.py:166-168 (registration)MCP tool registration for get_token_transfers_by_address in the FastMCP server.structured_output=False, annotations=create_tool_annotations("Get Token Transfers by Address"), )(get_token_transfers_by_address)
- Pydantic model AdvancedFilterItem used for output data validation in get_token_transfers_by_address and similar tools.class AdvancedFilterItem(BaseModel): """Represents a single item from the advanced filter API response.""" model_config = ConfigDict(extra="allow") # External APIs may add new fields; allow them to avoid validation errors from_address: str | None = Field( default=None, alias="from", description="The sender address.", ) to_address: str | None = Field( default=None, alias="to", description="The recipient address.", )
- blockscout_mcp_server/server.py:44-46 (registration)Import statement for the get_token_transfers_by_address handler in server.py.from blockscout_mcp_server.tools.transaction.get_token_transfers_by_address import ( get_token_transfers_by_address, )
- Generic ToolResponse model used as the return type for get_token_transfers_by_address, providing standardized output structure with pagination support.class ToolResponse(BaseModel, Generic[T]): """A standardized, structured response for all MCP tools, generic over the data payload type.""" data: T = Field(description="The main data payload of the tool's response.") data_description: list[str] | None = Field( None, description="A list of notes explaining the structure, fields, or conventions of the 'data' payload.", ) notes: list[str] | None = Field( None, description=( "A list of important contextual notes, such as warnings about data truncation or data quality issues." ), ) instructions: list[str] | None = Field( None, description="A list of suggested follow-up actions or instructions for the LLM to plan its next steps.", ) pagination: PaginationInfo | None = Field( None, description="Pagination information, present only if the 'data' is a single page of a larger result set.", )