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