BallStreet for AI agents

How to connect an AI assistant to BallStreet, and what it can and cannot do. Written for the assistant, not for you.

Pointing an assistant here? Give it this URL and your API key. It also exists as plain text at /llms.txt. You can create a key at https://ballstreetleague.com/dashboard/api-keys/.

What this is

You are an AI assistant, and someone has pointed you at this page and probably given you an API key. This page tells you how to connect to BallStreet, what you can do once connected, and what you cannot.

BallStreet is a fantasy-football game played like a stock market: members of a private league buy and sell shares of NFL players, and prices move on how those players perform against their projections. Balances are play money with no cash value. There is also Day Trading: one-day contests over a slate of games, where the market stays open while they are played and the best portfolio at the final whistle wins.

Your two useful jobs here are explaining the game to the person using you, with their real numbers, and — if they have given you a key that permits it — trading on their behalf.

Setup

Three steps. Do them in order.

1. Install the MCP server:

pip install ballstreet-mcp

If it is already installed, upgrade it instead, with `pip install -U ballstreet-mcp`. Newer releases add tools, and an old copy cannot see them. When one is out, your instructions start with UPDATE AVAILABLE and `whoami` reports `mcp.update_available`; tell the person to upgrade and restart their MCP client.

2. Make sure the person has an API key. If they have not given you one, send them this exact URL, as a link they can click:

https://ballstreetleague.com/dashboard/api-keys/

Give them the URL, not a menu path. Telling someone to look under "Account, API Keys" has already stranded a real person who could not find it — the link is the instruction. They must be signed in, and the key is shown only once, so tell them to copy it immediately. Ask which scopes they granted; if they only want explanations, a read-only key is the right choice and you should say so.

3. Connect, with the key in the environment:

claude mcp add ballstreet --env BALLSTREET_API_KEY=<their key> -- ballstreet-mcp

Then call `whoami`. It returns the scopes actually in effect and the league ids every other call needs. If you only have one league, you can omit `league_id` everywhere.

The tools you are offered depend on the key. A read-only key is never shown the trading tools at all, so if you cannot see `place_order`, the key does not permit trading — do not try to work around it, tell the person.

Before you form any strategy

This market does not behave like the order-book exchanges most trading writing describes. Getting this wrong is the most common way to lose money here for reasons that have nothing to do with football. Call `market_primer`, and `get_league_rules` for the league in question, before you reason about anything.

The short version:

  • Trading does not move prices. No order book, no per-trade impact, one posted price for everyone.
  • Speed is not an edge. Buys batch into a fill run whose member order rotates each cycle, so an order placed seconds after news fills alongside one placed hours later. Do not poll aggressively; you will only hit the rate limit. (Hardcore leagues and Day Trading are the exceptions: their market stays open during games and fills orders in one-minute batches, and a key can read them but not trade in them. `get_league_rules` says whether a league is hardcore; `get_rules` with topic `day-trading` has the Day Trading rules.)
  • Price moves on actual points versus PROJECTED points. Beating a small projection is worth more than meeting a large one.
  • A price can move on a day a player did not play, when his rest-of-season outlook changes.
  • League settings differ. Demand pricing is off in many leagues, so check before explaining a price.

Disclosure — tell the person this

The first time you place an order through an API key, that team is permanently marked as bot-operated and a BOT badge appears next to it in the standings, on both the website and the mobile app. Their league mates will see it.

Automation is allowed here. Hiding it is not. If the person has not obviously understood that trading through you will flag their team, say so before you place the first order.

If they want you to analyse without that happening, they should use a read-only key, or set BALLSTREET_READ_ONLY=1, which withholds the trading tools regardless of what the key allows.

If you cannot run MCP

Every tool is a thin wrapper over a REST API you can call directly with the same key:

curl -H "Authorization: Bearer <key>" https://ballstreetleague.com/api/v1/bot/whoami/

The rules are public and need no key at all: https://ballstreetleague.com/api/v1/rules/ — so you can explain the game to someone who does not have an account yet. Add ?topic=<section> for one section or ?q=<question> to search.

Every response is JSON. Errors carry a machine-readable `code` you can branch on: `float_exhausted`, `market_closed`, `player_locked`, `missing_scope`, `endpoint_not_allowed`, `hardcore_no_bots`, `throttled`.

Tools

Which of these you are offered depends on the key's scopes. A tool you cannot see is one the key does not permit.

Available with any key

  • whoami — Who the key belongs to, what it may do, and which leagues it reaches. Call this first.
  • market_primer — How this market differs from an order-book exchange. Read before forming any strategy.
  • get_rules — The official rules, glossary and FAQ, with every constant filled in from the live engine.
  • search_rules — Rank the rules against a specific question, e.g. "why can't I buy him".

With the `read` scope

  • get_league_rules — The rules as they actually apply in one league: whether demand pricing is on, the scoring format, shares per player, draft settings.
  • list_leagues — Every league this key can reach.
  • get_market_state — Open, halted, or settling, and the current week.
  • list_players — Browse the market: search, filter by position, sort by price.
  • get_player — One player: price, projection, injury status, remaining float, your position.
  • get_price_history — A player's price over time, with the trigger behind each move.
  • get_player_news — Recent news for one player.
  • get_holdings_news — News across every player currently held.
  • get_player_holders — Who else in the league holds a player, and how much float is left.
  • get_matchups — This week's NFL matchups for the league's players.
  • get_portfolio — Cash, buying power, holdings and marks.
  • get_portfolio_history — Portfolio value over time.
  • get_leaderboard — League standings.
  • get_live_stats — Live in-progress scoring and its provisional effect on prices.
  • list_orders — Order history, filterable by status and side.
  • get_pending_orders — Pending orders in the exact sequence they will fill.

Day Trading contests, read only (with the `read` scope)

  • list_contests — Your Day Trading contests. Their ids go into every other contest tool.
  • get_contest_rules — The Day Trading rules, filled in with one contest's own settings.
  • get_contest — One contest: state, its games with live scores, entrants, batch timing.
  • get_contest_players — The player pool with the prices you see: posted, your buy price, and what your holdings sell or cover for.
  • get_contest_portfolio — Cash, total value and holdings in one contest.
  • get_contest_leaderboard — Live contest standings.
  • get_contest_orders — Your contest orders, the queued ones in the order they will fill.
  • get_contest_trades — Every fill in a contest, by member, as each batch fills. Queued orders stay private.
  • get_contest_results — Final standings and your own result.

With the `trade` scope

  • place_order — Place a buy, sell, short or cover. No price argument: everyone transacts at the posted price.
  • cancel_order — Cancel a pending order.
  • reorder_pending_orders — Rearrange which of your own pending orders fills first.

With the `debug` scope (tester accounts only)

  • debug_league — League state as the pricing engine sees it, including the fill queue. Tester accounts only.
  • debug_player — Every component of one player's price, plus invariant checks. Tester accounts only.

What you cannot do

These are refused by the server, not merely absent from the tool list. An endpoint that is not explicitly permitted is denied.

Take part in the IPO (the draft)

Everywhere else the design is bot-neutral: buys batch into a fill run whose member order rotates each cycle, so reacting in three seconds fills at the same price as reacting in three hours. The draft is the one place that is not true, so it is not automatable. A human has to draft.

Create, join or leave a league

League membership is a decision for the person, not their agent.

Act as commissioner

Settings, invites, removing members, dues and starting a new season are all closed.

Read or post in league chat

The social side of the league is not available to a key, in either direction.

Create or revoke API keys

A leaked key cannot mint another key or widen its own scope.

Change the account

Display name, team name and account deletion are off limits.

Trade in a Day Trading contest

You can read a contest, but you cannot place, cancel or reorder its orders, or create, join or leave one. Orders there fill every minute while the games are on, so reaction time is an edge, and it is kept for people. Help the person decide; they place the orders.

  • There are no limit orders, stop orders or conditional orders. Every order is a market order at the posted price, so you cannot express "buy if it drops to $40" — you have to poll and decide.
  • You cannot be woken up. There are no webhooks, no push and no streaming for keys, so you only act when your client runs you. Reacting the instant news breaks is not possible through this interface — which matters less than it sounds, because fills batch and speed is not an edge.
  • You cannot buy a player who is IR, OUT or inactive, or one whose game has already kicked off this week. Selling and covering are always allowed.
  • You cannot trade in a hardcore league. Its orders fill in 60-second batches, so reacting first does buy an earlier batch there, and that edge is kept for people. You can still read the league; placing, cancelling or reordering an order answers 403 with code `hardcore_no_bots`.
  • You cannot buy shares that do not exist. Each player has league_size x 100 shares and no more can be created.
  • You cannot trade fractional shares, or spend cash already committed to pending buys.
  • You are rate limited to 120 reads and 30 writes per minute.
  • You cannot see another member's cost basis, or any league the key's owner is not in.
The full rules are at How to Play, and as JSON at /api/v1/rules/ — public, no key required.