rivalsdata-api 1.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- rivalsdata_api-1.0.0/.github/workflows/publish-pypi.yml +22 -0
- rivalsdata_api-1.0.0/.gitignore +8 -0
- rivalsdata_api-1.0.0/CONTRIBUTING.md +88 -0
- rivalsdata_api-1.0.0/LICENSE +21 -0
- rivalsdata_api-1.0.0/PKG-INFO +189 -0
- rivalsdata_api-1.0.0/README.md +154 -0
- rivalsdata_api-1.0.0/docs/API.md +90 -0
- rivalsdata_api-1.0.0/docs/PROJECT_CONTEXT.md +107 -0
- rivalsdata_api-1.0.0/pyproject.toml +51 -0
- rivalsdata_api-1.0.0/src/rivalsdata/__init__.py +22 -0
- rivalsdata_api-1.0.0/src/rivalsdata/client.py +282 -0
- rivalsdata_api-1.0.0/src/rivalsdata/exceptions.py +13 -0
- rivalsdata_api-1.0.0/src/rivalsdata/mcp_server.py +444 -0
- rivalsdata_api-1.0.0/src/rivalsdata/models.py +172 -0
- rivalsdata_api-1.0.0/src/rivalsdata/resources.py +248 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
publish:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
environment:
|
|
11
|
+
name: pypi
|
|
12
|
+
url: https://pypi.org/p/rivalsdata-api
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@v4
|
|
15
|
+
- uses: actions/setup-python@v5
|
|
16
|
+
with:
|
|
17
|
+
python-version: '3.x'
|
|
18
|
+
- run: python -m pip install build
|
|
19
|
+
- run: python -m build
|
|
20
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
21
|
+
with:
|
|
22
|
+
password: ${{ secrets.PYPI_API_TOKEN }}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
Thanks for helping improve rivalsdata-api. The client relies on undocumented
|
|
4
|
+
RivalsData endpoints, so contributions should keep requests conservative and
|
|
5
|
+
record how endpoint behavior was observed.
|
|
6
|
+
|
|
7
|
+
## Development setup
|
|
8
|
+
|
|
9
|
+
Use an isolated virtual environment:
|
|
10
|
+
|
|
11
|
+
```console
|
|
12
|
+
python -m venv .venv
|
|
13
|
+
# Windows PowerShell
|
|
14
|
+
.venv\Scripts\Activate.ps1
|
|
15
|
+
# macOS or Linux
|
|
16
|
+
source .venv/bin/activate
|
|
17
|
+
python -m pip install --upgrade pip
|
|
18
|
+
python -m pip install -e '.[dev]'
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Install the optional browser dependencies only when working on Camoufox:
|
|
22
|
+
|
|
23
|
+
```console
|
|
24
|
+
python -m pip install -e '.[browser,dev]'
|
|
25
|
+
python -m camoufox fetch
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
The browser extra does not include GeoIP support because the project does not
|
|
29
|
+
need geographic spoofing. A virtual environment also prevents this package's
|
|
30
|
+
dependencies from changing unrelated applications installed in system Python.
|
|
31
|
+
|
|
32
|
+
## Project map
|
|
33
|
+
|
|
34
|
+
- `src/rivalsdata/client.py`: HTTP client, username resolution, UID lookup,
|
|
35
|
+
shared GET/POST handling, and the optional Camoufox retry.
|
|
36
|
+
- `src/rivalsdata/models.py`: mapping-compatible response models and the typed
|
|
37
|
+
`Player` wrapper.
|
|
38
|
+
- `src/rivalsdata/resources.py`: lazy player and site-wide endpoint resources.
|
|
39
|
+
- `src/rivalsdata/exceptions.py`: public exception types.
|
|
40
|
+
- `src/rivalsdata/__init__.py`: package exports and version.
|
|
41
|
+
- `pyproject.toml`: build backend, package metadata, runtime and optional
|
|
42
|
+
dependencies.
|
|
43
|
+
- `docs/API.md`: observed site sections, endpoint inventory, response samples,
|
|
44
|
+
and open questions.
|
|
45
|
+
- `docs/PROJECT_CONTEXT.md`: contributor and new-chat handoff notes.
|
|
46
|
+
|
|
47
|
+
## How the client currently works
|
|
48
|
+
|
|
49
|
+
The client uses curl_cffi with browser TLS impersonation against
|
|
50
|
+
`https://api.rivalsdata.com`:
|
|
51
|
+
|
|
52
|
+
- `POST /players/search` with JSON `{"name": "..."}` returns search
|
|
53
|
+
suggestions. Search records include an `aid`, such as
|
|
54
|
+
`11001_1970288503`; the final numeric segment is the profile UID.
|
|
55
|
+
- `POST /player` with JSON `{"uid": 1970288503}` returns a typed `Player`
|
|
56
|
+
object. Profile keys work as both mapping values and attributes.
|
|
57
|
+
- Resource managers cover public leaderboard, hero, team-up, insight, faction,
|
|
58
|
+
match, and player-tab endpoints. See `docs/API.md` for the current inventory.
|
|
59
|
+
- If these requests are blocked and `use_browser_fallback=True`, the client
|
|
60
|
+
loads RivalsData in Camoufox and retries the POST from the page context.
|
|
61
|
+
|
|
62
|
+
These are observed implementation details, not a supported RivalsData contract.
|
|
63
|
+
Do not assume that `aid` formats, filters, routes, or JSON fields are permanent.
|
|
64
|
+
|
|
65
|
+
## Contribution workflow
|
|
66
|
+
|
|
67
|
+
1. Check the existing public API and exception behavior before changing it.
|
|
68
|
+
2. Keep changes focused, typed, and documented. Avoid adding new runtime
|
|
69
|
+
dependencies unless the feature needs them.
|
|
70
|
+
3. For endpoint changes, note the page or action that exposed the route and
|
|
71
|
+
the request shape. Never commit cookies, tokens, or browser profile data.
|
|
72
|
+
4. Add or update automated tests for behavior changes. Keep network-dependent
|
|
73
|
+
checks opt-in; routine tests should use mocked HTTP responses. The initial
|
|
74
|
+
repository does not yet include an automated test suite.
|
|
75
|
+
5. Run the checks for the code you changed:
|
|
76
|
+
|
|
77
|
+
```console
|
|
78
|
+
python -m pytest
|
|
79
|
+
ruff check .
|
|
80
|
+
python -m build
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
6. Update the README and project context if user-facing methods, dependencies,
|
|
84
|
+
routes, or setup steps changed.
|
|
85
|
+
|
|
86
|
+
There is no live API compatibility guarantee. If RivalsData changes a route,
|
|
87
|
+
prefer a clear typed error over returning an empty profile or silently
|
|
88
|
+
mislabeling a search result.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 rivalsdata-api contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: rivalsdata-api
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Python client and MCP server for public Marvel Rivals stats from RivalsData
|
|
5
|
+
Project-URL: Homepage, https://github.com/GS-Rionnag/rivalsdata-api
|
|
6
|
+
Project-URL: Repository, https://github.com/GS-Rionnag/rivalsdata-api
|
|
7
|
+
Project-URL: Issues, https://github.com/GS-Rionnag/rivalsdata-api/issues
|
|
8
|
+
Project-URL: Changelog, https://github.com/GS-Rionnag/rivalsdata-api/releases
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: api-client,game-stats,marvel-rivals,mcp,rivalsdata
|
|
12
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Topic :: Games/Entertainment
|
|
22
|
+
Classifier: Topic :: Internet :: WWW/HTTP
|
|
23
|
+
Requires-Python: >=3.10
|
|
24
|
+
Requires-Dist: curl-cffi>=0.7
|
|
25
|
+
Provides-Extra: browser
|
|
26
|
+
Requires-Dist: camoufox>=0.5.6; extra == 'browser'
|
|
27
|
+
Provides-Extra: dev
|
|
28
|
+
Requires-Dist: build>=1.2; extra == 'dev'
|
|
29
|
+
Requires-Dist: pytest>=8; extra == 'dev'
|
|
30
|
+
Requires-Dist: ruff>=0.11; extra == 'dev'
|
|
31
|
+
Provides-Extra: mcp
|
|
32
|
+
Requires-Dist: mcp-ui-server>=1.0.0; extra == 'mcp'
|
|
33
|
+
Requires-Dist: mcp<2,>=1.12; extra == 'mcp'
|
|
34
|
+
Description-Content-Type: text/markdown
|
|
35
|
+
|
|
36
|
+
# rivalsdata-api
|
|
37
|
+
|
|
38
|
+
An unofficial Python client for RivalsData's public Marvel Rivals data. It
|
|
39
|
+
uses the site's undocumented API, so routes and fields can change. The client
|
|
40
|
+
keeps unknown response fields accessible instead of discarding them.
|
|
41
|
+
|
|
42
|
+
## Install
|
|
43
|
+
|
|
44
|
+
Python 3.10 or newer:
|
|
45
|
+
|
|
46
|
+
```console
|
|
47
|
+
python -m pip install rivalsdata-api
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
For editable development, clone the repository and run
|
|
51
|
+
`python -m pip install -e '.[dev]'`. The optional Camoufox Cloudflare fallback
|
|
52
|
+
is installed with `python -m pip install 'rivalsdata-api[browser]'`, followed
|
|
53
|
+
by `python -m camoufox fetch`.
|
|
54
|
+
|
|
55
|
+
## Quick start
|
|
56
|
+
|
|
57
|
+
```python
|
|
58
|
+
from rivalsdata import RivalsDataClient
|
|
59
|
+
|
|
60
|
+
with RivalsDataClient() as rd:
|
|
61
|
+
player = rd.get_player("GS-") # numeric UID works too
|
|
62
|
+
print(player.name, player.level, player.rank_game_season)
|
|
63
|
+
|
|
64
|
+
# Player profile sections are lazy resource managers.
|
|
65
|
+
hero_season = player.heroes.fetch(season=20)
|
|
66
|
+
map_stats = player.stats.maps(season=20)
|
|
67
|
+
match_page = player.matches.fetch(season=20)
|
|
68
|
+
|
|
69
|
+
# Current match (None if the profile is not currently in a game).
|
|
70
|
+
live_game = player.live_game.fetch()
|
|
71
|
+
if live_game is not None:
|
|
72
|
+
print(live_game.players, live_game.team_avg_rank)
|
|
73
|
+
|
|
74
|
+
# Site-wide resources are available from the client.
|
|
75
|
+
leaderboard = rd.leaderboards.fetch(limit=100, season=20, platform=1)
|
|
76
|
+
tier_list = rd.heroes.tier_list(platform=1, rank="grandmaster_plus")
|
|
77
|
+
team_ups = rd.team_ups.fetch(platform=1, rank="grandmaster_plus")
|
|
78
|
+
xp_page = rd.insights.xp()
|
|
79
|
+
|
|
80
|
+
print(hero_season[0].win_rate) # integer percent when wins/losses are present
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## MCP server (ChatGPT and Claude)
|
|
84
|
+
|
|
85
|
+
Install the MCP extra and the package:
|
|
86
|
+
|
|
87
|
+
```console
|
|
88
|
+
python -m pip install 'rivalsdata-api[mcp]'
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
The server exposes read-only tools for player search and profiles, a player's
|
|
92
|
+
current live match (when they are in one), match history, player stats,
|
|
93
|
+
leaderboards, heroes, team-ups, public insights, matches, and factions. The
|
|
94
|
+
`show_player_dashboard` tool also returns an MCP-UI player report with rank and
|
|
95
|
+
competitive record, current match roster split by side, a hero win-rate chart,
|
|
96
|
+
and recent match form with K/D/A. It supports local stdio for Claude Desktop
|
|
97
|
+
and Streamable HTTP for remote MCP clients such as ChatGPT. Data comes from
|
|
98
|
+
RivalsData's undocumented API and may change; profile match history can be
|
|
99
|
+
private.
|
|
100
|
+
|
|
101
|
+
### How the MCP UI works
|
|
102
|
+
|
|
103
|
+
`show_player_dashboard` fetches current data, then returns an HTML UI resource
|
|
104
|
+
alongside the tool result. MCP-UI labels it with a `ui://` resource URI and
|
|
105
|
+
preferred size. A compatible host can render that resource in a sandboxed
|
|
106
|
+
panel; a host without UI support can still use the regular MCP tools and their
|
|
107
|
+
text/data responses. ChatGPT uses MCP-UI's Apps SDK adapter, while Claude is
|
|
108
|
+
listed as supporting MCP Apps directly. The dashboard is a snapshot from the
|
|
109
|
+
time the tool runs; ask for it again to refresh.
|
|
110
|
+
|
|
111
|
+
### Claude Desktop (local)
|
|
112
|
+
|
|
113
|
+
Add a server entry to Claude Desktop's `claude_desktop_config.json`, replacing
|
|
114
|
+
the path with the Python executable in the environment where the extra is
|
|
115
|
+
installed:
|
|
116
|
+
|
|
117
|
+
```json
|
|
118
|
+
{
|
|
119
|
+
"mcpServers": {
|
|
120
|
+
"rivalsdata": {
|
|
121
|
+
"command": "C:\\path\\to\\venv\\Scripts\\python.exe",
|
|
122
|
+
"args": ["-m", "rivalsdata.mcp_server"]
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
On macOS/Linux, use the environment's `bin/python` path. Restart Claude Desktop
|
|
129
|
+
after saving the configuration.
|
|
130
|
+
|
|
131
|
+
### ChatGPT or remote Claude connector
|
|
132
|
+
|
|
133
|
+
Run the server on a host reachable over HTTPS:
|
|
134
|
+
|
|
135
|
+
```console
|
|
136
|
+
rivalsdata-mcp --transport streamable-http --host 0.0.0.0 --port 8000
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
The MCP endpoint is `/mcp` (for example, `https://your-host.example/mcp`). Add
|
|
140
|
+
that endpoint through the client's custom/remote MCP connector settings. The
|
|
141
|
+
server does not implement authentication; put it behind an authenticated
|
|
142
|
+
HTTPS gateway before exposing it publicly. For local development, bind to
|
|
143
|
+
`127.0.0.1` instead. Use `python -m rivalsdata.mcp_server --help` to see options.
|
|
144
|
+
|
|
145
|
+
`Player` and returned `DataModel` objects support both mapping access and
|
|
146
|
+
attribute access (`player["level"]` or `player.level`). Nested dictionaries
|
|
147
|
+
and arrays are wrapped recursively; `.raw` returns a shallow copy of a model's
|
|
148
|
+
original JSON. For endpoints whose fields evolve, these generic typed wrappers
|
|
149
|
+
preserve the complete payload.
|
|
150
|
+
|
|
151
|
+
## Public resources
|
|
152
|
+
|
|
153
|
+
- `rd.leaderboards.fetch(...)` — global player ranking.
|
|
154
|
+
- `rd.heroes.tier_list(...)`, `.get(hero_id)`, `.meta(hero_id, range=90)`,
|
|
155
|
+
`.leaderboard(hero_id, **filters)` — hero metrics and ranking.
|
|
156
|
+
- `rd.team_ups.fetch(...)` — team-up stats.
|
|
157
|
+
- `rd.insights.punishments(...)`, `.xp(...)`, `.top_500(...)`, `.commbans(...)`,
|
|
158
|
+
`.leavers(...)` — public insights and cursor metadata.
|
|
159
|
+
- `rd.factions.get(faction_id)`, `rd.matches.get(match_id)`,
|
|
160
|
+
`rd.profiles.get(username)`, and `rd.favorites.fetch(uids)` — detail/profile
|
|
161
|
+
lookups.
|
|
162
|
+
- `player.heroes.fetch(...)`, `.matches.fetch(...)`, `.live_game.fetch()`, `.teammates.fetch(...)`,
|
|
163
|
+
`.crosshairs.fetch()`, `.proficiency.fetch()`, `.punishments.fetch()`,
|
|
164
|
+
`.name_history.fetch()` — profile sections.
|
|
165
|
+
- `player.stats.heroes(...)`, `.maps(...)`, `.bans(...)` — detailed profile stats.
|
|
166
|
+
|
|
167
|
+
See [the observed API inventory](docs/API.md) for methods, parameters, observed
|
|
168
|
+
response shapes, and endpoints that require a RivalsData account. The API
|
|
169
|
+
inventory distinguishes observed behavior from inferred/unverified details.
|
|
170
|
+
|
|
171
|
+
## Cloudflare fallback
|
|
172
|
+
|
|
173
|
+
Requests use curl_cffi with a Chrome TLS profile by default. If blocked, enable
|
|
174
|
+
the optional browser fallback:
|
|
175
|
+
|
|
176
|
+
```python
|
|
177
|
+
with RivalsDataClient(use_browser_fallback=True) as rd:
|
|
178
|
+
player = rd.get_player(1970288503)
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
## Errors and contributions
|
|
182
|
+
|
|
183
|
+
All package exceptions inherit from `RivalsDataError`. See
|
|
184
|
+
[CONTRIBUTING.md](CONTRIBUTING.md) for setup, code layout, change workflow, and
|
|
185
|
+
notes for new contributors. [docs/PROJECT_CONTEXT.md](docs/PROJECT_CONTEXT.md)
|
|
186
|
+
is the handoff document for new coding sessions.
|
|
187
|
+
|
|
188
|
+
This project is not affiliated with RivalsData, NetEase, or Marvel. Keep
|
|
189
|
+
request rates reasonable and respect the site's terms.
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
# rivalsdata-api
|
|
2
|
+
|
|
3
|
+
An unofficial Python client for RivalsData's public Marvel Rivals data. It
|
|
4
|
+
uses the site's undocumented API, so routes and fields can change. The client
|
|
5
|
+
keeps unknown response fields accessible instead of discarding them.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
Python 3.10 or newer:
|
|
10
|
+
|
|
11
|
+
```console
|
|
12
|
+
python -m pip install rivalsdata-api
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
For editable development, clone the repository and run
|
|
16
|
+
`python -m pip install -e '.[dev]'`. The optional Camoufox Cloudflare fallback
|
|
17
|
+
is installed with `python -m pip install 'rivalsdata-api[browser]'`, followed
|
|
18
|
+
by `python -m camoufox fetch`.
|
|
19
|
+
|
|
20
|
+
## Quick start
|
|
21
|
+
|
|
22
|
+
```python
|
|
23
|
+
from rivalsdata import RivalsDataClient
|
|
24
|
+
|
|
25
|
+
with RivalsDataClient() as rd:
|
|
26
|
+
player = rd.get_player("GS-") # numeric UID works too
|
|
27
|
+
print(player.name, player.level, player.rank_game_season)
|
|
28
|
+
|
|
29
|
+
# Player profile sections are lazy resource managers.
|
|
30
|
+
hero_season = player.heroes.fetch(season=20)
|
|
31
|
+
map_stats = player.stats.maps(season=20)
|
|
32
|
+
match_page = player.matches.fetch(season=20)
|
|
33
|
+
|
|
34
|
+
# Current match (None if the profile is not currently in a game).
|
|
35
|
+
live_game = player.live_game.fetch()
|
|
36
|
+
if live_game is not None:
|
|
37
|
+
print(live_game.players, live_game.team_avg_rank)
|
|
38
|
+
|
|
39
|
+
# Site-wide resources are available from the client.
|
|
40
|
+
leaderboard = rd.leaderboards.fetch(limit=100, season=20, platform=1)
|
|
41
|
+
tier_list = rd.heroes.tier_list(platform=1, rank="grandmaster_plus")
|
|
42
|
+
team_ups = rd.team_ups.fetch(platform=1, rank="grandmaster_plus")
|
|
43
|
+
xp_page = rd.insights.xp()
|
|
44
|
+
|
|
45
|
+
print(hero_season[0].win_rate) # integer percent when wins/losses are present
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## MCP server (ChatGPT and Claude)
|
|
49
|
+
|
|
50
|
+
Install the MCP extra and the package:
|
|
51
|
+
|
|
52
|
+
```console
|
|
53
|
+
python -m pip install 'rivalsdata-api[mcp]'
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
The server exposes read-only tools for player search and profiles, a player's
|
|
57
|
+
current live match (when they are in one), match history, player stats,
|
|
58
|
+
leaderboards, heroes, team-ups, public insights, matches, and factions. The
|
|
59
|
+
`show_player_dashboard` tool also returns an MCP-UI player report with rank and
|
|
60
|
+
competitive record, current match roster split by side, a hero win-rate chart,
|
|
61
|
+
and recent match form with K/D/A. It supports local stdio for Claude Desktop
|
|
62
|
+
and Streamable HTTP for remote MCP clients such as ChatGPT. Data comes from
|
|
63
|
+
RivalsData's undocumented API and may change; profile match history can be
|
|
64
|
+
private.
|
|
65
|
+
|
|
66
|
+
### How the MCP UI works
|
|
67
|
+
|
|
68
|
+
`show_player_dashboard` fetches current data, then returns an HTML UI resource
|
|
69
|
+
alongside the tool result. MCP-UI labels it with a `ui://` resource URI and
|
|
70
|
+
preferred size. A compatible host can render that resource in a sandboxed
|
|
71
|
+
panel; a host without UI support can still use the regular MCP tools and their
|
|
72
|
+
text/data responses. ChatGPT uses MCP-UI's Apps SDK adapter, while Claude is
|
|
73
|
+
listed as supporting MCP Apps directly. The dashboard is a snapshot from the
|
|
74
|
+
time the tool runs; ask for it again to refresh.
|
|
75
|
+
|
|
76
|
+
### Claude Desktop (local)
|
|
77
|
+
|
|
78
|
+
Add a server entry to Claude Desktop's `claude_desktop_config.json`, replacing
|
|
79
|
+
the path with the Python executable in the environment where the extra is
|
|
80
|
+
installed:
|
|
81
|
+
|
|
82
|
+
```json
|
|
83
|
+
{
|
|
84
|
+
"mcpServers": {
|
|
85
|
+
"rivalsdata": {
|
|
86
|
+
"command": "C:\\path\\to\\venv\\Scripts\\python.exe",
|
|
87
|
+
"args": ["-m", "rivalsdata.mcp_server"]
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
On macOS/Linux, use the environment's `bin/python` path. Restart Claude Desktop
|
|
94
|
+
after saving the configuration.
|
|
95
|
+
|
|
96
|
+
### ChatGPT or remote Claude connector
|
|
97
|
+
|
|
98
|
+
Run the server on a host reachable over HTTPS:
|
|
99
|
+
|
|
100
|
+
```console
|
|
101
|
+
rivalsdata-mcp --transport streamable-http --host 0.0.0.0 --port 8000
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
The MCP endpoint is `/mcp` (for example, `https://your-host.example/mcp`). Add
|
|
105
|
+
that endpoint through the client's custom/remote MCP connector settings. The
|
|
106
|
+
server does not implement authentication; put it behind an authenticated
|
|
107
|
+
HTTPS gateway before exposing it publicly. For local development, bind to
|
|
108
|
+
`127.0.0.1` instead. Use `python -m rivalsdata.mcp_server --help` to see options.
|
|
109
|
+
|
|
110
|
+
`Player` and returned `DataModel` objects support both mapping access and
|
|
111
|
+
attribute access (`player["level"]` or `player.level`). Nested dictionaries
|
|
112
|
+
and arrays are wrapped recursively; `.raw` returns a shallow copy of a model's
|
|
113
|
+
original JSON. For endpoints whose fields evolve, these generic typed wrappers
|
|
114
|
+
preserve the complete payload.
|
|
115
|
+
|
|
116
|
+
## Public resources
|
|
117
|
+
|
|
118
|
+
- `rd.leaderboards.fetch(...)` — global player ranking.
|
|
119
|
+
- `rd.heroes.tier_list(...)`, `.get(hero_id)`, `.meta(hero_id, range=90)`,
|
|
120
|
+
`.leaderboard(hero_id, **filters)` — hero metrics and ranking.
|
|
121
|
+
- `rd.team_ups.fetch(...)` — team-up stats.
|
|
122
|
+
- `rd.insights.punishments(...)`, `.xp(...)`, `.top_500(...)`, `.commbans(...)`,
|
|
123
|
+
`.leavers(...)` — public insights and cursor metadata.
|
|
124
|
+
- `rd.factions.get(faction_id)`, `rd.matches.get(match_id)`,
|
|
125
|
+
`rd.profiles.get(username)`, and `rd.favorites.fetch(uids)` — detail/profile
|
|
126
|
+
lookups.
|
|
127
|
+
- `player.heroes.fetch(...)`, `.matches.fetch(...)`, `.live_game.fetch()`, `.teammates.fetch(...)`,
|
|
128
|
+
`.crosshairs.fetch()`, `.proficiency.fetch()`, `.punishments.fetch()`,
|
|
129
|
+
`.name_history.fetch()` — profile sections.
|
|
130
|
+
- `player.stats.heroes(...)`, `.maps(...)`, `.bans(...)` — detailed profile stats.
|
|
131
|
+
|
|
132
|
+
See [the observed API inventory](docs/API.md) for methods, parameters, observed
|
|
133
|
+
response shapes, and endpoints that require a RivalsData account. The API
|
|
134
|
+
inventory distinguishes observed behavior from inferred/unverified details.
|
|
135
|
+
|
|
136
|
+
## Cloudflare fallback
|
|
137
|
+
|
|
138
|
+
Requests use curl_cffi with a Chrome TLS profile by default. If blocked, enable
|
|
139
|
+
the optional browser fallback:
|
|
140
|
+
|
|
141
|
+
```python
|
|
142
|
+
with RivalsDataClient(use_browser_fallback=True) as rd:
|
|
143
|
+
player = rd.get_player(1970288503)
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## Errors and contributions
|
|
147
|
+
|
|
148
|
+
All package exceptions inherit from `RivalsDataError`. See
|
|
149
|
+
[CONTRIBUTING.md](CONTRIBUTING.md) for setup, code layout, change workflow, and
|
|
150
|
+
notes for new contributors. [docs/PROJECT_CONTEXT.md](docs/PROJECT_CONTEXT.md)
|
|
151
|
+
is the handoff document for new coding sessions.
|
|
152
|
+
|
|
153
|
+
This project is not affiliated with RivalsData, NetEase, or Marvel. Keep
|
|
154
|
+
request rates reasonable and respect the site's terms.
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# RivalsData API inventory
|
|
2
|
+
|
|
3
|
+
This is an observed inventory of the public web client's API, gathered by
|
|
4
|
+
reviewing the RivalsData UI and its browser requests on 2026-09-29. The upstream
|
|
5
|
+
API is undocumented and can change. Field sets below are examples from live
|
|
6
|
+
responses, not schemas guaranteed by RivalsData. Response bodies are returned
|
|
7
|
+
as attribute-accessible `DataModel` / `StatRecord` objects, preserving unknown
|
|
8
|
+
keys.
|
|
9
|
+
|
|
10
|
+
## Implemented public read endpoints
|
|
11
|
+
|
|
12
|
+
| Site section | HTTP endpoint | Parameters sent by this client | Observed response |
|
|
13
|
+
| --- | --- | --- | --- |
|
|
14
|
+
| Search | `POST /players/search` | `{"name": name}` | Search rows; `aid` may contain the numeric UID after the final `_`. |
|
|
15
|
+
| Player overview | `POST /player` | `{"uid": number}` | Object keys observed: `cached_at`, `claimed`, `faction`, `icon`, `last_seen`, `leaderboard`, `level`, `login_os`, `match_history_is_visible`, `mood`, `name`, `rank_game_season`, `status`, `uid`, `xp`. `rank_game_season` is keyed by game/season ids; competitive rows include `battle_count`, `rank_game_id`, `rank_score`, and `win_count`. |
|
|
16
|
+
| Player live game | `POST /live` | `{"match_id": status.battle_id, "uid": number}` | Object keys observed: `players` (12 player entries keyed by team slot) and `team_avg_rank` (rank averages keyed by side). Player rows include `ai`, `games`, `icon`, `losses`, `name`, `proficiency`, `rank`, `side`, `team_id`, `top_heroes`, `uid`, and `wins`. The match ID comes from the player's current `/player` response; the endpoint was observed on a profile marked `In game (Competitive)`. |
|
|
17
|
+
| Player hero summary | `POST /player/heroes` | `uid`, optional `season` | Array rows: `assists`, `deaths`, `games`, `hero_id`, `kda`, `kills`, `losses`, `rank`, `wins`. |
|
|
18
|
+
| Player crosshairs | `POST /player/crosshairs` | `uid` | Array rows: `crosshair`, `uses`. |
|
|
19
|
+
| Player match history | `POST /player/matches/cached` (or `/player/matches`) | `uid`, `cursor`, optional `season`; cached endpoint also accepts `mode`, `hero`, `teammate` | Cached response keys observed: `matches`, `next_cursor`, `source`; match rows include `assists`, `deaths`, `game_mode_id`, `game_play_mode_id`, `hero_id`, `is_mvp`, `is_svp`, `is_win`, `kills`, `map_id`, `match_uid`, `os`, `placement`, `platform`, `rank_level`, `rank_score`, `score_change`, `season`, `team_score`, `timestamp`, `winner_camp`. A sample profile marked its history private; a private profile can return no visible match rows. |
|
|
20
|
+
| Player teammates | `POST /player/teammates` | `uid`, optional `season`, `mode` | Array rows: `games`, `icon`, `losses`, `name`, `teammate_uid`, `wins`. |
|
|
21
|
+
| Player proficiency | `POST /player/proficiency` | `uid` | Object keyed by account id (sample: `11001_{uid}`); inner structure varies. |
|
|
22
|
+
| Player hero stats | `POST /player/stats/heroes` | `uid`, optional `season` | Array rows: `competitive`, `hero_id`, `quickplay`, `rank`. |
|
|
23
|
+
| Player map stats | `POST /player/stats/maps` | `uid`, optional `season` | Array shape varies; captured from the profile Stats tab. |
|
|
24
|
+
| Player ban stats | `POST /player/stats/bans` | `uid`, optional `season` | Array shape varies; captured from the profile Stats tab. |
|
|
25
|
+
| Player punishments | `POST /player/punishments` | `uid` | Object keys observed: `chat`, `login`, `rank`. |
|
|
26
|
+
| Player name history | `POST /player/name-history` | `uid` | Array rows: `first_seen`, `name`. |
|
|
27
|
+
| Global leaderboard | `GET /leaderboards` | `limit`, optional `skip`, `season`, `os` (Python `platform`) | Object keys observed: `count`, `players`, `updated_at`; row keys: `heroes`, `icon`, `losses`, `name`, `os`, `position`, `rank_level`, `rank_score`, `season`, `status`, `uid`, `wins`. |
|
|
28
|
+
| Hero tier list | `GET /stats/tierlist` | `platform`, `rank` | Hero rows displayed with tier, win rate, pick rate, ban rate, and games; raw row keys preserved. |
|
|
29
|
+
| Hero detail | `GET /stats/heroes/{hero_id}` | Path parameter | Hero aggregate object; full key set varies by hero and season. |
|
|
30
|
+
| Hero trend/meta | `GET /stats/meta/{hero_id}` | `range` (30, 90, or 180 days) | Trend/analytics object; raw keys preserved. |
|
|
31
|
+
| Hero leaderboard | `GET /stats/leaderboards` | `hero` plus caller-supplied query filters | Used by hero leaderboard pages. Parameter combinations and response fields are not fully verified. |
|
|
32
|
+
| Team-up stats | `GET /stats/teamups` | `platform`, `rank`, optional `hero` | Team-up usage and win-rate rows; raw keys preserved. |
|
|
33
|
+
| Punishments log | `GET /stats/punishments` | `kind`, optional `cursor` | Object: `last_update`, `next`, `results`; sample row keys: `expires_at`, `icon`, `issued_at`, `kind`, `name`, `peak_rank_level`, `peak_rank_score`, `rank`, `reason`, `uid`. |
|
|
34
|
+
| XP leaderboard | `GET /stats/xp` | Optional `cursor` | Object: `last_update`, `next`, `results`; sample row keys: `icon`, `name`, `rank`, `uid`, `xp`. |
|
|
35
|
+
| Top 500 finishes | `GET /stats/oaa` | `os` (Python `platform`) | Object: `count`, `last_update`, `os`, `players`; sample row keys: `avg_placement`, `avg_score`, `finishes`, `icon`, `name`, `seasons`, `uid`. |
|
|
36
|
+
| Hero comm-ban insight | `GET /stats/commbans` | `mode` (`all` or `competitive`) | Object: `heroes`, `last_update`, `mode`, `overall_pct`; hero rows: `ci95`, `hero_id`, `pct`, `qualifying_players`, `vs_avg`, `weighted_banned`, `weighted_players`. |
|
|
37
|
+
| Hero AFK insight | `GET /stats/leavers` | `mode` (`all` or `competitive`) | Object: `heroes`, `last_update`, `mode`, `overall_pct`; hero rows: `ci95`, `games`, `hero_id`, `leaves`, `leaves_per_player`, `pct`, `players`, `vs_avg`. |
|
|
38
|
+
| Faction details | `GET /faction/{faction_id}` | Path parameter | Faction overview, public profile/member list, and results; nested schema varies. |
|
|
39
|
+
| Match details | `POST /match` | `{"match_id": "..."}` | Object keys observed: `match_uid`, `replay_id`, `winner_camp`, `duration_seconds`, `map_id`, `game_mode_id`, `game_play_mode_id`, `platform`, `timestamp`, `draft`, `teams`; team player rows include combat stats and per-hero usage. |
|
|
40
|
+
| Public profile card | `GET /profiles/{username}` | Username path parameter | Route observed in the profile frontend; complete response schema not captured. |
|
|
41
|
+
| Favorites lookup | `POST /favorites` | `{"uids": [uid, ...]}` | Request observed in frontend assets; response schema not captured. |
|
|
42
|
+
|
|
43
|
+
The client exposes these read resources through `RivalsDataClient` and `Player`;
|
|
44
|
+
see README examples and method docstrings. `DataModel.win_rate` returns an
|
|
45
|
+
integer percentage from a direct win-rate field, `wins`/`losses`, or the
|
|
46
|
+
competitive profile row's `win_count`/`battle_count`. If the source provides
|
|
47
|
+
none of these, it returns `None`.
|
|
48
|
+
|
|
49
|
+
## Observed UI and routes
|
|
50
|
+
|
|
51
|
+
| UI route | What the UI exposes |
|
|
52
|
+
| --- | --- |
|
|
53
|
+
| `/` | Search, top leaderboard, favorites, top heroes, and top team-ups. |
|
|
54
|
+
| `/leaderboard` | Name filter, online-only switch, platform, season, refresh, and player rows. |
|
|
55
|
+
| `/stats` | Hero tier list with rank/platform/role filters and tier/win/pick/ban/games sorting. |
|
|
56
|
+
| `/team-ups` | Team-up pairings with hero, rank, and platform filters. |
|
|
57
|
+
| `/insights/punishments`, `/insights/xp`, `/insights/oaa`, `/insights/toxicity`, `/insights/afk` | Punishment log, XP ranking, Top 500 finishes, hero comm-ban rate, and hero AFK rate. |
|
|
58
|
+
| `/player/{uid}` | Overview, hero summaries, teammates, crosshairs, Match History, Live Game, Proficiency, Stats, Punishments, and Name History tabs. Match History may be private. |
|
|
59
|
+
| `/heroes/{slug}/stats` | Hero statistics and selectable 30/90/180-day charts. |
|
|
60
|
+
| `/heroes/{slug}/leaderboard` | Hero-specific ranked players. |
|
|
61
|
+
| `/heroes/{slug}/counters` and `/heroes/{slug}/synergy` | The UI displayed “Coming Soon” during inspection; no public data call was observed. |
|
|
62
|
+
| `/factions/{faction_id}` | Faction description and members. |
|
|
63
|
+
| `/matches/{match_id}` | Match detail route linked from an expanded public match-history card. |
|
|
64
|
+
| `/profiles` | Account-facing profile management page. |
|
|
65
|
+
|
|
66
|
+
The Live Game tab requests `POST /live` for profiles whose `status.battle_id`
|
|
67
|
+
is set. The client exposes this as `player.live_game.fetch()`. Since game status
|
|
68
|
+
can change, load a fresh player profile before fetching; the method returns
|
|
69
|
+
`None` when that profile has no active battle ID.
|
|
70
|
+
|
|
71
|
+
## Account actions and unresolved endpoints
|
|
72
|
+
|
|
73
|
+
Frontend assets also reference `GET /profiles`, `POST /profiles/{username}/edit`,
|
|
74
|
+
`POST /bind/start`, and `POST /bind/check`. These are associated with profile
|
|
75
|
+
management and account linking. Their complete request/response contracts and
|
|
76
|
+
authentication behavior were not established. Profile edit and bind routes
|
|
77
|
+
can modify account state; they are documented here for completeness but are
|
|
78
|
+
not implemented as public methods. `GET /profiles/{username}` and
|
|
79
|
+
`POST /favorites` have thin read wrappers, but their response schemas remain
|
|
80
|
+
unverified.
|
|
81
|
+
|
|
82
|
+
Other open research items:
|
|
83
|
+
|
|
84
|
+
- Capture response bodies for the remaining Insights mode/filter variants.
|
|
85
|
+
- Verify the hero leaderboard query parameters and faction response shape from
|
|
86
|
+
real visible links.
|
|
87
|
+
- Determine whether match-history cursor pagination and the uncached route
|
|
88
|
+
remain available for accounts that have made history public.
|
|
89
|
+
- Recheck this inventory when the site changes. Do not infer a supported API
|
|
90
|
+
contract from a route string alone.
|