espn-mcp
This server gives an AI assistant full access to your ESPN fantasy football league — live draft help, roster and matchup analysis, waiver/trade advice, and value-based rankings — by fetching real league data and computing scarcity-aware metrics.
Draft tools: Get league settings, live draft state, available players ranked by VORP/projection/ADP, value board with replacement levels and tiers, and a one-call snapshots for when you're on the clock (
get_draft_context,next_pick).Draft management: Record picks manually or in bulk when ESPN's live draft API is unavailable, undo/reset picks, and refresh draft order after randomization.
Roster & matchup analysis: View any team's roster and unfilled starting slots, get full player details (projection, VORP, tier, ADP, injury), and analyze weekly matchups with optimal lineup suggestions.
Season-long tools: Evaluate rest-of-season projections, find waiver targets ranked by value over replacement, and analyze trades by comparing starting lineup strength before/after.
League-specific insights: Everything is computed relative to your league's team count, scoring rules, starting lineup positions, and draft type — so rankings and scarcity reflect your actual league.
Fast and reliable: Draft state is never cached (safe to poll), while player pools are TTL-cached; the server handles edge cases like placeholder picks, non-contiguous team IDs, and missing D/ST projections with clear messages.
Browser-script helpers: Includes scripts to drive a live draft room in a real browser, syncing picks into the server so the board stays correct.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@espn-mcpI'm on the clock, who should I take?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
espn-mcp
An MCP server that exposes your ESPN fantasy football league so an AI assistant can help you draft — live, during a snake draft, on the clock — and then manage the team through the season: start/sit by matchup, waiver claims, and trades.
It does not try to pick for you. It gives the model accurate, league-specific facts: who is actually available, what your roster still needs, how much value is left at each position, and how many picks you have before your next turn. The one thing it computes rather than reports is the value math (VORP, replacement level, tiers) — deterministic arithmetic that a language model should not be doing in its head.
Why VORP and not projected points
Ranking by projected points says take a QB first: the top QB outscores the top RB outright. That is wrong in a 1-QB league, because the twelfth QB also scores a lot, so the top QB's edge over a replacement-level starter is small. VORP measures each player against the last startable player at their position, which is the actual cost of passing on them.
Replacement level is derived from your league — team count and starting lineup — not from a rule of thumb. FLEX slots are allocated empirically: the server pools every flex-eligible player who is not already a dedicated starter, takes the best N by projection, and counts what positions they actually are. A league that starts 3 WR produces different scarcity than one that starts 2, and the board reflects that automatically.
Scoring is read from the league too, via scoringSettings.scoringItems, so PPR,
half-PPR, TE premium and fully custom scoring all work with no configuration.
Tiers come from 1-D k-means (Jenks natural breaks) over each position's draftable range, not a gap threshold. A global threshold does not work: elite players are genuinely far apart, so it makes each of them a singleton tier and dumps everyone else into one blob — which turns "players left in this tier" into a constant panic signal. Clustering adapts to the local scale. Each position also reports the next tier's size and the VORP drop into it, which is the number that actually answers "can I wait until my next pick?"
Related MCP server: Sleeper MCP Server
Setup
python3 -m venv .venv
./.venv/bin/pip install -e ".[dev]"
cp .env.example .env # then fill it inCredentials
ESPN_LEAGUE_ID is the number in your league URL:
https://fantasy.espn.com/football/league?leagueId=123456789
ESPN_TEAM_ID is the teamId in the URL when you open your own roster.
If the league is private (most are), you also need two cookies from a browser
logged in to ESPN — DevTools → Application → Cookies → fantasy.espn.com:
espn_s2— a long URL-encoded string, copy the whole valueSWID— a UUID including the surrounding braces
These are session credentials. Treat them like a password. They grant access
to your ESPN account's fantasy data. .env is gitignored; keep it that way, and
do not paste these into a chat, an issue, or a shared log. They also expire — if
tools start returning auth errors mid-season, re-copy them.
Verify before draft day
./.venv/bin/python scripts/doctor.pyPrints your league format, replacement levels and a top-10 board. If that works, the server works. Run it well before the draft, not ten minutes prior.
Register with Claude Code
claude mcp add espn-fantasy -- "$(pwd)/.venv/bin/python" -m espn_mcp.serverTools
Tool | Purpose |
| Team count, scoring, starting lineup, draft date and slot. Call once. |
| The on-the-clock call. State + your needs + best available + tier depth + position runs, in one round-trip. |
| Picks made, who's on the clock, your next picks. Never cached. |
| Undrafted players ranked by VORP, projection, or ADP. |
| Replacement levels and tier structure — the why behind the rankings. |
| Any team's roster and unfilled starting slots. |
| One player's projection, VORP, tier, ADP, injury status. |
| The on-the-clock call. Compact: candidates that fill a real hole, tier cliffs, picks until your turn. ~1KB. |
| Batch-record picks by name. Persisted, so you only ever send what's new. |
| Single pick, undo, and clearing state before a new draft. |
| Re-read the order and your slot after a randomized draw. |
| Force a pool re-fetch (injury news, depth chart change). |
In season:
Tool | Purpose |
| The weekly call. Your opponent, both lineups by this week's projection, the exact start/sit swaps and what they gain, holes on either side (bye, OUT, empty slot), ESPN's win probability. Pass |
| Every unrostered player scored by what adding him does to your optimal lineup (rest-of-season and this week), plus drop candidates, waiver clear times and your priority/FAAB. |
| Both sides of a proposed trade, before and after: starting-lineup strength, this week, bench value, roster size and position limits, suggested drops. |
| The league's transaction log, newest first: every lineup move (player, from slot, to slot), add, drop, waiver claim and trade, with team and timestamp. Filter by team, week or kind. The only view of history; rosters show the present. |
| Which teams are weak where you are strong and vice versa, with their tradeable players, your surplus, each team's trade block, and the best 1-for-1 that helps both sides. |
| In season: a team's starters and bench with lineup slots, this week's and rest-of-season projections, positional strength. |
The player pool is cached for ESPN_POOL_TTL seconds (default 15 min) because
it is slow and changes slowly. Draft picks are never cached; rosters are cached
for 60 seconds because waivers and trades move them.
During the draft
Ask in plain language — "I'm on the clock, what should I take?" — and the model
will call get_draft_context and reason over it. Useful follow-ups:
"How much RB value is left before the tier breaks?"
"Can I wait on TE until my next pick, or does the tier empty first?"
"Who's fallen furthest below their ADP?"
"What does team 7 still need?" (they pick right before you)
get_draft_context includes picks_between_this_and_next, which is the number
that actually matters at a turn: how many players come off the board before you
choose again.
Speed. Since ESPN publishes no picks until a draft ends, the picks you
report are the draft. They persist to state/, so each turn only needs the
picks made since the last one -- never the whole board. That, not the API, was
the real clock cost: re-stating 100+ names per turn. Recording 8 picks takes
~380ms (was ~540ms each), and next_pick answers in ~90ms with a ~1KB
payload. Server-side compute is 0.3ms; everything else is one ESPN round-trip.
ESPN's stat columns, and which matter for a draft
Mapping ESPN's glossary onto what this server exposes:
ESPN | Exposed as | Draft relevance |
PROJ |
| Yes — but the season total, not ESPN's weekly "upcoming game" figure |
%ROST |
| Weak. Popularity, already priced into ADP |
+/- |
| Moderate — a week's move in rostered % |
%ST |
| Weak pre-draft; no lineups have been set |
PRK |
| Recomputed by VORP, not ESPN's ranking |
OPRK | not exposed | No — a single-week matchup rating |
PVO | not exposed | No — position vs a specific week's opponent |
LAST | not exposed | No — last game's score; no games played yet |
OPRK, PVO and LAST are in-season lineup tools. They describe one week against one opponent and say nothing about a player's season value, which is what a draft is buying.
The most useful field is not in the glossary: averageDraftPositionPercentChange,
exposed as adp_moving ("earlier" / "later") plus adp_change_pct. ADP is
a lagging average — it is computed over drafts that already happened, so a
player who just won a starting job still carries a stale, too-late ADP. That
makes him look like a bargain in a value-vs-ADP comparison right up until the
moment he does not last to your pick. Direction of travel is what separates a
real value from a stale number, so every falling_below_adp entry is annotated
with it.
Note the sign convention: the change applies to the ADP number, so positive means being drafted later (cooling off), not hotter. The server reports a direction word rather than a bare signed float for exactly that reason.
get_draft_context also reports adp_as_of and adp_age_hours, since the
whole "will he last?" question rests on how current the market data is.
During the season
Two projections matter in season and they answer different questions, so every in-season record carries both:
week_proj— ESPN's projection for one week. It already reflects the NFL opponent, the injury designation and the bye, which is whyget_matchupuses it for start/sit: a player's season value is irrelevant to whether he should start this week against that defense.ros_pg— rest-of-season points per remaining game. ESPN publishes a full-season projection and season-to-date actuals but no rest-of-season figure, so ROS is the difference, divided by the games the player has left (a bye still ahead counts against him). This is what a roster spot is worth from here on, and it is the basis for in-season VORP, waiver value and trade value. In week 1 it equals the draft board.
Everything is measured as a change to your optimal starting lineup, because
that is the only thing that scores. A waiver pickup who sits behind what you
already have gains 0 no matter how good his projection looks; a trade is
judged by what each side's lineup projects to before and after. The lineup is
solved the same way for every team — dedicated slots first, then flex — so
team strength is comparable across the league, which is how
find_trade_partners spots a team weak at WR and deep at RB.
Typical asks:
"Who should I start this week?" →
get_matchup. Lists the swaps, with the gain;holesflags a starter on bye or OUT before kickoff does."Anyone worth a claim?" →
get_waiver_targets.targetsis ranked by lasting lineup gain,streamers_this_weekby this week only (D/ST and K live here),best_depth_by_ros_vorpis the stash list, anddrop_candidatesis who to cut for him.waivers_clearsays when a claim processes."Is this trade good for me?" →
analyze_trade. Give names, get both sides' before/after. The partner is inferred from the players you receive."Who should I be trading with?" →
find_trade_partners, optionally for one position.best_1_for_1is a concrete opener that helps both lineups;mutual: falsemeans every fit found is lopsided."Next week I have three guys on bye" →
get_matchup(week=N).
opp_rank_vs_pos is ESPN's OPRK — points a defense allows to a position, 1 =
softest matchup, 32 = stingiest. It is empty until games have been played, so
it appears from week 2.
Desktop: live matchup in the Omarchy bar
scripts/feed_sync.py bridges this league into the
Fantasy Feed Omarchy plugin
(a fork with league support). It writes your and your opponent's starters,
the league's scoring rules, and ESPN's live matchup totals into files the
plugin watches, so the bar shows ME 41.2 – 37.9 TM2 and the panel shows
both lineups scored the way ESPN scores them. The plugin never sees your
cookies; this script does the fantasy-API reads.
./.venv/bin/python scripts/feed_sync.py --once # sync now
./.venv/bin/python scripts/feed_sync.py --install-service # then enable the unit it printsThe service re-syncs every 15 minutes while nothing is on. While the plugin reports games in progress it re-syncs every minute, lineups included, so a start/sit change on ESPN reaches the bar within a minute.
ESPN quirks handled
Found by running against a real league; each has a regression test.
Placeholder picks, and negative player ids. An unstarted draft does not return an empty pick list. ESPN pre-seeds every slot — all 170 of them in a 10×17 league — with
playerId: -1, which at face value reads as a completed draft. The obvious filter,playerId > 0, then introduces a worse bug: D/ST ids are negative (-16001..-16034), so every drafted defense is silently dropped, the pick count drifts, and defenses stay in the available pool after being taken.-1must be matched exactly. Found by simulating a full 170-pick draft; invisible to spot checks of the top of the board.No D/ST projections. Every defense comes back projected at 0.0, so VORP for them would be a uniform 0 — which would sort them above genuinely negative-value players. Positions with no projections are marked
ranked_by: espn_adp, getvorp: null, and sort below everything ranked on real value while staying ADP-ordered among themselves.Non-contiguous team ids. A 10-team league can have ids
[1,2,3,6,7,8,9, 10,12,13]. Draft slot comes from position in the order, never from the id.Weekly projections are one week per request.
kona_player_inforeturns the stat split11{season}{week}only when the request'sscoringPeriodIdis that same week, whatever the filter asks for. Each week the season tools look at is therefore its own pool fetch (about half a second), cached per week.Draft time is epoch milliseconds in UTC. Any US evening draft therefore reads as the next day in UTC — a draft the league page shows as "Mon Sep 7 at 8:00 PM" comes back as
2026-09-08T00:00:00Z.get_league_settingsrenders it in the machine's local zone alongside the UTC value, plus a countdown, so it matches what the site says.Randomized draft order. Leagues that draw the order shortly before the draft rewrite it late. Two consequences, both handled: league settings are TTL-cached rather than cached forever, and the order is read from ESPN's published pick schedule — every slot in
draftDetail.pickscarries ateamIdeven before anyone picks — which is live, uncached, and updates the moment the draw happens.get_league_settingssetsdraft_slot_is_provisionalwhen the published order is still teams in id order, andrefresh_draft_orderforces a re-read after the draw.Using the published schedule also means the snake pattern is never assumed: formats like third-round reversal come through correctly because ESPN states who owns each pick rather than us inferring it.
Failure modes
This uses ESPN's undocumented v3 API. It can change or rate-limit without notice.
Snapshot first. Run
scripts/snapshot.pyshortly before the draft. It writes a full JSON and CSV board tosnapshots/, so an outage mid-draft leaves you with a usable board rather than nothing.Cookies expire. Re-copy them if you see auth errors. The server reports these as readable messages rather than raising.
Picks are not readable during a live draft. This is the big one, and it was verified end to end against a real 10-team league drafted start to finish. While the draft was in progress — dozens of picks made, visible in the browser — the read API reported
picks_made: 0and every roster empty, across ~60 polls over five minutes, unauthenticated and with cookies alike. The moment the draft completed, all 160 picks and all 160 roster entries appeared at once.ESPN's draft room is a separate real-time system; the league API is only written at completion. So polling cannot drive a live draft. Use
record_pickto enter picks by name as they happen — that path carried an entire real draft and is what draft day should rely on.A practice draft is worse still: it never persists at all, so it cannot even be used to test this.
Offline drafts, or a live draft that stops reporting. Use
record_pickto enter picks by name — "Gibbs" is enough. The team defaults to whoever the schedule says is on the clock, ambiguous names return candidates instead of guessing, and already-drafted players are refused. Manual picks merge with anything ESPN does report, so the pool stays correct either way. This is the insurance policy for draft night;undo_pickreverses mistakes.Run it locally. ESPN blocks some datacenter IP ranges.
Projections are ESPN's. They are mediocre in absolute terms. The value math and ADP-vs-value gaps are where the edge is, since ESPN's ADP reflects what your ESPN leaguemates will actually do.
Browser scripts (live draft room)
scripts/live_draft.py, autodraft.py, draft_player.py and sync_from_room.py
drive a real browser because ESPN has no live-draft API. Two things to know
before using them:
--attachuses Chrome's remote debugging port. Starting your browser with--remote-debugging-port=9222lets any local process read every tab, cookie and session in that browser, not just ESPN. Do it on a machine you control, close that browser instance when the draft ends, and never expose the port beyond127.0.0.1.state/holds session material.state/browser-profile/is a full logged-in browser profile (cookies, saved logins) andstate/discover.logcaptures raw draft-room traffic including every manager's member GUID. Both are gitignored. Do not copy or share them.
Tests
./.venv/bin/python -m pytest tests/ -q83 tests, no network or credentials required — the ESPN client is stubbed with real-shaped payloads, so the value math, snake pick ordering, board assembly, lineup solving, trade/waiver arithmetic and tool wiring are all verified offline.
Layout
src/espn_mcp/
config.py env loading
espn.py HTTP client, auth, error messages
constants.py ESPN's position/slot/team id maps
scoring.py league shape parsing, league-scored projections
value.py replacement level, VORP, tiers (pure, unit tested)
season.py rest-of-season, optimal lineups, trade/waiver deltas (pure, unit tested)
board.py caching layer, draft state, snake pick math, in-season rosters/matchups
server.py MCP tool definitions
scripts/
doctor.py pre-draft credential and access check
snapshot.py offline fallback board
feed_sync.py bridge to the Omarchy Fantasy Feed plugin (matchup + scoring)Available Tools
14 toolsget_available_playersA
Undrafted players, ranked.
Args: position: QB, RB, WR, TE, K or D/ST. Omit for all positions. limit: how many to return. sort_by: "vorp" (value over replacement, the default and usually right), "projected_points" (ignores scarcity), or "espn_adp" (what your leaguemates are likely to do).
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| sort_by | No | vorp | |
| position | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, and the description does not disclose any behavioral traits such as read-only, side effects, or data persistence. It only states what the tool returns, leaving the user to infer whether it modifies state or has other implications.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is succinct and well-organized. It uses a short introductory phrase, then a clear bullet-like list of parameters with no redundant or extraneous information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description gives enough context for a simple read operation: it confirms the output is a ranked list of undrafted players. It lacks details on returned fields or error handling, but given the low complexity and absence of an output schema, the information is adequate.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
All three parameters are fully described: position lists allowable values and the omit-all behavior, limit explains its purpose, and sort_by enumerates all options with explanations. This provides complete semantic coverage beyond the bare schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: 'Undrafted players, ranked.' It then enumerates each parameter with its meaning and valid values, leaving no ambiguity about what the tool does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains how to use each parameter (e.g., position options, sort_by choices, limit meaning) and indicates defaults. However, it does not explicitly state when to prefer this tool over similar siblings like get_player or get_roster, so guidance on tool selection is lacking.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_draft_contextA
One-call snapshot for when you are on the clock.
Bundles draft state, your roster needs, the best available at each position with tier depth, recent-pick position runs, and the biggest ADP fallers -- everything needed to make a pick inside a 60-90 second clock.
| Name | Required | Description | Default |
|---|---|---|---|
| top_per_position | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description must carry the burden of behavioral disclosure. It lists the data categories bundled, implying a read-only aggregation operation, but it never explicitly states that it is non-destructive or that it does not modify any state. It also does not mention performance or rate-limit implications despite aggregating many data points.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two concise sentences, front-loaded with the key phrase 'One-call snapshot'. It lists the bundled components in a clear, scannable list and wastes no words. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
While the description covers the main content categories, it omits the parameter explanation and provides no hint about the output structure. Since there is no output schema, the agent is left without information on how the response is formatted or how to interpret the bundled data.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has 0% description coverage and the tool description does not mention the 'top_per_position' parameter at all. The agent has no guidance on how to set this value beyond its name and default, making correct invocation a guess.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it is a 'One-call snapshot' that bundles draft state, roster needs, best available players, ADP fallers, etc. This makes the purpose unambiguous and distinguishes it from sibling tools that focus on individual data sources like get_draft_state or get_available_players.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly says 'when you are on the clock' and 'everything needed to make a pick inside a 60-90 second clock', conveying the ideal usage scenario. However, it does not explicitly mention when not to use it or direct to alternatives for more granular data, leaving some ambiguity about edge cases.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_draft_stateA
Live draft state: picks made so far, who is on the clock, your next picks.
Never cached. Safe to poll every few seconds during a live draft.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses two behavioral aspects: the tool is never cached, and it is safe for frequent polling. These facts imply a read-only, low-risk operation, giving the agent confidence about side effects and performance.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is extremely concise, consisting of two short sentences. Every word adds value, covering the tool's output and usage guidance without any fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description provides sufficient context about what the tool returns and how frequently it can be called. It omits details about the output format or potential error conditions, but for a simple state retrieval tool, the information is adequate.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes no parameters, so there is nothing to describe. The schema already reflects this, and the description adds no unnecessary parameter details. Perfect score is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool returns live draft state including picks made, who is on the clock, and the user's next picks. Though it uses a noun phrase instead of an explicit verb, the intention is unambiguous and distinct from sibling tools like get_draft_context.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly notes the tool is never cached and is safe to poll every few seconds during a live draft. This provides clear guidance on when to use it, though it does not contrast with alternatives or state when not to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_league_settingsA
League format: team count, scoring rules, starting lineup, draft type.
Call this once at the start of a session -- every other tool's numbers are relative to this league's shape.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It implies a read-only operation by describing a static league format and advising a single call, but it does not explicitly state that it has no side effects or that it can be called safely multiple times. The note about calling once suggests idempotence, but not explicitly. A getter typically needs to disclose read-only status, which is absent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, front-loads the core content (what the tool returns), and then gives usage guidance. There is zero waste; every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no parameters and no output schema, the description must explain what the tool returns and when to use it. It lists the key attributes and explains the foundational nature of the tool. This is complete for a zero-parameter getter with no side effects.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so the baseline is 4. The description adds no parameter-specific information, but none is needed. It correctly avoids redundant content.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description explicitly states the tool returns league format details (team count, scoring rules, starting lineup, draft type). This is a clear, specific resource that distinguishes it from siblings like get_draft_state or get_roster, which deal with different aspects of the draft.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly instructs to call this once at the start of a session and explains why: every other tool's numbers are relative to this league's shape. This provides clear timing and dependency guidance, making it obvious when to use this tool over alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_playerA
Full detail on one player: projection, VORP, tier, ADP, injury status.
Search by name (partial match) or exact player_id.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | ||
| player_id | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
There are no annotations to indicate side effects or safety. The description does not explicitly state that this is a read-only operation with no modifications, nor does it disclose any potential limitations or errors. Since annotations are absent, the description carries the full burden for behavioral transparency and falls short.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, concise and directly to the point. It efficiently conveys the output content and the search options without unnecessary fluff or repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description provides adequate detail on what is returned and how to search. However, it leaves ambiguity about whether at least one parameter must be provided, what happens if both are given, or behavior when neither is supplied. These gaps make it incomplete for fully guiding an agent in some edge cases.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description adds meaningful semantics to both parameters: 'name' is explicitly described as a partial match, and 'player_id' is described as exact. This clarifies the expected input format and behavior beyond the raw schema types, covering all parameters present in the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: retrieving full detail on one player, listing the specific attributes (projection, VORP, tier, ADP, injury status). It distinguishes itself from sibling tools by focusing on a single player and mentions the search methods.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description does not provide explicit guidance on when to use this tool versus alternatives. It does not mention that this should be used for single-player lookups while other tools handle lists, rosters, or draft context. The 'when to use' information is only implicitly conveyed through the tool name and sibling names.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_rosterA
A team's current roster and which starting slots are still unfilled.
Defaults to your team (ESPN_TEAM_ID).
| Name | Required | Description | Default |
|---|---|---|---|
| team_id | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description bears the full burden of behavioral disclosure. It states it returns a team's roster and unfilled starting slots, which implies a read-only operation, but it does not explicitly say it is read-only, mention any side effects, or describe error conditions (e.g., invalid team_id). It also does not mention authentication requirements, which are implied by 'your team.' This is minimal but not contradictory.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences with no filler. The core purpose is front-loaded, followed by the default behavior. Every word earns its place, making it easy for an agent to parse quickly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description should outline what the response contains. It says 'current roster' and 'unfilled starting slots,' which is the key information, but it does not describe the structure, whether player details are included, or any edge cases (e.g., empty roster, invalid team). Given the low complexity (one optional param), this is adequate but leaves room for improvement.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The only parameter, team_id, has zero schema description coverage. The description adds meaning by explaining that it defaults to ESPN_TEAM_ID when null, which is valuable. However, it does not elaborate on what team_id represents or the valid range/format, leaving some ambiguity. It compensates for the schema gap reasonably well but could be more explicit.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a specific verb ('get') and resource ('roster'), and goes further by specifying it also reports which starting slots are unfilled. It distinguishes itself from sibling tools like get_available_players and get_player by focusing on the team's current roster and lineup status. The purpose is unambiguous and immediately understood.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context by noting that it defaults to your team (ESPN_TEAM_ID), which implicitly tells the agent when no team_id is provided. It does not explicitly name alternatives or state when not to use it, but given the sibling set, the use case is evident. It lacks explicit exclusions or 'use instead' guidance, so it misses the top score.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_value_boardA
Replacement levels and tier structure for the league.
Explains why the rankings look the way they do: how many players at each position are startable league-wide, and what the last startable player at each position projects for.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses what information the tool returns (startable player counts per position and the last startable player's projection). It does not mention side effects, but given the nature of the content, it is inferred to be read-only. No annotations are present, so the description carries the burden adequately.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise, consisting of two sentences. It front-loads the main purpose ('Replacement levels and tier structure') and then elaborates with specific details, maintaining clarity without unnecessary verbosity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description adequately explains the tool's output conceptually, covering key aspects such as player counts per position and projections. However, it does not define 'replacement levels' explicitly, which might be assumed domain knowledge. Still, it is sufficient for an agent to understand the tool's function.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema is empty, so there are no parameters to describe. The description correctly omits any parameter details, and there is no missing information in this dimension.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: providing replacement levels and tier structure for the league. It expands on this by explaining why rankings look the way they do, which is a specific and unambiguous function.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description does not explicitly state when to use this tool versus the sibling tools (e.g., get_draft_state, get_available_players). It implies a use case for understanding rankings, but lacks direct contrast or guidance on selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
next_pickA
The single call to make when you are on the clock.
Returns only what a pick decision needs: the best available players that fill an actual roster hole, the tier cliff behind each, and how long until your next turn. Deliberately small -- a draft clock is 60 seconds.
| Name | Required | Description | Default |
|---|---|---|---|
| candidates | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden of disclosing behavior. It states the output contents and that the tool is intentionally lightweight, but it does not mention potential limitations, error conditions, or whether it performs any side effects. Some transparency is present, but not comprehensive.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, direct, and front-loaded. It conveys the purpose and key output details without unnecessary jargon or filler, making it easy to parse quickly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given a single parameter and no output schema, the description should clarify the parameter's role and possibly outline output format or caveats. It explains the overall purpose but leaves the parameter ambiguous and omits edge-case behavior, making it incomplete for a tool that requires user input.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The only parameter, 'candidates', is not described in the schema or the description. The schema provides only type and default, with zero coverage. The description does not compensate, leaving the parameter's meaning entirely unclear.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states that this is the go-to call when making a pick, and specifies exactly what it returns: best available players, roster fit, tier cliff, and time until next turn. This distinguishes it from general draft tools despite not explicitly naming siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly says to use it 'when you are on the clock' and notes it is 'deliberately small' for a 60-second draft clock, giving a clear temporal trigger. However, it could more explicitly contrast with sibling tools like get_draft_context or record_pick to fully guide selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
record_pickA
Manually record a pick when ESPN is not reporting the draft.
Use this if picks stop appearing in get_draft_state during a live draft, or for a draft held outside ESPN's draft room. Recorded picks merge with anything ESPN does report, so the available pool stays correct either way.
Args: player: Player name, full or partial ("Gibbs", "jahmyr gibbs"). player_id: Exact id, if you have it instead of a name. team_id: Who made the pick. Defaults to whoever is on the clock.
Ambiguous names are not guessed -- the candidates come back instead.
| Name | Required | Description | Default |
|---|---|---|---|
| player | No | ||
| team_id | No | ||
| player_id | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden of explaining behavior. It does mention merge behavior and ambiguous-name handling, but it does not disclose side effects, whether existing picks can be overwritten, or what errors/responses might occur.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise, well organized, and free of unnecessary detail. The Args section maps cleanly to the schema parameters and adds useful guidance without bloat.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description provides sufficient context for typical use: when to call it, how merging works, and how ambiguous names are handled. It lacks output/error expectations and explicit differentiation from record_picks, but the core usage context is present.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description adds meaning to all three parameters, including acceptable formats, defaults, and the difference between player name and player ID. It does not explicitly state that player and player_id are mutually exclusive, though the phrasing strongly implies it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: manually recording a pick when ESPN is not reporting draft data. It also provides concrete use cases and distinguishes the action from normal draft-state retrieval.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains when to use the tool (live draft reporting gaps or off-ESPN drafts) and notes how recorded picks merge with ESPN data. However, it does not explicitly differentiate this singular record_pick tool from the sibling record_picks tool, which could cause ambiguity in batch scenarios.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
record_picksA
Record several picks at once, in draft order, by name.
The fast path during a live draft: ESPN does not publish picks until the draft ends, so these ARE the draft. Recorded picks persist, so you only ever send the picks made since your last call -- never the whole board.
Re-sending the entire pick history is fine and is the intended way to sync -- players already recorded are counted and ignored, and only the new names are appended, in the order given. Unrecognised or ambiguous names are reported without blocking the rest.
| Name | Required | Description | Default |
|---|---|---|---|
| players | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It thoroughly explains that picks persist, only new names are appended, duplicates are ignored (idempotent re-sending), order is preserved, and unrecognized or ambiguous names are reported without blocking the rest. These are critical behavioral traits that go beyond the schema and give the agent full transparency into side effects and error handling.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three short paragraphs, each with a distinct purpose: the core function, the live-draft context, and the sync/error behavior. It is front-loaded with the main purpose and keeps each sentence informative without fluff. It could be slightly more concise, but the structure is logical and easy to scan.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with only one parameter, no output schema, and no annotations, the description is remarkably complete. It covers when to use (live draft, since ESPN delays publication), how to use (incremental vs full sync), and what to expect (duplicates ignored, ambiguous names reported). An agent has everything needed to call the tool correctly without further clarification.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has a single 'players' parameter with 0% description coverage, so the description must compensate. It does so by explaining that the array contains player names, that the order matters (draft order), and that names may be ambiguous or unrecognized and will be reported. While it does not specify the exact name format (e.g., first/last, team abbreviations), it adds meaningful semantics about ordering and error handling, which is more than the bare schema provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool records multiple picks by name in draft order, using a specific verb ('Record'), a resource ('picks'), and a scope ('several at once'). It implicitly distinguishes from the singular sibling record_pick by emphasizing 'several picks at once' and 'in draft order', giving an agent unambiguous understanding of its function.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit usage context: it is the fast path during a live draft because ESPN does not publish picks, and it explains the incremental sync strategy ('only ever send the picks made since your last call'). It also clarifies that re-sending the entire history is intended for syncing, which informs when to use this tool versus alternatives. While it does not name record_pick directly, the guidance is clear enough for an agent to select the correct tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
refresh_boardA
Force a re-fetch of the player pool, projections and value math.
The pool is cached for ESPN_POOL_TTL seconds. Call this if projections changed (injury news, depth chart move) or the cache looks stale.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden of disclosing behavior. It mentions that it forces a re-fetch and that the pool is cached for a TTL, which explains the operation's effect. It does not mention potential side effects like performance cost or return format, but the core behavior is transparent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, tightly focused on the action and its trigger condition. It front-loads the primary purpose and avoids any extraneous detail. No wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description explains what the tool does and when to use it, but there is no output schema and the description does not mention what the tool returns (e.g., status, updated data). This omission could leave an agent uncertain about the result. Given the simple nature of the tool, this is a minor gap but still incomplete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so the schema trivially covers everything. The description adds no parameter explanation, which is appropriate given there are none. The baseline for 0 params is 4, and the description does not need to elaborate further.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: forcing a re-fetch of the player pool, projections, and value math. It also provides the rationale for why this is needed (caching, staleness). This is a specific and unambiguous purpose.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says when to call the tool: when projections change (injury news, depth chart move) or the cache looks stale. It does not explicitly contrast with sibling tools like get_available_players, but the 'call this if...' condition gives clear usage direction.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
refresh_draft_orderA
Re-read the draft order and your slot.
Call this after a randomized draft order is drawn (many leagues randomize shortly before the draft starts). League settings are otherwise cached, so a session opened before the draw would keep the old order.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the burden. It discloses the refresh behavior and the caching rationale, which is useful context beyond the name. However, it doesn't state side effects (presumably none) or the return format, leaving some gaps.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with no waste. The primary action is front-loaded, and the usage context follows. Every word earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter refresh tool, the description explains what it does, when to call it, and why (caching issue). It doesn't describe output, but the purpose implies the returned draft order. This is adequate for correct agent invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has 0 parameters, so the description need not add parameter details. Per guidelines, baseline is 4 when no parameters exist. The description appropriately avoids extraneous parameter information.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific action ('Re-read the draft order and your slot') with a clear resource. It distinguishes itself from siblings by the refresh nature, though it doesn't explicitly name alternatives. The purpose is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It provides explicit guidance on when to call: 'after a randomized draft order is drawn' and explains the caching scenario. It doesn't mention alternatives, but the context is clear enough for correct invocation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
reset_draftA
Clear all manually recorded picks. Use before a new draft.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden of explaining behavior. It clearly indicates a destructive bulk reset ('clear all') but does not mention whether the action is reversible or if it affects other draft data. This is acceptable but not fully transparent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is extremely concise: two short sentences that state the action and the recommended usage context. There is no unnecessary fluff or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description is complete enough for this simple tool. It clearly states what is cleared and when to use it. However, it does not describe the post-condition (e.g., draft becomes empty), which would slightly enhance completeness. Still, given the simplicity, it is nearly complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes no parameters (schema coverage 100% with zero params), so the baseline score of 4 applies. The description correctly omits any parameter details since none exist.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description 'Clear all manually recorded picks' uses a specific verb ('clear') and a clear resource ('manually recorded picks'), distinguishing it from sibling tools like record_pick and undo_pick. It unambiguously states the action performed.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'Use before a new draft' provides explicit guidance on when to invoke this tool. It could be more detailed about when not to use it, but the primary use case is clearly communicated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
undo_pickA
Remove the most recently manually recorded pick.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations to fall back on, the description carries the full burden of disclosing behavior. It states that a pick is removed, but it does not mention permanence, error conditions when no manual pick exists, or any side effects beyond removal.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, focused sentence with no filler. It immediately states the action and the target, making it highly concise and well-structured.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with no parameters and no output schema, the description provides enough context to understand the core operation. It could mention what happens when there is no manual pick to remove, but that is a minor gap for such a simple action.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters and an empty input schema, so parameter descriptions are unnecessary. The baseline of 4 applies because no parameter guidance is needed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Remove') and a precise object ('the most recently manually recorded pick'), making the tool's purpose immediately clear and distinguishable from siblings like record_pick or reset_draft.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit guidance is given about when to use this tool versus alternatives, such as record_pick or reset_draft. The qualifier 'most recently manually recorded' implies a condition, but there is no direct 'use this when' or 'do not use for' instruction.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
14 tool updates
v0.1.0- First observed
get_available_players - First observed
get_draft_context - First observed
get_draft_state - First observed
get_league_settings - First observed
get_player - First observed
get_roster - First observed
get_value_board - First observed
next_pick - First observed
record_pick - First observed
record_picks - First observed
refresh_board - First observed
refresh_draft_order - First observed
reset_draft - First observed
undo_pick
TDQS
Scored across 14 tools
Most tools target a distinct data source or action, such as league settings, draft state, rosters, players, and the value board. The main ambiguity is between get_draft_context and next_pick, but their descriptions clearly separate a comprehensive snapshot from a deliberately minimal on-the-clock call.
The tool names overwhelmingly follow a snake_case verb_noun pattern: get_*, record_*, refresh_*, undo_pick, and reset_draft. next_pick is the one clear deviation from the verb-first convention, though it remains readable and does not undermine the overall consistency.
14 tools is well within the ideal range for a fantasy-draft assistant and each tool has a defined role in the draft workflow. The count covers pre-draft research, live draft operations, manual syncing, and cache refreshes without feeling bloated.
The tool surface covers the full draft lifecycle: league context, live draft state, player pool and valuations, roster needs, decision support, manual pick recording, undo/reset, and refreshes for both the board and draft order. There are no obvious dead ends for the stated purpose.
Maintenance
Related MCP Connectors
Read-only ESPN, Sleeper, and Fantrax fantasy leagues for Claude, ChatGPT, and other AI tools.
The full 2026 fantasy draft board, free to any AI agent. No key, no email, no signup.
- NFL MCPOAuthcom.nflmcp
NFL analytics tools for AI agents: stats, fantasy, injuries, schedules, and advanced analysis.
Read-only fantasy analysis for ESPN, Yahoo, and Sleeper leagues via MCP
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceAI-powered Yahoo Fantasy Football assistant for lineup optimization, draft strategy, and league management with player enhancement and multi-league support.82MIT
- FlicenseAqualityCmaintenanceEnables natural language interaction with Sleeper Fantasy Football API data, allowing queries about leagues, players, matchups, draft results, and trade analysis.1321-
- AlicenseNot gradedqualityCmaintenanceManages ESPN fantasy football teams post-draft, enabling lineup optimization, waiver/free agent recommendations, injury tracking, trade analysis, and playoff odds via read-only tools.MIT
- AlicenseAqualityBmaintenanceMCP server that acts as a live fantasy football draft assistant, syncing ESPN or Sleeper boards and providing pick recommendations with reasoning and survival odds.12253MIT