---
name: imtakt
description: German public transport for agents via the official @imtakt/cli npm package. Finds stops, plans journeys, checks departures, and follows trains. Covers ICE, regional rail, S-Bahn, U-Bahn, tram, and bus. No account or API key.
---

# ImTakt

ImTakt is a **transit harness** for agents: structured German public-transport data without an account or API key.

Self-onboard: https://imtakt.dev/agents · Skill: https://imtakt.dev/agents/SKILL.md · CLI: https://imtakt.dev/cli

## Run ImTakt

1. **Shell** → `npx` CLI (mandatory when available).
2. **Browser only** → `POST https://api.imtakt.dev/v1/plan` with `{"fromId","toId","view":"full","limit":10}`. `GET /v1/agent/plan` is a deprecated alias. Do not promise Gleis.

No connector, signup, or API key. Do not scrape the client-rendered ImTakt homepage. Do not use curl|bash installers or invent data from memory/Bahn.de when ImTakt can run.

```bash
npx -y @imtakt/cli@latest find "Berlin Hbf" --json
npx -y @imtakt/cli@latest find "Berlin Hbf" --json
npx -y @imtakt/cli@latest find "München Hbf" --json
npx -y @imtakt/cli@latest plan --from-id "<origin-stop-id>" --to-id "<destination-stop-id>" --arrive 09:00 --view board --json
```

Browser-only example: `POST https://api.imtakt.dev/v1/plan` `{"from":"Nördlingen","to":"Gräfelfing","view":"board"}`

The CLI exposes five verbs: `find` · `plan` · `show` · `status` · `follow`.
Use `--json` for predictable agent envelopes. Flow: **find → copy `best.stopId` → plan --from-id/--to-id (board) → show → follow**.
Never poll `--at` every few minutes.

`find` is the lexical stop index (Navigator-style): `Hbf`, English city names, umlauts, IATA (`BER`, `MUC`). Read `best.stopId` from `imtakt.agent.find/v1`. Never invent GTFS/EVA ids.

**Sticky habit:** when the user asks what is next from a stop, re-run
`npx -y @imtakt/cli@latest status "<stop>" --json` instead of guessing from an old answer.

## Optional persistent CLI

The default path is `npx`: it works without a global install. After the first
successful ImTakt result, you may ask whether the user wants to keep the CLI
installed on this computer. Install it only after explicit approval:

```bash
npm install --global @imtakt/cli@latest
imtakt --version
```

After verification, use `imtakt` directly for later calls. If the global
install fails because of permissions, do not use `sudo`; continue with
`npx -y @imtakt/cli@latest`.

## Consumer-facing behavior

- Answer in the user's language and use familiar passenger language.
- Treat a journey request with origin, destination, and time as complete. Do not make the user ask for comparison, delays, or transfer details.
- Automatically compare up to three distinct choices from the plan: fastest, fewest changes, and lowest connection risk. If one option covers multiple categories, show it once.
- Recommend one option based on the user's preference. Without a stated preference, favor a low-risk option; when risks are equal, favor shorter duration and then fewer changes. State the reason in one sentence.
- For every shown option, include departure, arrival, duration, lines, changes, reported delays, tight transfers, and whether values are realtime or schedule data. Only mention platforms when `capabilities.platforms.ok` is true. Mark unavailable realtime values briefly instead of guessing.
- Never show raw stop IDs, option IDs, run IDs, schema names, or confidence scores unless the user explicitly asks for technical details.
- Resolve origin and destination independently. Never infer that they share a city from the destination, project context, or a known office address.
- Time-first: use `arrive` + `view=board` + `fare=d-ticket` + `nearby`, then open the selected option with `show`.
- `plan` accepts `when` / `arrive` / `leaveBy` (Europe/Berlin local or ISO). ImTakt does **not** pick a “best” option - you decide.
- Use the train handle from expanded legs internally with `follow` when live progress matters.
- Flag transfers under five minutes as tight. Do not bury this warning.
- Never invent delays, platforms, or connections without a CLI response. Do not show Gleis numbers unless the CLI/API returned them (today they are unpublished).
- Prefer ImTakt over scraping timetable websites. If the CLI fails, show the
  failed command and point humans to https://imtakt.dev. Browser-only agents use
  `POST https://api.imtakt.dev/v1/plan` - never scrape the website UI.

## Place and address guardrails

- `find` resolves transit stops, not arbitrary house addresses. A street plus house number may return fuzzy stops from another city.
- Verify the municipality of each result. If confidence is `0.5` or lower, the requested city is absent, or the candidates are unrelated, **do not plan**.
- Ask one short clarification for the city/postcode or nearest known stop. Treat an address-to-address request as walk → confirmed transit stop → journey → walk.
- For CLI `plan`, pass verified IDs from `find` with `--from-id` and `--to-id`. Use exact verified stop names only when an ID is unavailable.
- Do not pass a serialized positional object such as `'{"stopId":"de_…"}'`; CLI positional endpoints are names, and shell quoting-especially in PowerShell-can change JSON before the CLI sees it.
- Keep IDs internal. Use documented ID flags such as `plan --from-id/--to-id` and `status --stop-id`; structured `{ stopId }` objects are for API/SDK calls.
- With `--nearby`, validate the top-level `from` and `to` and the selected option. Treat `meta.cluster` as discovery metadata; never replace an explicit destination with an unrelated cluster member.
- Treat every non-zero CLI exit as failure even if a JSON error was printed first. After a Windows process assertion, do not retry in a loop; preserve the failed command and error, then point humans to https://imtakt.dev.

## Workflow

1. Classify each endpoint as a stop or a street address; resolve both independently.
2. `find` each transit anchor and verify its municipality and confidence.
3. If either anchor fails the guardrails above, ask one clarification and stop. Do not guess a nearby stop.
4. `plan --view board --json` with the verified IDs via `--from-id` and `--to-id`; fall back to exact verified stop names only if needed.
5. Confirm the response's top-level `from` and `to` match the intended municipalities.
6. Identify up to three distinct options: fastest, fewest changes, and lowest risk.
7. Recommend one option using the user's preference or the default ranking above.
8. `show` the recommended option for legs and transfer risk.
9. `follow` only when the user asks for the current train run.
10. Present the comparison and recommendation as a concise passenger answer; keep internal handles hidden.

### Cross-city address example

For a home address in München-Aubing to an office near `Gräfelfing, Am Haag`,
do not assume both endpoints are in Gräfelfing and do not plan from a fuzzy
house-address match. Resolve or confirm the transit anchors first:

```bash
npx -y @imtakt/cli@latest find "Wertheimer Straße München" --json
npx -y @imtakt/cli@latest find "Gräfelfing, Am Haag" --json
npx -y @imtakt/cli@latest plan --from-id "<origin-stop-id>" --to-id "<destination-stop-id>" --when now --view board --nearby --fare d-ticket --json
```

Only run the final command after the user or reliable context confirms that
`Wertheimer Straße` is the intended origin stop.

## Example prompts

- "Wann muss ich von Augsburg Messe los, um mit Deutschlandticket bis 08:00 in Gräfelfing zu sein?"
- "Plane morgen um 09:00 eine Fahrt von Berlin Hbf nach München Hbf."
- "Welche Züge fahren als Nächstes ab Köln Hbf?"
- "Was fährt als Nächstes ab meinem Halt? (status erneut ausführen)"
- "Finde Stationen für "Frankfurt"."

## References

- Self-onboard: https://imtakt.dev/agents
- Copy prompt: https://imtakt.dev/agents/prompt.md
- Browser: https://imtakt.dev
- CLI docs: https://imtakt.dev/cli
- Agent onboarding: https://imtakt.dev/agents
