freemapperDeutsch

Manual › freemapper-courseplan

3. With an AI assistant

The assistant sets the courses for you. For this, freemapper-courseplan is an "MCP server", a tool that AI assistants can use. The program has no AI of its own. The assistant calls the same editing functions as the command line, and each call saves into your project file.

Set it up once

  • Claude Desktop:
    1. Open Settings > Developer > Edit Config.

    2. Add this to the file claude_desktop_config.json, with your own path (on Windows with doubled backslashes \\):

      {
        "mcpServers": {
          "freemapper-courseplan": {
            "command": "/Users/anna/Documents/freemapper-courseplan/freemapper-courseplan",
            "args": ["mcp"]
          }
        }
      }
      
    3. Restart Claude Desktop.

  • Claude Code: type claude mcp add freemapper-courseplan -- /path/to/freemapper-courseplan mcp in a terminal.
  • Other assistants: any assistant with MCP support takes the same entry: the program and the argument mcp.

The assistant reads the tool texts in the language of your system. To fix the language, write "--lang", "en" before "mcp" in the arguments, or set FREEMAPPER_LANG=en in the environment of the program. Tool names and field names stay English in every language.

Let the assistant set it up

The archive holds, besides the program, the READMEs, the licence, this manual and AGENTS.md, instructions for AI assistants. An assistant that can run commands on your computer (such as Claude Code or Codex) downloads the program, checks and unpacks it by the steps in that file and then works through the command line; it needs no registration. Only an assistant that cannot run commands needs the registration described above. Tell it:

Read AGENTS.md from github.com/HenryJobst/freemapper-courseplan and set up freemapper-courseplan.

On a Mac it removes the block on unsigned programs and tells you so. Depending on its settings it asks before each command. Claude Desktop runs no commands; there you register the program by hand as described above.

Set a course

The assistant does not see the map. It can ask for the extent of the map and, for a point, for the map objects around it, each with its symbol number, its kind (point, line, area) and its distance. It knows no names such as "south door" or "gym", and the query does not tell it where exactly an object lies. So give it positions, in map millimetres or relative to the extent of the map, for example:

Start an event from ~/maps/hall.omap. Put the start a quarter of the way in from the left edge, at half the height, and the finish 10 mm to the right of it. Add three controls spread over the map and tell me for each which map objects lie within 2 mm. Make a course "Short" from them for class D10, place the control numbers and tell me the length.

The assistant then works like this:

  1. It starts the event. The project file lands next to the map, named hall.courseplan.toml.
  2. It asks for the extent of the map, that is its smallest and largest corner in map millimetres, the scale and the map kind, and works out the positions from it.
  3. It adds the start, the finish and the controls at these positions.
  4. For each control it asks for the map objects nearby and tells you their symbol numbers and distances, such as "symbol 521, area, 0.4 mm". Look up what a symbol means in the symbol set of the map.
  5. It adds the course, places the control numbers and reads the length and the climb.

You can also continue in a later chat. Give the assistant the path of the project file and it picks up from there.

What to know

  • Paths are absolute or start with ~. A relative path is refused, because the assistant does not know the working folder of the program.
  • Every change is saved at once. If the program refuses a change, for example a point outside the map or a code that is taken, the file stays as it was and the assistant gets the reason.
  • If the project file changed after the assistant read it, for example because you moved a control in the editor, the program writes nothing. The assistant gets " changed on disk after it was read, so nothing was written. Read the project again and repeat the change" and repeats the change with the new state.
  • Positions are in map millimetres at map scale, with y pointing down. Look at every control position yourself on the map. check tests distances, angles and codes against the rules (chapter 8), but not whether the control stands at the right feature.
  • The program places control numbers only when the assistant asks for it. If the assistant then changes legs or the order, it has to have them placed again. A number placement set for a control or in a course stays.
  • Automatic placement puts a number behind the circle, in line with the leg that leads to the control. If the course hardly turns, the next leg runs there, and the number goes outside, at the tip of the angle. It stands on a point or line symbol of the map only when no free place is left; it may cover areas. If you dislike the position, set it yourself.
  • The number stands 0.5 to 5 mm from the circle (distance from the circle line to the number box, rule wkb2026.number.gap). Automatic placement starts at 0.5 mm and moves outward in steps of 0.5 mm before it turns away from the preferred direction. check warns when a stored gap lies outside the range, for example a number set by hand at 6 mm.
  • When the order of a course changes, every leg that now runs to another stop loses its bends and its taped flag. The assistant gets a list of these legs.
  • Individual and score courses can be edited (see Score courses below). info gives the length of individual courses; for a score course it gives controls, points and time limit, and score length measures it. Team and relay courses cannot be edited yet; the program says so.
  • The project file is plain TOML. freemapper-courseplan info <project> shows what the assistant did, and list controls|courses|specials|classes <project> lists the details; map extent <project> and map near <project> --at X,Y --radius MM report the map. All of them take --json.
  • Score courses

    On a score course the runners visit the controls in any order within a time limit. Each control is worth points, and every started minute over the limit costs points. These commands build such a course; check tests it (section 8).

    freemapper-courseplan course add hall.courseplan.toml Score45 --kind score --start S1 --finish F1 --time-limit 45
    freemapper-courseplan score controls hall.courseplan.toml Score45 31,32,43,54
    freemapper-courseplan score link add hall.courseplan.toml Score45 31 54
    freemapper-courseplan score settings hall.courseplan.toml --value-max 5 --good-pace 4:10
    freemapper-courseplan score course set hall.courseplan.toml Score45 --penalty 6
    
    • The code carries the value: the second digit of a two-digit code, the last digit of a longer one. So 43 is worth 3 points and 54 is worth 4. score controls reads the value from the code. A value you write after =, as in 43=3, has to match it; if it differs, the program refuses and says to change the code. score value follows the same rule, so it only repairs a value in the file that no longer matches its code. A code that carries no value, such as A1, needs one: A1=2.
    • Values run from 1 to the highest value of the event, 5 by default and at most 9 (score settings --value-max).
    • Without --penalty the course stores no penalty and uses the default: the highest control value of the course, at least the highest value of the event, so a minute over never pays off. The default follows the controls. score course set --penalty N stores your own number, and --no-penalty goes back to the default.
    • Changing a control's code (control code) gives it the value of the new code. A code that carries no value keeps the old value, and check reports the difference.
    • A link names two controls that the runner has to visit directly one after the other, in either direction. A runner who does not is disqualified. A control takes at most two links, and links may not close a ring. A control with a link stays in the course until you remove the link (score link remove).
    • score settings writes the [score] table of the event: value range, the target bands (--good-band 87-93, --very-good-band 95-100, in percent), their tolerance (--band-tolerance 3, 0 to 10 percentage points), the paces of a good and a very good runner (seconds per kilometre, or 4:10), the share of hard controls and the seed. Four distances in metres on the ground decide where controls stand (ADR 0072): --value1-min (150 m) is the least distance of a control from start and finish, where value 1 begins; --min-gap (100 m, not lower) the least distance between two controls; --high-value-gap (200 m, at least --min-gap) the least distance between two high-valued controls, the upper four tenths of the values (4 and 5 at a highest value of 5); --max-reach the farthest distance from the start. Without it the reach is automatic, a quarter of the ground the good runner covers in the time limit (900 m at 15 minutes and 4:10 min/km); --auto-reach returns to that. A distance is a whole number of metres.
    • Each of these commands takes --json and prints what the MCP tool of the same name answers (add_score_course, set_score_controls, set_control_value, add_score_link, remove_score_link, set_score_settings, set_score_course_details). The editor runs the same operations, and undo takes each back.
    • Bends, legs, control numbers and course controls belong to individual courses; a score course refuses them. Classes, print scale, course rename and course remove work on both. Team and relay courses cannot be edited yet.
    • IOF XML export writes score courses too (see Export below). The Purple Pen export still skips them and says so. The editor draws score courses and has a Score panel (see "The Score panel" in the editor chapter).

    Lists and evaluation sheet

    freemapper-courseplan export hall.courseplan.toml --course Score45 --csv score45.csv --sheet score45.md
    

    --csv writes one row per control: code,value,x_mm,y_mm, ordered by code, with positions in map millimetres at map scale (y points down) and a dot as decimal separator. --sheet writes the evaluation sheet as Markdown, a text that prints well as it is: the time limit, the penalty per started minute (the stored one or the default), the rule that the faster runner wins on equal points, the mandatory links with the rule that a runner who does not run a link directly is disqualified, and a table of the controls with their values. Both need --course and refuse a course that is not a score course. An existing file is replaced. The tools are export_score_csv and export_score_sheet, with project, course and path (ending in .csv or .md). The decisions are in ADR 0070.

    Suggestions, draft and length

    These three commands read the map and search routes on a raster of its symbols (no elevation), so each takes a few seconds on a large map. The start and the finish must lie outside buildings and blocked areas; if one does not, the program says the start or finish cannot be reached.

    freemapper-courseplan score suggest hall.courseplan.toml --limit 30
    freemapper-courseplan score draft hall.courseplan.toml Score45 --time-limit 45
    freemapper-courseplan score draft hall.courseplan.toml Score45 --time-limit 45 --apply
    freemapper-courseplan score length hall.courseplan.toml Score45
    
    • score suggest lists control sites, best route choice first, each with its position, the symbol code of the map feature, route choice and difficulty from 0 to 1, the time from the start for the good runner and the value it would get. It writes nothing. --limit sets the number (60 by default, at most 200), --min-distance the smallest distance in map millimetres (by default the setting min_gap_m, 100 m on the ground). Sites closer than value1_min_m to the start or finish are dropped, and with --course so are sites beyond the reach from the start. score draft also keeps the gap between high-valued controls; check warns when a course falls below it or below the minimum gap. --course NAME takes the start and finish of that score course (--start and --finish still win); without it the first start and finish of the event count. Sites in out-of-bounds and dangerous areas, on or inside map areas with the symbol 520, 709 or 714, and within 4 m of a forbidden route, are excluded. With --json and over MCP each candidate also has a free code that carries its value. It is null when no free code is left: only the best-ranked candidates get one.
    • score draft picks controls from these sites and gives them values and codes, so that the good runner scores 87 to 93 percent of all points by default within the limit and the very good runner takes every control and finishes after 95 to 100 percent of it by default. Both bands are targets, and so is their tolerance: a result up to 3 percentage points outside a band, by default, counts as near the target. The bands and the tolerance are settings of the event. Without --apply it only prints the draft. With --apply it adds the controls and creates the score course, or replaces the controls of an existing score course and removes the controls that only it used. A course of another kind is refused. The editor can undo the change.
    • --link "X,Y;X,Y" makes two positions a mandatory link; each must be the position of a candidate from score suggest, run with a --limit of at least 60, the pool the draft uses. Repeat the option for more links.
    • Each runner ends up in the band, near the target or missed. In the band and near the target are successes: the command exits with 0, and for a draft near the target it names the deviation, for example "1.7 percentage points above the band ... within the tolerance of 3 percentage points". A draft that misses a band beyond the tolerance exits with 1. It names each missed band with the size of the miss, and one hint: a longer or shorter limit, more suitable sites, free codes (the control count is capped by the code space: raise the highest value with score settings --value-max, 9 at most, or free codes on the map), a faster good runner, or that these inputs cannot work.
    • score length analyses a course that exists, for example after you moved a control, and reports the same bands and deviations and says in which of the three states the course is. It never changes the course.
    • The same answers come from the tools score_suggest, score_draft and score_length; --json prints them. The draft is the same on every run for the same project.
    • score reject --at X,Y rejects a site: you know the place is wrong, for example a private yard or a corner nobody sees. The position goes into the project file (key rejected_sites), and score suggest, score draft and the candidate list of the editor leave it out from then on. A candidate within 3 m on the ground counts as the same site. score unreject --at X,Y takes it back and fails when the site is not rejected. A control that already stands there stays. The editor has a "Reject" button beside "Accept" in the candidate table; undo takes it back. The tools are reject_site and unreject_site with project and at, and --json prints their answer: at, added or removed, and rejected_sites, the number of rejected sites. The decision is ADR 0089.

    Version: v0.18.1 · Source on GitHub