Skip to main content

BallStreet MCP Server

Exposes the BallStreet API to MCP clients (Claude Code, Claude Desktop, or anything else that speaks MCP), so a model can explain the game, read your league, manage a portfolio, and place orders.

Two distinct uses, and most people want the first:

  • Ask questions about your league. A read-only key lets an assistant answer "why did my player drop overnight", "who is locked this week", "how many shares are left" using your actual numbers, and read the official rules from the server rather than guessing from how stock markets usually work.
  • Run a trading bot. A key with trade can place and manage orders.

The same server, with a debug key, is what we use to diagnose a live league from a terminal — see Debugging with it.

Setup

  1. Create a key at https://ballstreetleague.com/dashboard/api-keys/. Pick the narrowest scopes that do the job, and scope it to one league if the bot only plays in one.

  2. Install it:

    pip install ballstreet-mcp
    

    Dependencies are just mcp and httpx. The package does not import Django and does not need a running BallStreet server or database — it is an HTTP client, so it runs anywhere. Python 3.10 or newer.

  3. Register it:

    claude mcp add ballstreet \
      --env BALLSTREET_API_KEY=bsl_xxxxxxxx_... \
      -- ballstreet-mcp
    

    For Claude Desktop, in claude_desktop_config.json:

    {
      "mcpServers": {
        "ballstreet": {
          "command": "ballstreet-mcp",
          "env": { "BALLSTREET_API_KEY": "bsl_xxxxxxxx_..." }
        }
      }
    }
    

Configuration

Variable Default Purpose
BALLSTREET_API_KEY — Required.
BALLSTREET_BASE_URL https://ballstreetleague.com Point at a local server for development.
BALLSTREET_READ_ONLY unset 1 withholds the trading tools even if the key allows them.
BALLSTREET_MAX_SHARES_PER_ORDER unset Client-side per-order share cap.

BALLSTREET_READ_ONLY and the share cap exist so you can bound a strategy you are still experimenting with, without revoking and reissuing the key. They are convenience rails on the client; the server's scopes are the real boundary.

Upgrading

pip install -U ballstreet-mcp

then restart your MCP client so the new version loads. Newer releases add tools, and an older copy cannot see them. You do not have to watch for releases: from 1.1.1 the server knows which version is calling, and an out-of-date copy is told at startup (its instructions begin with UPDATE AVAILABLE, and whoami reports mcp.update_available), so your assistant will tell you. Copies older than 1.1.1 get the same notice.

Tools

Tools are registered from what the key actually allows, discovered at startup. A read-only key does not merely get refused when it calls place_order — the tool is never offered, so the model does not plan around a capability it does not have.

Always available: whoami, market_primer, get_rules, search_rules

read: get_league_rules, list_leagues, get_market_state, list_players, get_player, get_price_history, get_player_news, get_holdings_news, get_player_holders, get_matchups, get_portfolio, get_portfolio_history, get_leaderboard, get_live_stats, list_orders, get_pending_orders

trade: place_order, cancel_order, reorder_pending_orders

Day Trading contests (with read, and only when the key's owner has Day Trading access; read only): list_contests, get_contest_rules, get_contest, get_contest_players, get_contest_portfolio, get_contest_leaderboard, get_contest_orders, get_contest_trades, get_contest_results. A key cannot place, cancel or reorder contest orders, or create, join or leave a contest: orders there fill every minute while games are on, so reaction time is an edge kept for people. A key scoped to one league does not reach contests.

debug (tester accounts only): debug_league, debug_player

Answering questions about the game

get_rules returns the official rules, glossary, and FAQ from the server, with every constant filled in from the live engine settings — so it cannot quote a number that has since been retuned. search_rules ranks them against a specific question ("why can't I buy him", "what is a short").

get_league_rules is the one that matters most for support answers. The universal rules have to hedge — demand pricing is optional, round counts are configurable — and this resolves them against what the league is actually set to. Answering "why did his price go up" without it risks describing a demand premium in a league that has demand switched off.

The rules endpoint is public, so an assistant can explain the game to someone who does not have an account yet.

What a bot should know about this market

market_primer is fetched from the server at startup. The short version, because it is genuinely different from the order-book markets most trading code assumes:

  • Trading does not move prices. No order book, no per-trade impact. Prices move at settlement and on projection updates.
  • Speed is not an edge. Buys queue and fill in a batch run ordered by a per-member priority that rotates each cycle. An order placed three seconds after an injury report fills at the same price as one placed three hours after it. Polling every second buys you nothing but a rate limit. (Hardcore leagues are the exception: they trade through games in one-minute batches with their own demand rule, and a key can read them but not trade in them. get_rules(topic="hardcore") has the details.)
  • Float is finite. league_size x 100 shares per player. When it is gone, buys are refused. This is the real scarcity — and the one place ordering matters, via your own fill_priority within your queue.
  • Halted players cannot be bought. IR/OUT/inactive. You can always sell or cover.
  • Performance is measured against projections, not raw points.

Disclosure

Placing an order through an API key marks your league membership bot_operated, which your leaguemates can see. Bots are a supported way to play; undisclosed ones are not.

Debugging with it

A key with the debug scope (tester accounts only) adds two read-only tools that expose what no screen shows:

  • debug_league — market state, both week counters, and the fill queue ordered by settlement_priority. This is what answers "why did my order not fill" and "why is it showing the wrong week".
  • debug_player — every component of a price: base, each multiplier, the share basis the posted price was built from, your own buy and sell prices, and recent price rows with their components.

debug_player also evaluates the two invariants server-side, so a diagnosis never depends on a client reassembling the arithmetic:

  • sell_never_above_buy — a hard invariant. False means a real bug.
  • posted_matches_recomputed — informational only. The posted price deliberately lags its own share basis between settlements, so a mismatch mid-week is expected on any player carrying demand.

There is no write path in the debug surface, by design. Diagnosing a pricing question needs reads, and a credential that can mutate a live league while investigating it is a category of accident worth designing out.

Releasing

./release-mcp.sh patch from the repo root. See RELEASING.md.

Rate limits

120 read requests/minute and 30 writes/minute per key, metered per key rather than per user so one bot cannot starve another integration. A 429 comes back with Retry-After.

Metadata

Release files for ballstreet-mcp 1.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for ballstreet-mcp 1.1.1
File Size Uploaded Provenance
ballstreet_mcp-1.1.1.tar.gz 16.8 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for ballstreet-mcp 1.1.1
File Interpreter ABI Platform
ballstreet_mcp-1.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 35.3 kB

Release files / ballstreet_mcp-1.1.1.tar.gz

Download URL ballstreet_mcp-1.1.1.tar.gz
Size 16.8 kB
Tags Source
SHA-256 checksum
How to use checksums
84eac16542caa19379ebc7534a20ed00d6e439c4beef2bd690c68912455a7451
BLAKE2b-256 checksum
How to use checksums
b5b1aceca8643cec912bbf5355e271a15361ef4a55b3af53d810b1216ae202eb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 23, 2026.

Transparency log

Release files / ballstreet_mcp-1.1.1-py3-none-any.whl

Download URL ballstreet_mcp-1.1.1-py3-none-any.whl
Size 18.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f1abb7bf8970d7f74a9c15865e191e951ba5f5ed20593d2ea58ba1917f515ce2
BLAKE2b-256 checksum
How to use checksums
70899ee9d72349998cc4d8ffdb369dfa7706e41f0793151783b11fa0845964b3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 23, 2026.

Transparency log

Security for ballstreet-mcp 1.1.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for ballstreet_mcp-1.1.1.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 23, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page