mev-mcp
An MCP server for inspecting MEV-relevant activity on Polygon — pending mempool traffic, confirmed swap history, and gas pricing — exposed as tools an AI agent (or you, via Claude Desktop) can call directly.
This is a diagnostic and research tool, not a production MEV detector. It's built to be honest about what it sees and what it misses, rather than to look more capable than it is.
What it does
| Tool | What it tells you | Source |
|---|---|---|
check_pending_swaps_on_pool |
Pending transactions touching a given Uniswap v3 pool, broken down by route type, plus a self-check against confirmed history | Public mempool (eth_subscribe) |
check_confirmed_swaps_on_pool |
Ground-truth swap count and originating contracts for a pool over a recent block range | Finalized chain state (eth_getLogs) |
get_gas_price_percentiles |
Gas price distribution over recent blocks | eth_feeHistory |
hello |
Connectivity check | — |
Polygon only. Arbitrum uses a centralized sequencer with no public mempool, so pending-transaction tools aren't meaningful there.
The honest part: mempool coverage is partial, and the tool tells you so
Swaps on a given pool can be routed through many different contracts — Uniswap's own SwapRouter, SwapRouter02, UniversalRouter, or any of a long list of aggregators (1inch, Odos, Paraswap, and others). check_pending_swaps_on_pool currently decodes:
- Direct calls to the pool contract
SwapRouter/SwapRouter02single-hop swaps (exactInputSingle,exactOutputSingle) and multi-hop swaps (exactInput,exactOutput, via packed-path decoding)UniversalRouterV3_SWAP_EXACT_IN/V3_SWAP_EXACT_OUTcommands1inch AggregationRouter v6swaps
That's a meaningful slice of mempool traffic, but it is not exhaustive. In testing on a moderately active Polygon pool, well over half of confirmed swap volume routed through contracts outside this list — other aggregators, smart-contract wallets, and routing contracts we haven't decoded yet.
Rather than let that show up as a silent count: 0 — indistinguishable from "this pool is just quiet" — check_pending_swaps_on_pool runs a quick confirmed-swap check over a comparable window and returns a coverage_estimate field alongside the raw count:
{
"count": 0,
"routes": { "router_swap": 0, "universal_router_swap": 0, "aggregator_1inch": 0, "direct_pool_call": 0 },
"confirmed_check": { "swap_count": 4, "by_to_address": { "...": 1 } },
"coverage_estimate": "low — confirmed swaps exist on this pool but none were caught pending; likely routed through unrecognized contracts"
}
Possible coverage_estimate values:
no_recent_activity — no confirmed swaps in the last N blocks (~M min); this pool appears genuinely inactive— confirmed window large enough (≥300 blocks) to trust a zero resultinconclusive — … window too short to draw conclusions— confirmed window smaller than the minimum reliable thresholdlow — confirmed swaps exist on this pool but none were caught pending; likely routed through unrecognized contracts— pool is active but none of the pending transactions matched a known routerlow / medium / high (ratio R: N pending caught vs M confirmed)— at least some pending matches found; ratio against confirmed volume gives a coverage signalunknown — confirmed check failed: ExceptionType: message— the self-check itself threw an exception; rawcountstill standsunknown — confirmed check returned error: …— RPC or other error from the confirmed check endpoint
If you need a quick, reliable read on whether a pool is active at all — independent of mempool coverage — use check_confirmed_swaps_on_pool directly. It reads finalized blocks, so it has no router-coverage blind spot, only the same long-tail-of-aggregators caveat in its by_to_address breakdown (you'll see contract addresses it doesn't attempt to label).
Requirements
- Python 3.10+
- An RPC provider for Polygon with mempool (
eth_subscribe) support — most free-tier providers (including Alchemy's free tier) support this fornewPendingTransactions - For
check_confirmed_swaps_on_pool: aneth_getLogs-capable endpoint. Free-tier plans often cap the block range per call (Alchemy's free tier: 10 blocks); the tool chunks requests automatically, configurable viaMEV_MCP_LOGS_CHUNK_SIZE(default10). On a paid plan, raising this (e.g. to500) significantly speeds up confirmed-swap lookups.
Setup
git clone https://github.com/matiosera3-ops/mev-mcp
cd mev-mcp
pip install -e .
Add to your Claude Desktop config (claude_desktop_config.json):
{
"mcpServers": {
"mev-mcp": {
"command": "python",
"args": ["-m", "mev_mcp.server"],
"env": {
"POLYGON_RPC_URL": "https://your-polygon-rpc-url",
"MEV_MCP_LOGS_CHUNK_SIZE": "10"
}
}
}
}
Not yet published to PyPI — install from source for now.
Known limitations
- Router coverage is partial. See above. Contributions adding decoders for additional aggregators (Odos, Paraswap, 0x) are welcome — the existing
SwapRouter/UniversalRouter/1inchdecoders inpending_swaps.pyare a template for the calldata-matching pattern used. - Mempool visibility depends on your RPC provider. Different providers see different shares of the public mempool.
hashes_seen/hashes_resolvedin the raw tool output give you a sense of how much traffic your provider surfaces. - Free-tier
eth_getLogslimits makecheck_confirmed_swaps_on_poolslow on a free Alchemy plan (chunking in 10-block calls). Fine for occasional diagnostic use; not built for high-frequency polling. - No Arbitrum mempool support, structurally — there isn't a public one to watch.
License
MIT
Metadata
Release files for mev-mcp 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| mev_mcp-0.1.0.tar.gz | 196.3 kB | Without provenance | Details for mev_mcp-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| mev_mcp-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for mev_mcp-0.1.0-py3-none-any.whl |
Total release size: 214.6 kB
Release files / mev_mcp-0.1.0.tar.gz
| Download URL | mev_mcp-0.1.0.tar.gz |
|---|---|
| Size | 196.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f49f6bf2e17f3c81497ed362bb4c2a146889c577e50293022a32e42ac7c67662
|
|
BLAKE2b-256 checksum How to use checksums |
8bcff5da33b38d01ae83c9d4a9cfac6ab7a76c5bf88b98e8f75a869f04305cec
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.2
|
Release files / mev_mcp-0.1.0-py3-none-any.whl
| Download URL | mev_mcp-0.1.0-py3-none-any.whl |
|---|---|
| Size | 18.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
249389c7fef83382d04bbf9218e901261a4a17dca1efe20b0c80a948e8def495
|
|
BLAKE2b-256 checksum How to use checksums |
3e06f53a6eb3caea542662cc38f1682f9216b59ebe39532141e348087f051673
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.2
|
Security for mev-mcp 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.