Skip to main content
Glama

Get one course

ourpr_get_course
Read-onlyIdempotent

Read one published course: its place, distance, climb, how it was measured, and which streets carry it.

DELIBERATELY WITHOUT the elevation profile, the amenities and the centerline. Those are three more tools, because one course payload is about 83 KB and 91% of it is the profile.

Args:

  • slug (string): From ourpr_list_courses. Example: 'boston-marathon'.

  • response_format ('markdown' | 'json'): Default 'markdown'.

Returns: { "slug": string, "name": string, // the event's own name, title sponsor included "place": string | null, "alternate_names": string[], // curated geographic aliases "kind": string, "course_type": string, "distance_mi": number, // the stated race distance "measured_mi": number | null, // the centerline ourpr. measured "next_race_date": string | null, "days_out": number | null, "climb_ft": number | null, "descent_ft": number | null, "min_ft": number | null, "max_ft": number | null, "steepest_pct": number | null, "provenance": string | null, // one sentence on how it was built "sources": [{ "label": string, "value": string }], "recorded_on": string | null, // the watch that recorded the seed run "main_ways": [{ "name": string, "mi": number, "share_pct": number }], "through": string[], // named places the line passes through "photo_count": number, "counts": { "named_climbs_and_descents": number, "amenities": number, "mile_markers": number, "profile_points": number }, "page_url": string }

distance_mi is what the race calls itself; measured_mi is what the centerline measures. They differ by a few hundredths and both are reported rather than reconciled.

Examples:

  • "Tell me about the Boston Marathon course" -> slug="boston-marathon"

  • "How much does San Diego climb?" -> slug="san-diego-marathon", read climb_ft

  • Do not use when: you want the hill-by-hill shape. Use ourpr_get_course_terrain.

Error handling:

  • Returns the slug list suggestion when the slug is unknown.

Input Schema

NameRequiredDescriptionDefault
slugYesThe course's slug, exactly as ourpr_list_courses returns it. Example: 'boston-marathon'.
response_formatNoOutput format. 'markdown' reads well in a chat answer. 'json' carries every field for further computation.markdown

Output Schema

NameRequiredDescriptionDefault
kindYes
nameYes
slugYes
placeYes
countsYes
max_ftYes
min_ftYes
sourcesYes
throughYes
climb_ftYes
days_outYes
page_urlYes
main_waysYes
descent_ftYes
one_way_miYes
provenanceYes
course_typeYes
distance_miYes
measured_miYes
photo_countYes
recorded_onYes
steepest_pctYes
next_race_dateYes
alternate_namesYes

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed2 schema fields changed
    • removedOutput schema / properties / gpx_url
      Removed value: -{
      -  "type": "string"
      -}
    • changedOutput schema / required
      Previous value: -[
      -  "slug",
      -  "name",
      -  "place",
      -  "alternate_names",
      -  "kind",
      -  "course_type",
      -  "distance_mi",
      -  "one_way_mi",
      -  "next_race_date",
      -  "days_out",
      -  "climb_ft",
      -  "descent_ft",
      -  "min_ft",
      -  "max_ft",
      -  "steepest_pct",
      -  "measured_mi",
      -  "provenance",
      -  "sources",
      -  "recorded_on",
      -  "main_ways",
      -  "through",
      -  "photo_count",
      -  "counts",
      -  "page_url",
      -  "gpx_url"
      -]New value: +[
      +  "slug",
      +  "name",
      +  "place",
      +  "alternate_names",
      +  "kind",
      +  "course_type",
      +  "distance_mi",
      +  "one_way_mi",
      +  "next_race_date",
      +  "days_out",
      +  "climb_ft",
      +  "descent_ft",
      +  "min_ft",
      +  "max_ft",
      +  "steepest_pct",
      +  "measured_mi",
      +  "provenance",
      +  "sources",
      +  "recorded_on",
      +  "main_ways",
      +  "through",
      +  "photo_count",
      +  "counts",
      +  "page_url"
      +]
  2. First observed

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile (readOnlyHint, idempotentHint, destructiveHint=false), so the description's job is to add operational context, which it does: it discloses the ~83 KB payload size and that 91% of it is the profile, explaining the tool's partitioning. It also documents an error path ('Returns the slug list suggestion when the slug is unknown') and warns that distance_mi and measured_mi are reported 'rather than reconciled', which prevents a downstream agent from assuming they match. It stops short of stating rate limits or pagination, but neither appears relevant for a single-record fetch.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the one-line purpose, then cleanly sectioned into exclusions, args, returns, examples, and error handling. Almost every line carries information an agent would otherwise have to infer. The lengthy Returns block is partly redundant given that an output schema exists, though the inline field comments (e.g., the distance_mi vs measured_mi distinction) do add real meaning.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a two-parameter read tool, the definition covers purpose, scope boundaries against three sibling tools, argument sourcing, response shape, worked examples, and unknown-slug behavior. Nothing an agent needs in order to select and invoke it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so both parameters are already fully documented with type, length bounds, enum, and default. The description's Args block largely restates the schema ('From ourpr_list_courses', 'Default markdown') and adds no syntax or format detail beyond it. With the schema doing the heavy lifting, the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening sentence gives a specific verb and resource ('Read one published course') and enumerates exactly what the payload contains: place, distance, climb, measurement provenance, and streets. It further sharpens the boundary by naming what is deliberately excluded (elevation profile, amenities, centerline), so an agent can distinguish this from ourpr_get_course_terrain and ourpr_get_course_route without opening a schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is pinned down with concrete utterance-to-argument examples ('Tell me about the Boston Marathon course' -> slug="boston-marathon') plus an explicit negative rule: 'Do not use when: you want the hill-by-hill shape. Use ourpr_get_course_terrain.' It also explains that the excluded data lives in 'three more tools', giving the agent a routing map rather than a single alternative.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources