Swiss German Coach for ChatGPT
Provides an MCP connector for ChatGPT Apps, enabling ChatGPT in text or voice mode to act as a persistent Swiss German speaking coach with session plans, debriefs, corrections, spaced-repetition word reviews, and progress tracking.
This server does not currently have a deployable release on Glama. Follow the repository's setup instructions to install and configure it for your MCP client, including any required credentials and local dependencies.
Swiss German Coach for ChatGPT
A small, self-hosted MCP server that turns ChatGPT (text or voice mode) into a Swiss German (Züritüütsch by default) speaking coach that remembers you between chats.
The problem
ChatGPT is a good conversation partner for a dialect with few learning resources, but every new chat starts from zero. It forgets which words you can already use, repeats the same role-plays, can't tell you whether you're improving, and tends to make up progress ("great, 15 minutes today!"). Keeping a Markdown tracker by hand works for about a week.
Related MCP server: LingoChunk MCP
How it works
ChatGPT does the talking. This server is the coach's memory, exposed as tools in a ChatGPT App (connector):
Tool | What it does |
| Called first. Returns coaching rules, your mission, the last 3 session debriefs and today's plan: focus words, new words to introduce, and words due for light review. |
| Closes a session with an honest report, a full debrief the next chat continues from, max 3 next priorities, and (in one batch) all corrections, word results and new words not yet saved. |
| "Let's move on from these words" or "practise this one": saved for all future sessions. |
| Saves a correction (what you said → correct form, category). |
| Records a word use: |
| Saves genuinely new useful words, deduplicated. |
| Weekly scorecard (first-try answers out of 10, language switches per 10 min, ...). Unmeasured fields stay empty. |
| Read-only summaries. |
Design choices:
Spaced repetition (Leitner boxes). Intervals 1/2/4/7/14/30/60 days. A word only becomes secure after free use on 3 different days; repeating after the coach does not count.
Focus rotation. A small set of focus words (default 4). A word leaves focus once you use it freely or after 3 sessions, then stays in spaced review; the set refills automatically, alternating shaky and new words. Words you moved on from don't come back into focus.
Debrief as memory. Each
finish_sessionwrites what was talked about, what improved, what's shaky, what's done and shouldn't be repeated, and what to do next.start_sessionhands this to the next chat.Honesty rules. The server instructions tell the model never to invent minutes, scores, pronunciation judgements or streaks. The streak on the progress page counts participation, not proficiency.
Phases, milestones, benchmark day from your config, so the plan knows where you are in it.
Progress page: a read-only HTML page (no JavaScript, strict CSP,
noindex) at a separate secret URL.
Everything is one Python module, Python's built-in SQLite, and the official mcp SDK. No external services.
Setup
Requirements: Python 3.11+, a Linux box that's always on (a small VPS, home server or Raspberry Pi), and a way to expose HTTPS (Caddy with a domain, or a Cloudflare Tunnel).
git clone <this repo> ~/swiss-german-coach && cd ~/swiss-german-coach
python3 -m venv .venv
.venv/bin/pip install -r requirements-dev.txt # exact pins; or: pip install --require-hashes -r requirements.lock
cp config.example.toml config.toml # your name, goal, deadline, timezone, phases (gitignored)
cp .env.example .env && chmod 600 .env
python -c 'import secrets;print(secrets.token_urlsafe(32))' # paste as COACH_TOKEN
python -c 'import secrets;print(secrets.token_urlsafe(32))' # run again, paste as COACH_DASH_TOKEN
# set COACH_HOSTS to include your public hostname
.venv/bin/python -m pytest -q # testsOptional demo data (a fictional learner, invented sessions) to look around first:
COACH_DB=data/demo.db .venv/bin/python scripts/seed_demo.pyConfiguration (config.toml)
See config.example.toml. [learner] holds name, goal, deadline, timezone and an optional
mission_file (a longer Markdown plan returned verbatim by start_session; keep it in data/, which is
gitignored). [dialect] sets the dialect names used in the coaching rules, [coach] the focus size, rotation
length, benchmark weekday and "I'm done" words. [[phases]] and [[milestones]] describe your plan.
Authentication
There are no accounts. The MCP endpoint lives at a secret path: https://<host>/mcp/<COACH_TOKEN>. The
progress page uses its own secret, COACH_DASH_TOKEN (https://<host>/progress/<COACH_DASH_TOKEN>), so you can
bookmark it without exposing the connector URL. Both tokens are required and validated independently: the server
refuses to start if either is missing, shorter than 32 characters, not URL-safe, a placeholder, or the same as the
other. .env.example ships them empty on purpose. Generate each with
python -c 'import secrets;print(secrets.token_urlsafe(32))'.
The token in the path is compared with secrets.compare_digest. A wrong token, /mcp itself, and every other path
return 404. The Host header is checked against COACH_HOSTS for every request, including the progress page
(DNS-rebinding protection; unknown hosts get 421), and the server only binds 127.0.0.1.
Limits against abuse: tool arguments have maximum lengths and item counts in their schemas (oversized calls are
rejected before anything is written), request bodies are capped at 512 KiB, there is an in-process rate limit of
COACH_RATE_LIMIT requests per minute per client IP (default 120) plus a cap on concurrent requests, and the
progress page is paginated. Behind Cloudflare Tunnel every request comes from 127.0.0.1, so the rate limit is
effectively global, which is fine for one user.
Treat the connector URL like a password: anyone with it can read and write your learning data. To rotate, change
COACH_TOKEN, restart, and update the connector in ChatGPT. If you ran an earlier version of this template (which
left uvicorn's access log on), rotate both tokens: they may be in your journal. This is deliberately simple single-user auth; if you
need multiple users, put OAuth in front (the mcp SDK supports it).
Run it with systemd
mkdir -p ~/.config/systemd/user
cp deploy/swiss-german-coach.service ~/.config/systemd/user/ # adjust paths if not ~/swiss-german-coach
systemctl --user daemon-reload
systemctl --user enable --now swiss-german-coach
loginctl enable-linger "$USER" # keep running after logout
journalctl --user -u swiss-german-coach -fExpose it over HTTPS
Option A: Caddy (you have a domain pointing at the server, ports 80/443 open). Use
deploy/Caddyfile.example; Caddy fetches certificates automatically. Its access
log is discarded so the secret path doesn't end up in log files.
Option B: Cloudflare Tunnel (no open ports, works behind NAT). Use
deploy/cloudflared.example.yml and
deploy/cloudflared.service:
cloudflared tunnel login
cloudflared tunnel create swiss-german-coach
cloudflared tunnel route dns swiss-german-coach coach.example.com
systemctl --user enable --now cloudflaredCheck it end to end (read-only):
.venv/bin/python scripts/smoke.py "https://coach.example.com/mcp/$COACH_TOKEN"Connecting in ChatGPT Apps
In ChatGPT, open Settings → Apps (formerly Connectors) and enable Developer mode under Advanced. Availability depends on your plan and workspace settings.
Create app: name it e.g. Züritüütsch Coach, paste
https://<host>/mcp/<COACH_TOKEN>as the MCP server URL, choose No authentication (the secret path is the auth), and confirm.In a new chat, add the app and say something like "Let's practise Swiss German". The model calls
start_session, then opens with a question in dialect. Say "fertig" when done so it callsfinish_session.Voice mode: start in a chat that has the app enabled. Tool calls may happen less often in voice, which is why
finish_sessionaccepts everything in one batch.
After changing tool definitions, refresh the app in ChatGPT's settings so it picks up the new schema.
Privacy
All data stays in one SQLite file on your server (
data/coach.dbby default). Nothing is sent anywhere except what ChatGPT itself receives through the tool calls, under OpenAI's terms for your account.config.toml,.env,data/and*.dbare gitignored. Don't commit them, and don't put real data in issues.The progress page is read-only, unindexed, uncached, no-referrer, and runs no scripts.
The server runs uvicorn with its access log disabled (
access_log=False), so request lines containing the secret path are never logged. As a backstop, a logging filter replaces anything that looks like/mcp/<token>or/progress/<token>, and the configured tokens themselves, with<redacted>in every log record. Startup and error messages still go to journald. Keep your reverse proxy from logging the path too (the Caddy example discards its access log; Cloudflare does not log request paths to your machine).Delete everything by deleting the database file.
Development
.venv/bin/python -m pytest -qTests run against a temporary database with the example config and a fixed fake date. They cover config loading,
spaced repetition, focus rotation, the batch finish_session, benchmarks, streaks, the HTTP transport, token
validation (missing, short, placeholder, non-URL-safe), secret-path auth (wrong token is 404), Host checks on every
path, input-size limits, the rate limit, pagination, disabled access log, log redaction and HTML escaping.
Dependencies: requirements.txt pins the direct dependencies exactly; requirements.lock is a pip freeze of the
tested environment with sha256 hashes (pip install --require-hashes -r requirements.lock for a reproducible
deployment). Check them with pip install pip-audit && pip-audit -r requirements.lock.
License
MIT © Luka van Maren
This server cannot be deployed
Maintenance
Related MCP Connectors
Free: turn your AI chats into spaced-repetition vocabulary. 13 tools, reads and writes.
Language coaching in Codex with durable per-account memory on en-ai.ru.
Language learning memory: due flashcard reviews, past mistakes and level, shared with any AI tutor.
Save vocabulary from any AI chat; see each word in every language you know; review it with FSRS.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceServes daily language lessons from a structured curriculum, enabling natural practice through conversation with AI tutors that track progress.5 npm1Apache 2.0
- AlicenseAqualityDmaintenanceTurns a coding agent into a language tutor grounded in your LingoChunk listening history, providing tools to access vocabulary, transcripts, audio clips, and create lessons.118 npmMIT
- AlicenseNot gradedqualityBmaintenanceConnects AI assistants like Claude to MindDory to automatically capture new vocabulary and grammar mistakes into spaced-repetition flashcards during language practice conversations.MIT
- AlicenseNot gradedqualityBmaintenanceEnables an AI assistant to act as the memory of a personal English-learning app: read progress and words due for review, run short practice conversations, and store sentences, corrections, new words, rubric scores, and checked exercises back to the user's dashboard. Also lets the assistant grow the flashcard deck and adjust word familiarity, which reschedules spaced-repetition reviews.MIT