Connect AI assistants to Teamfight Tactics data via MCP. 19 tools cover player profiles, TFT stats, match history, live game, leaderboards, player comparison and AI placement coaching. No Riot API key needed, and it works in Claude Desktop, ChatGPT and any MCP client. By MrBridge (mr-bridge.com)
README: added a Features section, a How to use section and an image of a real tft_get_league_top response (EUW Challenger, player names replaced). The Apify Universal MCP section is now titled "Use it with AI agents and MCP clients" and links to the other MrBridge MCP servers (League of Legends, ESPN, Latest News). A short line near the Issues link invites an honest review and a bookmark. No change to the server or its tools.
2026-11-09 (2.1.4)
Full request limits again
Fixed
Each instance of the server can use the whole of Riot's request limits again, as before 2.1.3. Version 2.1.3 described the server's Riot key wrongly and kept each instance to half of each limit.
The four ladder tools now report riotIdsResolved, the number of players whose Riot ID was found. The Riot IDs are looked up at a steady pace that leaves room for other calls, and when Riot's limit is near the lookups stop early. The other players keep their PUUID.
A rate limit that Riot applies while the server reloads its key is now reported as a rate limit, not as an invalid key.
2026-11-09 (2.1.3)
Limits of the server's Riot production key
Fixed
Request limits now follow the server's Riot production key. The server used to assume the much lower limits of a personal key, so busy sessions waited when they did not need to. Each running instance of the server can use at most half of each limit, which keeps room for the other instances.
A call that would have to wait longer than a tool call allows now ends at once with a message that says when to try again, instead of hanging. That call is not charged.
When Riot limits a single endpoint, only the calls to that endpoint wait. The other tools keep working.
2026-11-08 (2.1.2)
Several callers share Riot's limits
Fixed
Several callers at once now share Riot's request limits without hitting refusals. The server reads how many requests Riot has already counted in each region and waits when that region is near its limit, instead of sending calls that Riot would refuse. A busy region does not slow down the others.
2026-11-07 (2.1.1)
Live game errors no longer billed, Riot's wait time honoured
Fixed
tft_get_live_game no longer answers "not in a game" when Riot fails. A Riot server error whose text held "404" used to read that way and was charged as Match Data. It now comes back as an error, never charged.
When Riot answers "too many requests", the server now waits the time Riot asks for (its Retry-After header) before trying again, and no longer waits after its last attempt. A wait that would push a tool call past 40 seconds is skipped, and the call returns the rate-limit error, which is not charged.
For ph2 or th2, tft_get_account and the two compatibility stubs no longer say the data comes from SG2. Riot accounts are global, and the stubs read no data. The other ph2 and th2 answers keep the notice.
Changed
llms.txt now lists the 14 regions of the README and explains that PH2 and TH2 were merged into SG2. It also says that featured games return a free notice, and no longer lists defaultLanguage, a setting the server does not read.
The input form and the README now mark defaultLanguage as ignored, since the server never read it. It stays so that saved inputs keep working.
2026-11-06 (2.1.0)
Asian regions fixed, PH2 and TH2 served by SG2, clearer Riot errors
Fixed
Riot ID lookups now work in OC1, SG2, TW2 and VN2. tft_get_account, player profiles, comparisons, analyses and live games failed there, and the ladders showed no Riot IDs.
ph2 and th2 work again. Riot merged both servers into SG2 on 2025-01-09, so the server now answers them from SG2, and each answer says so in a short notice.
A Riot refusal (HTTP 403) now names its cause: a routing value the endpoint does not serve, an endpoint Riot retired, or a region merged into SG2. It no longer blames the API key.
Changed
tft_get_featured_games now says that Riot retired the featured games endpoint (Spectator-V5) in October 2025. This notice is never charged.
2026-11-06 (2.0.1)
Read-only tool hints, JSON-RPC errors and the real version
Changed
Every tool now has a title and declares that it only reads data. Clients that read these hints can skip the confirmation prompt before each call.
Fixed
A request with a malformed JSON body now gets a JSON-RPC parse error instead of an HTML page. A body over 100 KB gets a JSON-RPC error too.
The server now reports its real version, 2.0.1, instead of a fixed 2.0.0.
2026-11-04
Billing fairness: errors and input errors are never charged
Fixed
tft_get_featured_games now returns an error when Riot refuses the key tier (403). It used to return an "unavailable" message that was charged as Data Retrieval. Errors are never charged.
tft_analyze_champion called without a unit name now returns an input error and is not charged. It used to be charged as an AI Analysis.
tft_get_live_game now answers "not currently in a TFT game" when the player is not playing, billed as Match Data like any other answer. It used to return a "Resource not found" error.
Once the spending limit of the run (ACTOR_MAX_TOTAL_CHARGE_USD) is reached, further tool calls are rejected right away, as the README states. They used to keep running without being billed.
Changed
New offline test suite for the billing rules of all 19 tools: one charge per successful call, made after Riot answered (answers without data included), and no charge on errors, input errors or the two free compatibility stubs.
2026-06-11
Billing fairness — error responses and compatibility stubs are no longer charged
Fixed
Error responses are never charged. Billing now fires only on successful tool responses (!result.isError); a typo'd Riot ID, a missing player, or any handler error no longer costs money. Previously every call was billed, success or error.
The two compatibility stubs are free.tft_get_champion_mastery and tft_get_match_timeline return a static "not available for TFT" message with no Riot API call — they are now in a FREE_TOOLS allowlist and never charged (previously $0.003 / $0.005 per call).
Changed
Standby port now prefers the documented ACTOR_WEB_SERVER_PORT, with APIFY_CONTAINER_PORT as legacy fallback
pay_per_event.json event descriptions updated: ladder/leaderboard/status/featured-games tools now listed under Data Retrieval; dead mastery/timeline mentions removed; player profile + live game listed under Match Data
README pricing section simplified: the live price table now lives on the Pricing tab (single source of truth) instead of being duplicated in the README; added the ACTOR_MAX_TOTAL_CHARGE_USD cost-cap note
Legal section rewritten for commercial use (Riot Games API ToS compliance, trademark notice) — replaces the "educational and personal use" wording
tft_get_match_history now supports start, startTime, endTime (pagination + date range)
Surfaces Riot's status.message + endpoint on unhandled HTTP errors for easier diagnosis
Notes
tft_get_featured_games degrades gracefully when the API key tier lacks spectator featured-games access (returns a clear message, not an error)
2026-06-05
Data layer rewired to the TFT API + zero-config built-in key
Fixed (major)
Re-pointed the entire data layer from the League of Legends API to the TFT API. Ranked now returns RANKED_TFT / Hyper Roll / Double Up; match details return placement, traits, starred units, items, augments and the Little Legend; summoner, status and live game use the TFT endpoints. Previously these returned League of Legends data.
tft_get_match_timeline and tft_get_champion_mastery now report "not available for TFT" (no such Riot endpoint) instead of hitting a LoL endpoint
Analysis tools (tft_analyze_performance, tft_get_improvement_tips, tft_analyze_champion) recomputed on TFT placement metrics (avg placement, top-4 / top-1 rate, most-played units & traits) and now accept a Riot ID directly
Changed
Built-in dedicated Riot API key — no user key, no setup, no 24-hour rotation (zero-config). Standby always uses the built-in key.
README realigned with the LoL MCP Server (zero-config Quick Start, sample output, API usage, cross-sell)
Data Dragon resolution switched to TFT assets (units, traits, augments, items, Little Legends, queues)
2026-05-19
Pay-per-event consolidation (5 events → 3)
Pricing simplification
Removed the tool-live ($0.008) and tool-compare ($0.025) events
tft_get_live_game now charges as tool-match ($0.005, price decrease)
tft_compare_players now charges as tool-analysis ($0.015, price decrease)
Final structure: tool-read $0.003 / tool-match $0.005 / tool-analysis $0.015
Why
Apify recommends 2–4 events; 5 made the pricing page noisy
live_game is fundamentally a match-data lookup; compare_players is an AI/analysis feature
Aligns the event taxonomy with the LoL sibling Actor
2026-03-31
Billing robustness
Fixed
Spending limit: the tool result is returned with a warning instead of being silently thrown
Charge on error: calls are billed even when the handler fails (the Riot API calls were already consumed)
Missing mapping: explicit throw if a tool has no billing mapping (instead of a silent fallback to tool-read)
Billing failures: log.error with a consecutive counter and an alert at 5 failures (BILLING_FAILURE)
Simplified
Removed dead code (SPENDING_LIMIT_RESPONSE, getToolPricing, getToolBillingEvent)
PRICING reduced to Record<BillingEvent, number> (removed the unused description field)
Unified billing flow in server.ts: a single chargeForTool call after the handler's try/catch
2026-03-26
PPE audit fixes
Spending limit: added SPENDING_LIMIT_RESPONSE handling in billing.ts / server.ts (returned when eventChargeLimitReached)
Content fix: replaced all League of Legends references with TFT across README, index.ts, schemas and package.json
Streamable HTTP only + Claude Desktop fix — migrated to the official Apify MCP pattern.
BREAKING CHANGE
SSE removed: the /sse and /messages endpoints no longer exist
Port: uses APIFY_CONTAINER_PORT instead of ACTOR_STANDBY_PORT
Changed
Stateless Streamable HTTP: a fresh server + transport per request (sessionIdGenerator: undefined), no session management
CORS: added the cors middleware with exposedHeaders: ['Mcp-Session-Id'] for Claude Desktop compatibility
GET /mcp and DELETE /mcp return 405 Method Not Allowed
Automatic cleanup: transport.close() and server.close() on res.on('close')
2026-02-11
Readiness probe fix
Apify readiness probe: / returns a plain 200 OK instead of creating an unnecessary MCP session
Finding: Apify's Standby proxy does not forward external requests to / (only the internal readiness probe hits it); the MCP connection URL must include /mcp
2026-02-10
Standby support & Console pages
Streamable HTTP: added the /mcp endpoint
Riot API key via the RIOT_API_KEY environment variable; graceful start without a key
Mode detection via APIFY_META_ORIGIN
Improved Input & Information page copy on the Apify Console, with detailed use cases
Categories set to AI, MCP_SERVERS, INTEGRATIONS; actor.json aligned with the Console