rivalsdata-api 1.0.0__tar.gz → 1.1.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 → rivalsdata_api-1.1.0}/PKG-INFO +58 -18
- {rivalsdata_api-1.0.0 → rivalsdata_api-1.1.0}/README.md +186 -147
- {rivalsdata_api-1.0.0 → rivalsdata_api-1.1.0}/docs/API.md +18 -16
- {rivalsdata_api-1.0.0 → rivalsdata_api-1.1.0}/docs/PROJECT_CONTEXT.md +8 -6
- {rivalsdata_api-1.0.0 → rivalsdata_api-1.1.0}/pyproject.toml +2 -5
- rivalsdata_api-1.1.0/src/rivalsdata/__init__.py +148 -0
- {rivalsdata_api-1.0.0 → rivalsdata_api-1.1.0}/src/rivalsdata/client.py +29 -7
- rivalsdata_api-1.1.0/src/rivalsdata/hero_ids.py +80 -0
- {rivalsdata_api-1.0.0 → rivalsdata_api-1.1.0}/src/rivalsdata/mcp_server.py +510 -431
- rivalsdata_api-1.1.0/src/rivalsdata/models.py +966 -0
- {rivalsdata_api-1.0.0 → rivalsdata_api-1.1.0}/src/rivalsdata/resources.py +108 -68
- rivalsdata_api-1.1.0/tests/test_hero_names.py +31 -0
- rivalsdata_api-1.1.0/tests/test_typed_responses.py +90 -0
- rivalsdata_api-1.0.0/src/rivalsdata/__init__.py +0 -22
- rivalsdata_api-1.0.0/src/rivalsdata/models.py +0 -172
- {rivalsdata_api-1.0.0 → rivalsdata_api-1.1.0}/.github/workflows/publish-pypi.yml +0 -0
- {rivalsdata_api-1.0.0 → rivalsdata_api-1.1.0}/.gitignore +0 -0
- {rivalsdata_api-1.0.0 → rivalsdata_api-1.1.0}/CONTRIBUTING.md +0 -0
- {rivalsdata_api-1.0.0 → rivalsdata_api-1.1.0}/LICENSE +0 -0
- {rivalsdata_api-1.0.0 → rivalsdata_api-1.1.0}/src/rivalsdata/exceptions.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: rivalsdata-api
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.1.0
|
|
4
4
|
Summary: Python client and MCP server for public Marvel Rivals stats from RivalsData
|
|
5
5
|
Project-URL: Homepage, https://github.com/GS-Rionnag/rivalsdata-api
|
|
6
6
|
Project-URL: Repository, https://github.com/GS-Rionnag/rivalsdata-api
|
|
@@ -31,6 +31,7 @@ Requires-Dist: ruff>=0.11; extra == 'dev'
|
|
|
31
31
|
Provides-Extra: mcp
|
|
32
32
|
Requires-Dist: mcp-ui-server>=1.0.0; extra == 'mcp'
|
|
33
33
|
Requires-Dist: mcp<2,>=1.12; extra == 'mcp'
|
|
34
|
+
Requires-Dist: uvicorn>=0.30; extra == 'mcp'
|
|
34
35
|
Description-Content-Type: text/markdown
|
|
35
36
|
|
|
36
37
|
# rivalsdata-api
|
|
@@ -55,7 +56,10 @@ by `python -m camoufox fetch`.
|
|
|
55
56
|
## Quick start
|
|
56
57
|
|
|
57
58
|
```python
|
|
58
|
-
from rivalsdata import RivalsDataClient
|
|
59
|
+
from rivalsdata import RivalsDataClient, hero_id, hero_name
|
|
60
|
+
|
|
61
|
+
print(hero_name(1016)) # Loki
|
|
62
|
+
print(hero_id("Loki")) # 1016
|
|
59
63
|
|
|
60
64
|
with RivalsDataClient() as rd:
|
|
61
65
|
player = rd.get_player("GS-") # numeric UID works too
|
|
@@ -91,22 +95,37 @@ python -m pip install 'rivalsdata-api[mcp]'
|
|
|
91
95
|
The server exposes read-only tools for player search and profiles, a player's
|
|
92
96
|
current live match (when they are in one), match history, player stats,
|
|
93
97
|
leaderboards, heroes, team-ups, public insights, matches, and factions. The
|
|
94
|
-
`show_player_dashboard` tool
|
|
95
|
-
competitive record
|
|
96
|
-
|
|
98
|
+
`show_player_dashboard` tool returns an MCP-UI player card with rank and
|
|
99
|
+
competitive record plus one optional data section per call: current match
|
|
100
|
+
roster, hero win-rate chart, or recent match form with K/D/A. This keeps each
|
|
101
|
+
dashboard pull to the profile plus at most one additional endpoint. It supports
|
|
102
|
+
local stdio for Claude Desktop
|
|
97
103
|
and Streamable HTTP for remote MCP clients such as ChatGPT. Data comes from
|
|
98
104
|
RivalsData's undocumented API and may change; profile match history can be
|
|
99
105
|
private.
|
|
100
106
|
|
|
107
|
+
Known `hero_id` and `top_hero_id` fields in MCP results include corresponding
|
|
108
|
+
`hero_name` and `top_hero_name` fields. The `resolve_hero` tool accepts either
|
|
109
|
+
a hero name or numeric ID. The pip package also exports `hero_name(id)` and
|
|
110
|
+
`hero_id(name)`; returned `DataModel` rows provide `.hero_name` and
|
|
111
|
+
`.top_hero_name` conveniences. Those resolved fields are included in mapping
|
|
112
|
+
iteration and `.to_dict()` output to simplify serialization; `.raw` remains the
|
|
113
|
+
untouched source payload.
|
|
114
|
+
|
|
101
115
|
### How the MCP UI works
|
|
102
116
|
|
|
103
117
|
`show_player_dashboard` fetches current data, then returns an HTML UI resource
|
|
104
|
-
alongside the tool result.
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
118
|
+
alongside the tool result. It advertises the dashboard through
|
|
119
|
+
`_meta.ui.resourceUri`, uses the `text/html;profile=mcp-app` resource MIME type,
|
|
120
|
+
and registers that URI for `resources/read` so the host can actually load the
|
|
121
|
+
app frame. The tool result carries the rendered dashboard as structured content
|
|
122
|
+
for the app frame and an embedded HTML resource for older MCP-UI clients. It
|
|
123
|
+
also includes `openai/outputTemplate` as a ChatGPT compatibility alias. Hosts
|
|
124
|
+
without UI support still receive a text result and can use the regular MCP
|
|
125
|
+
tools. The dashboard is a snapshot from the time the tool runs; ask for it
|
|
126
|
+
again to refresh.
|
|
127
|
+
The `section` argument defaults to `live_match`; use `hero_form` or
|
|
128
|
+
`recent_matches` in separate calls when you need those views.
|
|
110
129
|
|
|
111
130
|
### Claude Desktop (local)
|
|
112
131
|
|
|
@@ -133,20 +152,41 @@ after saving the configuration.
|
|
|
133
152
|
Run the server on a host reachable over HTTPS:
|
|
134
153
|
|
|
135
154
|
```console
|
|
136
|
-
rivalsdata
|
|
155
|
+
uvicorn rivalsdata.mcp_server:app --host 0.0.0.0 --port 8000
|
|
137
156
|
```
|
|
138
157
|
|
|
139
158
|
The MCP endpoint is `/mcp` (for example, `https://your-host.example/mcp`). Add
|
|
140
159
|
that endpoint through the client's custom/remote MCP connector settings. The
|
|
141
160
|
server does not implement authentication; put it behind an authenticated
|
|
142
161
|
HTTPS gateway before exposing it publicly. For local development, bind to
|
|
143
|
-
`127.0.0.1` instead.
|
|
162
|
+
`127.0.0.1` instead. The `app` is the MCP SDK's Streamable HTTP ASGI
|
|
163
|
+
application; Uvicorn manages its lifespan and session manager.
|
|
164
|
+
|
|
165
|
+
Every implemented response route now has named endpoint models and row models
|
|
166
|
+
with annotations for fields observed in the API inventory. This includes
|
|
167
|
+
`Player`, `Match`, `MatchHistory`, `MatchTeam`, `MatchPlayer`, `Character`,
|
|
168
|
+
`ProficiencyResponse`, `LeaderboardResponse`, `PunishmentsPage`, `XPPage`,
|
|
169
|
+
`Top500Response`, and typed teammate, crosshair, stats, faction, and insight
|
|
170
|
+
records. For example, `rd.matches.get(match_id)` returns a `Match`,
|
|
171
|
+
`player.matches.fetch()` returns a `MatchHistory`, and
|
|
172
|
+
`player.proficiency.fetch()` returns a `ProficiencyResponse`. Nested match
|
|
173
|
+
teams and participants are converted to `MatchTeam` and `MatchPlayer`; embedded
|
|
174
|
+
character records use `Character`. Models support mapping access
|
|
175
|
+
(`player["level"]`) and attribute access (`player.level`). Unknown upstream
|
|
176
|
+
fields are still preserved and available through `.raw`; endpoint schemas
|
|
177
|
+
that have not been observed completely are annotated only for known fields.
|
|
144
178
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
179
|
+
```python
|
|
180
|
+
with RivalsDataClient() as rd:
|
|
181
|
+
player = rd.get_player(1970288503) # Player
|
|
182
|
+
proficiency = player.proficiency.fetch() # ProficiencyResponse
|
|
183
|
+
account = next(iter(proficiency.accounts.values())) # Proficiency
|
|
184
|
+
hero = account.hero_proficiency_infos["1011"] # HeroProficiency
|
|
185
|
+
print(hero.proficiency_level, hero.proficiency_point)
|
|
186
|
+
|
|
187
|
+
tier_list = rd.heroes.tier_list() # TierListResponse
|
|
188
|
+
print(tier_list.heroes[0].hero_id) # Character
|
|
189
|
+
```
|
|
150
190
|
|
|
151
191
|
## Public resources
|
|
152
192
|
|
|
@@ -1,154 +1,193 @@
|
|
|
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
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
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, hero_id, hero_name
|
|
24
|
+
|
|
25
|
+
print(hero_name(1016)) # Loki
|
|
26
|
+
print(hero_id("Loki")) # 1016
|
|
27
|
+
|
|
28
|
+
with RivalsDataClient() as rd:
|
|
29
|
+
player = rd.get_player("GS-") # numeric UID works too
|
|
30
|
+
print(player.name, player.level, player.rank_game_season)
|
|
31
|
+
|
|
32
|
+
# Player profile sections are lazy resource managers.
|
|
33
|
+
hero_season = player.heroes.fetch(season=20)
|
|
34
|
+
map_stats = player.stats.maps(season=20)
|
|
35
|
+
match_page = player.matches.fetch(season=20)
|
|
36
|
+
|
|
37
|
+
# Current match (None if the profile is not currently in a game).
|
|
38
|
+
live_game = player.live_game.fetch()
|
|
39
|
+
if live_game is not None:
|
|
40
|
+
print(live_game.players, live_game.team_avg_rank)
|
|
41
|
+
|
|
42
|
+
# Site-wide resources are available from the client.
|
|
43
|
+
leaderboard = rd.leaderboards.fetch(limit=100, season=20, platform=1)
|
|
44
|
+
tier_list = rd.heroes.tier_list(platform=1, rank="grandmaster_plus")
|
|
45
|
+
team_ups = rd.team_ups.fetch(platform=1, rank="grandmaster_plus")
|
|
46
|
+
xp_page = rd.insights.xp()
|
|
47
|
+
|
|
48
|
+
print(hero_season[0].win_rate) # integer percent when wins/losses are present
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## MCP server (ChatGPT and Claude)
|
|
52
|
+
|
|
53
|
+
Install the MCP extra and the package:
|
|
54
|
+
|
|
55
|
+
```console
|
|
56
|
+
python -m pip install 'rivalsdata-api[mcp]'
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
The server exposes read-only tools for player search and profiles, a player's
|
|
60
|
+
current live match (when they are in one), match history, player stats,
|
|
61
|
+
leaderboards, heroes, team-ups, public insights, matches, and factions. The
|
|
62
|
+
`show_player_dashboard` tool returns an MCP-UI player card with rank and
|
|
63
|
+
competitive record plus one optional data section per call: current match
|
|
64
|
+
roster, hero win-rate chart, or recent match form with K/D/A. This keeps each
|
|
65
|
+
dashboard pull to the profile plus at most one additional endpoint. It supports
|
|
66
|
+
local stdio for Claude Desktop
|
|
67
|
+
and Streamable HTTP for remote MCP clients such as ChatGPT. Data comes from
|
|
63
68
|
RivalsData's undocumented API and may change; profile match history can be
|
|
64
69
|
private.
|
|
65
70
|
|
|
66
|
-
|
|
67
|
-
|
|
71
|
+
Known `hero_id` and `top_hero_id` fields in MCP results include corresponding
|
|
72
|
+
`hero_name` and `top_hero_name` fields. The `resolve_hero` tool accepts either
|
|
73
|
+
a hero name or numeric ID. The pip package also exports `hero_name(id)` and
|
|
74
|
+
`hero_id(name)`; returned `DataModel` rows provide `.hero_name` and
|
|
75
|
+
`.top_hero_name` conveniences. Those resolved fields are included in mapping
|
|
76
|
+
iteration and `.to_dict()` output to simplify serialization; `.raw` remains the
|
|
77
|
+
untouched source payload.
|
|
78
|
+
|
|
79
|
+
### How the MCP UI works
|
|
80
|
+
|
|
68
81
|
`show_player_dashboard` fetches current data, then returns an HTML UI resource
|
|
69
|
-
alongside the tool result.
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
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:
|
|
82
|
+
alongside the tool result. It advertises the dashboard through
|
|
83
|
+
`_meta.ui.resourceUri`, uses the `text/html;profile=mcp-app` resource MIME type,
|
|
84
|
+
and registers that URI for `resources/read` so the host can actually load the
|
|
85
|
+
app frame. The tool result carries the rendered dashboard as structured content
|
|
86
|
+
for the app frame and an embedded HTML resource for older MCP-UI clients. It
|
|
87
|
+
also includes `openai/outputTemplate` as a ChatGPT compatibility alias. Hosts
|
|
88
|
+
without UI support still receive a text result and can use the regular MCP
|
|
89
|
+
tools. The dashboard is a snapshot from the time the tool runs; ask for it
|
|
90
|
+
again to refresh.
|
|
91
|
+
The `section` argument defaults to `live_match`; use `hero_form` or
|
|
92
|
+
`recent_matches` in separate calls when you need those views.
|
|
93
|
+
|
|
94
|
+
### Claude Desktop (local)
|
|
95
|
+
|
|
96
|
+
Add a server entry to Claude Desktop's `claude_desktop_config.json`, replacing
|
|
97
|
+
the path with the Python executable in the environment where the extra is
|
|
98
|
+
installed:
|
|
99
|
+
|
|
100
|
+
```json
|
|
101
|
+
{
|
|
102
|
+
"mcpServers": {
|
|
103
|
+
"rivalsdata": {
|
|
104
|
+
"command": "C:\\path\\to\\venv\\Scripts\\python.exe",
|
|
105
|
+
"args": ["-m", "rivalsdata.mcp_server"]
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
On macOS/Linux, use the environment's `bin/python` path. Restart Claude Desktop
|
|
112
|
+
after saving the configuration.
|
|
113
|
+
|
|
114
|
+
### ChatGPT or remote Claude connector
|
|
115
|
+
|
|
116
|
+
Run the server on a host reachable over HTTPS:
|
|
117
|
+
|
|
118
|
+
```console
|
|
119
|
+
uvicorn rivalsdata.mcp_server:app --host 0.0.0.0 --port 8000
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
The MCP endpoint is `/mcp` (for example, `https://your-host.example/mcp`). Add
|
|
123
|
+
that endpoint through the client's custom/remote MCP connector settings. The
|
|
124
|
+
server does not implement authentication; put it behind an authenticated
|
|
125
|
+
HTTPS gateway before exposing it publicly. For local development, bind to
|
|
126
|
+
`127.0.0.1` instead. The `app` is the MCP SDK's Streamable HTTP ASGI
|
|
127
|
+
application; Uvicorn manages its lifespan and session manager.
|
|
128
|
+
|
|
129
|
+
Every implemented response route now has named endpoint models and row models
|
|
130
|
+
with annotations for fields observed in the API inventory. This includes
|
|
131
|
+
`Player`, `Match`, `MatchHistory`, `MatchTeam`, `MatchPlayer`, `Character`,
|
|
132
|
+
`ProficiencyResponse`, `LeaderboardResponse`, `PunishmentsPage`, `XPPage`,
|
|
133
|
+
`Top500Response`, and typed teammate, crosshair, stats, faction, and insight
|
|
134
|
+
records. For example, `rd.matches.get(match_id)` returns a `Match`,
|
|
135
|
+
`player.matches.fetch()` returns a `MatchHistory`, and
|
|
136
|
+
`player.proficiency.fetch()` returns a `ProficiencyResponse`. Nested match
|
|
137
|
+
teams and participants are converted to `MatchTeam` and `MatchPlayer`; embedded
|
|
138
|
+
character records use `Character`. Models support mapping access
|
|
139
|
+
(`player["level"]`) and attribute access (`player.level`). Unknown upstream
|
|
140
|
+
fields are still preserved and available through `.raw`; endpoint schemas
|
|
141
|
+
that have not been observed completely are annotated only for known fields.
|
|
140
142
|
|
|
141
143
|
```python
|
|
142
|
-
with RivalsDataClient(
|
|
143
|
-
player = rd.get_player(1970288503)
|
|
144
|
+
with RivalsDataClient() as rd:
|
|
145
|
+
player = rd.get_player(1970288503) # Player
|
|
146
|
+
proficiency = player.proficiency.fetch() # ProficiencyResponse
|
|
147
|
+
account = next(iter(proficiency.accounts.values())) # Proficiency
|
|
148
|
+
hero = account.hero_proficiency_infos["1011"] # HeroProficiency
|
|
149
|
+
print(hero.proficiency_level, hero.proficiency_point)
|
|
150
|
+
|
|
151
|
+
tier_list = rd.heroes.tier_list() # TierListResponse
|
|
152
|
+
print(tier_list.heroes[0].hero_id) # Character
|
|
144
153
|
```
|
|
145
|
-
|
|
146
|
-
##
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
154
|
+
|
|
155
|
+
## Public resources
|
|
156
|
+
|
|
157
|
+
- `rd.leaderboards.fetch(...)` — global player ranking.
|
|
158
|
+
- `rd.heroes.tier_list(...)`, `.get(hero_id)`, `.meta(hero_id, range=90)`,
|
|
159
|
+
`.leaderboard(hero_id, **filters)` — hero metrics and ranking.
|
|
160
|
+
- `rd.team_ups.fetch(...)` — team-up stats.
|
|
161
|
+
- `rd.insights.punishments(...)`, `.xp(...)`, `.top_500(...)`, `.commbans(...)`,
|
|
162
|
+
`.leavers(...)` — public insights and cursor metadata.
|
|
163
|
+
- `rd.factions.get(faction_id)`, `rd.matches.get(match_id)`,
|
|
164
|
+
`rd.profiles.get(username)`, and `rd.favorites.fetch(uids)` — detail/profile
|
|
165
|
+
lookups.
|
|
166
|
+
- `player.heroes.fetch(...)`, `.matches.fetch(...)`, `.live_game.fetch()`, `.teammates.fetch(...)`,
|
|
167
|
+
`.crosshairs.fetch()`, `.proficiency.fetch()`, `.punishments.fetch()`,
|
|
168
|
+
`.name_history.fetch()` — profile sections.
|
|
169
|
+
- `player.stats.heroes(...)`, `.maps(...)`, `.bans(...)` — detailed profile stats.
|
|
170
|
+
|
|
171
|
+
See [the observed API inventory](docs/API.md) for methods, parameters, observed
|
|
172
|
+
response shapes, and endpoints that require a RivalsData account. The API
|
|
173
|
+
inventory distinguishes observed behavior from inferred/unverified details.
|
|
174
|
+
|
|
175
|
+
## Cloudflare fallback
|
|
176
|
+
|
|
177
|
+
Requests use curl_cffi with a Chrome TLS profile by default. If blocked, enable
|
|
178
|
+
the optional browser fallback:
|
|
179
|
+
|
|
180
|
+
```python
|
|
181
|
+
with RivalsDataClient(use_browser_fallback=True) as rd:
|
|
182
|
+
player = rd.get_player(1970288503)
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
## Errors and contributions
|
|
186
|
+
|
|
187
|
+
All package exceptions inherit from `RivalsDataError`. See
|
|
188
|
+
[CONTRIBUTING.md](CONTRIBUTING.md) for setup, code layout, change workflow, and
|
|
189
|
+
notes for new contributors. [docs/PROJECT_CONTEXT.md](docs/PROJECT_CONTEXT.md)
|
|
190
|
+
is the handoff document for new coding sessions.
|
|
191
|
+
|
|
192
|
+
This project is not affiliated with RivalsData, NetEase, or Marvel. Keep
|
|
193
|
+
request rates reasonable and respect the site's terms.
|
|
@@ -3,9 +3,11 @@
|
|
|
3
3
|
This is an observed inventory of the public web client's API, gathered by
|
|
4
4
|
reviewing the RivalsData UI and its browser requests on 2026-09-29. The upstream
|
|
5
5
|
API is undocumented and can change. Field sets below are examples from live
|
|
6
|
-
responses, not schemas guaranteed by RivalsData.
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
responses, not schemas guaranteed by RivalsData. The client converts every
|
|
7
|
+
implemented route to endpoint-specific model and row classes (such as `Match`,
|
|
8
|
+
`Character`, `PlayerSummary`, `ProficiencyResponse`, and `PunishmentsPage`).
|
|
9
|
+
Known fields are annotated; unknown keys remain accessible through `DataModel`
|
|
10
|
+
and `.raw` so upstream additions are not discarded.
|
|
9
11
|
|
|
10
12
|
## Implemented public read endpoints
|
|
11
13
|
|
|
@@ -18,27 +20,27 @@ keys.
|
|
|
18
20
|
| Player crosshairs | `POST /player/crosshairs` | `uid` | Array rows: `crosshair`, `uses`. |
|
|
19
21
|
| 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
22
|
| 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}`);
|
|
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
|
|
24
|
-
| Player ban stats | `POST /player/stats/bans` | `uid`, optional `season` | Array
|
|
25
|
-
| Player punishments | `POST /player/punishments` | `uid` | Object keys
|
|
23
|
+
| Player proficiency | `POST /player/proficiency` | `uid` | Object keyed by account id (sample: `11001_{uid}`); each account has `hero_proficiency_infos` keyed by hero id, with `proficiency_level` and `proficiency_point`. |
|
|
24
|
+
| Player hero stats | `POST /player/stats/heroes` | `uid`, optional `season` | Array rows: `competitive`, `hero_id`, `quickplay`, `rank`. Each mode includes games, wins/losses, KDA, MVP/SVP counts, accuracy, and `per_10`/`per_game` combat averages. |
|
|
25
|
+
| Player map stats | `POST /player/stats/maps` | `uid`, optional `season` | Array rows: `map`, `competitive`, `quickplay`; each mode has games, wins, losses, winrate. |
|
|
26
|
+
| Player ban stats | `POST /player/stats/bans` | `uid`, optional `season` | Array rows: `hero_id`, `matches`, `wins`, `losses`, `winrate`. |
|
|
27
|
+
| Player punishments | `POST /player/punishments` | `uid` | Object keys: `chat`, `login`, `rank`; non-null entries include `expire`, `name`, `reason`, `time`, `uid`. |
|
|
26
28
|
| Player name history | `POST /player/name-history` | `uid` | Array rows: `first_seen`, `name`. |
|
|
27
29
|
| 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` |
|
|
29
|
-
| Hero detail | `GET /stats/heroes/{hero_id}` | Path parameter |
|
|
30
|
-
| Hero trend/meta | `GET /stats/meta/{hero_id}` | `range`
|
|
31
|
-
| Hero leaderboard | `GET /stats/leaderboards` | `hero` plus caller-supplied query filters |
|
|
32
|
-
| Team-up stats | `GET /stats/teamups` | `platform`, `rank`, optional `hero` |
|
|
30
|
+
| Hero tier list | `GET /stats/tierlist` | `platform`, `rank` | Object: `last_update`, `heroes`; rows include hero id, picks/bans, total games, winrate, pick rate, ban rate, and score. |
|
|
31
|
+
| Hero detail | `GET /stats/heroes/{hero_id}` | Path parameter | Object: `hero`, `last_update`, `season`; `hero` contains aggregate per-10 stats and pick/ban rates. |
|
|
32
|
+
| Hero trend/meta | `GET /stats/meta/{hero_id}` | `range` as `30d`, `90d`, or `180d` | Object: `hero_id`, `last_update`, `points`, `range`, `window_days`; point rows include timestamp, games, pick/ban rates, and winrate without mirror matches. |
|
|
33
|
+
| Hero leaderboard | `GET /stats/leaderboards` | `hero` plus caller-supplied query filters | Object: `last_update`, `players`; rows include combat averages, placement, score, rank, and wins/losses. |
|
|
34
|
+
| Team-up stats | `GET /stats/teamups` | `platform`, `rank`, optional `hero` | Object: `last_update`, `heroes`, where `heroes` maps hero ids to slot ids and rows with `bond_id`, `games`, `nm_winrate`, `pickrate`, `winrate`. |
|
|
33
35
|
| 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
36
|
| XP leaderboard | `GET /stats/xp` | Optional `cursor` | Object: `last_update`, `next`, `results`; sample row keys: `icon`, `name`, `rank`, `uid`, `xp`. |
|
|
35
37
|
| 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
38
|
| 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
39
|
| 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
|
|
40
|
+
| Faction details | `GET /faction/{faction_id}` | Path parameter | Faction `captain`, `description`, `members`, `name`, `region`, `results`, `tag`, `type`; member records contain account id, config/rank, game status, and name. |
|
|
39
41
|
| 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/{
|
|
41
|
-
| Favorites lookup | `POST /favorites` | `{"uids": [
|
|
42
|
+
| Public profile card | `GET /profiles/{uid}` | Numeric UID path parameter; `Profiles.get` resolves usernames | Object: `leaderboard_social`, `socials`, `uid`, `updated_at`. |
|
|
43
|
+
| Favorites lookup | `POST /favorites` | `{"uids": [numeric_uid, ...]}` | Array of public player summaries with `aid`, `config_server`, `games`, `name`, and `status`. |
|
|
42
44
|
|
|
43
45
|
The client exposes these read resources through `RivalsDataClient` and `Player`;
|
|
44
46
|
see README examples and method docstrings. `DataModel.win_rate` returns an
|
|
@@ -15,7 +15,7 @@ as public, stable methods. Keep requests respectful and conservative.
|
|
|
15
15
|
## Current package
|
|
16
16
|
|
|
17
17
|
- Distribution: `rivalsdata-api`; import: `rivalsdata`.
|
|
18
|
-
- Version: `
|
|
18
|
+
- Version: `1.1.0`.
|
|
19
19
|
- Python `>=3.10`, Hatchling build, `src/` layout.
|
|
20
20
|
- Runtime HTTP dependency: `curl-cffi`; optional browser fallback: Camoufox.
|
|
21
21
|
- Public entry point: `RivalsDataClient`.
|
|
@@ -48,8 +48,9 @@ Lazy subresources include `player.heroes.fetch(...)`, `player.matches.fetch(...)
|
|
|
48
48
|
`player.name_history.fetch()`, and `player.stats.heroes/maps/bans(...)`.
|
|
49
49
|
Client-wide resources include `client.leaderboards`, `client.heroes`,
|
|
50
50
|
`client.team_ups`, `client.insights`, `client.factions`, and `client.matches`.
|
|
51
|
-
`client.profiles` and `client.favorites` have
|
|
52
|
-
|
|
51
|
+
`client.profiles` and `client.favorites` have typed read methods. The profile
|
|
52
|
+
endpoint takes a numeric UID; the wrapper can resolve a username first.
|
|
53
|
+
Favorites requires numeric UIDs and returns player summary rows.
|
|
53
54
|
Rows offer `.win_rate` and `.winrate` integer-percent access when data supports
|
|
54
55
|
it; all original data remains in mapping access.
|
|
55
56
|
|
|
@@ -70,8 +71,8 @@ detail pages. Main public request families are:
|
|
|
70
71
|
opened from the public GS- profile. The returned object contains replay id,
|
|
71
72
|
mode/map/time, draft picks/bans, both teams, players' combat stats, and hero
|
|
72
73
|
usage.
|
|
73
|
-
- `GET /profiles/{
|
|
74
|
-
|
|
74
|
+
- `GET /profiles/{uid}` returns profile social metadata and `POST /favorites`
|
|
75
|
+
returns public player summaries. Both were checked through the browser.
|
|
75
76
|
|
|
76
77
|
The hero detail Counters and Synergy tabs showed “Coming Soon” on inspection.
|
|
77
78
|
The Live Game tab did not expose data for the sampled player. Do not invent
|
|
@@ -84,7 +85,8 @@ endpoints can change account state and are intentionally not implemented by
|
|
|
84
85
|
this read-only package yet. `client.matches.get` uses the verified `match_id`
|
|
85
86
|
payload.
|
|
86
87
|
|
|
87
|
-
The
|
|
88
|
+
The hero meta endpoint requires `range=30d`, `90d`, or `180d`; bare integers
|
|
89
|
+
are rejected. The website currently shows Season 10 / season value 20 and OS `1` for PC on
|
|
88
90
|
the inspected UI. Treat those as site values, not permanent constants.
|
|
89
91
|
|
|
90
92
|
## Contributor workflow
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "rivalsdata-api"
|
|
7
|
-
version = "1.
|
|
7
|
+
version = "1.1.0"
|
|
8
8
|
description = "Python client and MCP server for public Marvel Rivals stats from RivalsData"
|
|
9
9
|
keywords = ["marvel-rivals", "rivalsdata", "game-stats", "api-client", "mcp"]
|
|
10
10
|
readme = "README.md"
|
|
@@ -34,12 +34,9 @@ Changelog = "https://github.com/GS-Rionnag/rivalsdata-api/releases"
|
|
|
34
34
|
|
|
35
35
|
[project.optional-dependencies]
|
|
36
36
|
browser = ["camoufox>=0.5.6"]
|
|
37
|
-
mcp = ["mcp>=1.12,<2", "mcp-ui-server>=1.0.0"]
|
|
37
|
+
mcp = ["mcp>=1.12,<2", "mcp-ui-server>=1.0.0", "uvicorn>=0.30"]
|
|
38
38
|
dev = ["build>=1.2", "pytest>=8", "ruff>=0.11"]
|
|
39
39
|
|
|
40
|
-
[project.scripts]
|
|
41
|
-
rivalsdata-mcp = "rivalsdata.mcp_server:main"
|
|
42
|
-
|
|
43
40
|
[tool.ruff]
|
|
44
41
|
line-length = 88
|
|
45
42
|
target-version = "py310"
|