Blockscout MCP Server
August 5, 2026 · View on GitHub
Project Structure
mcp-server/
├── blockscout_mcp_server/ # Main Python package for the server
│ ├── __init__.py # Makes the directory a Python package
│ ├── llms.txt # Machine-readable guidance file for AI crawlers
│ ├── api/ # REST API implementation
│ │ ├── __init__.py # Initializes the api sub-package
│ │ ├── dependencies.py # Dependency providers for the REST API
│ │ ├── helpers.py # Shared utilities for REST API handlers
│ │ └── routes.py # REST API route definitions
│ ├── resources/ # Skill-as-resource enumeration and content access (`skill_resources.py`)
│ ├── __main__.py # Entry point for `python -m blockscout_mcp_server`
│ ├── server.py # Core server logic: FastMCP instance, tool registration, CLI
│ ├── templates/ # Static HTML templates for the web interface
│ │ └── index.html # Landing page for the REST API
│ ├── config.py # Configuration management (e.g., API keys, timeouts, cache settings)
│ ├── constants.py # Centralized constants used throughout the application, including data truncation limits
│ ├── logging_utils.py # Logging utilities for production-ready log formatting and client-disconnect log noise suppression
│ ├── analytics.py # Centralized Mixpanel analytics for tool invocations (HTTP mode only)
│ ├── telemetry.py # Fire-and-forget community telemetry reporting
│ ├── client_meta.py # Shared client metadata extraction helpers and defaults
│ ├── observability.py # Resource-read observability helpers
│ ├── pro_api_key_context.py # Request-scoped client-supplied PRO API key state, resolver, and @pro_api_key_scope decorator; per-invocation credit sink and @pro_api_credit_scope decorator; auth-origin and key-fingerprint helpers for analytics/telemetry; client-key presence helper for response assembly
│ ├── session_gate.py # Session-gating policy: HMAC session tokens, typed gate errors, @session_gate decorators, request-scoped remaining-budget value
│ ├── session_lifecycle.py # HTTP-app lifecycle: gated-startup validation, session-store init/status, lifespan coordinator (incl. WEB3_POOL closure), sweep loop
│ ├── session_store.py # SQLite-backed per-session call counters for the session-gated free tier (atomic check-and-increment, refund, sweep)
│ ├── cache.py # Simple in-memory cache for chain data
│ ├── web3_pool.py # Async Web3 connection pool manager
│ ├── models.py # Defines standardized Pydantic models for all tool responses
│ └── tools/ # Sub-package for tool implementations
│ ├── __init__.py # Initializes the tools sub-package
│ ├── common.py # Shared utilities and common functionality for all tools
│ ├── decorators.py # Logging decorators like @log_tool_invocation
│ ├── address/ # Address-related tools grouped by functionality
│ │ ├── __init__.py
│ │ ├── get_address_info.py
│ │ ├── get_tokens_by_address.py
│ │ └── nft_tokens_by_address.py
│ ├── block/
│ │ ├── __init__.py
│ │ ├── get_block_info.py
│ │ └── get_block_number.py
│ ├── chains/
│ │ ├── __init__.py
│ │ └── get_chains_list.py
│ ├── contract/
│ │ ├── __init__.py
│ │ ├── _shared.py # Shared helpers for contract tools
│ │ ├── get_contract_abi.py
│ │ ├── inspect_contract_code.py
│ │ └── read_contract.py
│ ├── direct_api/
│ │ ├── __init__.py
│ │ ├── direct_api_call.py
│ │ ├── dispatcher.py
│ │ └── handlers/
│ │ ├── __init__.py
│ │ ├── address_logs_handler.py
│ │ ├── transaction_summary_handler.py
│ │ ├── transaction_logs_handler.py
│ │ └── user_operation_handler.py
│ ├── ens/
│ │ ├── __init__.py
│ │ └── get_address_by_ens_name.py
│ ├── initialization/
│ │ ├── __init__.py
│ │ └── unlock_blockchain_analysis.py
│ ├── search/
│ │ ├── __init__.py
│ │ └── lookup_token_by_symbol.py
│ └── transaction/
│ ├── __init__.py
│ ├── _shared.py # Shared helpers for transaction tools
│ ├── get_token_transfers_by_address.py
│ ├── get_transaction_info.py
│ └── get_transactions_by_address.py
├── tests/ # Test suite for all MCP tools
│ ├── integration/ # Integration tests that make real network calls
│ │ ├── __init__.py # Marks integration as a sub-package
│ │ ├── helpers.py # Shared utilities for integration assertions
│ │ ├── test_common_helpers.py # Integration tests for shared API helper contracts
│ │ ├── address/ # Address tool integration tests (one file per tool)
│ │ │ ├── test_get_address_info_real.py # Integration tests for get_address_info
│ │ │ ├── test_get_tokens_by_address_real.py # Integration tests for get_tokens_by_address
│ │ │ └── test_nft_tokens_by_address_real.py # Integration tests for nft_tokens_by_address
│ │ ├── block/
│ │ │ ├── test_get_block_info_real.py # Integration tests for get_block_info
│ │ │ └── test_get_block_number_real.py # Integration tests for get_block_number
│ │ ├── chains/
│ │ │ └── test_get_chains_list_real.py # Integration tests for get_chains_list
│ │ ├── contract/
│ │ │ ├── Web3PyTestContract.sol # Fixture contract for live calls
│ │ │ ├── test_get_contract_abi_real.py # Integration tests for get_contract_abi
│ │ │ ├── test_inspect_contract_code_real.py # Integration tests for inspect_contract_code
│ │ │ ├── test_read_contract_real.py # Integration tests for read_contract
│ │ │ └── web3py_test_contract_abi.json # ABI fixture for Web3Py tests
│ │ ├── direct_api/
│ │ │ ├── test_address_logs_handler_real.py # Integration tests for address logs handler
│ │ │ ├── test_direct_api_call_real.py # Integration tests for direct_api_call
│ │ │ ├── test_transaction_logs_handler_real.py # Integration tests for transaction logs handler
│ │ │ ├── test_transaction_summary_handler_real.py # Integration tests for transaction summary handler
│ │ │ └── test_user_operation_handler_real.py # Integration tests for user operation handler
│ │ ├── ens/
│ │ │ └── test_get_address_by_ens_name_real.py # Integration tests for get_address_by_ens_name
│ │ ├── search/
│ │ │ └── test_lookup_token_by_symbol_real.py # Integration tests for lookup_token_by_symbol
│ │ └── transaction/
│ │ ├── test_get_token_transfers_by_address_real.py # Integration tests for get_token_transfers_by_address
│ │ ├── test_get_transaction_info_real.py # Integration tests for get_transaction_info
│ │ └── test_get_transactions_by_address_real.py # Integration tests for get_transactions_by_address
│ ├── api/ # Unit tests for the REST API
│ │ ├── test_api_helpers.py # Unit tests for REST error-handling helpers (e.g. handle_rest_errors)
│ │ ├── test_resource_routes.py # Unit tests for resource discovery routes (/v1/resources)
│ │ ├── test_routes.py # Unit tests for API route definitions
│ │ ├── test_routes_session_gate.py # Unit tests for session-gate enforcement on REST routes
│ │ ├── test_routes_session_gate_e2e.py # End-to-end REST session-gate tests
│ │ ├── test_routes_session_passthrough.py # Unit tests for session_id passthrough on REST routes
│ │ └── test_skill_resource_routes.py # Unit tests for the bundled skill HTTP mirror
│ ├── analytics_ctx_helpers.py # Shared request/context test doubles for the analytics test modules
│ ├── conftest.py # Shared test fixtures: mock_ctx, pristine_config, and reset_analytics_state
│ ├── pro_api_key_helpers.py # Shared request-context builders for PRO API key / auth-signal tests
│ ├── evals/ # Evaluation artifacts and runner configs for tool output checks
│ │ ├── .env.example
│ │ ├── .gemini/
│ │ │ └── settings.json
│ │ ├── .gitignore
│ │ ├── docker-compose.yml
│ │ ├── eval-set.json # Evaluation case definitions
│ │ ├── GEMINI-evals.md # Notes on Gemini-based eval runs
│ │ ├── output-format-rules.md # Output formatting requirements for evals
│ │ ├── README.md
│ │ ├── results/
│ │ │ └── .gitkeep
│ │ └── run.sh # Script to execute eval runs
│ ├── test_analytics.py # Unit tests for analytics event tracking
│ ├── test_analytics_helpers.py # Unit tests for analytics helper utilities
│ ├── test_analytics_identity.py # Unit tests for distinct_id identity-basis selection
│ ├── test_analytics_source.py # Unit tests for analytics source detection
│ ├── test_cache.py # Unit tests for cache behavior
│ ├── test_client_meta.py # Unit tests for client metadata extraction
│ ├── test_observability.py # Unit tests for resource-read observability
│ ├── test_pristine_config_fixture.py # Unit tests for the autouse pristine_config fixture contract
│ ├── test_pro_api_key_context.py # Unit tests for client-supplied PRO API key resolution
│ ├── test_pro_api_key_context_auth_signals.py # Unit tests for ctx-derived auth-origin and PRO API key fingerprint signals
│ ├── test_hatch_build.py # Unit tests for custom Hatch build hook helpers
│ ├── test_instructions_data.py # Unit tests for the InstructionsData payload model
│ ├── test_integration_helpers.py # Unit tests for integration test helpers
│ ├── test_logging_utils.py # Unit tests for logging utilities
│ ├── test_logging_utils_disconnect_filter.py # Unit tests for the client-disconnect log demotion filter
│ ├── test_models.py # Unit tests for Pydantic response models
│ ├── test_server.py # Unit tests for server CLI and startup logic
│ ├── test_server_instructions.py # Unit tests for the composed_instructions string
│ ├── test_server_session_gate.py # Unit tests for gated-startup config validation
│ ├── test_server_session_gate_lifespan.py # Unit tests for real-lifespan session-store wiring and periodic sweep-task fault tolerance
│ ├── test_server_structured_output.py # Unit tests for the _wrap_tool_for_structured_output wrapper
│ ├── test_bundled_skill_artifacts.py # Unit tests for bundled skill packaging artifacts
│ ├── test_session_store.py # Unit tests for the SQLite session store
│ ├── test_session_store_limits.py # Unit tests for check_and_increment ceiling semantics
│ ├── test_session_gate.py # Unit tests for session token issuance/verification and gate predicates
│ ├── test_session_gate_http_transport.py # Unit tests for HTTP-mode-only session gate activation
│ ├── test_session_gate_tool_coverage.py # Completeness check: every registered MCP tool enforces the session gate
│ ├── test_skill_resources_server.py # Unit tests for MCP resource registration
│ ├── test_telemetry.py # Unit tests for telemetry reporting
│ ├── test_tool_usage_report.py # Unit tests for the ToolUsageReport telemetry payload model
│ ├── test_web3_pool.py # Unit tests for web3 pool management
│ ├── resources/ # Unit tests for server-owned resource modules
│ │ ├── __init__.py
│ │ └── test_skill_resources.py # Unit tests for bundled skill resource enumeration
│ └── tools/ # Unit test modules for each tool implementation
│ ├── address/ # Tests for address-related MCP tools
│ │ ├── test_get_address_info.py # Unit tests for get_address_info
│ │ ├── test_get_tokens_by_address.py # Unit tests for get_tokens_by_address
│ │ ├── test_nft_tokens_by_address.py # Unit tests for nft_tokens_by_address
│ │ └── test_nft_tokens_by_address_pagination.py # Unit tests for nft_tokens_by_address pagination
│ ├── block/ # Tests for block-related MCP tools
│ │ ├── test_get_block_info.py # Unit tests for get_block_info
│ │ └── test_get_block_number.py # Unit tests for get_block_number
│ ├── chains/ # Tests for chain-related MCP tools
│ │ └── test_get_chains_list.py # Unit tests for get_chains_list
│ ├── contract/ # Tests for contract-related MCP tools
│ │ ├── conftest.py # Shared w3 mock-chain factory for read_contract tests
│ │ ├── test_fetch_and_process_contract.py # Unit tests for fetch_and_process_contract
│ │ ├── test_get_contract_abi.py # Unit tests for get_contract_abi
│ │ ├── test_inspect_contract_code.py # Unit tests for inspect_contract_code
│ │ ├── test_read_contract.py # Unit tests for read_contract
│ │ └── test_read_contract_normalization.py # Unit tests for read_contract result normalization
│ ├── transaction/ # Tests for transaction-related MCP tools
│ │ ├── test_get_token_transfers_by_address.py # Unit tests for get_token_transfers_by_address
│ │ ├── test_get_transaction_info.py # Unit tests for get_transaction_info
│ │ ├── test_get_transactions_by_address.py # Unit tests for get_transactions_by_address
│ │ ├── test_get_transactions_by_address_pagination.py # Unit tests for transactions pagination
│ │ └── test_helpers.py # Unit tests for transaction helper utilities
│ ├── direct_api/ # Tests for the direct API MCP tool
│ │ ├── handlers/
│ │ │ ├── test_address_logs_handler.py # Unit tests for address logs handler
│ │ │ ├── test_transaction_logs_handler.py # Unit tests for transaction logs handler
│ │ │ ├── test_transaction_summary_handler.py # Unit tests for transaction summary handler
│ │ │ └── test_user_operation_handler.py # Unit tests for user operation handler
│ │ ├── test_dispatcher.py # Unit tests for direct API dispatcher
│ │ ├── test_direct_api_call.py # Unit tests for direct_api_call
│ │ └── test_direct_api_call_validation.py # Unit tests for direct_api_call input validation
│ ├── ens/ # Tests for ENS-related MCP tools
│ │ └── test_get_address_by_ens_name.py # Unit tests for get_address_by_ens_name
│ ├── initialization/ # Tests for initialization MCP tools
│ │ └── test___unlock_blockchain_analysis__.py # Unit tests for __unlock_blockchain_analysis__
│ ├── search/ # Tests for search-related MCP tools
│ │ └── test_lookup_token_by_symbol.py # Unit tests for lookup_token_by_symbol
│ ├── test_chain_support.py # Unit tests for the ensure_chain_supported helper
│ ├── test_common.py # Unit tests for shared tool utilities
│ ├── test_common_truncate.py # Unit tests for truncation helpers
│ ├── test_common_post_request.py # Unit tests for POST request helper
│ ├── test_decorators.py # Unit tests for logging decorators
│ ├── test_session_gate_decorator.py # Unit tests for the @session_gate tool decorators
│ ├── test_session_gate_surface_ceilings.py # Unit tests for per-surface ceilings and the zero-ceiling policy
│ ├── test_session_budget_note.py # Unit tests for the remaining-budget response note
│ ├── test_session_id_redaction.py # Unit tests for session_id masking in invocation logging
│ ├── test_credit_tracking_sink.py # Unit tests for CreditSink running-minimum semantics
│ ├── test_credit_tracking_capture.py # Unit tests for x-credits-remaining capture via HTTP helpers
│ ├── test_credit_tracking_decorator.py # Unit tests for the @pro_api_credit_scope decorator
│ ├── test_credit_tracking_note.py # Unit tests for the build_tool_response low-credits note
│ └── test_credit_tracking_end_to_end.py # End-to-end MCP-mode low-credits advisory note tests
├── mcpb/ # MCP Bundle package for Claude Desktop
│ ├── README.md # MCPB documentation and build instructions
│ ├── manifest.json # Bundle manifest for production builds
│ ├── manifest-dev.json # Bundle manifest for development builds
│ ├── build.sh # Build script for creating the MCP Bundle
│ └── blockscout.png # Bundle icon file
├── agent-skills/ # Git submodule: AI agent skills for blockchain analysis (https://github.com/blockscout/agent-skills). Its `blockscout-analysis/` subtree is bundled into the wheel at `blockscout_mcp_server/_bundled_skill/` at build time and served through the MCP resources channel and the `/skill/` HTTP mirror.
├── hatch_build.py # Hatch custom build hook: emits `_bundled_skill_manifest.json` into the wheel.
├── scripts/
│ └── bake_skill_metadata.py # Helper invoked before `docker build` to write `.bundle_skill_commit_info.json`.
├── Dockerfile # For building the Docker image
├── pytest.ini # Pytest configuration (excludes integration tests by default)
├── API.md # Detailed documentation for the REST API
├── README.md # Project overview, setup, and usage instructions
├── SPEC.md # Technical specification and architecture documentation
├── TESTING.md # Testing instructions for HTTP mode with curl commands
├── pyproject.toml # Project metadata and dependencies (PEP 517/518)
├── .gitmodules # Git submodule configuration (tracks agent-skills)
└── .env.example # Example environment variables
Overview of Components
-
mcp-server/(Root Directory)README.md:- Provides a comprehensive overview of the project.
- Includes detailed instructions for local setup (installing dependencies, setting environment variables) and running the server.
- Contains instructions for building and running the server using Docker.
- Lists all available tools and their functionalities.
API.md:- Provides detailed documentation for all REST API endpoints.
- Includes usage examples, parameter descriptions, and information on the standard response structure.
SPEC.md:- Contains technical specifications and detailed architecture documentation.
- Outlines the system design, components interaction, and data flow.
- Describes key architectural decisions and their rationales.
TESTING.md:- Provides comprehensive instructions for testing the MCP server locally using HTTP mode.
- Contains curl command examples for testing all major tools and functionality.
- Serves as a practical guide for developers to understand and test the server's capabilities.
pyproject.toml:- Manages project metadata (name, version, authors, etc.).
- Lists project dependencies, which will include:
mcp[cli]: The Model Context Protocol SDK for Python with CLI support.httpx: For making asynchronous HTTP requests to Blockscout APIs.pydantic: For data validation and settings management (used bymcpandconfig.py).pydantic-settings: For loading configuration from environment variables.anyio: For async task management and progress reporting.uvicorn: For HTTP Streamable mode ASGI server.typer: For CLI argument parsing (included inmcp[cli]).
- Lists optional test dependencies:
pytest: Main testing framework for unit tests.pytest-asyncio: Support for async test functions.pytest-cov: For code coverage reporting.
- Configures the build system (e.g., Hatchling).
Dockerfile:- Defines the steps to create a Docker image for the MCP server.
- Specifies the base Python image.
- Copies the application code into the image.
- Installs Python dependencies listed in
pyproject.toml. - Sets up necessary environment variables (can be overridden at runtime).
- Defines the
CMDto run the MCP server in stdio mode by default (python -m blockscout_mcp_server).
.env.example:- Provides a template for users to create their own
.envfile for local development. - Lists all required environment variables, such as:
BLOCKSCOUT_BS_TIMEOUT: Timeout for Blockscout API requests.BLOCKSCOUT_BENS_URL: Base URL for the BENS (Blockscout ENS) API.BLOCKSCOUT_BENS_TIMEOUT: Timeout for BENS API requests.BLOCKSCOUT_METADATA_TIMEOUT: Timeout for PRO API metadata requests.BLOCKSCOUT_PRO_API_KEY: Server-configured Blockscout PRO API key used as the default/fallback credential for data requests.BLOCKSCOUT_PRO_API_KEY_REQUIRED_NOTICE: Operator-configured notice appended to tool responses when the request lacked a client-supplied PRO API key (empty disables the feature).BLOCKSCOUT_CHAINSCOUT_URL: URL for the Chainscout API (for chain resolution).BLOCKSCOUT_CHAINSCOUT_TIMEOUT: Timeout for Chainscout API requests.BLOCKSCOUT_CHAINS_LIST_TTL_SECONDS: Time-to-live for the Chains List cache.BLOCKSCOUT_PROGRESS_INTERVAL_SECONDS: Interval for periodic progress updates in long-running operations.BLOCKSCOUT_NFT_PAGE_SIZE: Page size for NFT token queries (default: 10).BLOCKSCOUT_LOGS_PAGE_SIZE: Page size for address logs queries (default: 10).BLOCKSCOUT_ADVANCED_FILTERS_PAGE_SIZE: Page size for advanced filter queries (default: 10).
- Provides a template for users to create their own
-
mcpb/(MCP Bundle - Development Only)- This directory contains the MCP Bundle (.mcpb) for Claude Desktop integration - for development and testing purposes only.
- Note: For production use with Claude, install the official Blockscout connector from the Anthropic Connectors Directory.
README.md:- Provides documentation for the MCPB specification and development workflow.
- Contains build instructions for creating the development bundle.
manifest.json:- Defines the bundle manifest with configurable MCP server URL for development.
- Specifies the server configuration using Node.js with mcp-remote proxy.
- Allows developers to connect to local or custom MCP server instances.
build.sh:- Automated build script for creating the development bundle.
- Handles dependency installation and bundle packaging.
-
agent-skills/(Git Submodule)- Git submodule: agent-skills repository
- Contains AI agent skills that provide structured guidance for enhanced blockchain data analysis using the Blockscout MCP Server.
- Build-time bundling: a Hatch build hook (
hatch_build.py) writesblockscout_mcp_server/_bundled_skill_manifest.jsoncontaining the submodule's commit hash and ISO 8601 commit timestamp. The MCP server reads this manifest at startup and uses the timestamp as thelastModifiedannotation on every bundled skill resource. The commit metadata is baked outside Docker byscripts/bake_skill_metadata.py, which CI invokes beforedocker build.
-
tests/(Test Suite)- This directory contains the complete test suite for the project, divided into two categories:
tests/tools/: Contains the comprehensive unit test suite. All external API calls are mocked, allowing these tests to run quickly and offline. Tool-specific tests live in dedicated modules under category folders (for example,tests/tools/address/test_get_address_info.py), and shared utilities are covered by modules liketest_common.py.- Each test file corresponds to a single MCP tool and provides comprehensive test coverage:
- Success scenarios: Testing normal operation with valid inputs and API responses.
- Error handling: Testing API errors, chain lookup failures, timeout errors, and invalid responses.
- Edge cases: Testing empty responses, missing fields, malformed data, and boundary conditions.
- Progress tracking: Verifying correct MCP progress reporting behavior for all tools.
- Parameter validation: Testing optional parameters, pagination, and parameter combinations.
- Uses
pytestandpytest-asynciofor async testing with comprehensive mocking strategies. - All tests maintain full isolation using
unittest.mock.patchto mock external API calls.
- Each test file corresponds to a single MCP tool and provides comprehensive test coverage:
tests/integration/: Contains the integration test suite. These tests make real network calls and are divided into two categories:- Helper-level tests in
test_common_helpers.pyverify basic connectivity and API availability. - Tool-level tests live in domain-specific folders (for example,
tests/integration/address/). Eachtest_*_real.pymodule exercises exactly one MCP tool to keep test contexts focused for coding agents. All integration tests are marked with@pytest.mark.integrationand are excluded from the default test run.
- Helper-level tests in
-
blockscout_mcp_server/(Main Python Package)__init__.py: Standard file to mark the directory as a Python package.llms.txt: Machine-readable guidance file for AI crawlers.__main__.py:- Serves as the entry point when the package is run as a script (
python -m blockscout_mcp_server). - Imports the main execution function (e.g.,
run_server()) fromserver.pyand calls it.
- Serves as the entry point when the package is run as a script (
models.py:- Defines a standardized, structured
ToolResponsemodel using Pydantic. - Ensures all tools return data in a consistent, machine-readable format, separating the data payload from metadata like pagination and notes.
- Includes specific data models for complex payloads, like the response from
__unlock_blockchain_analysis__.
- Defines a standardized, structured
server.py:- The heart of the MCP server.
- Initializes a
FastMCPinstance using constants fromconstants.py. - Imports all tool functions from the modules in the
tools/sub-package. - Registers each tool with the
FastMCPinstance using the@mcp.tool()decorator. This includes:- Tool name (if different from the function name).
- Tool description (from the function's docstring or explicitly provided).
- Argument type hints and descriptions (using
typing.Annotatedandpydantic.Fieldfor descriptions), whichFastMCPuses to generate the input schema.
- Implements CLI argument parsing using
typerwith support for:--http: Enable HTTP Streamable mode--http-host: Host for HTTP server (default: 127.0.0.1)--http-port: Port for HTTP server (default: 8000)
- Defines
run_server_cli()function that:- Parses CLI arguments and determines the mode (stdio or HTTP)
- For stdio mode: calls
mcp.run()for stdin/stdout communication - For HTTP mode: configures stateless HTTP with JSON responses and runs uvicorn server
templates/:index.html: Landing page for the REST API.
config.py:- Defines a Pydantic
BaseSettingsclass to manage server configuration. - Loads configuration values (e.g., API keys, timeouts, cache settings) from environment variables.
- Provides a singleton configuration object that can be imported and used by other modules, especially by
tools/common.pyfor API calls. mcp_allowed_hosts: str: Comma-separated list of allowedHostheader values for DNS rebinding protection (default: empty, auto-detected based on bind host).mcp_allowed_origins: str: Comma-separated list of allowedOriginheader values for DNS rebinding protection (default: empty, auto-detected based on bind host).pro_api_key_header: str: Name of the request header an HTTP client (MCP-over-HTTP or REST) uses to supply its own Blockscout PRO API key (default:Blockscout-MCP-Pro-Api-Key; empty string disables the feature).
- Defines a Pydantic
constants.py:- Defines centralized constants used throughout the application, including data truncation limits.
- Ensures consistency between different parts of the application.
- Used by both
server.pyandtools/initialization/unlock_blockchain_analysis.pyto maintain a single source of truth.
logging_utils.py:- Provides utilities for configuring production-ready logging.
- Contains the
replace_rich_handlers_with_standard()function that eliminates multi-line Rich formatting from MCP SDK logs. - Contains the
install_client_disconnect_filter()function that demotes routine client-disconnect errors in MCP SDK logs.
analytics.py:- Centralized Mixpanel analytics for MCP tool invocations.
- Enabled only in HTTP mode when
BLOCKSCOUT_MIXPANEL_TOKENis set. - Generates a deterministic anonymous
distinct_id— key-fingerprint-based where a key distinguishes the caller, otherwise an IP/name/version composite. - Tracks tool invocations with client metadata, protocol version, and call source (MCP vs REST).
- Includes IP geolocation metadata for Mixpanel and graceful error handling to avoid breaking tool execution.
telemetry.py:- Sends anonymous usage reports from self-hosted servers when direct analytics are disabled.
- Designed as fire-and-forget and never disrupts tool execution.
observability.py:- Provides
log_resource_read(), the shared entry point for observing successful skill-resource reads (MCP resource channel and the REST/skillmirror).
- Provides
client_meta.py:- Shared utilities for extracting client metadata (name, version, protocol, user_agent) from MCP Context.
- Provides
ClientMetadataclass andextract_client_meta_from_ctx()function. - Falls back to User-Agent header when MCP client name is unavailable.
- Ensures consistent sentinel defaults ("N/A", "Unknown") across logging and analytics modules.
- Also provides
format_client_meta_suffix(), the shared client-metadata suffix formatter reused by tool-invocation and resource-read logging.
pro_api_key_context.py:- Owns request-scoped resolution of a client-supplied Blockscout PRO API key, kept separate from logging/observability.
- Provides a
ContextVarof the per-request client-key state, a normalization/validation helper,extract_client_pro_api_key_from_ctx(),resolve_pro_api_key()(precedence: valid client key → server key → not-configured error; malformed client key → terminal error, no fallback), and the@pro_api_key_scopedecorator. - Also provides the
ctx-derived helpercompute_auth_signals(), used by the analytics and community-telemetry paths. - Honored for any HTTP request that carries the configured header (MCP-over-HTTP or REST); the key is never logged or placed in cache keys.
- Also defines the per-invocation credit-tracking symbols:
CreditSink, the_credit_sinkContextVar, and the@pro_api_credit_scopedecorator (a sibling of@pro_api_key_scope).
cache.py:- Encapsulates in-memory caching of chain data with TTL management.
web3_pool.py:- Manages pooled
AsyncWeb3instances with sharedaiohttpsessions. - Provides a custom provider to ensure Blockscout RPC compatibility and connection reuse.
- Manages pooled
api/(API layer):helpers.py: Shared utilities for REST API handlers, including parameter extraction and error handling.routes.py: Defines all REST API endpoints that wrap MCP tools.dependencies.py: Dependency providers for the REST API, such as a mock context for stateless calls.
resources/:skill_resources.py: Enumerates bundledblockscout-analysisskill Markdown as MCP resources and serves cached content to the/skill/HTTP mirror.
tools/(Sub-package for Tool Implementations)__init__.py: Markstoolsas a sub-package. May re-export tool functions for easier import intoserver.py.common.py:- Provides shared utilities and common functionality for all MCP tools.
- Handles API communication, chain resolution, pagination, data processing, and error handling.
- Implements standardized patterns used across the tool ecosystem.
- Includes logging helpers such as the
@log_tool_invocationdecorator.
decorators.py:- Contains the
log_tool_invocationdecorator and other logging helpers.
- Contains the
- Individual Tool Modules (e.g.,
address/get_address_info.py,transaction/get_transaction_info.py):- Each MCP tool lives in its own module named after the tool function.
- Modules are organized by domain (
address/,block/,contract/,transaction/, etc.) to keep related tools together while preserving a 1:1 mapping. - Shared helpers used by multiple tools in the same domain live in
_shared.pymodules alongside the individual tool files. - Tool functions remain
async, accept aContextargument for progress reporting, and usetyping.Annotated/pydantic.Fieldfor argument descriptions. - The function docstring provides the description surfaced to FastMCP clients.
- Example modules:
initialization/unlock_blockchain_analysis.py: Implements__unlock_blockchain_analysis__, the mandatory session-initialization call, returningInstructionsData(models.py).chains/get_chains_list.py: Implementsget_chains_list, returning a formatted list of blockchain chains with their IDs.ens/get_address_by_ens_name.py: Implementsget_address_by_ens_namevia the BENS API.search/lookup_token_by_symbol.py: Implementslookup_token_by_symbol(chain_id, symbol)with a strict result cap.contract/inspect_contract_code.py: Uses helpers fromcontract/_shared.pyto return metadata or source files for verified contracts.address/get_tokens_by_address.py: Implements paginated ERC-20 holdings responses withNextCallInfofor follow-up requests.transaction/get_transactions_by_address.py: Uses_shared.pyhelpers for smart pagination and filtering of advanced transactions.