Skip to main content
Glama
blockscout

Blockscout MCP Server

Official

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
NameRequiredDescriptionDefault
chain_idYesThe ID of the blockchain
addressYesAddress which either transfer initiator or transfer receiver
age_fromNoStart 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_toNoEnd date and time (e.g 2025-05-22T22:30:00.00Z). Can be omitted to get all transfers up to the current time.
tokenNoAn ERC-20 token contract address to filter transfers by a specific token. If omitted, returns transfers of all tokens.
cursorNoThe 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)
  • 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.",
        )
  • 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.",
        )

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/blockscout/mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server