trek-mcp-ops
Skill1 starsChanged 14 days agoMITView on GitHub
Run and operate the self-hosted TREK travel planner (Docker + built-in MCP server, 135 tools) on this machine. Use this whenever a travel-planning task needs a real itinerary stored in TREK: starting Docker and the auth-proxy, creating or editing trips, days, places, timelines, budgets, packing lists and reservations, and shutting everything down afterwards to free RAM and CPU. Also covers the TREK field-naming traps where a mistyped key is silently ignored.
In this repository30 other files it gives its agents.
- AGENTS.mdAGENTS.md
- notion-im-helper/CLAUDE.mdCLAUDE.md
- 3d-printing-cad-designSkill
- agent-skills-syncSkill
- captain-resourceSkill
- csdn-publish-mcpSkill
- deep-research-report-pipelineSkill
- doc-plain-zhSkill
- feishu-bot-configSkill
- first-shotSkill
- investment-analysisSkill
- layoutfixSkill
- md2docx-formalSkill
- md-to-70asunflower-latexSkill
- multi-publish-mcpSkill
- notebook-patchingSkill
- notion-im-helperSkill
- paper-figuresSkill
- paper-reviewSkill
- paper-writingSkill
- project-initSkill
- project-reviewSkill
- siyuan-backup-syncSkill
- siyuan-kernel-opsSkill
- siyuan-markdown-formula-formatterSkill
- snapSkill
- strict-docx-auditSkill
- visual-diagramsSkill
- weekreportSkill
- xhs-pipelineSkill
The file
We split this skill into the rules it gives an agent
7 rules. About 0 are common, 1 is distinctive, and 6 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈1
Distinctive · estimate
This author's own choices. Worth a look.
6
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 15
Run every command from that folder.
- Very specific: line 56
If something is wrong, trek.cmd doctor prints every resolved path plus a concrete fix for each problem.
- Very specific: line 72
Always pass arguments through an
@file.json: Write the JSON to a file first, then reference it with @. - Very specific: line 107
Never invent a
dayId: Read the real ids from the create_trip response or get_trip_summary. - Very specific: line 123
create_packing_itemhas no dedupe: Never blind-recreate a list. - Distinctive: line 143
When TREK is flaky, geocode without it by calling Nominatim directly — this has no dependency on the container being alive:
- Very specific: line 215
Prefer a small temp .mjs file over a complex inline node -e "...".
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
TREK MCP Operations
TREK is a self-hosted travel planner running in Docker on this machine. It exposes an MCP server with 135 tools (trips, days, places, itinerary timing, budgets, packing, reservations, transit, maps). This skill is the complete runbook: start it, drive it, shut it down.
Skill folder: 本技能目录(各 runtime 的 skills/trek-mcp-ops/,junction 到仓库 70asunflower-skills/trek-mcp-ops/)
Run every command from that folder. The two .cmd launchers find Node themselves, so
you never need a Node path and node does not have to be on PATH.
Quick start (3 commands)
cd <本技能目录>
trek.cmd start # brings up Docker + TREK + proxy, then self-tests
trek-call.cmd --list trip # see what you can do
trek.cmd stop # when finished — frees all resourcestrek.cmd start is idempotent and safe to re-run. When it finishes it prints
OK — 135 MCP tools reachable (to the log) only when the whole chain really works,
so if it succeeds you can trust the system is up.
No black window.
trek.cmd startruns hidden by default — the 26 s–2 min actual work (Docker boot, compose, proxy, self-test) runs windowless. Only a brief console window flashes to print "started in background, check the log", then closes. Progress is written totrek-start.log/trek-start.errnext totrek.cmd. Check readiness any time withtrek.cmd status. If you want the live progress window, usetrek.cmd start --show.
1. START
trek.cmd doctor # optional: verify every path/dependency, changes nothing
trek.cmd status # is it already running?
trek.cmd start # hidden, no window — then poll trek.cmd status
trek.cmd start --show # same, but in a visible window (live progress)start performs: launch Docker Desktop headlessly if the daemon is down (waits up to
4 min on a cold boot) → docker compose up -d → wait for /api/health → start the
auth-proxy supervisor (detached, survives a WorkBuddy restart) → run a real MCP
handshake as a self-test. Any failure stops with an actionable message.
If something is wrong, trek.cmd doctor prints every resolved path plus a concrete fix
for each problem. Start there before debugging anything by hand.
2. USE
Calling tools
trek-call.cmd --list # all 135 tools
trek-call.cmd --list budget # filter by keyword
trek-call.cmd --schema create_and_assign_place # exact accepted arguments
trek-call.cmd create_trip @args.json # call a toolAlways pass arguments through an @file.json. Write the JSON to a file first, then
reference it with @. Inline JSON gets mangled by cmd.exe quoting and is unusable for
Chinese text or long descriptions.
:: args.json
{ "title": "上海周末一日游", "currency": "CNY", "description": "..." }
trek-call.cmd create_trip @C:\Users\qilin\AppData\Local\Temp\args.jsonThis bridge talks to the local proxy directly, so it works in any conversation with no
WorkBuddy restart. Native mcp__trek__* functions only appear if the proxy was
already listening when WorkBuddy started — do not count on them; trek-call.cmd always works.
The one trap that matters
TREK silently ignores unknown argument keys and still returns success. A typo like
durationMinutes (correct: duration_minutes) looks like it worked while nothing changed.
trek-call.cmd guards against this: it validates your arguments against the tool's own
schema and aborts with a "did you mean" hint before sending anything. Do not use --force
to get around it — fix the key name instead.
Naming is genuinely inconsistent, so check --schema rather than guessing:
- IDs are camelCase:
tripId,dayId,placeId,assignmentId,itemId - Data fields are snake_case:
start_date,end_date,duration_minutes,place_time,end_time,total_price,category_id
Tool quirks worth knowing
- Pass
start_date+end_datetocreate_trip. TREK then auto-generates exactly the right number of days, already dated (a 20–22 Nov trip yields 3 days dated 20/21/22). Omit the dates and you get 7 undated placeholder days instead — andupdate_daycannot add a date afterwards, so you would have to delete and rebuild. Getting this right in the first call saves the whole mess. - Never invent a
dayId. Read the real ids from thecreate_tripresponse orget_trip_summary; a guessed id is what producesDay not found. create_dayonly matters when you need to append an extra day later (it does acceptdateandnotes).update_dayaccepts onlytitle. Day notes go throughcreate_day_note/update_day_note.update_assignment_time {tripId, assignmentId, place_time, end_time}builds the timeline. GetassignmentIdfrom thecreate_and_assign_placeresponse.create_budget_itemneedstripId,name,total_price. Omitmember_idsto split across everyone. There is noget_budget— read the budget fromget_trip_summary.- Verify writes by reading back with
get_trip_summary {tripId}— one call returns metadata, days, assignments, notes and budget. - Coordinates live on the
placeobject, not theassignment.get_trip_summarydoes not echolat/lngonto assignments, so verify geocoding at the place level or you will get a false "0 places have coordinates". - No map pins or route = places have no
lat/lng. TREK draws the map purely from place coordinates. Always geocode after creating places, or the map stays blank. create_packing_itemhas no dedupe. Never blind-recreate a list;get_trip_summaryfirst. If you do end up with duplicates, remove them withdelete_packing_item {tripId, itemId}.d.packingis an object{items, total, checked}— not an array. Same ford.budget({items, ...}). Reading.lengthoff them silently yieldsundefined.update_reservationrequires onlytripId+reservationId;statusispending|confirmed|cancelled. Hotel reservations additionally needplace_id+start_day_id+end_day_idall three at creation time.
Geocoding places (do this or the map is empty)
search_place works (OpenStreetMap, no Google key) but is fuzzy — "Akihabara Tokyo"
once returned Honolulu. Two rules:
- Query in Japanese/local script with the prefecture, e.g.
城ヶ崎海岸 伊東市, not the romanised name. Then sanity-check the returned lat/lng is in the right country. - Query the building or POI name, not the street number. Japanese banchi
addresses like
外神田1-18-18return nothing; the building name (Bito Akiba Plaza) hits exactly. Hotels usually resolve from their full name (亀の井ホテル伊豆高原→ hotel POI).
When TREK is flaky, geocode without it by calling Nominatim directly — this has no dependency on the container being alive:
curl -s -A "your-app/1.0" --get "https://nominatim.openstreetmap.org/search" \
--data-urlencode "q=亀の井ホテル伊豆高原" --data-urlencode "format=json" --data-urlencode "limit=2"Then write the result back with update_place {tripId, placeId, lat, lng, address}.
Cross-check plausibility: two places that should be a 10-minute walk apart must land
~300–800 m apart.
Recommended build order
create_tripwithstart_date,end_date,currency,descriptionget_trip_summary→ collect the generateddayIdscreate_and_assign_placeper place (tripId+ the realdayId) → note eachplaceIdandassignmentIdupdate_place→duration_minutes,lat/lng,address,descriptionupdate_assignment_time→place_time/end_timefor the timelinecreate_budget_itemper costget_trip_summaryagain to verify, then show the user http://localhost:3000
A fully worked example and the 135 tools grouped by domain are in
references/toolmap.md. Read it when you need a tool you have not used before.
The web UI is at http://localhost:3000 — offer it to the user to view the result on a map.
3. CLOSE — always do this
trek.cmd stopStops the proxy supervisor → docker compose down (trip data is preserved on bind
mounts) → quits Docker Desktop and its backend helpers, then verifies and prints the
final state.
Docker Desktop keeps a WSL2 VM warm and eats RAM/CPU even when idle, so run stop as
soon as travel planning is finished. Skip the Docker quit only if the user has other
containers or WSL distros running — in that case run docker compose down alone.
Troubleshooting
| Symptom | Fix |
| Anything unexpected | trek.cmd doctor — resolves and reports every path, dependency and runtime state |
Cannot reach the TREK MCP proxy | TREK is down: trek.cmd start |
Day not found | Create the day first with create_day |
| Tool call "succeeds" but nothing changed | Wrong key name — trek-call.cmd --schema <tool> and re-check camelCase vs snake_case |
Argument check failed | Intended. Read the "did you mean" line and fix the key |
mcp__trek__* functions missing | Normal. Use trek-call.cmd; it needs no restart |
| Docker will not start | Open Docker Desktop manually once, then trek.cmd start |
| Proxy keeps dying | Read proxy.log in the proxy folder shown by trek.cmd doctor |
| A node black console window keeps reappearing after you close it | That is the auth-proxy's console. The supervisor self-heals and respawns it 2s after any exit, so closing the window just loops. Never close it by hand — run trek.cmd stop to shut the whole stack down cleanly. (The proxy is launched windowless via windowsHide; if a window ever shows, re-run trek.cmd stop then trek.cmd start.) |
Tool calls hang forever, write 0-byte output files and print nothing to stderr; curl http://127.0.0.1:3001/mcp never returns | Stale upstream MCP session — the proxy is alive but wedged. Killing the proxy child alone does not help (the supervisor respawns the same bad session). Only a full trek.cmd stop then trek.cmd start rebuilds it. |
trek.cmd stop prints cannot stop container: ... did not receive an exit event | Harmless as long as the next line shows Docker Desktop quit. Continue to start. |
trek.cmd start produces no output for minutes | The script can block on its final verification long after the stack is actually up. Do not wait on it — check independently with docker ps (container trek should be healthy) and netstat -ano | grep -E ":(3000|3001)". If both are good, just start calling tools. |
Shell environment gotchas (Windows / Git Bash)
sleepdoes not exist (sleep: command not found). Do not put rate-limit sleeps in loops — either drop them or space calls out across separate commands.rmneeds absolute paths. The safe-delete wrapper rejects relative ones (relative path rejected (must be absolute)), sorm -f _tmp.jsonsilently fails. Userm -f "C:/full/path/_tmp.json".- Shell functions run in the default cwd, not the directory you
cd'd into earlier in the pipeline — temp files land in the workspace root. Write scratch files with explicit absolute paths, and clean them up the same way. - Prefer a small temp
.mjsfile over a complex inlinenode -e "..."; nested quotes innode -eare a reliable source ofSyntaxError: Unexpected token ')'.
Setup / portability notes
Paths are resolved at runtime — no Node version, Docker path or deploy folder is
hardcoded. Override any of them with TREK_DEPLOY_DIR, TREK_PROXY_CONFIG,
TREK_DOCKER_CLI, TREK_DOCKER_DESKTOP, or with
C:\Users\qilin\.workbuddy\trek-mcp-ops.json.
OAuth credentials live outside this skill in proxy-config.json (inside the TREK
deploy folder) and are deliberately never bundled here. On a fresh machine copy
scripts/proxy/proxy-config.example.json to ~/.workbuddy/trek-proxy-config.json and
fill in a Machine client id/secret from TREK → Settings → Integrations.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

