Agent tools
Point your MCP client at https://thetennisdesk.com/api/mcp. Free questions need no key, so your agent can look up teams, players, clubs and leagues with the address alone.
A forecast, or a question about you, needs a sign-in. A client that supports OAuth 2.1 signs you in with a code the Desk emails you. Otherwise, make a free key on the agent page and send it in the header Authorization: Bearer <key>.
The steps for each client are on Connect an agent, which also says how many calls your account gets.
Which tool answers which question
Ask in your own words, and your agent picks the right tool.
Several tools give a player's Desk level, the Desk's own estimate of how well they're playing now, worked out from match results every day. A Desk level uses the same scale as your NTRP rating. Your league still goes by the rating USTA gives you.
Teams and leagues
| question | tool |
|---|---|
| “How has Tiburon's team been doing, and who do they play next?” | query_team_record |
| “What happened the last time we played Mill Valley?” | query_matchup |
| “Who is on Tiburon's roster this season, and at what ratings?” | query_roster |
| “What is our team's win rate this season?” | compute_aggregate |
| “How are their 4.0 players doing compared with their 3.5s?” | compute_roster_strength |
| “Which match did we put out our strongest lineup in this season?” | compute_match_line_ratings |
| “When is our next match, and is it home or away?” | query_team_forecast |
| “Where did we finish in our league this season?” | query_league_standings |
| “How have our playoff chances changed this season?” | query_playoff_history |
| “What did the Desk give us last match, and how did it go?” | query_forecast_results |
Players
| question | tool |
|---|---|
| “How has my doubles partner done in their last few matches?” | query_player_history |
| “How did my Desk level change over this season, match by match?” | query_match_log |
| “How strong a player is my next singles opponent?” | query_player_rating |
Clubs
| question | tool |
|---|---|
| “Which teams does Belvedere have this year?” | query_club_teams |
| “How is Scott Valley doing against other clubs this season?” | query_club |
Forecasts, with a Desk Pass
| question | tool |
|---|---|
| “How strong is Tiburon on each line, and what are our chances?” | plan_lineup |
| “If my partner and I play their top doubles pair, who is likely to win?” | predict_matchup |
| “What are our chances of making the playoffs?” | project_standings |
| “Can you scout Tiburon's men's 3.5 team for me?” | scout_team |
About you, signed in
| question | tool |
|---|---|
| “Which teams have I played for this year?” | query_my_teams |
| “Where do I rank among the 4.0 men in my age group?” | query_cohort_standing |
| “Do I have the Desk Pass, and how many forecasts do I have left?” | get_desk_pass |
USTA NorCal forms
| question | tool |
|---|---|
| “Who should play each line on Saturday, from who said yes on NorCal?” | plan_lineup_from_availability |
| “How do I enter last night's scores on NorCal?” | prepare_score_entry |
| “Can we post our home match for Saturday evening?” | match_date_check |
| “Who hasn't answered for Sunday, and what should I text them?” | availability_loop |
Research
| question | tool |
|---|---|
| “How do players usually do the season after they get bumped up?” | read_research |
The Desk itself
| question | tool |
|---|---|
| “What is a Desk level, and how does it compare with my NTRP rating?” | read_docs |
| “Which leagues and areas does the Desk cover?” | query_coverage |
Each tool, and what your agent reads
The Desk's server lists 29 tools. Under each tool's name are its title and what it gives, and its fold holds the description your agent reads, word for word, with the tool's arguments.
An answer that names a team, player, club or league the Desk covers also holds pages, the address of each one's Desk page. Your agent can link the name to it.
Notes on signing in
Three tools end their descriptions with the same notes: your own teams (query_my_teams), where you rank by Desk level (query_cohort_standing) and your Desk Pass and forecasts (get_desk_pass).
The shared notes
Needs a signed-in member, because it answers about them. A key with no member gets the error member_required.
What deskPass holds
Without a Desk Pass, four tools return their free part and a deskPass object: plan_lineup, predict_matchup, project_standings and scout_team. Your agent gives the person its message, while the other fields are there for code that reads the answer.
| field | what it holds |
|---|---|
error | desk_pass_required, but free_forecast_used when the person has used this week's free forecast. |
tool | The name of the tool that was called. |
reason | Why there's no pass: no_member (no account behind the key), no_subscription (no pass), not_current (a pass that has ended) or billing_off (the pass isn't on sale yet). |
offer | full the first time in a conversation, then short, because the person already has the full offer. It's not_on_sale while the pass isn't on sale, and always needs_pass in ChatGPT. |
message | The line your agent gives the person, in the Desk's words. A full offer says what the pass adds and how to buy it, with the price when it's known. A short one gives a link, but in ChatGPT the line only says what needs the pass. |
whatThePassAdds | One sentence on what the pass adds, which is the same for every tool. |
pricingUrl | The address of the pricing page, which shows today's price. |
deskPassDocsUrl | The address of the help page that says what the pass adds. |
price | The price and how often it renews, in a full offer only. It's left out when the price can't be read. |
checkoutUrl | A link to buy the pass, already tied to the key's account. It's left out when no link could be made, as for a key with no account. |
checkoutExpiresAt | When checkoutUrl stops working, 30 minutes after the link was made. |
In ChatGPT, deskPass holds only error, tool, reason, offer and message, because OpenAI's app rules allow no price and no link.
plan_lineup
Your lineup and line chances
Lists who has played most for your team. Against an opponent the Desk has a roster for, it adds each team's Desk level on each line, from who has played it this season, and your win chance there. In a Combo or Mixed league, each pair's total sits beside the league number. Tell it who's out, so your side is read without them. Or tell it who plays each line, so those lines are read from the players you pick. After your free forecast each week, it needs a Desk Pass. Without one it lists your players by Desk level and the pairs your league allows. It also gives the Desk's last forecast for your team, line by line, with how each went.
Description and arguments
Plans a doubles and singles lineup for a team the Desk covers. It lists who has played most for your team this season, with their appearances, usual line and Desk level, the Desk's estimate of how they play now. Against a covered opponent it adds each line's win chance, each team's Desk level there and the expected number of lines won. Call it for 'what lineup should we play against X', 'who has played most for us' or 'how do we beat X'. Pass `unavailable` for your players who are out, but pass `lineup` only for the players the person put on each line. Needs a Desk Pass after the member's free forecast each week. Past that, a call gets the free part, with no chance for anything still to be played, and `deskPass`, whose `message` you give the person. Its error is free_forecast_used, or desk_pass_required for a key with no member.
| argument | type | required | what it is |
|---|---|---|---|
team | string | yes | Your team, e.g. 'Belvedere 18AM3.5A', or its Desk page link or number. Must be a covered team. |
opponent | string | no | The opponent team to plan against, by name or Desk page link. Optional. |
season | integer | no | Season year. Defaults to the current season. |
unavailable | list of string | no | Players on YOUR team who are out. They leave your list and the averages your side of each line is read from. Names may be abbreviated ('Jane'). |
lineup | list of object | no | Your own team's lineup, only as the person states it, line by line. Never fill it in yourself. Each line named is read from those players. |
asked | string | no | The person's question word for word, never paraphrased. Leave it out rather than invent one. |
query_team_record
A team's results and next matches
Gives a team's most recent results, line by line, and its next scheduled matches, which works for any team in the leagues the Desk covers. It also lists every team match of the season, and counts the season's record for you, by stage and by month.
Description and arguments
Returns the recorded lines of any team the Desk covers, in any league and season, each with an evidenceId you can cite. It also gives the team's record, which is already counted, every team match of the period and its next matches. Call it when someone asks about a named team's matches, results or next match, or before you state a fact about them.
| argument | type | required | what it is |
|---|---|---|---|
team | string | yes | Team name or partial name to resolve, e.g. 'Tiburon' or 'Mill Valley men's 18'. Or the team's Desk page link or number. |
season | integer | no | Optional season year to filter to, e.g. 2026 |
includeAllSeasons | boolean | no | Set true ONLY when the user explicitly asks about prior years / all history. |
phase | string | no | Optional competition phase: 'sectionals', 'playoffs', 'postseason', or 'regular season'. Pass it when the member names one — a sectional match keeps its REGULAR-SEASON league name in our data, so there is no other way to find it. Omit to return every phase. |
date | string | no | Optional match day, as YYYY-MM-DD, e.g. '2026-02-05'. The rows are then that day's lines, from any season unless `season` is given. Pass it when the question names the day of a match. |
limit | integer | no | Max rows to return (default 9, max 60). |
asked | string | no | The person's question word for word, never paraphrased. Leave it out rather than invent one. |
query_matchup
Recent results between two teams
Gives the most recent results from the matches two teams played against each other, line by line, so you see who won each line.
Description and arguments
Returns the recorded lines from the scorecards where two named teams played each other, in any season, each with an evidenceId. Call it for the head-to-head between two teams, or before you state a fact about it.
| argument | type | required | what it is |
|---|---|---|---|
team_a | string | yes | First team name or partial name to resolve. Or the team's Desk page link or number. |
team_b | string | yes | Second team name or partial name to resolve. Or the team's Desk page link or number. |
season | integer | no | Optional season year to filter to, e.g. 2026 |
includeAllSeasons | boolean | no | Set true ONLY when the user explicitly asks about prior years / all history. |
limit | integer | no | Max rows to return (default 9, max 60). |
asked | string | no | The person's question word for word, never paraphrased. Leave it out rather than invent one. |
query_roster
A team's roster and ratings
Gives a team's roster for a season, which lists each player's NTRP rating, their record on that team, and their Desk level when there is one.
Description and arguments
Returns a team's roster for a season, one row per player with an evidenceId: name, NTRP rating, wins, losses, matches and Desk level. Call it when someone asks who is on a team, or before you state a fact about a roster. Pass `season` when the person named a year, because without it the answer covers the current season. If `moreRows` is true, call again with a larger `limit`, up to 60.
| argument | type | required | what it is |
|---|---|---|---|
team | string | yes | Team name or partial name to resolve. Or the team's Desk page link or number. |
season | integer | no | Optional season year to filter to, e.g. 2026 |
includeAllSeasons | boolean | no | Set true ONLY when the user explicitly asks about prior years / all history. |
limit | integer | no | Max roster rows to return (default 30 = the full roster, max 60). Omit to get the whole team. |
asked | string | no | The person's question word for word, never paraphrased. Leave it out rather than invent one. |
query_player_history
A player's recent results
Gives a player's most recent results, line by line, and their record in singles and doubles for the season and for all years. It also gives the season's record for each team and league they played in, and for each stage: the regular season, the playoffs and the sectionals.
Description and arguments
Returns the recorded lines a named player appeared in, as cited rows told from the player's side, with the player's record, which is already counted by season, team and stage. Call it when someone asks about a player's results, form or history. Never guess at their injury or availability, because the Desk does not hold it.
| argument | type | required | what it is |
|---|---|---|---|
player | string | yes | Player name to resolve, e.g. 'First Last'. Or the player's Desk page link or number. |
season | integer | no | Optional season year to filter to, e.g. 2026 |
includeAllSeasons | boolean | no | Set true ONLY when the user explicitly asks about prior years / all history. |
limit | integer | no | Max rows to return (default 9, max 60). |
asked | string | no | The person's question word for word, never paraphrased. Leave it out rather than invent one. |
query_match_log
Desk level, match by match
Gives a player's matches in one season, with their Desk level before and after each one, so you see how it moved. It also gives the levels of the other players on court.
Description and arguments
Returns a player's match-by-match rating history for one season: each match they played, their level before and after it, and the other players on court with their levels then. Call it when someone asks how a player's level changed, how they reached it, what one result did to it, or asks to see their matches. Prefer it to query_player_history when the question is about the level rather than the results, because it follows the level match by match.
| argument | type | required | what it is |
|---|---|---|---|
player | string | yes | Player name as the member wrote it. Or the player's Desk page link or number. |
season | integer | no | Season year. Omit for the current season. |
asked | string | no | The person's question word for word, never paraphrased. Leave it out rather than invent one. |
compute_aggregate
A team's win rate and counts
Counts a team's wins, losses or lines played, or works out its win rate, which it reads from the lines it played.
Description and arguments
Works out one number for any covered team, in any league or season, in code from its recorded lines: `win_rate`, `win_count`, `loss_count` or `match_count`. Call it whenever you would state a count, an average or a win rate, and quote its value exactly rather than working one out. With no `phase` it counts the playoffs and sectionals too, so pass phase:'regular season' for a league record alone.
| argument | type | required | what it is |
|---|---|---|---|
team | string | yes | Team key or display name. Or the team's Desk page link or number. |
kind | string | yes | Which number to compute, over the lines the team played: 'win_rate' (the share of them won, from 0 to 1), 'win_count' (lines won), 'loss_count' (lines lost) or 'match_count' (lines played). |
season | integer | no | Optional season year to filter to, e.g. 2026 |
includeAllSeasons | boolean | no | Set true ONLY when the user explicitly asks about prior years / all history. |
phase | string | no | Optional competition phase: 'sectionals', 'playoffs', 'postseason', or 'regular season'. Pass it when the member names one, or when they ask for a LEAGUE record — a sectional match keeps its REGULAR-SEASON league name in our data, so there is no other way to separate them. Omit to count every phase. |
asked | string | no | The person's question word for word, never paraphrased. Leave it out rather than invent one. |
compute_roster_strength
Each rating group's record
Groups a team's players by NTRP rating and gives each group's record, which is counted in player appearances.
Description and arguments
Splits a team's roster by published NTRP level and gives each level group's players, wins, losses and win rate this season, over every league line those players appeared in. Call it for a roster's shape rather than its results, as in 'how strong is their 4.0 half' or 'who carries this team'. It works even before a season has been played, because it then reads the season before.
| argument | type | required | what it is |
|---|---|---|---|
team | string | yes | Team key or display name. Or the team's Desk page link or number. |
season | integer | no | Optional season year, e.g. 2026 |
phase | string | no | Optional competition phase: 'sectionals', 'playoffs', 'postseason', or 'regular season'. Pass it when the member names one, or when they ask how a level group did in their LEAGUE — a sectional match keeps its REGULAR-SEASON league name in our data, so there is no other way to separate them. Omit to count every phase. |
asked | string | no | The person's question word for word, never paraphrased. Leave it out rather than invent one. |
compute_match_line_ratings
Matches ranked by lineup strength
Ranks a team's matches in a season by how strong a lineup it put out, which it works out from its players' current Desk levels.
Description and arguments
Ranks a team's recorded matches by how strong a lineup it fielded, from each player's current Desk level, so it is not a rating at the time of the match. Call it when someone asks which match had the strongest or weakest lineup, or how a team's line strength moved.
| argument | type | required | what it is |
|---|---|---|---|
team | string | yes | Team key or display name to resolve, e.g. 'Belvedere mixed 8.0'. Or the team's Desk page link or number. |
season | integer | no | Optional season year to filter to, e.g. 2026 |
includeAllSeasons | boolean | no | Set true ONLY when the user explicitly asks about prior years / all history. |
asked | string | no | The person's question word for word, never paraphrased. Leave it out rather than invent one. |
query_player_rating
A player's Desk level and record
Gives a player's Desk level, when there is one, their win-loss record across every season on record, and each season's record in singles and doubles. Each season's record is also split by the teams and leagues they played in, and by stage, from the regular season to the sectionals. It also gives a level for singles, doubles, mixed and combo once the player has played enough lines in that format, and no Desk page shows those. A format level does not forecast results better than the Desk level, and in singles it forecasts worse. Use the Desk level for predictions.
Description and arguments
Returns the Desk's read of a named player: their Desk level, their record by season, team, stage and format, the model card id and the lines behind it. Call it when someone asks how strong a player is, or about their rating, level, trend or bump risk. The USTA band is not here, because it is the `rating` on a query_roster row. The Desk publishes no bump prediction.
| argument | type | required | what it is |
|---|---|---|---|
player | string | yes | Player name to resolve, e.g. 'First Last'. Or the player's Desk page link or number. |
asked | string | no | The person's question word for word, never paraphrased. Leave it out rather than invent one. |
predict_matchup
One line's win chance
Gives the win chance for one singles or doubles line between the players you name. After your free forecast each week, it needs a Desk Pass, but without one it gives each player's Desk level and record.
Description and arguments
Gives the home side's win probability for one line between named players. It weighs each player's Desk level, how a pair plays together and who is available, while a player the Desk has not yet rated gets a default level. Call it when someone asks who would win, the odds of a matchup, or how a pairing stacks up. Needs a Desk Pass after the member's free forecast each week. Past that, a call gets the free part, with no chance for anything still to be played, and `deskPass`, whose `message` you give the person. Its error is free_forecast_used, or desk_pass_required for a key with no member.
| argument | type | required | what it is |
|---|---|---|---|
home_players | list of string | yes | Home-side player name(s), ideally as they appear on recorded lines, e.g. 'Last, First'. Each may also be a player's Desk page link or number. |
away_players | list of string | yes | Away-side player name(s), ideally as they appear on recorded lines. Each may also be a player's Desk page link or number. |
line_type | string | no | Optional; inferred from side sizes when omitted. One of 'singles' or 'doubles'. |
asked | string | no | The person's question word for word, never paraphrased. Leave it out rather than invent one. |
query_team_forecast
Upcoming matches
Gives a team's upcoming matches, or a player's across their teams: the opponent, the day, the start time, and home or away.
Description and arguments
Returns a team's upcoming matches on the league schedule, or those of every team a player is on: the opponent, the day, the start time, and home or away. Call it for a next match, today's or tomorrow's match, or the schedule. Pass `team` for a named team, or `player` for a first-person ask like 'who am I playing'. It gives no team win chance. A team match's chance is only in the live playoff report from project_standings, which comes with the Desk Pass.
| argument | type | required | what it is |
|---|---|---|---|
team | string | no | Team name to resolve, e.g. 'Belvedere mixed 8.0' or 'BELVEDERE TC 40MX8.0A'. Or the team's Desk page link or number. |
player | string | no | Player whose teams' upcoming matches to fetch, e.g. 'First Last'. Or the player's Desk page link or number. |
asked | string | no | The person's question word for word, never paraphrased. Leave it out rather than invent one. |
query_club_teams
A club's teams this year
Gives the teams a club has this year, and which one plays next.
Description and arguments
Returns the teams a named club fields this year, and which of them plays next. Call it whenever someone asks about a whole club by name, before you narrow the question to a single team. For how the club is doing, call query_club, which reads the club's page. Pass any league words the person used in `qualifier`, such as 'combo', 'mixed', 'womens', '40 & over' or '3.5', because dropping them answers a different question.
| argument | type | required | what it is |
|---|---|---|---|
club | string | yes | The club name, e.g. 'Belvedere'. |
qualifier | string | no | Any league words the asker used alongside the club — 'combo', 'mixed', 'womens', '40 and over', '3.5'. Omit only when they named the club alone. |
asked | string | no | The person's question word for word, never paraphrased. Leave it out rather than invent one. |
query_club
What a club's page shows
Gives what a club's page shows, for its newest season or a past one you name. That's each of its teams with its place in the Desk's unofficial league table and its record. While a team has a team match left, it also says whether the team can still finish first. Then come the club's next matches, its latest results, its record against other clubs, and every season the club fielded a team, each with its page. Asked for a briefing, it gives the club's week instead: its team matches and the checks the Desk writes from the records.
Description and arguments
Returns what a club's page on The Tennis Desk shows, in one call. That is its teams in a season by league, each with its place in the Desk's unofficial league table and its record. It also gives the club's next matches, latest results and record against each other club. Call it when someone asks how a club is doing, its record against other clubs, or where its teams stand. For only its list of teams, or which plays next, query_club_teams is enough. Pass `club`: the club's name as people say it or as USTA prints it, or its page address or number. Pass `season`, a year, for that season's page, and `briefing` true for the club's week. A team's `firstPlace` says whether it can still finish first, which assumes each scheduled match is played. In a result, * marks a line won or lost by default.
| argument | type | required | what it is |
|---|---|---|---|
club | string | yes | The club: its name as people say it or as USTA prints it, e.g. 'Scott Valley', or its club page address or number, e.g. '/c/218'. |
briefing | boolean | no | True for the club's week instead of its page: every team match in the next 7 days, counting the day of the call in Pacific time, each with the other team's place in the Desk's unofficial league table and their earlier meetings this season, and the checks the Desk writes from the records, each with the pages it rests on. Its `firstPlace` says whether each club team that plays in those days can still finish first, and when none plays, each team with a team match left. The answer's `briefing` is null when no team match falls in those days. Leave it out, or call again without it, for the club's page. |
season | integer | no | A season year, 2022 or later: the club's page in that season, its teams, places and records then. Leave it out for the newest season the club fielded a team. A season the club has no team in is not found, and the answer names the seasons it has. |
asked | string | no | The person's question word for word, never paraphrased. Leave it out rather than invent one. |
query_my_teams
Your own teams
Gives the teams you are on or have played for, in the leagues the Desk covers. It needs a key you made while signed in.
Description and arguments
Returns the member's own teams, the ones they are on or have played for, which come from their affiliations. Call it when the person asks about their own teams, as in 'what teams am I on', and set thisYear:true for this year's. A question that names a team, a club or a player is about that one, so use the other tools for it, signed in or not.
| argument | type | required | what it is |
|---|---|---|---|
thisYear | boolean | no | Set true for 'this year / this season' — the current league year's teams only. Omit for all covered teams. |
asked | string | no | The person's question word for word, never paraphrased. Leave it out rather than invent one. |
query_cohort_standing
Where you rank by Desk level
Ranks players by Desk level within an age group, gender or NTRP rating you choose, with your own place when you are in it. It needs a key you made while signed in.
Description and arguments
Ranks a group of players by Desk level and gives the member's place in it. Call it for 'where do I stand', 'how do I compare to the top players', a ranking or a percentile, or the top players in an age group or level. Define the group with `ageBand`, `division` and `level`, or leave them out so it fills the group from the member's team.
| argument | type | required | what it is |
|---|---|---|---|
ageBand | string | no | Age group: '18', '40', '55', '65', or '70' (the '& Over' band). |
division | string | no | 'men', 'women', or 'mixed' — the gender ladder. Omit to use the member's own. |
level | string | no | NTRP level as a string, e.g. '4.0' or '8.0' (mixed). Omit for a whole age-group ladder. |
topN | integer | no | How many top players to show (default 10). |
season | integer | no | Optional league year for cohort membership, e.g. 2026. Defaults to the current season. |
includeAllSeasons | boolean | no | Set true ONLY to pool cohort membership across all years. |
asked | string | no | The person's question word for word, never paraphrased. Leave it out rather than invent one. |
query_league_standings
An unofficial league table
Works out the league table for a team's flight, or for a league in an area you name, from recorded results, with the team's place in it. It says whether the regular season is over, who won the playoffs when the Desk holds them, and what split teams on the same record. It also counts how far each team finished behind first place and behind the last place in the playoffs. It isn't USTA's official table, because a few USTA rules can't be worked out from results alone.
Description and arguments
Builds the Desk's unofficial league table for a team's flight, with the named team's place, which it ranks from recorded results by the league's own rule and tie-breaks. Call it for the standings, how a team finished, who won the league or 'the table'. Pass the team name, or nothing for the member's own team. For a whole league, pass `league` and `area` instead, such as "55 & over men's 8.0" and 'Marin'. Never pass a club or an area as the team.
| argument | type | required | what it is |
|---|---|---|---|
team | string | no | Team or club name whose league table to build, e.g. 'Belvedere' or 'Belvedere mixed 8.0'. Omit to use the signed-in member's own team, or to ask by `league`. Or the team's Desk page link or number. |
league | string | no | A league to build the table of when no team is named, with every league word the question gives, the age group included: its name, e.g. 'Adult 55 & Over Mens 8.0', or its words, e.g. "55 & over men's 8.0" or "women's combo 6.5 daytime". Used only without `team`. |
area | string | no | The area of that league, as the Desk names it, e.g. 'Marin' or 'San Francisco'. Used only with `league`. |
season | integer | no | League year, e.g. 2025. Defaults to the current season. |
asked | string | no | The person's question word for word, never paraphrased. Leave it out rather than invent one. |
plan_lineup_from_availability
A lineup from NorCal availability
Plans your lineup from the answers your players gave on the NorCal availability grid, with each player's USTA player id and the values for the lineup form. Each line's win chance comes with a Desk Pass, after your free forecast each week.
Description and arguments
Plans a lineup from the availability a member's agent read on the USTA NorCal league site, so the agent can fill in the lineup form. Pass the team, the match and each player's answer in USTA's own words: yes, No, maybe, call last, First shift only or Second shift only. The result also holds the values for the lineup form, and what to confirm with the member before Save. Each line's win chance needs a Desk Pass after the member's free forecast each week. The Desk never acts on the USTA site, so the member, or their own agent in their own session, presses Save. Call it when someone pastes or describes who can play a match and asks for a lineup.
| argument | type | required | what it is |
|---|---|---|---|
team | string | yes | The member's team: the Desk's team id, which is USTA NorCal's own team id, a link to its team page, or its name. |
opponent | string | no | The other team in the match, as the schedule names it. With date, or alone. |
date | string | no | The match date, as 2026-10-24. With opponent, or alone. With neither, the plan is for the team's next match. |
matchId | string | no | USTA NorCal's own id for the match, read from the link on the team page. Optional: it fills in the form's path. |
availability | list of object | yes | Each player's answer, as the agent read it on NorCal's availability grid or as the member pasted it. |
season | integer | no | Season year. Defaults to the current season. |
asked | string | no | The person's question word for word, never paraphrased. Leave it out rather than invent one. |
prepare_score_entry
Values for the score form
Turns the scores you report into what the NorCal score form takes, each set from the winning team's side, and checks them against the form's rules. Given the posted score too, it says where the two differ.
Description and arguments
Prepares the values for the score form on the USTA NorCal league site, from the scores a member reports. Pass the team, the match and each line: its players on both sides, its set scores, and its status when a line was not completed. Give the sets from the member's own side, unless scoresFrom says otherwise. Pass posted too, with each line as NorCal shows it, so it can list every line where the two differ. The Desk never acts on the USTA site, so the member, or their own agent in their own session, presses Submit. Call it when someone wants to enter or check a match score on NorCal.
| argument | type | required | what it is |
|---|---|---|---|
team | string | yes | The member's team: the Desk's team id, which is USTA NorCal's own team id, a link to its team page, or its name. |
opponent | string | no | The other team in the match, as the schedule names it. With date, or alone. |
date | string | no | The date the match was played, as 2026-10-11. The form takes the date played, even when the schedule shows another. |
matchId | string | no | USTA NorCal's own id for the match, read from the link on the team page. Optional: it fills in the form's path. |
weAreHome | boolean | no | Whether the member's team was the home team. Read from the schedule when left out. |
lines | list of object | yes | Each line as the member reports it. |
posted | list of object | no | Each line as NorCal shows it after the other team entered the score, to compare with the member's record. |
season | integer | no | Season year. Defaults to the current season. |
asked | string | no | The person's question word for word, never paraphrased. Leave it out rather than invent one. |
match_date_check
A home match date, checked
Checks a date and start time you want to post for a home match against what the NorCal form accepts. It also warns that posting the date emails the other team at once.
Description and arguments
Checks a proposed date and time for a home match before the captain posts it on the USTA NorCal league site. Pass the team, the match and the proposed date and start time, and the format and second-shift time if the captain has them. It says whether the form offers that time, which formats the form offers for the team's lines, and whether the team already plays that day. The Desk never acts on the USTA site, so the captain, or their own agent in their own session, presses Submit. Call it when a captain asks whether a date works, or before an agent fills the post-dates form.
| argument | type | required | what it is |
|---|---|---|---|
team | string | yes | The member's team: the Desk's team id, which is USTA NorCal's own team id, a link to its team page, or its name. |
opponent | string | no | The other team in the match, as the schedule names it. With date, or alone. |
date | string | no | The date the schedule shows for the match now, as 2026-10-24, to find it. Optional with opponent. |
proposedDate | string | yes | The date the captain wants to post, as 2026-10-24. |
proposedTime | string | yes | The start time the captain wants, as 6:30 PM. |
format | string | no | The match format, as the form names it: All 3, 2/1 or 1/2 for three lines, and All 5, 3/2, 2/3, 4/1 or 1/4 for five. |
secondShiftTime | string | no | The second shift's start time, for a two-shift format. |
season | integer | no | Season year. Defaults to the current season. |
asked | string | no | The person's question word for word, never paraphrased. Leave it out rather than invent one. |
availability_loop
Chase who hasn't answered
Takes the NorCal availability grid your agent read and lists the players who haven't answered the next match or said maybe. It writes one group message for your team and a short text for each player, for you to send yourself, and asks a maybe for a yes or no. It says when to run it again, and plans the lineup and its team email at the deadline. Each line's win chance comes with a Desk Pass, after your free forecast each week.
Description and arguments
Finds the players who have not answered the next match on the USTA NorCal availability grid. Pass the team and the grid as your agent read it: each match column's header, and each player's row with one cell per column. It lists each player whose answer is blank or maybe, and writes one group message for the team with the deadline and the team grid link. Each line's win chance needs a Desk Pass after the member's free forecast each week. The Desk writes, and the captain sends every message from their own phone or email. Never send a text or an email yourself, and never read a teammate's phone or email. Call it when a captain asks who has not answered on NorCal, or wants reminder texts.
| argument | type | required | what it is |
|---|---|---|---|
team | string | no | The team the grid is for: the Desk's team id, which is NorCal's own team id, a link to its team page, or its name. Left out, the signed-in member's own team this season. |
columns | list of string | no | Each match column's header on the grid, as NorCal prints it, in order, for example #8 Sunday 10/18/26. |
rows | list of object | no | One row for each player on the grid. |
deadline | string | no | The answer deadline, as 2026-10-16 1:00 PM. Left out, 48 hours before the match starts. |
signAs | string | no | The captain's first name, which signs the lineup email. |
format | string | no | The match format, as the NorCal post-dates form names it: All 3 or All 5 for one shift, or a split such as 2/1. |
lineupNow | boolean | no | Set true to plan the lineup now, before the deadline, from the answers so far. |
matchId | string | no | NorCal's own id for the match, from the Line-up link. Optional: it fills in the lineup form's path. |
season | integer | no | Season year. Defaults to the current season. |
asked | string | no | The person's question word for word, never paraphrased. Leave it out rather than invent one. |
read_docs
Paragraphs from the Desk's docs
Gives the docs' own paragraphs on a question about the Desk itself, word for word, which it finds by topic on any page, each with a link to its section.
Description and arguments
Reads The Tennis Desk's own docs, word for word. They cover what the Desk is, a Desk level, what is free and what the Desk Pass adds, coverage and updates, agents, privacy and how a league table is ordered. Call it when someone asks about the Desk itself rather than a team, a player or a match. Pass `about`, a few words on what to find, and `pages` for a page you know. It needs no Desk Pass, and a call does not count toward the account's daily or monthly limit.
| argument | type | required | what it is |
|---|---|---|---|
pages | list of string | no | One or two docs pages, each named by its address after /docs/, as https://thetennisdesk.com/docs.md lists them, for example 'desk-level'. The front page is 'index'. A page read_docs does not hold is answered with the pages it holds. Optional: leave it out to find a topic on any page. |
about | string | no | A few words on what to find, for example 'how it compares with NTRP'. With no `pages`, the sections of any page that match it. |
asked | string | no | The person's question word for word, never paraphrased. Leave it out rather than invent one. |
read_research
The Desk's research figures
Gives the Desk's published research about players in general, word for word: each piece's headline, its answers with their figures, and the group of past players it counts. It also gives every figure the piece prints, so a split by rating or by season comes back with the rest.
Description and arguments
Reads the Desk's published research about players in general, word for word. Each piece comes with its question, headline, answers and figures, the group of past players it counts and the day it was measured. Call it when someone asks about players or teams in general, such as how often players move up or back down, or home advantage. Never call it for one named player, team or match, because every figure is a rate over a group. Pass `about`, a few words on the question, or `pieces` for a piece you know. It needs no Desk Pass.
| argument | type | required | what it is |
|---|---|---|---|
about | string | no | A few words on the question, for example 'how players do after a bump, and how many move back down'. |
pieces | list of string | no | One or two pieces, each named by its address after /research/, as https://thetennisdesk.com/research lists them. Optional. |
asked | string | no | The person's question word for word, never paraphrased. Leave it out rather than invent one. |
query_coverage
What the Desk covers
Says what the Desk covers: which areas, leagues, levels, clubs, teams and seasons, what kinds of question it can answer, and where to ask for another area.
Description and arguments
Answers what the Desk covers: which areas, leagues, levels, clubs, teams and seasons are on record, and what kinds of question it can answer at all. Call it whenever someone asks what you can look up, what data you have, or which leagues, levels or areas are covered. It takes no arguments, because it reports the whole census rather than a slice of it.
| argument | type | required | what it is |
|---|---|---|---|
asked | string | no | The person's question word for word, never paraphrased. Leave it out rather than invent one. |
project_standings
How a league could finish
Gives your team's live playoff report: its playoff chance today and the biggest jump or drop in it this season, with the matches played in that time. It also gives its chance for each number of matches left it could win, from none to all, and the projected table with each team's chance of each place. Every match left is listed too, with each side's chance and the result that helps you most, and your team's chance of each of its lines. It adds the help your team needs from other matches and its chance of each seed. It needs a Desk Pass. Without one it gives where your team stands, its matches left and how many results can still take it to the playoffs.
Description and arguments
Projects how a league table could finish, from the matches left and the Desk's line forecasts. It gives each team's likely place, its chance to finish first and, when the Desk knows the playoff cut, its chance to make the playoffs. It also says what the named team needs, while a Desk Pass adds the team's live playoff report. Call it for a team's playoff chances or what it needs. Pass the team, or `league` and `area` for a whole league, or neither for the member's own team. Needs a Desk Pass. Without one, a call gets the free part, with no chance in it, and `deskPass`, whose `message` you give the person.
| argument | type | required | what it is |
|---|---|---|---|
team | string | no | The team whose league to project, e.g. 'Belvedere men's 7.5'. Omit for the signed-in member's own team. Or the team's Desk page link or number. |
league | string | no | A league to project when no team is named, with its words, e.g. "55 & over men's 8.0". Used only without `team`. |
area | string | no | The area of that league, e.g. 'Marin'. Used only with `league`. |
asked | string | no | The person's question word for word, never paraphrased. Leave it out rather than invent one. |
query_playoff_history
Past playoff chances
Gives your team's playoff chances from a week ago and earlier, one a week, and what moved them most: the change between two days and the matches played between them. Today's chance is not in it.
Description and arguments
Gives a team's playoff chances from a week ago and earlier, one a week, each as of its day. It also says what moved the chance most: the change between two days and the matches played between them. Call it for how a team's playoff chances have changed, or what its chances were last week. Pass the team, or nothing for the member's own team. It never gives today's chance: the `project_standings` tool gives that, with the Desk Pass.
| argument | type | required | what it is |
|---|---|---|---|
team | string | no | The team, e.g. 'Belvedere men's 7.5'. Omit for the signed-in member's own team. Or the team's Desk page link or number. |
asked | string | no | The person's question word for word, never paraphrased. Leave it out rather than invent one. |
query_forecast_results
How past forecasts did
Gives your team's latest matches the Desk forecast before they were played: each line's chance for your team, and whether you won that line and the match. Matches still to come are not in it.
Description and arguments
Gives a team's latest matches that the Desk forecast before they were played. For each line, it gives the team's chance as the Desk logged it the night before, and whether the team won the line. It also gives each match's result. Call it for how the Desk's forecasts did for a team, or what the Desk gave a team in a past match. Pass the team, or nothing for the member's own team. It gives only matches already played, never a chance for a match still to come, which comes with the Desk Pass.
| argument | type | required | what it is |
|---|---|---|---|
team | string | no | The team, e.g. 'Belvedere men's 7.5'. Omit for the signed-in member's own team. Or the team's Desk page link or number. |
asked | string | no | The person's question word for word, never paraphrased. Leave it out rather than invent one. |
scout_team
A written scout of one team
Writes the Desk's scout of one team: its ranked reads of who matters and how the lines go, each with its evidence. It needs a Desk Pass, but without one it gives the team's record, recent results, strongest players by Desk level and its free scout page.
Description and arguments
Writes the Desk's scout of one team it covers: its ranked reads of who matters and how the lines go, each with its evidence. Call it when someone asks for a scout, a breakdown of a team, or how to beat a named team. Pass `team`, a team the Desk covers, by name or Desk page link. Never call it for a whole club, because a scout is of one team. Needs a Desk Pass. Without one, a call gets the free part, with no chance in it, and `deskPass`, whose `message` you give the person.
| argument | type | required | what it is |
|---|---|---|---|
team | string | yes | The team to scout, e.g. 'Belvedere 18AM3.5A', or its Desk page link or number. |
asked | string | no | The person's question word for word, never paraphrased. Leave it out rather than invent one. |
get_desk_pass
Your Desk Pass and forecasts
Says whether you hold the Desk Pass and when it renews, and how many forecasts you have left this week. It needs you signed in.
Description and arguments
Says whether the signed-in member holds the Desk Pass, when it renews or ends, how many forecasts they have left this week and when more come. Call it when someone asks about their Desk Pass or their forecasts. It takes no arguments.
| argument | type | required | what it is |
|---|---|---|---|
asked | string | no | The person's question word for word, never paraphrased. Leave it out rather than invent one. |
The Desk records how pages are used, including what is typed, and keeps recordings for up to 30 days, as the terms explain.