Inspiration

I'm a huge Premier League fan and follow the transfer market closely, so I wanted to explore how AI could make complicated transfer decisions clearer. I built this to help understand how transfer fees, wages, amortization, and PSR rules actually affect a club's decisions and possibly automate the transfer market old legacy brute force system with modern Agentic AI application software. With WebMCP, the AI can make recommendations and decisions while the website remains the source of truth for the calculations and rules.

Premier League clubs aren't allowed to lose more than £105m (about $133m) over three seasons. Break it and you don't get a fine — you lose league points. Everton were docked 10 points for going £16.6m over, then 2 more for a second breach. Nottingham Forest lost 4 points for going £34.5m over. Points decide relegation, and relegation costs a club around £100m.

And the maths behind it is genuinely counterintuitive. A transfer fee isn't a cost when you pay it — it's spread across the contract, capped at five years since 2023. A £110m signing is a £22m charge this season, not £110m. A sale books its profit immediately, and an academy graduate has a book value of zero, so their whole fee is pure profit. That's why clubs sell their own young players every June, racing a June 30 accounting deadline that Sky Sports calls football's unofficial transfer deadline day.

So I tried asking ChatGPT to do it, with no tools. It got close it knew about amortisation. But I had to hand it every single number, and it still told me flatly: "headline accounts alone cannot establish a breach." It couldn't answer, and it knew it couldn't.

That's the whole idea. Not "AI is bad at maths" but that an agent with no access to the real numbers can only ever guess, and in this domain guessing costs you league points.

What it does

You manage a Premier League club through a transfer window, with an AI agent working alongside you. The page exposes 14 WebMCP tools it can call directly: search the market, price deals, rank sale candidates, edit the plan.

What it cannot do is state a number it didn't get from the page.

Ask it to sign a £110m striker with £20.3m of headroom and it doesn't apologise and comply. The plan turns red, submission is blocked, and it comes back with the exact figure: £12.1m over, £22m annual amortisation, £10.4m of wages.

Then ask who to sell, and it gets genuinely interesting. It recommended Leon Bailey at £30m worth £34.2m to the PSR position, more than the fee, because you also shed his wages and remaining amortisation. And it noted that Morgan Rogers would be worth more (+£62.7m) but Bailey was the cleaner fix from a crowded midfield. It weighed a trade-off but every number in that trade-off came from the page.

How I built it

React + TypeScript + Vite. No backend, no auth, no API keys it deploys as static files.

The rules engine (src/engine/rules.ts) is pure functions with a test suite: PSR aggregation, fee amortisation capped at five years, profit on sale against book value, and squad registration (25 seniors, max 17 non-homegrown, U21s exempt). The 14 tools are thin wrappers over it, so the model never does the arithmetic itself.

The tools sit in three tiers with standard MCP annotations derived from the tier, so the hint an agent reads can't drift from what the UI shows:

  • Read-only (9) — readOnlyHint, idempotentHint
  • Reversible (4) — every change undoable
  • Consequential (1) — submit_window, destructiveHint

Crucially, agent and human mutate through the same store. A tool call and a button click run the identical code path, so the agent has no privileged back door and you watch the board change under its hands.

Why WebMCP and not a normal MCP server

submit_window doesn't return when called. It raises a confirmation in the page and suspends the promise resolves only when a human confirms or declines, and it honours the AbortSignal if the call is cancelled.

An agent working against a REST API could always call POST /submit. Here there is no server, so there is nothing to call. The gate isn't a prompt asking the agent to behave; it's the only path through, and it needs a hand on it.

Challenges

The API is still moving. The W3C proposal exposes navigator.modelContext; the Chrome docs show document.modelContext. Registration is either per-tool registerTool or a bulk provideContext. Rather than betting on one, I wrote a small adapter that detects whatever the browser provides one file to change when the spec settles.

Making the gate genuinely block. My first version returned "awaiting confirmation" immediately, which let the agent wrap up while the decision was still open. Rewriting it to suspend inside the tool call is what turned "the agent chose to stop" into "the agent structurally cannot finish."

Calibrating the data so the demo is honest. The rules are real, but I had to invent every financial figure and tune them so each club sits in a distinct, legible position Villa tight at £20.3m, Forest at £8.1m, Everton nearly gone at £2.6m. Villa also had to genuinely need a striker, so the story starts from a real problem.

What I learned

Good tool descriptions do more work than I expected. The agent correctly explained the five-year amortisation cap and derived its own spending formula 5 × (£20.3m − first-year wages) entirely from reading the tool descriptions. It extended the rule rather than just following it.

I also learned the interesting failure mode isn't hallucination. It's a model being nearly right confidently, with working shown while missing the pieces it has no access to. Being off by £700k sounds trivial until you remember Everton lost 10 points for £16.6m.

Honesty about the data

Club and player names are real, because the constraints only mean something if you recognise them. Every financial figure is invented. They are not club accounts and shouldn't be cited as such. The rules are real and public that's what the page enforces, and it's the part worth learning.

What's next

Roles as tool tiers. The gate currently means any human. In a real club it would mean a specific one a scout gets read-only tools, an analyst can build a plan, and only a sporting director's click resolves submit_window.

And beyond football. The failure mode here isn't specific to sport. It's what every agent does when handed a calculator-shaped problem and no calculator: assert arithmetic it can't actually do, somewhere being wrong carries a real penalty. Tax. Benefits eligibility. Medical billing. Export control.

Give the page the rulebook, and make the agent ask.

Built With

Share this project:

Updates

Submission history