Skip to main content
Glama
blockscout

Blockscout MCP Server

Official

get_transactions_by_address

Read-only

Retrieve native currency transfers and smart contract interactions for a blockchain address, excluding token transfers. Filter by date range or method signatures to analyze transaction history.

Instructions

Retrieves native currency transfers and smart contract interactions (calls, internal txs) for an address.
**EXCLUDES TOKEN TRANSFERS**: Filters out direct token balance changes (ERC-20, etc.). You'll see calls *to* token contracts, but not the `Transfer` events. For token history, use `get_token_transfers_by_address`.
A single tx can have multiple records from internal calls; use `internal_transaction_index` for execution order.
Use cases:
  - `get_transactions_by_address(address, age_from)` - get all txs to/from the address since a given date.
  - `get_transactions_by_address(address, age_from, age_to)` - get all txs to/from the address between given dates.
  - `get_transactions_by_address(address, age_from, age_to, methods)` - get all txs to/from the address between given dates, filtered by method.
**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 sender or receiver of the transaction
age_fromNoStart date and time (e.g 2025-05-22T23:00:00.00Z).
age_toNoEnd date and time (e.g 2025-05-22T22:30:00.00Z).
methodsNoA method signature to filter transactions by (e.g 0x304e6ade)
cursorNoThe pagination cursor from a previous response to get the next page of results.

Implementation Reference

  • The primary handler function for the 'get_transactions_by_address' tool. It queries the Blockscout API's advanced filters endpoint, handles date/method filtering, cursor-based pagination, progress reporting, data transformation, and returns a paginated ToolResponse with AdvancedFilterItem instances.
    @log_tool_invocation
    async def get_transactions_by_address(
        chain_id: Annotated[str, Field(description="The ID of the blockchain")],
        address: Annotated[str, Field(description="Address which either sender or receiver of the transaction")],
        ctx: Context,
        age_from: Annotated[str | None, Field(description="Start date and time (e.g 2025-05-22T23:00:00.00Z).")] = None,
        age_to: Annotated[str | None, Field(description="End date and time (e.g 2025-05-22T22:30:00.00Z).")] = None,
        methods: Annotated[
            str | None,
            Field(description="A method signature to filter transactions by (e.g 0x304e6ade)"),
        ] = 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]]:
        """
        Retrieves native currency transfers and smart contract interactions (calls, internal txs) for an address.
        **EXCLUDES TOKEN TRANSFERS**: Filters out direct token balance changes (ERC-20, etc.). You'll see calls *to* token contracts, but not the `Transfer` events. For token history, use `get_token_transfers_by_address`.
        A single tx can have multiple records from internal calls; use `internal_transaction_index` for execution order.
        Use cases:
          - `get_transactions_by_address(address, age_from)` - get all txs to/from the address since a given date.
          - `get_transactions_by_address(address, age_from, age_to)` - get all txs to/from the address between given dates.
          - `get_transactions_by_address(address, age_from, age_to, methods)` - get all txs to/from the address between given dates, filtered by method.
        **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 = {
            "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 methods:
            query_params["methods"] = methods
    
        apply_cursor_to_params(cursor, query_params)
    
        tool_overall_total_steps = 12.0
    
        await report_and_log_progress(
            ctx,
            progress=0.0,
            total=tool_overall_total_steps,
            message=f"Starting to fetch transactions 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 transactions...",
        )
    
        filtered_items, has_more_pages = await _fetch_filtered_transactions_with_smart_pagination(
            base_url=base_url,
            api_path=api_path,
            initial_params=query_params,
            target_page_size=config.advanced_filters_page_size,
            ctx=ctx,
            progress_start_step=2.0,
            total_steps=tool_overall_total_steps,
        )
    
        await report_and_log_progress(
            ctx,
            progress=tool_overall_total_steps,
            total=tool_overall_total_steps,
            message="Successfully fetched transaction data.",
        )
    
        fields_to_remove = [
            "total",
            "token",
            "token_transfer_batch_index",
            "token_transfer_index",
        ]
    
        final_items, pagination = create_items_pagination(
            items=filtered_items,
            page_size=config.advanced_filters_page_size,
            tool_name="get_transactions_by_address",
            next_call_base_params={
                "chain_id": chain_id,
                "address": address,
                "age_from": age_from,
                "age_to": age_to,
                "methods": methods,
            },
            cursor_extractor=extract_advanced_filters_cursor_params,
            force_pagination=has_more_pages and len(filtered_items) <= config.advanced_filters_page_size,
        )
        transformed_items = [
            AdvancedFilterItem.model_validate(_transform_advanced_filter_item(item, fields_to_remove))
            for item in final_items
        ]
    
        return build_tool_response(data=transformed_items, pagination=pagination)
  • Registration of the get_transactions_by_address tool in the FastMCP server instance, with annotations and structured_output disabled.
        structured_output=False,
        annotations=create_tool_annotations("Get Transactions by Address"),
    )(get_transactions_by_address)
  • Pydantic model defining the structure of individual transaction items returned by the tool (AdvancedFilterItem), used in ToolResponse[list[AdvancedFilterItem]]. Allows extra fields for API compatibility.
    # --- Model for get_transactions_by_address and get_token_transfers_by_address Data Payload ---
    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.",
        )
  • Generic Pydantic response model (ToolResponse[T]) used by the tool for output, including data, notes, instructions, and pagination.
    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.",
        )
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, so the agent knows this is a safe read operation. The description adds valuable behavioral context beyond annotations: it explains pagination behavior ('SUPPORTS PAGINATION'), clarifies that a single transaction can have multiple records from internal calls, and provides guidance on using 'internal_transaction_index' for execution order. This adds meaningful operational context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured with clear sections (purpose, exclusions, internal transaction explanation, use cases, pagination). It's appropriately sized for the tool's complexity, though the use case examples could be slightly more concise. Most sentences earn their place by providing valuable information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (6 parameters, no output schema), the description provides good contextual completeness. It explains what the tool returns (native transfers and smart contract interactions), what it excludes (token transfers), how to handle internal transactions, provides use case examples, and explains pagination. The main gap is lack of information about return format or structure, but this is mitigated by the comprehensive parameter guidance.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all 6 parameters thoroughly. The description provides use case examples that illustrate how parameters work together (e.g., showing age_from alone vs with age_to and methods), but doesn't add significant semantic value beyond what's already in the schema descriptions. Baseline 3 is appropriate when schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool 'retrieves native currency transfers and smart contract interactions (calls, internal txs) for an address' and explicitly distinguishes it from sibling tools by stating 'EXCLUDES TOKEN TRANSFERS' and pointing to 'get_token_transfers_by_address' for token history. This provides specific verb+resource+scope with clear sibling differentiation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit guidance on when to use this tool vs alternatives: 'For token history, use get_token_transfers_by_address'. It also includes specific use cases with parameter examples and explains what the tool excludes, giving clear context for when to use this tool and when not to.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

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