{"name":"msge-no","description":"Read-only MCP for msge.no: kva Markus les, lyttar til, reiser og legg ut — the site’s live data as tools.","endpoint":"https://msge.no/mcp","transport":"streamable-http","authentication":"none","tools":[{"name":"get_site_info","description":"What msge.no is: the owner, every public page, the Atom feeds and the identity links. Nettstadskartet i eitt kall."},{"name":"get_now_playing","description":"The track Markus is listening to right now (or the most recent one). Kva som spelar akkurat no."},{"name":"get_recent_tracks","description":"Recently played tracks (scrobbles), newest first. Nyleg avspela musikk."},{"name":"get_music_stats","description":"All-time listening stats (total scrobbles, span, top albums) plus the last 30 days’ top tracks."},{"name":"get_besett","description":"What Markus is listening to far MORE than usual right now — a different question from what he listens to most. Over a 7-day window an artist or album must clear a share of the window, a lift over its own all-time share, and a play floor; a track is judged as a runaway against the runner-up instead. Each grain is null when nothing qualifies, which is the normal state. An artist absent from the upstream 100-row all-time ranking carries ny:true and loft:null rather than an invented multiple."},{"name":"get_artist","description":"One artist, whole: every track grouped by the release it belongs to, the play count per track, a month-by-month series, the gigs Markus went to (with the setlist crossed against his own play counts) and the guest features filed under other artists. Only artists with a curated discography have an entry — which release a track belongs to cannot be derived, because Last.fm files every single twice. Omit `slug` for every curated artist. Tracks the discography has not placed yet are listed in utanfor[] rather than dropped, and an upcoming gig carries a DATE and no countdown, since a stored countdown is wrong within the hour."},{"name":"get_reading","description":"The books Markus is currently reading (live BookWyrm shelf). Kva han les akkurat no."},{"name":"get_books","description":"Every book Markus has read (the /bokhylla shelf): totals, and per-book title, author, pages, language, genre, finish date. Optionally filtered by year."},{"name":"get_bok_arkiv","description":"The /bok/arkiv aggregations over every book Markus has finished, along four axes: genre, calendar month, author and language. Pass `akse` for one of them, or omit it for all four plus the headline totals and the records. THE COVERAGE BLOCK IS PART OF THE ANSWER, NOT GARNISH. (1) `dekning.aar` marks each year in the span with why it cannot be compared: `importert` (the figures describe an import, not a period), `ujamn` (the count is a remainder, not a measurement), `tom` (no rows at all) or `lopande` (not over yet). (2) `dekning.utelate` lists exactly those years, and every record in `rekordar` was computed with them withheld — so quote a superlative as \"of the comparable years\", never as \"ever\". (3) The RUNNING MONTH is withheld the same way and is never a winner. (4) `dekning.atterhald` carries what the dataset does not know about itself, and it is the one field a summary must not drop: the shelf begins at the StoryGraph export, so everything read before it is simply absent, and BookWyrm's own count is higher than the one served here. `rekordar` is null rather than zeroes for an empty history, because \"0 sider\" reads as a real measurement."},{"name":"get_train_stats","description":"Train travel stats from Viaduct: scope \"year\" = current year, \"all\" = all-time with operator and per-year breakdowns. Counts trips from departure, so planned journeys are not in the totals — the ones still ahead are listed under schedule[], the leg under way (if any) under current. Togreisene til Markus."},{"name":"get_train_countries","description":"How many kilometres Markus has ridden by train in each country, and which legs put them there. Derived, not recorded: the archive stores a leg as two stations and one distance, so each station pair is routed over the rail network, intersected with country polygons and prorated back to the leg's own distance — which is why the totals reconcile exactly with get_train_stats. A leg counts in every country it passes through, including ones it never stops in, so the per-country leg counts sum to more than the number of trips. Ferries and legs that have not departed yet are excluded, and both are reported separately. Kor mange kilometer i kvart land."},{"name":"get_train_month","description":"The train archive bucketed by calendar month. Omit `maanad` for every month ranked against the others plus a year-by-month grid; supply one (YYYY-MM) for that month in full: kilometres, legs, hours, stations, countries, records, the named journeys touched and the posts written aboard. Months are Europe/Oslo calendar months and a leg counts from its departure, so the totals reconcile with get_train_stats. THE RUNNING MONTH IS DELIBERATELY EXCLUDED from every ranking and average and is flagged `ufullstendig`, because a month three days in would otherwise win \"quietest ever\" every month. A well-formed month with no travel returns an honest empty month rather than an error. Togmånad for månad."},{"name":"get_train_year","description":"The train archive bucketed by calendar year — the \"year in review\" view. Omit `aar` for every year ranked against the others; supply one (YYYY) for that year in full: kilometres, legs, hours, night trains, stations, countries, records, the named journeys that started in it, a month-by-month grid and the posts written aboard. Every year carries `del`, its SHARE of all travel ever — but only for the additive quantities (km, hours, legs, night trains, journeys). Countries, stations and operators are NOT additive (the same country is travelled in many years), so they come as `avAlt: [n, m]` counts and never as a percentage. Years are Europe/Oslo calendar years and a leg counts from its departure, so the totals reconcile with get_train_stats and get_train_month. UNLIKE the running month, THE RUNNING YEAR IS RANKED like any other — it is flagged `ufullstendig` and drawn as such, but competes (ADR 0030). A well-formed year with no travel returns an honest empty year rather than an error. Året mitt på skjener."},{"name":"get_train_routes","description":"The train archive by STATION PAIR — which routes Markus actually travels. A strekning is an unordered pair of stations; a gjennomgang is one crossing of it, meaning a contiguous run of legs from one end to the other with no station visited twice and no stop-over longer than 30 hours. That definition is why Bergen–Hamburg exists at all: it is never one train, it is four via Oslo, Göteborg and Malmö. Omit `strekning` for the ranking, which comes in two lists — `strekningar` (the real routes) and `lokale` (hops averaging under 50 km, split out so a 1 km S-Bahn shuttle does not outrank Bergen–Hamburg) — or supply a slug (`bergen--oslo-s`) for one pair in full: every gjennomgang with its via-stations, the direction split, fastest/median/slowest crossing, the gaps between crossings, the fastest turnaround, kilometres per country, records, and which strekningar sit inside it and which it sits inside. STREKNINGAR OVERLAP AND THEIR FIGURES MUST NEVER BE SUMMED ACROSS PAIRS: one Bergen→London trip is simultaneously a Bergen–Oslo, a Bergen–Hamburg and a Hamburg–London gjennomgang, so `del` is each pair's share of the whole archive and the column does not add to 1. `del` exists only for additive quantities (km, hours, legs, night trains); countries and operators recur across pairs and come as `avAlt: [n, m]` counts, never a share. Only pairs crossed three or more times are ranked, but ANY pair he has travelled answers in full — that is what the `delAv` links point at. PLANNED TRIPS ARE SHOWN AND NEVER COUNTED (ADR 0039): every figure above is over legs that have DEPARTED, and what is booked sits apart in `planlagt` on each pair (null when nothing is booked), in `nye` on the payload (pairs booked but never yet ridden, named but never ranked — a booking cannot earn a rank), and in `planlagtIAlt` (the whole plan as LEGS, which is not the sum of the per-pair blocks because pairs overlap). `talPar` counts pairs actually travelled. The status field is deliberately never read — Viaduct rows stay marked \"Planned\" until Markus edits them — so a cancelled trip he has not deleted still shows until its departure passes. A leg counts from its departure, so the totals reconcile with get_train_stats. Rutene eg faktisk reiser."},{"name":"get_train_upcoming","description":"Everything Markus has booked and not yet taken. A trip counts from DEPARTURE everywhere on this site, so planned legs are excluded from every total get_train_stats, get_train_year, get_train_month and get_train_countries report — this tool is where they are, and NOTHING here is counted anywhere else. Returns the legs ahead, the named journeys they belong to (with what is left of each beside the whole journey), the months they fall in, the kilometres per country, and the stations, operators and countries the archive has never seen. `del` is a share of the EVENTUAL total, travelled plus planned, and exists only for additive quantities (kilometres, hours, legs, night trains); `motReist` is the same quantities over what he has actually ridden and may exceed 1. Stations, operators and countries recur, so they come as `avAlt: [new, all]` counts and never as a share. A Viaduct row is a booking, not a fact: the status field is deliberately never read, because rows stay marked \"Planned\" until Markus edits them, so a cancelled trip he has not deleted still appears until its departure time passes. Det som ligg framfor."},{"name":"get_tog","description":"The /tog page as data: the leg under way (with its stop-by-stop calls, realtime times and how far along it is), the next departure, every named multi-leg journey, and the records. Progress is measured from Entur inside Norway and cross-border, and computed from the timetable elsewhere — `predicted: true` says which. Kvar Markus er på skjenene."},{"name":"get_garden","description":"The Tankehav digital garden (markus.plus): sections and recently touched pages."},{"name":"get_togselfies","description":"The #togselfie gallery: every train selfie with its toginfo (alt text), status text, date, optional place, and the rolling stock where known (type, litra, car number, station, line, operator). `train.number` is the number on the END he stood in front of, not the set: a set carries a different number in each cab, so `train.sett` is the derived set and `train.andreEnden` the number painted on the far end — use `sett` to tell whether two selfies are the same train. Both are null for a loco (one number, two cabs) and for foreign stock. `train.aboard` is false when Markus photographed the train rather than rode it. Set located_only for just the ones with coordinates."},{"name":"get_watched","description":"Every film and TV series Markus has watched: title, year, genre, director, the date he watched it and how (cinema/streaming/…), newest first. Filter by year, genre or category. Totals and per-year/genre breakdowns come back on every call."},{"name":"get_film_arkiv","description":"The /film/arkiv aggregations over every film and series Markus has watched, along four axes: genre, calendar month, director and decade of release. Pass `akse` for one of them. THE COVERAGE BLOCK IS PART OF THE ANSWER, NOT GARNISH, and here it is most of it: 69 % of this archive sits in three IMPORTED years (2014-2016), two years are missing outright and two more hold a single title each. (1) `dekning.aar` marks every year in the span — `importert`, `ujamn`, `tom` or `lopande` — with a curated `grunn` where somebody wrote one down. A year marked `importert` is a backfill, NOT a year of watching, and answering \"his biggest year was 2014\" from these numbers is a confident lie. (2) `dekning.utelate` lists the withheld years and `rekordar` was computed without them; the running month is withheld the same way. (3) THE DIRECTOR AXIS HAS NO PODIUM: 604 distinct directors with a top count of four, ten of them tied. Report the tie, never one name. (4) `kino` is this site's own reading of free-text notes, so it is an estimate — get_watched carries the raw note beside it."},{"name":"get_skvip_stats","description":"Engagement summary for @markus@skvip.lol: total favourites, boosts and replies, and the top posts. Aggregert — aldri råstraumen."},{"name":"get_poppis","description":"The popularity ranking: human page views for the open sites and msge.no pages. window is one of today/7d/30d/90d/all or a year key like y2026 (default \"all\")."},{"name":"get_tuben","description":"Markus' YouTube watch archive as the site renders it: archive totals, the per-year index with its three-way Shorts split, the 24-hour profile and the top channels. Pass `year` for one year's row. THE CAVEATS ARE PART OF THE ANSWER, NOT GARNISH. (1) `tid` carries THREE hour figures and never one, because this archive holds NO watch duration at all — it records that a video was opened, and the length is the VIDEO'S length. All three are upper bounds, and they are null rather than 0 when nothing in the bucket had a length at all. `dekningPct` says what share even had one; the rest contribute zero, so the true figure is not merely lower, it is unmeasurable. (2) Every split is three-way — shorts / lang / ukjend. There is no Shorts flag in the data, under three minutes is a heuristic, and a row with no duration is UNKNOWN, never folded into either side. (3) `utanKanal` watches can appear in no channel ranking, so a channel list always sums to less than the total beside it. (4) Years flagged `mistenkeleg` (2012-2014, 2024) are export gaps rather than quiet years: quote them as a property of the export, and never let a superlative answer with one — nor with the current year, which is not finished. (5) The two Google accounts OVERLAP in time; this is not a switchover on a date."}],"documentation":"https://msge.no/llms.txt"}