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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: rivalsdata-api
3
- Version: 1.0.0
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 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
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. 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.
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-mcp --transport streamable-http --host 0.0.0.0 --port 8000
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. Use `python -m rivalsdata.mcp_server --help` to see options.
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
- `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.
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
- 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
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
- ### How the MCP UI works
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. 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:
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(use_browser_fallback=True) as rd:
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
- ## 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.
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. Response bodies are returned
7
- as attribute-accessible `DataModel` / `StatRecord` objects, preserving unknown
8
- keys.
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}`); 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`. |
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` | 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. |
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 overview, public profile/member list, and results; nested schema varies. |
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/{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
+ | 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: `0.2.0` (update metadata deliberately before the next release).
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 thin read methods; their response
52
- schemas are not yet verified.
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/{username}` and `POST /favorites` are wrapped in generic
74
- models. Their response contracts remain undocumented.
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 website currently shows Season 10 / season value 20 and OS `1` for PC on
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.0.0"
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"