udisc
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., "@udiscWhich holes at my home course cost me the most strokes?"
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.
disc-golf-trends
Your disc golf rounds and practice throws, from your own exports. It has three parts: a read-only
MCP server that lets Claude answer questions about your rounds, courses and
scoring trends, an offline HTML dashboard of the same data, and a website where anyone can pick their own
CSV and see the dashboard in the browser. (Formerly disc-golf-journal and udisc-mcp. Not affiliated with UDisc or
TechDisc.)
No credentials and no network access. UDisc has no public API, and its Terms prohibit scraping, so this project never contacts UDisc or TechDisc. It only reads the CSV files their apps export. Nothing is modified.
Get your data
In the UDisc mobile app: You tab → menu (top right) → Rounds → menu (top right) → Export to CSV.
Move the file into a folder of your choice. One export holds your whole history; re-export now and then to pick up
new rounds. Every *.csv in the folder is read and overlapping exports are de-duplicated, so you can drop new
exports next to old ones.
Related MCP server: strava-mcp
Setup
Python 3.10 or newer.
git clone https://github.com/cin/disc-golf-trends.git
cd disc-golf-trends
python -m venv .venv
.venv\Scripts\pip install -e ".[dev]" # Linux/macOS: .venv/bin/pip
copy .env.example .env # then edit it.env (see .env.example):
Variable | Meaning |
| Folder holding your export(s) |
| Your name exactly as in the |
| Optional. Folder holding a TechDisc throw export; may be the same folder as |
| Optional. Rounds a hole needs before |
The .env file is git-ignored. It holds only paths and a name, no secrets. The server exits at startup with a clear
message if UDISC_CSV_DIR or UDISC_PLAYER is missing or MIN_HOLE_ROUNDS is invalid, and on Linux/macOS if .env
is readable by other users (chmod 600 .env). A setting that goes wrong later (say the folder is deleted) fails that
one tool call, not the server.
Register with Claude
Claude Code:
claude mcp add udisc -- C:\path\to\disc-golf-trends\.venv\Scripts\python C:\path\to\disc-golf-trends\udisc_mcp.pyClaude Desktop (claude_desktop_config.json):
{
"mcpServers": {
"udisc": {
"command": "C:\\path\\to\\disc-golf-trends\\.venv\\Scripts\\python.exe",
"args": ["C:\\path\\to\\disc-golf-trends\\udisc_mcp.py"]
}
}
}Tools (all read-only)
Tool | Answers |
| How fresh is the data? Newest round, export age, stale warning |
| Rounds by date range and course, newest first |
| Hole-by-hole scores vs par for one round |
| Courses, layouts, rounds played, first/last played |
| Average/best/worst rounds, per-layout stats, 3 best and worst holes; |
| Score vs par by month or season, optionally per course |
| Share of holes at eagle or better, birdie, par, bogey, double, triple or worse; overall, by month or by season |
| Holes that cost the most strokes over par, with blow-up counts (a blow-up is a double bogey or worse) |
| Two calendar years side by side |
| TechDisc: throw count, first/last throw, export age, stale warning |
| TechDisc: throws by date range, Backhand/Forehand and Hyzer/Flat, newest first |
| TechDisc: speed, distance, spin and angle averages/maxima, overall and by throw style |
| TechDisc: those numbers by month or season |
Dates (start, end) are YYYY-MM-DD and inclusive; anything else is rejected with a message instead of silently
returning the wrong rounds. group_by accepts only month or season. list_rounds and list_throws return at most
500 rows.
Example questions: "Which holes at my home course cost me the most strokes?", "How has my scoring trended each season?", "Compare 2025 and 2026."
Dashboard
.venv\Scripts\python dashboard.py # writes dashboards\udisc-dashboard.htmlOne self-contained HTML file with three tabs, opened by double-clicking it: Scoring (strokes over par and round rating by month, quarter or season, with the best and worst periods ringed; every round as a dot, with new personal bests at a course in blue; the three costliest holes highlighted; birdies and blow-ups per round; the share of holes at each score by season; a courses table), Holes (where the strokes go on a chosen course, and a hole-by-season heatmap) and Throws (TechDisc speed and distance trends). Filters at the top scope the whole page by course and date range; "Highlight season" shades one season on the charts and dims the others without filtering anything. Every chart has a table view. Holes shows one course at a time, so with "All courses" it asks you to pick one (and offers your most played). Throws only uses the date range, and says so next to the greyed-out course and season controls.
Themes (menu at the top right, remembered in the browser): System follows your light or dark setting,
Mocha is Catppuccin Mocha, and the third entry is the opposite of your system look (Dark on a light system, Light
on a dark one). ?theme=system, ?theme=mocha, ?theme=dark or ?theme=light in the address picks one; dark or
light only applies when it is the opposite of the system look. It makes no network requests and has no animation. Re-run the command after each new export.
--player "Name" builds the same dashboard for another player in your export (name matched exactly, ignoring case),
written to dashboards\udisc-dashboard-name.html. The export only holds rounds you scored together, so that
dashboard covers those rounds, and your TechDisc throws are left out.
The file embeds real rounds, so dashboards/ is git-ignored. Each file holds one player's rows.
Website
Live at https://cin.github.io/disc-golf-trends/. site/ is the same dashboard as a static web page: a visitor
picks their own UDisc and/or TechDisc CSV export and sees the charts. Nothing is uploaded. The files are read in the
browser tab, and the built page's content security policy stops the page from making network requests. It is written
in TypeScript (a port of udisc_data.py and techdisc_data.py) and draws with the same dashboard_template.html as
the Python dashboard, so there is one set of charts to maintain. A scorecard export includes everyone you played
with; the page asks whose rounds to show and starts with the player who has the most. "Try it with sample data" loads
made-up rounds and throws. The two setup cards (choose files, choose player) minimize to a one-line summary once you
have picked, so the dashboard starts near the top; click a summary to change the choice, or drop new files on the
picker even while it is minimized.
Working on it needs Node.js 22.12 or newer (24 recommended); the Python parts do not need Node.
cd site
npm install
npm run dev # http://localhost:5173/, add ?sample to load made-up data
npm test # unit tests, plus a check that the port gives the Python implementation's answers
npm run build # static files in site/dist/The port is held to the Python code by tests/golden.py: it runs every query over the fixtures (including a larger
made-up dataset) and writes site/tests/golden.json, and the TypeScript tests must reproduce it exactly. After
changing the Python statistics, run .venv\Scripts\python tests\golden.py and commit the result; a Python test fails
when the file is stale. Pushes to main that touch site/, the dashboard template or the fixtures are published to
GitHub Pages by .github/workflows/pages.yml.
Data notes
The export has a
Parrow before each round's player rows. Par comes from there.A score of
0means the hole was not played. Rounds with no scores are ignored, and partial rounds are left out of averages and trends.Totals are the sum of the hole scores. The file's
Totalcolumn is only a cross-check: when you scratch a hole ("-" in the app), UDisc still writes a placeholder score in that hole's column but leaves it out of its own total. If the holes add up to exactly one hole's score more thanTotal, that hole is treated as not played. If no single hole explains the gap (or several could), nothing is dropped and the gap is reported instead.get_roundshowsscratched_holesandtotal_gap,export_statuscounts the affected rounds, and the website notes them.Hole numbers are only compared within one course layout.
The UDisc export has no throws, putts or penalty columns, so none are reported.
TechDisc throws are practice data and are not linked to rounds (the export has no course or round column). Throw times come from
timeSecondsand are shown in this computer's local time zone.When both exports share a folder, each loader ignores the other's files by header, and
export_statusonly looks at scorecard files.
Development
.venv\Scripts\python -m pytest -q
.venv\Scripts\ruff check .
cd site && npm test && npm run typecheck # the website, needs Node.jsTests use made-up data in tests/fixtures/ (sample.csv and throws.csv, plus larger generated
synthetic_*.csv). Never commit your real export: *.csv is git-ignored except for tests/fixtures/.
.github/workflows/ci.yml runs all of the above on every push and pull request.
License
MIT, see LICENSE.
Available Tools
13 toolscompare_seasonsBRead-onlyIdempotent
Compare two calendar years: rounds, average score vs par, best/worst round and the change.
| Name | Required | Description | Default |
|---|---|---|---|
| course | No | ||
| year_a | Yes | ||
| year_b | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, so the safety profile is covered. The description adds which aggregates are computed, but says nothing about edge cases such as a year with no rounds, how 'change' is calculated, or how the optional course scoping affects results.
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?
A single compact sentence with the core action front-loaded and the output metrics listed after the colon. No filler.
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 metric list partially substitutes for return-value documentation, which is helpful. But the unexplained 'course' parameter and undefined direction of 'the change' leave gaps an agent needs to resolve before calling confidently.
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?
Schema description coverage is 0%, so the description must carry parameter meaning and largely doesn't. It implies year_a/year_b ('two calendar years') but never explains the optional 'course' parameter, which materially scopes the comparison, nor which year is the baseline for 'the change'.
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?
States a specific verb (compare) and resource (two calendar years) and enumerates the metrics produced: rounds, average score vs par, best/worst round, and the change. It is clear what the tool does, though it doesn't name a sibling (e.g. scoring_trends) to distinguish itself from multi-year trend tooling.
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?
Usage is only implied — an agent can infer this is the tool for year-over-year comparison, but there is no explicit when-to-use, when-not-to-use, or alternative named among siblings like scoring_trends or course_stats.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
course_statsARead-onlyIdempotent
Average, best and worst rounds, per-layout stats and the 3 best and worst holes for a course (substring match).
include_holes adds the average for every hole; that list is long for multi-layout courses.
| Name | Required | Description | Default |
|---|---|---|---|
| course | Yes | ||
| layout | No | ||
| include_holes | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnly, idempotent, non-destructive, closed-world), so the bar is lower. The description adds real behavioral context: course is a substring match, and include_holes materially inflates the result size for multi-layout courses. This output-volume disclosure is exactly the kind of trait annotations cannot express.
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 compact sentences with the primary purpose front-loaded and the caveat trailing. No filler; the parenthetical about substring matching is load-bearing.
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 usefully enumerates the returned statistics, and it explains the substring-match behavior of the required parameter. The gap is the undefined 'layout' parameter and the absence of any routing guidance against the many sibling stats tools.
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?
Schema coverage is 0%, so the description must carry parameter meaning. It does explain 'course' (substring match) and 'include_holes' (adds per-hole averages, long for multi-layout courses), but 'layout' is never defined in either the schema or the description, leaving one of three parameters opaque.
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 names a specific verb (compute stats) and resource (a course), and enumerates the concrete outputs: average/best/worst rounds, per-layout stats, and top-3 best/worst holes. It is clearly distinct from siblings like throw_stats or scoring_trends, though it never explicitly contrasts itself with them.
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?
There is no statement of when to use this tool versus the many sibling stats tools (throw_stats, scoring_distribution, hole_problem_report). The only usage-adjacent information is the note that include_holes produces a long list for multi-layout courses, which is a caveat rather than guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
export_statusBRead-onlyIdempotent
How fresh the data is: newest round, newest export file, and a stale warning.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, so the safety profile is fully covered by structured data. The description adds the content of the response (freshness signals), which is useful given there is no output schema, but it doesn't explain what threshold triggers 'stale' or how the warning is computed.
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?
A single compact sentence with the payload front-loaded after the freshness framing. No filler, though the colon-list style leaves terms like 'stale warning' undefined.
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 a full annotation set, the main gap is output detail: no output schema exists, and the description only gestures at the returned fields without defining 'stale' or the warning semantics. Adequate to invoke, thin for interpreting results.
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 zero parameters, so the baseline is 4; there is nothing for the description to disambiguate. No enum or format concerns apply.
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?
States concretely what it reports: freshness metadata consisting of newest round, newest export file, and a stale warning. The verb is implied ('reports/shows') but the resource and payload are specific. It doesn't explicitly distinguish itself from the sibling throw_export_status, which likely covers similar freshness ground.
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?
There is no statement of when to call this versus list_rounds, list_throws, or throw_export_status. The agent must infer that this is a freshness/data-health check. No prerequisites or exclusions are given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_roundARead-onlyIdempotent
Hole-by-hole scores for one round. round_id is 'YYYY-MM-DD HHMM' from list_rounds, or a date if unambiguous.
| Name | Required | Description | Default |
|---|---|---|---|
| round_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, so the safety profile is covered. The description adds only the identifier format and ambiguity fallback, which is parameter guidance rather than behavior; it says nothing about return size or pagination. A 3 is appropriate given annotations carry the behavioral burden.
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 short sentences, zero waste, with the output scope front-loaded and the identifier guidance immediately after. Every clause 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 single-parameter read-only tool with no output schema, the description conveys what is returned (hole-by-hole scores) and how to build the input. It stops short of describing the return shape beyond the one-line summary, but nothing critical for correct invocation is missing.
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?
Schema description coverage is 0%, so the description must compensate for the lone parameter and it does: it specifies the 'YYYY-MM-DD HHMM' format and the date-only fallback when unambiguous. It does not explain how to disambiguate an ambiguous date, which keeps it from a 5.
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?
States a specific verb (retrieves) and resource (hole-by-hole scores for one round), which naturally distinguishes it from list_rounds (lists rounds, not scores) and throw_stats/course_stats (aggregates). It does not explicitly name a sibling, but the singular-round scope makes the boundary inferable.
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?
Points the agent at list_rounds as the source for round_id, establishing the intended workflow chain. It also notes a fallback (a plain date if unambiguous). No explicit when-not guidance is given, so it falls short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
hole_problem_reportBRead-onlyIdempotent
Holes that have cost the most total strokes over par, with average and blow-up counts.
A blow-up is a hole played 2 or more strokes over par (double bogey or worse).
| Name | Required | Description | Default |
|---|---|---|---|
| top_n | No | ||
| course | No | ||
| layout | No | ||
| min_rounds | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, non-destructive and closed-world, so safety behavior is covered. The description adds useful domain semantics by defining 'blow-up' as 2+ strokes over par, which is genuinely beyond the structured fields, but it says nothing about filtering behavior or result ranking beyond the title.
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 short sentences, front-loaded with the core output and followed by a definition the reader needs to interpret the reported counts. Nothing is wasted and the term definition 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?
An output schema exists, so return values need no prose, but with 0% parameter coverage and no usage context, an agent cannot tell how to scope the report (which course, how many rounds minimum) or when this beats sibling analytic tools.
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?
Schema description coverage is 0% for four parameters (top_n, course, layout, min_rounds), so the description carries the full burden of explaining them and explains none. Parameter names are partly self-evident, but there is no statement of what course/layout filter on or how min_rounds thresholds the ranking.
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?
States a specific resource and metric set: holes ranked by total strokes over par, with average and blow-up counts. It is clearly distinguishable from siblings like scoring_distribution or course_stats, though it never names or contrasts them explicitly.
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 when-to-use guidance, no prerequisites, no alternatives offered. The second sentence defines 'blow-up' (terminology) rather than telling the agent when this report is the right choice over course_stats or scoring_trends.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_coursesCRead-onlyIdempotent
Courses played, with rounds played, layouts and first/last played dates.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint and destructiveHint=false, so the safety profile is fully covered. The description adds no behavioral context beyond that — no note on scope (all courses vs. played courses), ordering, or whether unplayed courses appear, even though 'Courses played' hints at a filter.
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?
One short clause with no filler and the most useful content (the returned fields) up front. The only structural weakness is that it reads as a noun-phrase label rather than an actionable statement.
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 an output schema present and annotations covering safety, the description needn't explain return values, and it doesn't. It is minimally adequate, but for a list endpoint sitting among many aggregating siblings it omits the relationship/ordering context that would prevent mis-selection.
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 zero parameters, so the baseline is 4. There is nothing for the description to disambiguate beyond the implicit 'played courses only' scope, which it does mention.
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 names the resource (courses) and the payload it exposes (rounds played, layouts, first/last played dates), but it is a sentence fragment with no verb and never says it *lists* the courses the user has played. It also does nothing to separate this from siblings like list_rounds or course_stats.
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?
There is no when-to-use guidance at all. An agent has no signal on when to pick list_courses over course_stats (per-course metrics) or list_rounds, both of which are plausible alternatives for overlapping data.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_roundsARead-onlyIdempotent
List rounds, newest first. start/end are YYYY-MM-DD (inclusive); course matches by substring.
| Name | Required | Description | Default |
|---|---|---|---|
| end | No | ||
| limit | No | ||
| start | No | ||
| course | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, non-destructive, and closed-world, so the safety profile is covered. The description usefully adds result ordering and inclusive date filtering, but says nothing about pagination or how the default limit of 50 bounds results.
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 tight sentences with no filler; the core action and ordering lead, and the format/matching details follow. Every clause carries information the schema does not.
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 simple read-only list tool with an output schema already describing return values, this is nearly complete: filters, formats, and ordering are covered. Only result-count/pagination behavior and sibling routing are missing.
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?
Schema description coverage is 0%, so the description must carry the load, and it does for three of four parameters: start/end formats (YYYY-MM-DD), inclusivity, and substring matching for course. The limit parameter (default 50) is left unaddressed, a minor remaining gap.
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?
States a specific verb+resource ('List rounds') plus ordering ('newest first') and filter semantics, which clearly separates it from the singular sibling get_round. It does not explicitly name siblings like list_courses or course_stats, so it falls short of full differentiation.
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?
Usage is implied by the description (a listing tool with optional date and course filters), but there is no explicit when-to-use, when-not-to-use, or pointer to alternatives such as get_round or compare_seasons. An agent can infer the context but gets no routing help.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_throwsBRead-onlyIdempotent
List TechDisc throws, newest first. primary_type is Backhand/Forehand; throw_type is e.g. Hyzer/Flat.
| Name | Required | Description | Default |
|---|---|---|---|
| end | No | ||
| limit | No | ||
| start | No | ||
| throw_type | No | ||
| primary_type | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false, and openWorldHint=false, so safety and side-effect behavior is covered. The description contributes one genuine extra trait, 'newest first' ordering, but says nothing about pagination behavior, the default limit of 50, or how the date window interacts with the limit.
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 short sentences with no padding. The core purpose and ordering are front-loaded, and the parameter hints follow immediately after.
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?
An output schema exists, so return values need not be described. However, for a five-parameter listing tool with zero schema documentation, the absence of date format guidance for start/end and any note on limit bounds or pagination leaves the agent short of what it needs to call this correctly.
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?
Schema description coverage is 0% across 5 parameters, so the description carries the full burden. It usefully supplies value domains for two filters (primary_type: Backhand/Forehand; throw_type: Hyzer/Flat) where the schema has no enums, but start, end, and limit are completely undocumented and the date format is unknown.
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?
States a specific verb and resource ('List TechDisc throws') plus an ordering guarantee, which is more than a restated name. It does not, however, distinguish itself from data-oriented siblings like throw_stats or throw_trends, so an agent must infer that this returns raw records rather than aggregates.
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?
There is no explicit when-to-use or when-not-to-use guidance and no alternative tool is named. The presence of throw_stats, throw_trends, and throw_export_status as siblings makes the absence of routing information a real gap.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
scoring_distributionBRead-onlyIdempotent
Share of holes scored eagle or better, birdie, par, bogey, double and triple or worse.
start/end are YYYY-MM-DD (inclusive). group_by is omitted for one overall row, or 'month' or 'season'.
| Name | Required | Description | Default |
|---|---|---|---|
| end | No | ||
| start | No | ||
| course | No | ||
| layout | No | ||
| group_by | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, non-destructive, closed-world, so the safety profile is covered. The description adds the inclusive date-range convention and the shape of grouped output, which is useful context. It says nothing about course/layout filtering effects or result volume, so it adds only modest value beyond the annotations.
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 short paragraphs, front-loaded with the core purpose and then the parameter conventions. Every sentence carries information and there is no filler. Slightly dense first sentence but well-structured overall.
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?
An output schema exists, so return values need not be described, and the bucket list plus grouping explanation covers the main behavior. The gap is the undocumented course/layout filters, which an agent would have to infer. Adequate but with a clear hole for a 5-param tool.
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?
Schema description coverage is 0%, so the description carries the load, and it does explain start/end format/inclusivity and group_by semantics. However, course and layout (two of five params) are left entirely undocumented in both the schema and the description. Partial compensation for the coverage gap, not full.
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 opening sentence states a specific computed resource: the share of holes falling into each scoring bucket (eagle+, birdie, par, bogey, double, triple+). An agent can tell this is an aggregate scoring-outcome breakdown, distinct from a trend or comparison tool. It does not explicitly contrast itself with the nearby scoring_trends/compare_seasons siblings, so it stops short of a 5.
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?
There is no when-to-use guidance and no alternative named. The only routing-like hint is the group_by behavior ('omitted for one overall row, or month or season'), which is parameter semantics rather than tool-selection guidance. An agent gets no signal on when to pick this over scoring_trends or course_stats.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
scoring_trendsBRead-onlyIdempotent
Average score vs par over time, grouped by 'month' or 'season' (calendar year); complete rounds only.
| Name | Required | Description | Default |
|---|---|---|---|
| course | No | ||
| layout | No | ||
| group_by | No | month |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, non-destructive, closed-world behavior, so the safety profile is covered. The description adds real value beyond them by disclosing the 'complete rounds only' filter and the calendar-year interpretation of season, but says nothing about aggregation method, sample sizes, or output shape.
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?
Extremely compact single fragment with the metric front-loaded and the grouping options immediately after. Nothing is wasted, though the terse fragment style slightly hurts scannability for the filter clauses.
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?
An output schema exists, so return values need not be explained, and annotations cover the safety profile. However, with zero schema description coverage and two unexplained parameters (course, layout), an agent cannot know how to scope the query, which leaves the definition short of 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?
Schema coverage is 0%, so the description must carry the load, but it only partially does: it explains group_by's allowed values and clarifies that 'season' means calendar-year grouping. The course and layout parameters are never mentioned, leaving two of three parameters undocumented anywhere.
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?
Names a specific metric (average score vs par) and its time-series nature, which distinguishes it from static siblings like scoring_distribution and course_stats. It does not, however, explicitly name or contrast itself with the closest sibling, compare_seasons, which also aggregates over time.
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?
Provides no when-to-use or when-not-to-use guidance and names no alternative. The 'complete rounds only' clause is a scope constraint on the data, not guidance about when an agent should pick this tool over compare_seasons or scoring_distribution.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
throw_export_statusARead-onlyIdempotent
How fresh the TechDisc data is: throw count, first/last throw, export file age and a stale warning.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, non-destructive and closed-world, so the safety profile is covered. The description goes beyond that by disclosing the return contents and flagging a 'stale warning', which is genuine behavioral context an agent can act on. It stops short of explaining what triggers staleness or the format of the age value.
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?
A single sentence, front-loaded with the core purpose ('how fresh the TechDisc data is') followed by the concrete outputs. No filler 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?
With no output schema, the description correctly carries the burden of describing return values and does so with four concrete items. It is nearly complete for a zero-argument read-only status tool, missing only the sibling distinction and the stale-threshold semantics.
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 zero parameters, so per the rubric the baseline is 4. There is nothing for the description to clarify about arguments, and it does not waste words inventing any.
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 reports data freshness for TechDisc throw data and enumerates what it surfaces (throw count, first/last throw, export file age, stale warning). However, it never differentiates itself from the sibling tool 'export_status', so an agent cannot tell the two apart without opening both schemas.
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?
There is no when-to-use guidance, no prerequisites, and no mention of alternatives. The description is purely a statement of what is returned; the agent must infer that this should be called to check data freshness before running throw analyses.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
throw_statsCRead-onlyIdempotent
TechDisc averages and maxima (speed, distance, spin, angles), overall and by throw style.
| Name | Required | Description | Default |
|---|---|---|---|
| end | No | ||
| start | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare this as a safe, read-only, idempotent, non-destructive operation, so the safety profile is covered. The description adds that results are aggregated averages and maxima, grouped overall and by throw style, but it does not disclose date-range filtering behavior or response structure.
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, front-loaded sentence with no wasted words. It efficiently conveys the tool's core output scope and grouping.
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 stats tool with optional start/end date filters and no output schema, the description omits any mention of date-range behavior or filtering semantics. The annotations cover safety, but the description is not complete enough for an agent to understand how to constrain the aggregation.
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 two optional parameters, start and end, with 0% description coverage. The description does not mention these date parameters at all, so it provides no meaning beyond the bare schema names and fails to compensate for the coverage gap.
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 names a specific resource (TechDisc throw stats) and specifies the metrics returned: averages and maxima for speed, distance, spin, and angles, both overall and by throw style. It is clear what the tool computes, though it does not explicitly distinguish itself from siblings like throw_trends or list_throws.
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 gives no guidance on when to use this tool versus alternatives such as throw_trends, list_throws, or compare_seasons. It implies a stats/aggregation use case but provides no explicit context or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
throw_trendsBRead-onlyIdempotent
TechDisc speed, distance and spin over time, grouped by 'month' or 'season' (calendar year).
| Name | Required | Description | Default |
|---|---|---|---|
| group_by | No | month | |
| throw_type | No | ||
| primary_type | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false, so the safety profile is covered structurally. The description adds the meaningful behavioral detail that 'season' means calendar-year grouping, but says nothing about time range, pagination, or returned granularity.
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?
A single tight sentence with the subject (metrics) and grouping behavior front-loaded. No filler, though the parenthetical about calendar year could be folded more cleanly.
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?
An output schema exists, so return-shape explanation is not required. However, for a trends tool with no date-range parameter and two undocumented filter parameters, the description leaves open how the trend window and filtering actually work.
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?
Schema description coverage is 0% across 3 parameters. The description clarifies group_by values ('month' or 'season', with season meaning calendar year), which is genuinely additive, but throw_type and primary_type are left completely unexplained, so a third of the parameters remain opaque.
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 names the concrete metrics (TechDisc speed, distance, spin) and the temporal framing ("over time"), plus the grouping dimension. This distinguishes it from throw_stats (aggregate) and scoring_trends (different metric family), though it stops short of explicitly contrasting with those 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?
There is no when-to-use guidance, no exclusions, and no mention of alternatives such as throw_stats or scoring_trends. The agent must infer selection purely from the tool name and metrics listed.
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.
13 tool updates
v0.1.0- First observed
compare_seasons - First observed
course_stats - First observed
export_status - First observed
get_round - First observed
hole_problem_report - First observed
list_courses - First observed
list_rounds - First observed
list_throws - First observed
scoring_distribution - First observed
scoring_trends - First observed
throw_export_status - First observed
throw_stats - First observed
throw_trends
TDQS
Scored across 13 tools
Tools are mostly distinct: list/get for rounds, stats/trends for scoring, and separate throw tools. Minor overlap between course_stats (includes best/worst holes) and hole_problem_report, and between scoring_trends and compare_seasons, but descriptions clarify.
All names use snake_case, but the pattern mixes verb-first (list_rounds, get_round, compare_seasons) with noun-phrase (course_stats, scoring_distribution, throw_export_status). This is a mixed convention, though still readable.
13 tools are well within the typical 3-15 range and cover both round analysis and TechDisc throw analysis without obvious bloat.
The tool set covers round listing/retrieval, course and hole statistics, scoring distributions/trends, season comparison, and TechDisc throw stats/trends, plus export freshness for both data sources. Minor gaps might include a dedicated tool for per-round summary or course comparison, but the surface is largely complete for analysis.
Maintenance
Related MCP Connectors
Read-only PDGA disc golf data — players, events, courses and season statistics.
- GonkbotOAuthcom.gonkbot
Log golf rounds in ChatGPT/Claude; scorecards, trends, unofficial WHS math.
Ask questions about a CSV in plain English and get answers, charts and cleaned data back.
Search disc golf courses worldwide, find nearby courses, and retrieve course details and updates.
Related MCP Servers
- FlicenseAqualityDmaintenanceEnables comprehensive analysis of CSV files and SQLite databases through tools for statistics, correlations, anomaly detection, pivot tables, time series analysis, visualization, and automated insights discovery.16-
- FlicenseNot gradedqualityBmaintenanceEnables querying and analyzing personal Strava activity data through natural language, including activities, segments, gear, and training trends.-
- FlicenseNot gradedqualityDmaintenanceEnables analysis of FitNotes workout data through an LLM, providing insights on progress, muscle groups, and personalized recommendations.4-
- FlicenseAqualityDmaintenanceEnables querying and analyzing sports activities from Strava and Garmin Connect, including sleep and recovery data.10-