eventor-mcp
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., "@eventor-mcp list orienteering events in Norway next weekend"
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.
eventor-mcp
An MCP server that exposes the Norwegian/Swedish orienteering federation's Eventor REST API as typed tools, so an MCP client (e.g. Claude) can query events, clubs, entries and competitors -- and optionally publish start/result lists -- without ever seeing your API key or Eventor password.
Why this exists
Eventor's own API documentation (the "Hämta data via API"
guide)
only documents authentication and one example call. The actual endpoint shapes
used here were taken from a real, working integration (ttime.pl) against this
API.
Related MCP server: Evento Public MCP Server
Security model
Credentials (
EVENTOR_API_KEY,EVENTOR_USERNAME,EVENTOR_PASSWORD) are read only from environment variables, by the server process itself.They are never included in any tool result, logged, or written to disk by this project.
.envis git-ignored -- only.env.example(with empty values) is committed.An MCP client (including an LLM) only ever calls tools like
list_events(from_date, to_date); it never handles the raw key/password.
If you ever paste your API key into a chat, file, or issue, treat it as compromised and regenerate it in Eventor under Klubben -> Klubbinnstillinger.
Setup
Requires uv.
uv sync --extra dev
cp .env.example .env # then fill in your own values in .envuv sync creates .venv and installs everything pinned in uv.lock. Run
project commands with uv run <command> (e.g. uv run pytest), or activate
the environment yourself (.venv\Scripts\activate on Windows,
source .venv/bin/activate on macOS/Linux) if you prefer.
Two separate credential types are used by Eventor's API:
Credential | Used for | Where to get it |
|
| Eventor -> Klubben -> Klubbinnstillinger (club admin only) |
|
| Your personal Eventor login |
Running
uv run python -m eventor_mcp.serverThis starts the server on stdio, ready for an MCP client to connect.
Registering with Claude Code
This repo ships a project-scoped .mcp.json, so opening this folder in
Claude Code (or the Claude desktop app's Code tab) offers to enable the
eventor server automatically -- you'll see a one-time approval prompt
(project MCP servers can run arbitrary commands, so Claude Code always
asks first). It runs uv run python -m eventor_mcp.server with this
project directory as its working directory, so it picks up your local
.env on its own; no credentials are stored in .mcp.json.
To register it globally instead (available from any directory, not just this one), use the CLI:
claude mcp add eventor -- uv run --directory /path/to/eventor-mcp python -m eventor_mcp.serverEither way, credentials come from your environment / local .env --
never hardcode them anywhere in this repo.
Installing as a standalone tool (no clone needed)
If you just want to run the server -- not modify or test the code -- you don't need a checkout at all:
uv tool install git+https://github.com/bjorges/eventor-mcpThis puts an eventor-mcp command on your PATH, in its own isolated
environment. There's no project directory here for .env auto-loading to
find, so set credentials as real environment variables instead (see
.env.example for the full list), then register it:
claude mcp add eventor -- eventor-mcpUpgrade with uv tool upgrade eventor-mcp, remove with
uv tool uninstall eventor-mcp.
If uv warns that its tool bin directory isn't on your PATH, run
uv tool update-shell and restart your shell before eventor-mcp (or
claude mcp add ... -- eventor-mcp) will resolve.
Tools
Tool | Auth | Notes |
| API key | Dates as |
| API key | All clubs/districts/federations |
| Username/password | Classes for one event |
| Username/password | Full entries: name, class, club, control cards (a list -- Emit, emiTag and SI are distinct systems and a person can have more than one) |
| Username/password | Just entry/modify timestamps |
| Username/password | Registered club members |
| Username/password | Writes to Eventor -- publishes a start list |
| Username/password | Writes to Eventor -- publishes results |
import_startlist and import_resultlist expect a complete
IOF XML 3.0 document as a string;
this project does not (yet) build that XML for you.
Testing
uv run pytestLimitations / TODO
No XML-building helpers for
import_startlist/import_resultlistyet -- callers must supply valid IOF XML 3.0.No caching, even though Eventor's usage terms ask integrations to cache frequently-fetched data (e.g. club member lists) client-side.
Only tested against the Norwegian instance (
eventor.orientering.no); the Swedish instance (eventor.orientering.se) uses the same API shape viaEVENTOR_BASE_URL.
Available Tools
8 toolsget_competitorsB
Get all registered competitors for one or more clubs.
Args: organisation_ids: Comma-separated Eventor organisation id(s).
Requires EVENTOR_USERNAME and EVENTOR_PASSWORD.
Inputs: organisation_ids (required). Returns: result
get_entry_changesB
Get entry/modification timestamps for a specific event (who entered or changed their entry, and when), without full competitor details.
Requires EVENTOR_USERNAME and EVENTOR_PASSWORD.
Inputs: event_id (required). Returns: result
get_event_classesA
Get the competition classes defined for a specific event.
Requires EVENTOR_USERNAME and EVENTOR_PASSWORD (a personal Eventor login) -- this endpoint does not accept the club API key.
Inputs: event_id (required). Returns: result
get_event_entriesB
Get all entries for a specific event: competitor name, class, club and control card number.
Requires EVENTOR_USERNAME and EVENTOR_PASSWORD.
Inputs: event_id (required). Returns: result
import_resultlistA
Upload a result list to Eventor.
THIS WRITES DATA: it publishes results. Only call this after the user has explicitly confirmed they want to publish these exact results.
Args: iof_xml: A complete IOF XML 3.0 ResultList document as a string.
Requires EVENTOR_USERNAME and EVENTOR_PASSWORD.
Inputs: iof_xml (required). Returns: result
import_startlistA
Upload a start list to Eventor.
THIS WRITES DATA: it changes what is published in Eventor. Only call this after the user has explicitly confirmed they want to publish this exact start list -- treat it like any other irreversible "publish" action, not a routine read.
Args: iof_xml: A complete IOF XML 3.0 StartList document as a string.
Requires EVENTOR_USERNAME and EVENTOR_PASSWORD.
Inputs: iof_xml (required). Returns: result
list_eventsA
List events (competitions/activities) from Eventor within a date range.
Args: from_date: Start date, format YYYY-MM-DD. to_date: End date, format YYYY-MM-DD. organisation_ids: Optional comma-separated Eventor organisation id(s) to filter by (a club or district). Omit for all events in range.
Requires EVENTOR_API_KEY (a club API key from Eventor -> Klubben -> Klubbinnstillinger).
Inputs: to_date (required), from_date (required), organisation_ids. Returns: result
list_organisationsA
List all organisations (clubs, districts, federations) known to Eventor.
Requires EVENTOR_API_KEY.
Inputs: no named parameters. Returns: result
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 8 tools
Most tools target distinct resources (events, organisations, classes, imports), and the descriptions clarify scope. However, get_event_entries, get_competitors, and get_entry_changes all concern 'who is participating' and differ mainly by scope (event vs club vs timestamps), which could cause occasional misselection.
All eight tools follow a clean snake_case verb_noun pattern using get_, list_, and import_ prefixes consistently. The convention is predictable and easy to reason about.
Eight tools is well-scoped for an orienteering event data server, with a sensible split between read operations and two publish/import writes. Each tool clearly earns its place.
The surface covers the core lifecycle: listing events/organisations, reading classes, entries, competitors, and publishing start/result lists. Minor gaps exist, such as no single-event detail fetch and no update/delete of entries, but agents can work around these.
Maintenance
Related MCP Connectors
Find concerts, theatre, sport and festivals in Sweden. Authless, read-only MCP.
Norwegian company search, accounts, roles, groups and websites from Brønnøysund, remote MCP.
PredictHQ MCP — wraps the PredictHQ Events API (predicthq.com)
Remote MCP tools for pay-per-call email, domain, SEO and Swedish data utilities (x402).
Related MCP Servers
- AlicenseAqualityDmaintenanceExposes the OpenProject REST API as MCP tools for project management, including creating and managing projects, work packages, relations, attachments, users, notifications, watchers, boards, and reference data.3759 npmMIT
- AlicenseAqualityDmaintenanceMCP server to list and get events from Evento's public API using an API key.21ISC
- AlicenseBqualityBmaintenanceMCP server providing typed tools for Norwegian public data sources, enabling natural language queries to official datasets like SSB, Brønnøysund, MET, Kartverket, Entur, and more, without requiring API keys.47MIT
- AlicenseAqualityBmaintenanceEnables querying Swedish Transport Administration open data for live train departures and arrivals, railway disruptions, road incidents, and measured road weather through MCP tools.8MIT