Skip to main content
Glama
hkaanengin

opendota-mcp-server

by hkaanengin
README.md
# OpenDota MCP Server

A [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server that provides seamless access to the [OpenDota API](https://docs.opendota.com) for querying Dota 2 player statistics, match data, and hero information through AI assistants like Claude.

## Features

- **20+ Tools** across 5 categories for comprehensive Dota 2 data access
- **Natural Language Support** - Fuzzy matching for hero names, lane positions, and stat fields
- **Dual Transport** - Supports both stdio (local) and HTTP (remote) modes
- **Rate Limiting** - Built-in protection respecting OpenDota API limits
- **Reference Data Caching** - Fast lookups with local hero/item data

## Available Tools

### Player Tools (6 tools)
Query player statistics, win/loss records, hero preferences, and performance metrics:
- `get_player_info` - Get player profile, win rate, and favorite heroes
- `get_player_win_loss` - Win/loss stats with advanced filtering
- `get_heroes_played` - Detailed statistics for all heroes played
- `get_player_peers` - Find frequent teammates
- `get_player_totals` - Aggregated player statistics
- `get_player_histograms` - Distribution of matches across statistical fields

### Hero Tools (4 tools)
Access hero information, matchups, and item builds:
- `get_heroes` - List all heroes with attributes
- `get_hero_matchups` - Matchup data and win rates
- `get_hero_item_popularity` - Popular item builds by game phase
- `get_hero_stats` - Aggregated hero statistics and pick rates

### Match Tools (3 tools)
Retrieve detailed match information and parsed data:
- `get_match_details` - Comprehensive match information
- `get_parsed_match_details` - Parsed match data with advanced analytics
- `get_player_recent_matches` - Recent matches for a player

### Lookup Tools (4 tools)
Convert names to IDs with fuzzy matching:
- `get_hero_id_by_name` - Hero name → ID (handles typos)
- `get_hero_by_id` - Get hero details by ID
- `convert_lane_name_to_id` - Lane/position → lane_role ID
- `resolve_time_name` - Time period names → OpenDota filter parameters

### Misc Tools (3 tools)
Search and utility functions:
- `search_players` - Search for players by name
- `get_constants` - Get OpenDota constants and reference data
- `get_player_counts` - Get player count by rank tier

## Installation

### Prerequisites
- Python 3.10 or higher
- pip package manager

### Install from Source

```bash
# Clone the repository
git clone https://github.com/hkaanengin/opendota-mcp-server.git
cd opendota-mcp-server

# Create virtual environment
python3 -m venv .venv
source .venv/bin/activate  # On Windows: .venv\Scripts\activate

# Install with dev dependencies
pip install -e ".[dev]"

# Or install runtime only
pip install -e .
```

## Usage

### Option 1: Local Server (stdio mode)

Best for Claude Desktop integration on your local machine.

#### Using Claude Desktop

**Config file location:**
- macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
- Windows: `%APPDATA%\Claude\claude_desktop_config.json`
- Linux: `~/.config/Claude/claude_desktop_config.json`

**Recommended: Using the installed command**

After running `pip install -e .`, add to your `claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "opendota": {
      "command": "/path/to/your/opendota-mcp-server/.venv/bin/opendota-mcp"
    }
  }
}
```

> **Note:** Replace `/path/to/your/opendota-mcp-server` with the actual path where you cloned this repository. On macOS/Linux, run `pwd` in the project directory to find this path. On Windows, run `cd` to see the full path.

**Alternative: Using Python module directly**

```json
{
  "mcpServers": {
    "opendota": {
      "command": "/path/to/your/opendota-mcp-server/.venv/bin/python",
      "args": ["-m", "opendota_mcp.server"]
    }
  }
}
```

**Alternative: Using the shell script**

```json
{
  "mcpServers": {
    "opendota": {
      "command": "/path/to/your/opendota-mcp-server/start_mcp.sh"
    }
  }
}
```

**Using Docker:**

```json
{
  "mcpServers": {
    "opendota": {
      "command": "docker",
      "args": [
        "run",
        "-i",
        "--rm",
        "-e", "MCP_TRANSPORT=stdio",
        "hkaanengin/opendota-mcp-server:latest"
      ]
    }
  }
}
```

After updating the config:
1. Save the file
2. Restart Claude Desktop completely
3. Start a new conversation
4. Your OpenDota tools should now be available!

#### Manual Testing

```bash
# Run the server directly
opendota-mcp

# Or using Python module
python -m opendota_mcp.server

# Or using the shell script
./start_mcp.sh
```

### Option 2: Remote Server (HTTP mode)

Access a deployed server from anywhere.

#### Public Server

Use the publicly deployed server at:
```
https://opendota-mcp-server-jylza6gata-ew.a.run.app/mcp
```

#### Claude Desktop (Remote Connection)

Add to your `claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "opendota": {
      "command": "npx",
      "args": [
        "-y",
        "@modelcontextprotocol/server-remote-http",
        "https://opendota-mcp-server-jylza6gata-ew.a.run.app/mcp"
      ]
    }
  }
}
```

#### Claude.ai Web Interface

1. Go to Claude.ai → Settings → MCP Servers
2. Click "Add Server"
3. Enter Server URL: `https://opendota-mcp-server-jylza6gata-ew.a.run.app/mcp`
4. Save and start chatting!

### Option 3: Deploy Your Own

Deploy to Google Cloud Run or any container platform:

```bash
# Build Docker image
docker build -t opendota-mcp-server .

# Run in HTTP mode
docker run -p 8080:8080 \
  -e MCP_TRANSPORT=http \
  -e PORT=8080 \
  opendota-mcp-server
```

## Configuration

### Environment Variables

Create a `.env` file in the project root (or copy from `.env.example`):

```env
# OpenDota API Key (optional)
# Get your API key from: https://www.opendota.com/api-keys
OPENDOTA_API_KEY=

# Logging level (DEBUG, INFO, WARNING, ERROR)
LOG_LEVEL=INFO

# Transport mode (stdio or http)
MCP_TRANSPORT=stdio

# HTTP server port (for HTTP mode)
PORT=8080
```

### OpenDota API Key (Optional)

An API key is **optional** but recommended for higher rate limits and better performance.

**Rate Limits:**
- **Without API key**: 60 requests/minute (anonymous)
- **With API key**: Higher limits for registered users

**How to get an API key:**

1. Visit [https://www.opendota.com/api-keys](https://www.opendota.com/api-keys)
2. Sign in with your Steam account
3. Click "Create API Key"
4. Copy the generated API key
5. Add it to your `.env` file:
   ```env
   OPENDOTA_API_KEY=your-api-key-here
   ```
6. Restart the server

The server will automatically detect and use the API key when configured. You'll see a confirmation message in the logs:
```
✅ OpenDota API key configured (higher rate limits enabled)
```

## Contributing

Contributions are welcome! Please:

1. Fork the repository
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request

## Acknowledgments

- [OpenDota](https://www.opendota.com/) for providing the excellent Dota 2 API
- [FastMCP](https://github.com/jlowin/fastmcp) for the MCP framework
- The Model Context Protocol team at Anthropic
- The Dota 2 community

## Support

For issues, questions, or contributions:
- Open an issue on [GitHub](https://github.com/hkaanengin/opendota-mcp-server/issues)
- Check existing issues for solutions
- Review the [OpenDota API documentation](https://docs.opendota.com)

---

**Made with ❤️ for the Dota 2 community**

TDQS

A4.5/5.0

Scored across 18 tools

Disambiguation5/5

Each tool targets a distinct resource: player profile, win/loss, heroes, totals, histograms, peers, match details, heroes, items, aghs upgrades, matchups, item popularity, benchmarks, records, and scenario timings. The descriptions explicitly cross-reference similar tools to prevent confusion, e.g., 'For simple win/loss counts, use get_player_win_loss() instead'.

Naming Consistency4/5

All tools use a 'get_' prefix except for request_parse_match, which breaks the pattern. While most names are clear and consistent (get_player_*, get_hero_*, get_scenarios_*), minor grammatical variations like get_heroes_played (past participle) and get_player_win_loss (compound noun) create slight inconsistency.

Tool Count4/5

18 tools is slightly above the typical well-scoped range of 3-15, but justified given the broad Dota 2 domain covering players, matches, heroes, items, records, and scenarios. The count is manageable and each tool has a unique purpose, though it borders on heavy.

Completeness4/5

The toolset covers the core lifecycle: player overview, detailed match info (including parse request), hero reference, item reference, and various analytics. Minor gaps exist (no list-all-heroes/items tool, no opponent-only stats, no global hero tier list), but agents can work around these using the provided tools.

Maintenance

ActivityInactive
ResponsivenessNo issues