CourseProfiler MCP — Trail Running & Race Pacing

Tools for trail running and ultramarathon analysis, runner evidence insights and race pacing. CourseProfiler provides a Model Context Protocol (MCP) endpoint for ChatGPT and other MCP-capable agents, reusing the same analysis and planning services as the CourseProfiler application.

What can an agent help you do?

Supported sources include GPX, FIT, CRSProf course files and USRProf runner profiles. Capability and evidence support are not guarantees of race-day performance. Uploads, profile preparation and plan application have separate consent boundaries.

Find CourseProfiler in the official MCP Registry as com.courseprofiler/courseprofiler, or configure the endpoint below in a compatible client. A directory listing does not automatically connect or authorize an agent; client support and user permission are still required.

Endpoint

https://courseprofiler.com/mcp

Tools

Use attached profile files

For an attached USRProf or CRSProf, prefer import_profile_attachment before asking for a manual upload. It declares openai/fileParams: ChatGPT supplies a file object with required download_url and file_id, and optional file_name and mime_type. Never invent those values or pass a sandbox path.

Obtain explicit permission to send the selected attachment to CourseProfiler, then set upload_authorized=true and profile_type=usrprof|crsprof. The tool stores original bytes unchanged (non-empty, maximum 25 MiB), without validation, migration, regeneration, preparation or evidence selection. It creates a new private source artifact, not a replacement profile. Do not expose temporary URLs or file handles. Automatically pass the returned artifact_id to inspection or planning; those tools validate the profile. This upload permission does not authorize preparation or strategy application.

Host file handoff depends on the connector; local registration is not proof of ChatGPT acceptance. If unavailable, explain the limitation immediately and offer the browser upload page, which accepts USRProf as well as GPX/FIT/CRSProf. Do not substitute a raw-file assessment for requested canonical inspection.

Inspect runner evidence

inspect_runner_profile requires usrprof_artifact_id and explicit query: summary, quality, recency, course_fit, coverage or insights. Reads existing USRProf or uploaded USRProf source artifacts; legacy .userprof requires explicit migration. Stored readiness is not current fitness or a new pacing gate. No reconstruction, model activation, Strava access or profile replacement occurs.

course_artifact_id is required for course_fit, optional for coverage and rejected elsewhere. Course context uses current v3 reference geometry; selection is a preview, never applied. Paged queries default to offset 0 and limit 20 (maximum 100). The insights query rejects offset, limit and course context.

Insights returns durability, uphill, observed/stored GAP, run/hike, terrain mechanics and terrain-relative strength. Preserve their distinct age scopes, fitted/default boundaries, extrapolation and support disclosures. Above 1,000,000 eligible RUN×HIKE pairs, run/hike is resource_limited while the other families remain available. Recent trends, form drift, evidence range bars and technicity response are unavailable in MCP, not missing athlete evidence; experimental gates are unchanged. Invalid numerical results fail explicitly rather than return partial metrics.

The server owns inspection time; no caller clock override. Results include bounded evidence references, not source identities or full graph arrays. Confirm deployed availability with tools/list (24 tools in this revision); documentation of this revision does not establish deployment acceptance.

Planning decision reports

Both planning tools require course_artifact_id (current v3 reference plan) and usrprof_artifact_id. assess_finish_time_goal requires positive target_elapsed_seconds, including saved dwell, and evaluates 5% shapes. compare_pacing_strategies accepts split_percent, default 5, range 0–15 inclusive. All nine alternatives preserve saved movement locks, dwell, checkpoint windows, cutoffs and GAP settings.

estimation_model defaults to load_response_evidence_v2; experimental v3 requires explicit user approval and must match the stored model. allow_profile_preparation defaults to false. Obtain explicit user approval before allowing in-memory reconstruction; never silently retry with true. Results disclose reuse versus reconstruction. No source replacement, evidence selection, Strava access or automatic model migration.

These tools create a new private planning_report: non-read-only, non-idempotent and non-destructive. Strategies are not applied. Summaries are bounded, not sampled calculations; preserve confidence, fallback and omission disclosures. Use get_artifact with report_artifact_id for the complete diagnostic report, not an exportable course plan. A supported goal is not a guarantee of finishing. Local registration is not hosted acceptance.

Analyse an activity with one tool

Prefer analyze_activity for a supplied activity or route: no catalog search or runner profile is needed. Supply course_file (content/base64), or source (URL/artifact). If the client cannot read local bytes or perform a direct REST upload, send the user to the fixed browser upload handoff. The page creates the private upload session internally; the user uploads the GPX/FIT/CRSProf file and copies its artifact ID into the conversation. MCP does not create a session-specific browser-upload link.

Defaults are 0.25 m/s moving threshold, 30 s minimum stop, and 60 m merge distance with the existing combined-speed guard. Options are moving_threshold, auto_stop_threshold, auto_stop_merge_distance, algorithm (omitted: PACE_BASED for timestamped input, SLOPE_BASED for untimed routes), and include_routes (default true). Existing CRSProf is preserved; options supplied for it produce warnings rather than silent reanalysis.

The result contains job and summary. Check job status/errors first. Summary units are explicit: metres, seconds, seconds/km, bpm and both-leg spm. Missing timing means no invented full-course pace. Known partial timestamps are retained and flagged as incomplete, intentionally differing from the browser's profile-import fallback that may discard mixed timestamps. Detected-stop elapsed can include moving portions and differs from total non-moving time. Stop details are limited to the first 20 (with omitted count); all source points and intervals remain in the artifact. Analysis currently runs synchronously; use inspect_analysis for detailed climb/range queries.

Inspect and compare canonical artifacts

inspect_analysis accepts artifact_id and query: segments, splits, climbs, stops, range or quality. Pages default to 20 rows, maximum 100; follow next_offset and check total_matches. Climb groups use existing UP movement rows. Missing/UNKNOWN terrain falls back to the browser's net-grade policy using the saved flat-grade threshold (default zero), without smoothing or new segmentation. Check terrain_source, terrain_classification_status and unavailable_terrain_segment_count: missing classification is not proof of no climbs. Stop filters distinguish actual_elapsed, actual_nonmoving and planned_dwell; unknown durations are explicitly excluded when filtering. Ranges require from_m/to_m, with explicit axis=reference|execution for comparisons. Distances are metres and time is seconds; adjacent ranges own stationary boundary time once, with terminal dwell in the final range. Split separate_boundary_* metrics describe structural table separators, not detected stops; their distance and timing remain separate from both the table subtotal and separate_stop_* metrics.

compare_execution accepts plan_artifact_id, execution_artifact_id, and optional stop_association_distance_m (default 60). It uses the full browser comparison pipeline, not stop redetection. Returns {job, summary}: first 20 splits/stops, quality, and server-owned findings shared with the UI. Check job errors first; failed jobs have null summary. Largest split deltas exclude separate dwell, and matched planned stops are not unplanned. Review row references are capped at 20 per finding with omitted counts and focus retained; full geometry, chronology and references remain in the output artifact. Both tools require v3 CRSProf: analyse GPX/FIT first or explicitly migrate legacy data. Confirm deployed availability with tools/list.

Choose the workflow

import_course remains an artifact-only alternative: no catalog search, runner profile, or waypoint enrichment is required. Prefer analyze_activity for structured answers. Use get_job and get_artifact to retrieve artifacts. Search the catalog first only when resolving a named race without a supplied source.

Normal workflows use CRSProf v3; legacy inputs require explicit migration. Planning requirements below do not apply to basic activity analysis.

generate_runner_profile.profile_intent is advisory context for the agent. The server does not filter or select evidence from it. Submit only user-approved sources, and ask clarifying questions only when intent is not already clear.

MCP action annotations describe read-only, creation, and external interactions. They are hints, not consent or authorization; repeated creation calls can create new artifacts/jobs.

Waypoint/resource completeness

Catalog CRSProf files may already include official waypoints/resources/cutoffs. If they do, agents can use the catalog CRSProf URL directly for segmentation and race-plan creation. If official aid-station, water/food/crew, checkpoint, or cutoff data is missing, call enrich_course_waypoints with structured rows or ask the user for official aid/resource details before segmentation. If official pages and regulation PDFs disagree, or exact aid locations are not machine-readable, ask the user to confirm and include only confirmed aid stations.

Route-only plans are incomplete unless the user explicitly accepts missing aid/resource/cutoff details. If no waypoint data is available, ask the user whether a route-only plan is acceptable and label the resulting plan as missing aid/resource details. Resource values are canonical: use values such as water, drinks, food, fruit, hot_meal, crew, drop_bag, medic, toilet, or rest_area. Unsupported/free-text resource strings are ignored with warnings; preserve non-canonical details in waypoint notes/source text instead of inventing resource identifiers.

Course file fallback

GPX, FIT and CRSProf URLs are supported. FIT responses are identified by filename or FIT header and use the same converter as uploaded files.

If the catalog has no confirmed CRSProf and an official or third-party GPX/FIT/CRSProf URL cannot be fetched, is blocked, or returns 403, assistants must stop and ask the user to download the official route file and upload it through the artifact upload flow. Do not treat a blocked direct URL as permission to reconstruct the course. Do not create race plans from roadbooks, checkpoint tables, elevation profiles, aid-station lists, screenshots, or other synthetic/reconstructed route data; those are enrichment/context only and are not valid course geometry. Continue with the returned source_file artifact as course.source.kind=artifact.

Runner profile / evidence

Personalized plans require runner input. If the user does not already have a runner profile, call get_runner_profile_requirements and explain the options in user-facing terms: export a .usrprof from CourseProfiler, upload GPX/FIT activities as evidence, use public evidence URLs, or call build_runner_profile_from_strava. Open its private browser authorization link, resume the same job as instructed, then use its USRProf artifact. Never request credentials or tokens through MCP. Manual activity selection/export in the web app remains an alternative.

Hosted-client file uploads

MCP clients that can read local files may pass file bytes inline inside a file object as course_file.content or runner_profile_file.content for text formats such as GPX/XML/JSON/USRProf, or as course_file.base64 / runner_profile_file.base64 for binary formats such as FIT. Include name or file_name so CourseProfiler can infer the format.

Hosted MCP clients such as ChatGPT may not be able to pass local binary files directly to MCP tools. Bare local filesystem paths never work on the hosted MCP server; do not pass local paths or file:// URLs. If inline content/base64 is not available, call get_artifact_upload_requirements for instructions or upload local files through the public REST upload-to-artifact flow outside MCP: POST /api/artifact-uploads, PUT the bytes to the returned private upload URL while replaying all returned headers exactly, then complete with POST /api/artifact-uploads/{upload_id}/complete. Completion returns a source_file artifact ID. The helper is not a raw-byte MCP upload tool; MCP exposes instructions, not local file upload bytes. For USRProf/CRSProf, prefer the consent-bound import_profile_attachment file handoff above; otherwise use inline/proxied files or the REST/browser upload flow.

Option schemas

import_course.options and course.import_options accept only boolean include_segments and include_routes. Unknown fields, including file_name, and non-boolean values are rejected. Existing CRSProf files are preserved, with analysis_options_not_applied warnings if these analysis options are supplied. Omit them for CRSProf reuse; use generate_course_segments for segmentation changes.

generate_course_segments.options accepts only segmentation options such as algorithm, flat_grade, slope_change_threshold, flat_max_delta, minimum_distance, flexible_minimum_distance, flexible_flat_max_delta, instant_mode, and include_routes. estimate.options accepts only strategy, gap_algorithm, and flat_grade. Put race metadata, start times, and waypoint/cutoff data in the course/waypoint fields, not in generic options.

Examples

Inline GPX course file plus inline USRProf file:

{
  "course_file": {
    "name": "course.gpx",
    "content_type": "application/gpx+xml",
    "content": "<gpx>...</gpx>"
  },
  "runner_profile_file": {
    "name": "runner.usrprof",
    "content_type": "application/vnd.courseprof.usrprof+json",
    "content": "{...}"
  },
  "pdf": { "enabled": true }
}

Uploaded CRSProf/course source artifact:

{
  "course": {
    "source": { "kind": "artifact", "artifact_id": "art_uploaded_course_source" },
    "segments": { "mode": "generate" }
  },
  "runner": {
    "sources": [{ "kind": "artifact", "artifact_id": "art_uploaded_usrprof_source" }]
  },
  "pdf": { "enabled": true }
}

Already-converted USRProf artifact:

{
  "course": { "crsprof_artifact_id": "art_course" },
  "runner": { "usrprof_artifact_id": "art_converted_usrprof" },
  "pdf": { "enabled": true }
}

Testing

In ChatGPT, enable Developer mode for Apps/Connectors if available, then create a connector pointing to https://courseprofiler.com/mcp. Availability and review requirements are controlled by the assistant platform.

Privacy and contact