Unofficial Mantle MCP Server written in Python

Mantle Network MCP Server (mantle-mcp)

A highly optimized Model Context Protocol (MCP) server built with Python and FastMCP. This server exposes a suite of tools that enable agentic frameworks and LLM interfaces (like KinetiFi) to interact with the Mantle Network (Layer 2 on Ethereum) for querying native and ERC-20 balances, checking allowances, retrieving DEX swap quotes (V2 and V3 architectures), estimating L2 gas costs, and managing on-chain Real World Assets (RWA) and ERC-8004 Agent Identities/Reputations.

Features

  • Asynchronous Architecture: Built from the ground up using asyncio and web3[async] to minimize latency and maximize performance when handling multiple requests.
  • Dynamic Token Resolution: Resolves token symbols (e.g., USDC, WETH) dynamically by checking a local registry first, then falling back to Blockscout Explorer APIs for both mainnet and testnet.
  • Uniswap V3 / Merchant Moe / Agni Finance Integration: Computes exact, real-time swap quotes (quoteExactInputSingle) using standard Uniswap V3 QuoterV2 logic.
  • ERC-8004 Identity & Reputation: Implements the proposed ERC-8004 standard on Mantle to register agent ownership and verify reputation scores on-chain.
  • RWA Yield Optimization: Integrates Mantle Staked Ether (mETH) yield index queries and Ondo USDY transaction generators.
  • Zero-Trust & Stateless: Exposes read-only queries and generates unsigned EVM transaction payloads (to, data, value). Never requests, handles, or stores private keys.
  • Offline Test Suite: A robust and comprehensive test suite using pytest and unittest.mock for fully offline, fast, and deterministic verification of all L2 RPC and API interactions.

Repository Structure

mantle-mcp/
├── .env                  # Environment configurations for L2 RPC endpoints
├── README.md             # Server documentation
├── requirements.txt      # Project Python dependencies
├── server.py             # Main entrypoint initializing FastMCP and registering tools
├── tools/                # Sub-modules implementing individual blockchain queries
│   ├── __init__.py       # Web3 client initializer and network constant definitions
│   ├── balance.py        # Native MNT balance lookup
│   ├── dex.py            # V2 and V3 DEX swap quotes (Uniswap V2 Router & V3 QuoterV2)
│   ├── erc20.py          # ERC-20 balanceOf and allowance query functions
│   ├── gas.py            # L2 gas units and gas price estimation
│   ├── identity.py       # ERC-8004 Agent Identity registry & Reputation metrics
│   ├── network.py        # Network metadata and connection health checker
│   ├── rwa.py            # Ondo USDY and mETH yield rate query & wrap tools
│   └── tokens.py         # Dynamic token symbol-to-address resolution
└── tests/                # Deterministic async offline tests
    ├── test_dex.py       # V2 & V3 Swap quote mocks & assertions
    ├── test_erc20.py     # ERC-20 allowance and balance mocks
    ├── test_identity.py  # ERC-8004 Identity & Reputation mock tests
    ├── test_rwa.py       # mETH yields and USDY wrap payload mock tests
    ├── test_server.py    # Native balance, gas, network info, and server endpoints
    └── test_tokens.py    # Local registry and API fallback tests

Prerequisites

Before setting up the project, ensure you have the following installed:

  • Python 3.10+ (tested and verified on Python 3.14)
  • Virtual Environment Tool (venv)
  • MCP Host (e.g., Claude Desktop, Cursor, Roo-Code, or any custom client)

Installation & Setup

Follow these steps to set up the Mantle MCP server locally:

1. Clone & Navigate to Directory

cd /home/tmalone1250/KinetiFi_local/mantle-mcp

2. Create and Activate Virtual Environment

python3 -m venv .venv
source .venv/bin/activate

3. Install Dependencies

pip install --upgrade pip
pip install -r requirements.txt

Configuration

Environment variables are managed using a .env file in the project root. Create or update .env as follows:

# Mantle Network MCP Server Environment Variables
# Leave blank to use the official public RPC endpoints, or override them below.

# Mainnet RPC Endpoint (Default: https://rpc.mantle.xyz)
MANTLE_RPC_URL=

# Sepolia Testnet RPC Endpoint (Default: https://rpc.sepolia.mantle.xyz)
MANTLE_SEPOLIA_RPC_URL=

Fallback Network Constants

If the environment variables are left blank, the server automatically falls back to these defaults:

Parameter Mainnet Testnet (Sepolia)
RPC URL https://rpc.mantle.xyz https://rpc.sepolia.mantle.xyz
Block Explorer https://explorer.mantle.xyz https://explorer.sepolia.mantle.xyz
Chain ID 5000 5003
Native Currency MNT MNT

Running the Server

You can run the Mantle MCP server in two modes:

Development Mode (with Live Reload)

To inspect tools, test outputs, and log streams via a graphical web interface, run:

fastmcp dev server.py

Production Mode

Run the server to handle MCP JSON-RPC standard input/output streams:

python server.py

Integrating with MCP Clients

To link mantle-mcp to your favorite LLM assistant client, register it under the custom MCP servers config file:

For Claude Desktop

Add this to your Claude Desktop configuration (typically at ~/.config/Claude/claude_desktop_config.json):

{
  "mcpServers": {
    "mantle-mcp": {
      "command": "/home/tmalone1250/KinetiFi_local/mantle-mcp/.venv/bin/python",
      "args": [
        "/home/tmalone1250/KinetiFi_local/mantle-mcp/server.py"
      ],
      "env": {
        "MANTLE_RPC_URL": "https://rpc.mantle.xyz",
        "MANTLE_SEPOLIA_RPC_URL": "https://rpc.sepolia.mantle.xyz"
      }
    }
  }
}

MCP Tool Reference

mantle-mcp exposes 13 native blockchain tools to clients:

1. get_native_balance

Retrieves the native MNT balance of an address on the Mantle Network.

  • Arguments:
    • address (string, required): The EVM address to query.
    • network (string, optional): The network to query ('testnet' or 'mainnet'). Defaults to 'testnet'.
  • Response Format:str representing a human-readable balance (e.g., "12.3450 MNT").

2. get_erc20_balance

Retrieves the ERC-20 token balance for a specific wallet address. Automatically resolves token symbols to addresses and formats the balance using the token's decimals.

  • Arguments:
    • wallet_address (string, required): The EVM wallet address to query.
    • token_symbol (string, required): The token symbol (e.g., 'USDC', 'WETH', 'USDT').
    • network (string, optional): The network to query ('testnet' or 'mainnet'). Defaults to 'testnet'.
  • Response Format:
    {
      "wallet": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
      "token": "USDC",
      "balance": 150.5,
      "network": "testnet"
    }
    

3. get_erc20_allowance

Retrieves the ERC-20 token allowance granted by a wallet to a specific spender.

  • Arguments:
    • wallet_address (string, required): The EVM wallet address that owns the tokens.
    • spender_address (string, required): The EVM address authorized to spend the tokens.
    • token_symbol (string, required): The token symbol (e.g., 'USDC', 'WETH').
    • network (string, optional): The network to query ('testnet' or 'mainnet'). Defaults to 'testnet'.
  • Response Format:
    {
      "wallet": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
      "spender": "0x70997970C51812dc3A010C7d01b50e0d17dc79C8",
      "token": "USDC",
      "allowance": 500.0,
      "network": "testnet"
    }
    

4. get_swap_quote (Uniswap V2)

Gets a swap quote (expected output) for a given trade pair on the FusionX DEX router using Uniswap V2 Router logic.

  • Arguments:
    • sell_symbol (string, required): The token symbol to sell (e.g., 'USDC').
    • buy_symbol (string, required): The token symbol to buy (e.g., 'WETH').
    • amount_in (float, required): The human-readable amount of sell_symbol to swap.
    • network (string, optional): The network to query ('testnet' or 'mainnet'). Defaults to 'testnet'.
  • Response Format:
    {
      "sell_token": "USDC",
      "buy_token": "WETH",
      "amount_in": 100.0,
      "expected_output": 0.05,
      "network": "testnet"
    }
    

5. get_dex_quote (Uniswap V3)

Gets a V3 swap quote (exact input) from specific DEXes like merchant_moe or agni_finance on Mantle.

  • Arguments:
    • dex_name (string, required): The DEX name to query ('merchant_moe' or 'agni_finance').
    • token_in (string, required): EVM contract address of the incoming token.
    • token_out (string, required): EVM contract address of the outgoing token.
    • amount_in_wei (integer, required): The amount of input token, in raw wei.
    • fee_tier (integer, optional): The pool fee tier (e.g., 3000 representing 0.30%). Defaults to 3000.
    • network (string, optional): The network to query ('mainnet' or 'testnet'). Defaults to 'mainnet'.
  • Response Format:
    {
      "dex": "merchant_moe",
      "amount_out_wei": 50000000000000000,
      "estimated_gas_from_quoter": 150000,
      "status": "success"
    }
    

6. estimate_l2_gas

Estimates the gas units and total cost required to execute a transaction on Mantle L2.

  • Arguments:
    • to_address (string, required): The target EVM address of the recipient or contract.
    • data (string, optional): The hex data payload of the transaction. Defaults to '0x'.
    • value_wei (integer, optional): The native currency value to send, in wei. Defaults to 0.
    • network (string, optional): The network to query ('testnet' or 'mainnet'). Defaults to 'testnet'.
  • Response Format:
    {
      "success": true,
      "network": "testnet",
      "estimated_gas_units": 21000,
      "gas_price_gwei": 1.0,
      "estimated_cost_mnt": 0.000021,
      "estimated_cost_wei": 21000000000000
    }
    

7. get_token_address

Dynamically resolves a token symbol to its smart contract address on Mantle. If the token is not cached in the local registry, it falls back to querying the Blockscout explorer API.

  • Arguments:
    • symbol (string, required): The token symbol (e.g., 'USDC', 'WETH', 'WMNT').
    • network (string, optional): The network to query ('testnet' or 'mainnet'). Defaults to 'testnet'.
  • Response Format:
    {
      "symbol": "USDC",
      "address": "0x09Bc4E0D864854c6aFB6eB9A9cdF58aC190D0dF9",
      "network": "mainnet",
      "source": "local_registry"
    }
    

8. get_mantle_network_info

Returns the network metadata and connection parameters (including connectivity check) for the requested Mantle Network.

  • Arguments:
    • network (string, optional): The network name to query ('testnet' or 'mainnet'). Defaults to 'testnet'.
  • Response Format:
    {
      "success": true,
      "network": "testnet",
      "chain_id": 5003,
      "rpc_url": "https://rpc.sepolia.mantle.xyz",
      "explorer_url": "https://explorer.sepolia.mantle.xyz",
      "native_currency": "MNT",
      "rpc_connection_active": true
    }
    

9. fetch_meth_yield

Fetches the current mETH (Mantle Staked Ether) yield exchange rate from the on-chain contract.

  • Arguments:
    • network (string, optional): The network name to query ('mainnet' or 'testnet'). Defaults to 'mainnet'.
  • Response Format:
    {
      "asset": "mETH",
      "exchange_rate_raw": 1052000000000000000,
      "exchange_rate_formatted": 1.052,
      "status": "success"
    }
    

10. prepare_usdy_wrap

Generates an unsigned transaction payload to wrap USDC into Ondo USDY.

  • Arguments:
    • amount_wei (integer, required): The raw amount of USDC in wei to wrap.
    • usdy_address (string, optional): The USDY target wrap contract address. Defaults to Ondo USDY Mainnet.
    • network (string, optional): The network ('mainnet' or 'testnet'). Defaults to 'mainnet'.
  • Response Format:
    {
      "chainId": 5000,
      "to": "0x5bE26527e817998A7206475496fDE1E68957c5A6",
      "data": "0xwrap...",
      "value": "0x0",
      "readModel": {
        "protocol": "Ondo USDY",
        "method": "wrap(uint256)",
        "params": [1000000]
      }
    }
    

11. verify_erc8004_identity

Checks the owner address of an ERC-8004 Agent Identity on the Mantle Network.

  • Arguments:
    • identity_id (integer, required): The ID of the agent identity NFT to query.
    • network (string, optional): The network to query ('mainnet' or 'testnet'). Defaults to 'mainnet'.
  • Response Format:
    {
      "identity_id": 42,
      "owner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
      "network": "mainnet",
      "status": "registered"
    }
    

12. query_erc8004_reputation

Queries an agent's on-chain trust reputation score on the Mantle Network.

  • Arguments:
    • identity_id (integer, required): The ID of the agent identity NFT to query.
    • network (string, optional): The network to query ('mainnet' or 'testnet'). Defaults to 'mainnet'.
  • Response Format:
    {
      "identity_id": 42,
      "score": 95,
      "total_updates": 5,
      "network": "mainnet"
    }
    

13. prepare_agent_registration

Returns an unsigned payload to register and mint an ERC-8004 Identity NFT on the Mantle Network.

  • Arguments:
    • owner_address (string, required): The EVM address that will own the agent NFT.
    • metadata_uri (string, required): The IPFS/HTTPS metadata link for the agent identity.
    • network (string, optional): The network to query ('mainnet' or 'testnet'). Defaults to 'mainnet'.
  • Response Format:
    {
      "chainId": 5000,
      "to": "0x8004A169FB4a3325136EB29fA0ceB6D2e539a432",
      "data": "0xregister...",
      "value": "0x0",
      "readModel": {
        "protocol": "ERC-8004 Identity",
        "method": "register(address,string)",
        "params": ["0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", "ipfs://QmMock"]
      }
    }
    

Token Registry Details

The server includes a built-in fast local registry for common assets. If a token is queried that does not exist in the local registry, the server issues an asynchronous HTTP query to the Blockscout Explorer Search API to resolve the address dynamically.

Local Registry Addresses

Mainnet
  • MNT: native
  • WMNT: 0x78c1b0C915c4FAA5FffA6CAbf0219DA63d7f4cb8
  • WETH: 0xdEAddEaDdeadDEadDEADDEAddEADDEAddead1111
  • USDC: 0x09Bc4E0D864854c6aFB6eB9A9cdF58aC190D0dF9
  • USDT: 0x201EBa5CC46D216Ce6DC03F6a759e8E766e956aE
Testnet (Sepolia)
  • MNT: native
  • WMNT: 0x1404c04fE52478546D869Ff94119DF37eAA6e1c4
  • WETH: 0x7383D62D50E7dF82c6114dDF603952a2DE549B8a
  • USDC: 0x2D4a161f36402E8d4234baC5aC6f12e873aC1A62
  • USDT: 0xC216f40A3Ceb03F4f03936F76E296e8346cbDE6e

Testing

The project has a 100% mocked, deterministic test suite, meaning you can run all tests offline without needing live RPC access or internet connectivity.

Run all tests using the virtual environment pytest executable:

.venv/bin/pytest -v

Security & Architectural Standards

  1. Explicit Type Hints: Every function signature specifies types for input parameters and return shapes.
  2. Robust Error Handling: System calls catch RPC connection failures, contract reverts, and invalid address validation errors, returning structured error messages rather than crashing.
  3. Zero State Modification: The MCP server tools are read-only (view and gas estimation). They do not store private keys, hold funds, or initiate state-changing transactions directly, rendering the server highly secure.

MCP Server · Populars

MCP Server · New

    jackccrawford

    Geniuz

    Your AI remembers now. Geniuz stores everything in a local database locally on Mac, Windows, Linux, Raspberry Pi. No cloud. No account. No API keys. Nothing leaves your machine. It's open source; you can read every line of code.

    Community jackccrawford
    ggui-ai

    ggui

    The universal interface layer between AI agents and humans. Generate rich UIs on demand via MCP.

    Community ggui-ai
    aanno

    CocoIndex Code MCP Server

    An RAG for code development, implemented as MCP server with cocoindex

    Community aanno
    timescale

    Tiger Linear MCP Server

    A wrapper around the Linear API for internal LLMs

    Community timescale
    choplin

    MCP Gemini CLI

    MCP Server

    Community choplin