Skip to main content
Glama
kukapay

tornado-cash-mcp

by kukapay

Tornado Cash MCP

An MCP server that tracks Tornado Cash deposits and withdrawals to reveal hidden asset trails and wallet interactions.

GitHub License Python Version Status

Features

  • Query Latest Deposits: Retrieve the most recent deposit events with details including sender address (from), amount, block number, timestamp, and commitment.

  • Query Latest Withdrawals: Fetch the latest withdrawal events with details including recipient address (to), amount, block number, and timestamp.

Related MCP server: phalcon-mcp

Prerequisites

  • Python 3.10+

  • uv (recommended package manager)

  • A valid The Graph API key for accessing the Tornado Cash Subgraph

Installation

  1. Clone the repository:

    git clone https://github.com/kukapay/tornado-cash-mcp.git
    cd tornado-cash-mcp
  2. install dependencies using uv:

    uv sync
  3. Installing to Claude Desktop:

    Install the server as a Claude Desktop application:

    uv run mcp install main.py --name "tornado-cash-mcp"

    Configuration file as a reference:

    {
       "mcpServers": {
           "Tornado Cash": {
               "command": "uv",
               "args": [ "--directory", "/path/to/tornado-cash-mcp", "run", "main.py" ],
               "env": { "THEGRAPH_API_KEY": "the_graph_api_key"}               
           }
       }
    }

    Replace /path/to/tornado-cash-mcp with your actual installation path, and the_graph_api_key with your API key from The Graph.

Tools

Use the MCP Inspector UI or integrate with a compatible client (e.g., Claude Desktop) to call the tools.

Query Latest Deposits

Example prompt:

"Show me the latest 3 deposits from Tornado Cash."

Example output:

+------------+---------------+--------------+---------------------+--------------+
| from       | amount        | blockNumber  | time                | commitment   |
+============+===============+==============+=====================+==============+
| 0xdef...   |           0.1 | 12345678     | 2023-10-12 15:30:00 | 0xabc...     |
| 0xdee...   |             1 | 12345677     | 2023-10-12 15:28:20 | 0xabd...     |
| 0xdef...   |            10 | 12345676     | 2023-10-12 15:26:40 | 0xabe...     |
+------------+---------------+--------------+---------------------+--------------+

Query Latest Withdrawals

Example prompt:

"Get the most recent 2 withdrawals from Tornado Cash."

Example output:

+------------+---------------+--------------+---------------------+
| to         | amount        | blockNumber  | time                |
+============+===============+==============+=====================+
| 0x789...   |             1 | 12345679     | 2023-10-13 14:40:00 |
| 0x78a...   |           100 | 12345678     | 2023-10-13 14:38:20 |
+------------+---------------+--------------+---------------------+

License

This project is licensed under the MIT License. See LICENSE for details.

Available Tools

2 tools
query_latest_depositsA
Query the most recent deposits from Tornado Cash Subgraph and return results as a formatted table.

Parameters:
    limits (int): The maximum number of deposit records to return. Must be positive. Default is 10.

Returns:
    A string containing a tabulated representation of deposit records with columns: id, amount, timestamp, commitment, blockNumber, from.
ParametersJSON Schema
NameRequiredDescriptionDefault
limitsNo

TDQS

A3.6/5.0
Behavior3/5

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

With no annotations provided, the description carries the full burden of behavioral disclosure. It describes the query operation and output format, but lacks details about potential rate limits, authentication requirements, data freshness, error conditions, or whether this is a read-only operation. The description doesn't contradict any annotations since none exist.

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

Conciseness5/5

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

The description is well-structured and appropriately sized. It begins with a clear purpose statement, then provides parameter details in a labeled section, followed by return value information. Every sentence adds value without redundancy, making it easy to scan and understand.

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

Completeness3/5

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

For a query tool with no annotations, no output schema, and minimal parameters, the description provides adequate coverage of the basic operation and parameters. However, it lacks details about the Tornado Cash Subgraph source, potential limitations, error handling, or the specific format of the returned table beyond column names, leaving some contextual gaps.

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

Parameters4/5

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

The description adds significant value beyond the input schema, which has 0% description coverage. It explains the 'limits' parameter's purpose (maximum number of deposit records), constraints (must be positive), and default value (10), while the schema only provides the title and type. For a single parameter tool with poor schema coverage, this is good compensation.

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

Purpose4/5

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

The description clearly states the tool's purpose: querying recent deposits from Tornado Cash Subgraph and returning them as a formatted table. It specifies the verb ('query'), resource ('most recent deposits'), and output format ('formatted table'), but doesn't explicitly differentiate from its sibling 'query_latest_withdrawals' beyond the deposit/withdrawal distinction.

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

Usage Guidelines3/5

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

The description implies usage context by specifying it returns 'most recent deposits' as a formatted table, suggesting it's for retrieving recent deposit data in a readable format. However, it doesn't provide explicit guidance on when to use this tool versus alternatives like the sibling withdrawal query or other data retrieval methods.

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

query_latest_withdrawalsB
Query the most recent withdrawals from Tornado Cash Subgraph and return results as a formatted table.

Parameters:
    limits (int): The maximum number of withdrawal records to return. Must be positive. Default is 10.

Returns:
    A string containing a tabulated representation of withdrawal records with columns: id, amount, timestamp, to, blockNumber.
ParametersJSON Schema
NameRequiredDescriptionDefault
limitsNo

TDQS

B3.4/5.0
Behavior3/5

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

With no annotations provided, the description carries the full burden of behavioral disclosure. It describes the action (querying and formatting withdrawals) and the output format (a tabulated string), but lacks details on potential errors, rate limits, authentication needs, or data freshness. It adds some context but is incomplete for a tool interacting with an external data source.

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

Conciseness5/5

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

The description is well-structured and concise, with a clear opening sentence stating the tool's purpose, followed by dedicated sections for parameters and returns. Each sentence adds value without redundancy, making it easy to scan and understand quickly.

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

Completeness3/5

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

Given the tool's moderate complexity (querying external data with one parameter) and lack of annotations and output schema, the description is adequate but has gaps. It covers the basic operation and output format but omits details on error handling, data source limitations, or integration context, which could be important for an agent.

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

Parameters4/5

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

The description adds significant meaning beyond the input schema, which has 0% description coverage. It explains the 'limits' parameter's purpose (maximum number of records), constraints (must be positive), default value (10), and how it affects the output. This compensates well for the schema's lack of details, though it doesn't cover all possible edge cases.

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

Purpose4/5

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

The description clearly states the tool's purpose: querying recent withdrawals from Tornado Cash Subgraph and returning them as a formatted table. It specifies the verb ('query'), resource ('withdrawals'), and data source ('Tornado Cash Subgraph'), but does not explicitly differentiate from its sibling tool 'query_latest_deposits' beyond the resource type.

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

Usage Guidelines2/5

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

The description provides no guidance on when to use this tool versus alternatives, such as its sibling 'query_latest_deposits'. It mentions the tool's function but offers no context on use cases, prerequisites, or comparisons, leaving the agent to infer usage based on the tool name alone.

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

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 2 tool updatesv1.0.0
    • First observedquery_latest_deposits
    • First observedquery_latest_withdrawals

TDQS

A3.5/5.0

Scored across 2 tools

Disambiguation5/5

The two tools have clearly distinct purposes: one queries deposits and the other queries withdrawals. There is no overlap or ambiguity between them, as each targets a different transaction type within the Tornado Cash domain.

Naming Consistency5/5

Both tools follow a consistent verb_noun pattern with 'query_latest_' prefix followed by the transaction type. This predictable naming scheme makes it easy to understand what each tool does at a glance.

Tool Count2/5

With only 2 tools, this server feels significantly under-scoped for a Tornado Cash integration. While deposits and withdrawals are core operations, a complete MCP server for this domain would typically include tools for other operations like querying specific transactions, getting pool statistics, or interacting with smart contracts.

Completeness2/5

The tool surface is severely incomplete for a Tornado Cash server. While it covers basic querying of deposits and withdrawals, there are significant gaps including: no ability to query specific transactions by ID, no tools for interacting with pools or contracts, no filtering capabilities beyond simple limits, and no write operations that might be expected in a privacy tool integration.

Maintenance

ActivityInactive
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers