joreilly/FantasyPremierLeague: A Compose Multiplatform Sample, Not an FPL App
Fantasy Premier League Kotlin/Compose Multiplatform sample
At a glance
- What is it?
- This repository is John O'Reilly's Kotlin Multiplatform sample that renders Fantasy Premier League data on Android, iOS and Desktop, and also ships an MCP server and a Koog AI agent. It is a reference implementation for KMP patterns, not a tool for managing a real FPL team.
- Who is it for?
- Adopt this repository if you are learning Compose Multiplatform and want a working example that combines Room, DataStore, Navigation 3, Koin, SKIE and an MCP server in one codebase. Do not adopt it if you want an app to manage an actual Fantasy Premier League team, because the README describes no sign-in, no league entry and no squad editing.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly Jupyter Notebook, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 1, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What joreilly/FantasyPremierLeague actually is
The README opens by calling this a Compose Multiplatform project running on Android, iOS and Desktop. The Fantasy Premier League name refers to the data domain, not to a product for playing the game. The repository is one of a list of samples by the same author, alongside PeopleInSpace, Confetti, BikeShare and others, and it is filed under topics such as kotlin-multiplatform, compose-multiplatform, jetpack-room and mcp-server. Anyone arriving from a search for a fantasy premier league app download will be disappointed: there is no published binary here, and the README gives no store links. What there is instead is a Kotlin codebase that fetches and displays FPL-related data, with the shared logic in the common module and platform entry points in app, ios and compose-desktop. The primary language listed for the repository is Jupyter Notebook, which reflects the FantasyPremierLeague.ipynb notebook at the top level, not the bulk of the application code.
The layered structure: shared code, three UIs, and a notebook
The top-level entries show the shape of the project. common/ holds the Kotlin Multiplatform shared code. app/ is the Android application, ios/ contains the Xcode project at ios/FantasyPremierLeague/FantasyPremierLeague.xcodeproj, and compose-desktop/ is a JVM target that renders the same Compose UI on the desktop. The README states that the project uses Jetpack ViewModel, Navigation 3, Room and DataStore, all of which run from shared code rather than from a single platform. Room gives local persistence, DataStore handles key-value storage, and Navigation 3 drives screen transitions. Koin appears in the topic list as the dependency injection layer, and SKIE is listed alongside it, which points to Swift interop generation for the iOS side. The notebook is a separate artifact: the README shows Kotlin Notebook screenshots, so the same data access can be exercised interactively outside the app. The MCP server module reuses the shared KMP code, which is the most interesting architectural decision here, because it means the tool surface exposed to an AI client and the data layer behind the mobile UI are the same code rather than two parallel implementations.
Running the Android, iOS, Desktop and MCP targets
The README lists four run paths, one per target, and none of them involve installing a package from a registry. For Android, open the project in Android Studio and run the app configuration. For iOS, open the Xcode project and run. For Desktop, use the Gradle task shown below, which starts the JVM Compose application.
./gradlew :compose-desktop:runThe MCP server is built as a fat jar with the shadowJar task:
./gradlew :mcp-server:shadowJarAfter that build, the README shows how to register the resulting jar with Claude Desktop through the Developer Settings Edit Config option. The path in the example is the author's own machine, so it has to be replaced with the local path to serverAll.jar before the configuration will work:
{
"mcpServers": {
"fantasy-premier-league": {
"command": "java",
"args": [
"-jar",
"/Users/john.oreilly/github/FantasyPremierLeague/mcp-server/build/libs/serverAll.jar",
"--stdio"
]
}
}
}The README states that this endpoint returns player and fixture information. The AI agent described in the README is separate from the MCP server and needs a Gemini API key, set as apiKeyGoogle in FantasyPremierLeagueAgent. Without that key the agent path will not work, and the README does not describe a fallback.
The Koog agent and what a Gemini key buys you
The README says the project includes an AI agent built with Koog, using Gemini with tool calling, running in shared KMP code. That placement is the notable part: the agent is not bolted onto one platform, it lives where the rest of the shared logic lives. A related post is linked specifically about adding the Koog assistant with structured output, so the design intent is documented outside the repository. The practical constraint is the key. The README instructs you to set apiKeyGoogle in FantasyPremierLeagueAgent, and nothing else in the repository substitutes for it. There is no mention of a local model, a proxy, or a mock. If you clone this to study the agent wiring, you can read the code without a key, but you cannot exercise the tool-calling loop. That is a normal boundary for a sample that depends on a hosted model, and it is worth knowing before you plan a demo around it.
Where this sample stops short
The README describes display of player and fixture information. It does not describe authentication against the Fantasy Premier League service, squad selection, transfers, leagues or scoring. Searches for a fantasy premier league sign in or a fantasy premier league login have no answer in this repository, because there is no account flow. Treat it as a viewer and a technology demonstration. The second limitation is toolchain sensitivity. The README pins Kotlin 2.4.10 in a badge, and the project leans on Navigation 3, Room and SKIE, all of which move quickly. A sample like this is usually kept in step with the author's own environment, and the README gives no compatibility matrix for older Android Studio or Xcode versions. The third is scope: the MCP server exposes tools over stdio for a desktop client. The README does not describe authentication, rate limiting or a hosted deployment, so running it as a shared service is outside what the documentation covers.
Compared with a plain Android-only sample
The obvious alternative is a single-platform Jetpack Compose sample, which is simpler to build and has fewer moving parts. The difference in approach is where the code lives. A single-platform sample puts ViewModel, Room and navigation inside the Android module, and the iOS story is a rewrite. This repository puts those pieces in common/ and adds SKIE to make the shared Kotlin usable from Swift, which is why the same screenshots appear for Android, iOS and Desktop. That structure costs you a heavier build and a longer list of pinned dependencies, and it buys you one implementation of the data and navigation logic across three targets plus the MCP server. If your goal is to learn Compose on Android only, the extra multiplatform scaffolding is overhead. If your goal is to see how far shared code can be pushed before platform code is unavoidable, including into a tool endpoint for an AI client, this is a more complete example than a single-target app.
Editorial conclusion
Adopt this repository if you are learning Compose Multiplatform and want a working example that combines Room, DataStore, Navigation 3, Koin, SKIE and an MCP server in one codebase. Do not adopt it if you want an app to manage an actual Fantasy Premier League team, because the README describes no sign-in, no league entry and no squad editing. Before cloning, verify that Kotlin 2.4.10 and the current Android Studio, Xcode and Gradle toolchains are available to you, and check whether the Gemini API key requirement in FantasyPremierLeagueAgent matters for the modules you plan to run.
Frequently asked questions
How can I install joreilly/FantasyPremierLeague?
The README does not describe installing a published package. It lists run paths instead: open the project in Android Studio and run the app configuration for Android, or open the Xcode project for iOS.
What is joreilly/FantasyPremierLeague?
It is a Compose Multiplatform sample that runs on Android, iOS and Desktop, and also includes a Koog AI agent, a Kotlin Notebook and an MCP server. The README describes it as a Compose Multiplatform project using shared Kotlin code.
How can I play Fantasy Premier League with joreilly/FantasyPremierLeague?
You cannot play through this repository. The README describes displaying player and fixture information in the app and through the MCP server tools, and documents no sign-in, squad editing or league entry.
How do I use joreilly/FantasyPremierLeague?
Run one of the targets the README lists: the app configuration in Android Studio, the Xcode project for iOS, or ./gradlew :compose-desktop:run for Desktop. The MCP server is built with ./gradlew :mcp-server:shadowJar and registered with a client such as Claude Desktop.
Why is my joreilly/FantasyPremierLeague not working?
The README does not include a troubleshooting section, so it does not answer this directly. The one failure mode it does name is the AI agent, which needs a Gemini API key set as apiKeyGoogle in FantasyPremierLeagueAgent.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/joreilly-fantasypremierleague)