Skip to content

The Tennis Desk

io.github.chungty/thetennisdeskchungtystreamable-httpv0.2.0Scanned

Ratings, line win chances and lineup help for USTA NorCal adult league tennis, from public results.

29 tools: 10 change things and 19 only read.

Tools: 0 delete, 0 irreversible, 10 write, 19 read.
  • Reads private data · 2
  • Reads text others write · 0
  • Can send data out · 0
  • 1 finding

Anlyon alternative

10 of these tools change something. Run those as governed actions.

Declare what an action changes, and Anlyon puts it under a shared limit, binds every approval to the exact request, and grades the outcome. It works on any HTTPS API you can describe as an action.

Anlyon does not run, proxy or govern this MCP server. A tool your own code calls directly is not routed through Anlyon and is not governed by it.

Import an OpenAPI spec →

Tools

Grouped by what each tool does, most consequential first. Open one for its reasons and full description; descriptions are the publisher's own words.

29 tools

Changes things 10Claude Code: ask
  • compute_aggregateWorks 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`.No findings

    Why it is in this group

    • Nothing in its name or description says what it does, so it is counted as a write.
    • The server marks it read-only (readOnlyHint: true), but an annotation never lowers a class.
    Description, as the server wrote it
    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.

    Annotations the server declares

    • title: A team's win rate and counts
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: false
    • idempotentHint: true
  • compute_match_line_ratingsRanks 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.No findings

    Why it is in this group

    • Nothing in its name or description says what it does, so it is counted as a write.
    • The server marks it read-only (readOnlyHint: true), but an annotation never lowers a class.
    Description, as the server wrote it
    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.

    Annotations the server declares

    • title: Matches ranked by lineup strength
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: false
    • idempotentHint: true
  • compute_roster_strengthSplits 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.No findings

    Why it is in this group

    • Nothing in its name or description says what it does, so it is counted as a write.
    • The server marks it read-only (readOnlyHint: true), but an annotation never lowers a class.
    Description, as the server wrote it
    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.

    Annotations the server declares

    • title: Each rating group's record
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: false
    • idempotentHint: true
  • match_date_checkChecks a proposed date and time for a home match before the captain posts it on the USTA NorCal league site.No findings

    Why it is in this group

    • Nothing in its name or description says what it does, so it is counted as a write.
    • The server marks it read-only (readOnlyHint: true), but an annotation never lowers a class.
    Description, as the server wrote it
    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.

    Annotations the server declares

    • title: A home match date, checked
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: false
    • idempotentHint: true
  • plan_lineupPlans a doubles and singles lineup for a team the Desk covers.No findings

    Why it is in this group

    • Nothing in its name or description says what it does, so it is counted as a write.
    • The server marks it read-only (readOnlyHint: true), but an annotation never lowers a class.
    Description, as the server wrote it
    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.

    Annotations the server declares

    • title: Your lineup and line chances
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: false
    • idempotentHint: true
  • plan_lineup_from_availabilityPlans 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.No findings

    Why it is in this group

    • Nothing in its name or description says what it does, so it is counted as a write.
    • The server marks it read-only (readOnlyHint: true), but an annotation never lowers a class.
    Description, as the server wrote it
    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.

    Annotations the server declares

    • title: A lineup from NorCal availability
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: false
    • idempotentHint: true
  • predict_matchupGives the home side's win probability for one line between named players.No findings

    Why it is in this group

    • Nothing in its name or description says what it does, so it is counted as a write.
    • The server marks it read-only (readOnlyHint: true), but an annotation never lowers a class.
    Description, as the server wrote it
    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.

    Annotations the server declares

    • title: One line's win chance
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: false
    • idempotentHint: true
  • prepare_score_entryPrepares the values for the score form on the USTA NorCal league site, from the scores a member reports.No findings

    Why it is in this group

    • Nothing in its name or description says what it does, so it is counted as a write.
    • The server marks it read-only (readOnlyHint: true), but an annotation never lowers a class.
    Description, as the server wrote it
    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.

    Annotations the server declares

    • title: Values for the score form
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: false
    • idempotentHint: true
  • project_standingsProjects how a league table could finish, from the matches left and the Desk's line forecasts.No findings

    Why it is in this group

    • Nothing in its name or description says what it does, so it is counted as a write.
    • The server marks it read-only (readOnlyHint: true), but an annotation never lowers a class.
    Description, as the server wrote it
    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.

    Annotations the server declares

    • title: How a league could finish
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: false
    • idempotentHint: true
  • scout_teamWrites the Desk's scout of one team it covers: its ranked reads of who matters and how the lines go, each with its evidence.1 finding

    Why it is in this group

    • The description's first verb is "write": a word for a change.
    • The server marks it read-only (readOnlyHint: true), but an annotation never lowers a class.

    Findings

    • Warn

      The server marks "scout_team" read-only (readOnlyHint: true), and its own name, description or input give the class "write".

      Matched text

      annotations: {"readOnlyHint":true,"destructiveHint":false,"idempotentHint":true,"openWorldHint":false}; The description's first verb is "write": a word for a change.

      What this check looks for
    Description, as the server wrote it
    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.

    Annotations the server declares

    • title: A written scout of one team
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: false
    • idempotentHint: true
Only reads 19Show 19 read-only tools
  • availability_loopFinds the players who have not answered the next match on the USTA NorCal availability grid.No findings

    Why it is in this group

    • The description's first verb is "find": a word for reading.
    Description, as the server wrote it
    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.

    Annotations the server declares

    • title: Chase who hasn't answered
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: false
    • idempotentHint: true
  • get_desk_passSays 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.No findings

    Why it is in this group

    • The name "get_desk_pass" says "get": a word for reading.
    Description, as the server wrote it
    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. Needs a signed-in member, because it answers about them. A key with no member gets the error member_required.

    Annotations the server declares

    • title: Your Desk Pass and forecasts
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: false
    • idempotentHint: true
  • query_clubReturns what a club's page on The Tennis Desk shows, in one call.No findings

    Why it is in this group

    • The name "query_club" says "query": a word for reading.
    Description, as the server wrote it
    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.

    Annotations the server declares

    • title: What a club's page shows
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: false
    • idempotentHint: true
  • query_club_teamsReturns the teams a named club fields this year, and which of them plays next.No findings

    Why it is in this group

    • The name "query_club_teams" says "query": a word for reading.
    Description, as the server wrote it
    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.

    Annotations the server declares

    • title: A club's teams this year
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: false
    • idempotentHint: true
  • query_cohort_standingRanks a group of players by Desk level and gives the member's place in it.No findings

    Why it is in this group

    • The name "query_cohort_standing" says "query": a word for reading.
    Description, as the server wrote it
    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. Needs a signed-in member, because it answers about them. A key with no member gets the error member_required.

    Annotations the server declares

    • title: Where you rank by Desk level
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: false
    • idempotentHint: true
  • query_coverageAnswers 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.No findings

    Why it is in this group

    • The name "query_coverage" says "query": a word for reading.
    Description, as the server wrote it
    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.

    Annotations the server declares

    • title: What the Desk covers
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: false
    • idempotentHint: true
  • query_forecast_resultsGives a team's latest matches that the Desk forecast before they were played.No findings

    Why it is in this group

    • The name "query_forecast_results" says "query": a word for reading.
    Description, as the server wrote it
    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.

    Annotations the server declares

    • title: How past forecasts did
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: false
    • idempotentHint: true
  • query_league_standingsBuilds 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.Reads private dataNo findings

    Why it is in this group

    • The name "query_league_standings" says "query": a word for reading.

    What it can reach

    • private-dataThe description's first sentence says "table": it reads databases.
    Description, as the server wrote it
    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.

    Annotations the server declares

    • title: An unofficial league table
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: false
    • idempotentHint: true
  • query_match_logReturns 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.No findings

    Why it is in this group

    • The name "query_match_log" says "query": a word for reading.
    Description, as the server wrote it
    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.

    Annotations the server declares

    • title: Desk level, match by match
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: false
    • idempotentHint: true
  • query_matchupReturns the recorded lines from the scorecards where two named teams played each other, in any season, each with an evidenceId.No findings

    Why it is in this group

    • The name "query_matchup" says "query": a word for reading.
    Description, as the server wrote it
    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.

    Annotations the server declares

    • title: Recent results between two teams
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: false
    • idempotentHint: true
  • query_my_teamsReturns the member's own teams, the ones they are on or have played for, which come from their affiliations.No findings

    Why it is in this group

    • The name "query_my_teams" says "query": a word for reading.
    Description, as the server wrote it
    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. Needs a signed-in member, because it answers about them. A key with no member gets the error member_required.

    Annotations the server declares

    • title: Your own teams
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: false
    • idempotentHint: true
  • query_player_historyReturns 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.No findings

    Why it is in this group

    • The name "query_player_history" says "query": a word for reading.
    Description, as the server wrote it
    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.

    Annotations the server declares

    • title: A player's recent results
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: false
    • idempotentHint: true
  • query_player_ratingReturns 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.No findings

    Why it is in this group

    • The name "query_player_rating" says "query": a word for reading.
    Description, as the server wrote it
    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.

    Annotations the server declares

    • title: A player's Desk level and record
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: false
    • idempotentHint: true
  • query_playoff_historyGives a team's playoff chances from a week ago and earlier, one a week, each as of its day.No findings

    Why it is in this group

    • The name "query_playoff_history" says "query": a word for reading.
    Description, as the server wrote it
    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.

    Annotations the server declares

    • title: Past playoff chances
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: false
    • idempotentHint: true
  • query_rosterReturns a team's roster for a season, one row per player with an evidenceId: name, NTRP rating, wins, losses, matches and Desk level.No findings

    Why it is in this group

    • The name "query_roster" says "query": a word for reading.
    Description, as the server wrote it
    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.

    Annotations the server declares

    • title: A team's roster and ratings
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: false
    • idempotentHint: true
  • query_team_forecastReturns 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.No findings

    Why it is in this group

    • The name "query_team_forecast" says "query": a word for reading.
    Description, as the server wrote it
    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.

    Annotations the server declares

    • title: Upcoming matches
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: false
    • idempotentHint: true
  • query_team_recordReturns the recorded lines of any team the Desk covers, in any league and season, each with an evidenceId you can cite.No findings

    Why it is in this group

    • The name "query_team_record" says "query": a word for reading.
    Description, as the server wrote it
    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.

    Annotations the server declares

    • title: A team's results and next matches
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: false
    • idempotentHint: true
  • read_docsReads The Tennis Desk's own docs, word for word.Reads private dataNo findings

    Why it is in this group

    • The name "read_docs" says "read": a word for reading.

    What it can reach

    • private-dataThe name "read_docs" says "read" and "doc": it reads documents.
    • private-dataThe description's first sentence says "read" and "doc": it reads documents.
    Description, as the server wrote it
    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.

    Annotations the server declares

    • title: Paragraphs from the Desk's docs
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: false
    • idempotentHint: true
  • read_researchReads the Desk's published research about players in general, word for word.No findings

    Why it is in this group

    • The name "read_research" says "read": a word for reading.
    Description, as the server wrote it
    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.

    Annotations the server declares

    • title: The Desk's research figures
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: false
    • idempotentHint: true

This is not a safety rating, and no finding is not a safety guarantee. The groups and findings come from fixed checks of the tool definitions the server returned on the date shown, not from its code or what it does when called. How the checks work.

Exfil surface

Which tools read private data, which read text someone else can write, and which can send data out. One of each is a path a prompt injection can use.

No private-data, untrusted-input, outbound path in this server alone: no tool is tagged untrusted-input or outbound.

Reads private data2
Reads files, mail, messages, databases, secrets, calendars or repositories.
Reads text others write0
Brings in text someone else can write: web pages, inbound email, messages, issues and comments.
Can send data out0
Can carry data to people or systems: it sends, posts or publishes, or takes a recipient, channel or URL.

Other servers in the same agent add their own tools to these paths. Audit your whole setup to see them together.

Findings

Matches of fixed checks, with the text they matched.

1 warn
  • The server marks "scout_team" read-only (readOnlyHint: true), and its own name, description or input give the class "write".

    Matched text

    annotations: {"readOnlyHint":true,"destructiveHint":false,"idempotentHint":true,"openWorldHint":false}; The description's first verb is "write": a word for a change.

    What this check looks for

History

Changes to its tool definitions and to its remote endpoint, newest first.

No change seen yet. Its tools are rescanned every day, and a remote endpoint is looked at once a week.

Install

Pinned to version 0.2.0. Values in angle brackets are yours to fill in.

claude mcp add --transport http thetennisdesk https://thetennisdesk.com/api/mcp
claude mcp add --transport http thetennisdesk https://thetennisdesk.com/api/mcp

Run in a terminal.

Claude Code permissions

Allow the reads, ask before a change or a way out, deny the deletes. Paste into .claude/settings.json.

.claude/settings.json
{
  "permissions": {
    "allow": [
      "mcp__thetennisdesk__query_team_record",
      "mcp__thetennisdesk__query_matchup",
      "mcp__thetennisdesk__query_roster",
      "mcp__thetennisdesk__query_player_history",
      "mcp__thetennisdesk__query_match_log",
      "mcp__thetennisdesk__query_player_rating",
      "mcp__thetennisdesk__query_team_forecast",
      "mcp__thetennisdesk__query_club_teams",
      "mcp__thetennisdesk__query_club",
      "mcp__thetennisdesk__query_my_teams",
      "mcp__thetennisdesk__query_cohort_standing",
      "mcp__thetennisdesk__query_league_standings",
      "mcp__thetennisdesk__availability_loop",
      "mcp__thetennisdesk__read_docs",
      "mcp__thetennisdesk__read_research",
      "mcp__thetennisdesk__query_coverage",
      "mcp__thetennisdesk__query_playoff_history",
      "mcp__thetennisdesk__query_forecast_results",
      "mcp__thetennisdesk__get_desk_pass"
    ],
    "ask": [
      "mcp__thetennisdesk__plan_lineup",
      "mcp__thetennisdesk__compute_aggregate",
      "mcp__thetennisdesk__compute_roster_strength",
      "mcp__thetennisdesk__compute_match_line_ratings",
      "mcp__thetennisdesk__predict_matchup",
      "mcp__thetennisdesk__plan_lineup_from_availability",
      "mcp__thetennisdesk__prepare_score_entry",
      "mcp__thetennisdesk__match_date_check",
      "mcp__thetennisdesk__project_standings",
      "mcp__thetennisdesk__scout_team"
    ],
    "deny": []
  }
}

Tools that only read are allowed, tools that change things ask first, tools that delete or cancel are denied. A read that can send data out (it takes a URL, say) asks first too. It assumes the server is installed as thetennisdesk. Review it before you use it.

Capability tags behind 2 rules
  • mcp__thetennisdesk__query_league_standings private-data
  • mcp__thetennisdesk__read_docs private-data

Pin

Keep the decision: fail CI when the tools change, follow every change, or show a badge.

Pin in CI

Fail a build when the tools you reviewed are not the tools the server serves today.

curl -s "https://anlyon.dev/api/v1/servers/io.github.chungty/thetennisdesk/verify?hash=9638848d3bd0f6686b507de0820f51cb20d493f05d58b019d603fb358e7f8693" | jq -e '.changed == false'

Pinned hash 9638848d3bd0, from Oct 29, 2026, 07:17 UTC.

Watch

Get told when its tools change: a new tool, a new description, a new class.

https://anlyon.dev/servers/io.github.chungty/thetennisdesk/changes.xml

An Atom feed. Works in any feed reader or Slack's RSS app.

Badge

anlyon.dev badge for io.github.chungty/thetennisdesk
[![anlyon.dev](https://anlyon.dev/badge/io.github.chungty/thetennisdesk.svg)](https://anlyon.dev/servers/io.github.chungty/thetennisdesk)

Source: MCP Registry. Synced Oct 29, 2026, 07:17 UTC.