Inspiration
Many households share a kitchen but not a language. A grandson texts in English; his grandmother reads Korean. Machine translation usually keeps the meaning, but Korean also encodes the relationship in every sentence ending. A message that is fine between friends can read as curt from a grandchild to a grandparent. Nunchi (눈치) is the Korean word for reading the room. We wanted an assistant that reads the relationship before it speaks.
What it does
- Relays messages between family members in each person's language. Minjun speaks English; Halmeoni (grandmother) speaks Korean.
- Checks Korean before it is sent. The server knows who is speaking to whom and which register that pair requires. A deterministic register gate, separate from the LLM, refuses selected high-risk violations: plain (반말) sentence endings, a plain clause inside a polite sentence, and plain or confrontational "you" (너, 너희, 당신) toward an elder.
send_messageenforces the same gate, so a refused draft cannot be delivered even if the model tries. - Warns without blocking when Korean is polite but stiff or archaic for family, and suggests a natural replacement (e.g.
연락드리겠습니다→연락드릴게요). - Turns replies into plans, grounded in the original words. From "그럼 토요일에 와. 갈비찜 해놓을게. 김치통 꼭 가져오고." the agent proposes a Saturday visit and a "bring the kimchi container" task. Every item must quote its evidence verbatim from the Korean original, or the server rejects it.
- Keeps people in control.
propose_planschedules nothing. Only the person the message was for can confirm, and only then doescommit_plansave to shared household state. The host also blocks any agent attempt to callcommit_plan. - Follows the family's norm, not a textbook. Some close families speak casually to grandparents. A person can allow casual speech for a pair. The setting is deliberately not an MCP tool, so the agent cannot relax the gate it is checked by. Plain "you" toward an elder stays refused either way.
How we built it
- MCP server: Python MCP SDK (FastMCP), Streamable HTTP, protocol 2025-11-25. Seven tools:
get_household,check_register,send_message,get_inbox,propose_plan,commit_plan,get_board. In-memory state, no database. - Register gate: dependency-free Korean linter with per-sentence results and English explanations, so reviewers who do not read Korean can follow each decision.
- Simulated Alexa+ household: a two-screen web app (grandson / grandmother) plus a live log of every MCP call. A host agent loop lets the LLM choose tools over real MCP. Live mode uses the Gemini API free tier; browser speech APIs provide optional voice input and output.
- Recorded replay: live runs are captured and converted into a replay that preserves the model's actual tool choices and wording, while every MCP call, register check and state change executes again. A converter rejects incomplete or unconfirmed runs; if a real tool result differs from the recording, the replay stops.
- Tests: 57 automated tests (unit, MCP-over-HTTP integration, end-to-end scenario, replay integrity).
Challenges we ran into
- The model quoted the wrong language. In the first live run, Gemini used the English translation as plan evidence. The server rejected it five times. We fixed the instructions, not the check. We also removed the demo's own answer strings from the prompt, then re-ran twice (the demo and a new "library / borrowed books" reply). Both quoted the Korean original on the first try.
- Honest demos. The LLM's generic translation is sometimes plain and sometimes polite. We did not re-run until we got a dramatic result. The video uses one recorded run in which the generic translation happened to be plain, and labels it as such.
- Not overclaiming the linter. Korean politeness depends on context. We scoped the gate to selected high-risk patterns and measured it against native-speaker labels (below) instead of claiming general accuracy.
- No public Alexa+ add-on tooling. We built a standard MCP server and a simulated web experience, which the rules allow.
Accomplishments that we're proud of
- A safety gate the model cannot talk its way past: refusal is enforced by the server, not requested in a prompt.
- Plans that must cite the speaker's exact words before a person confirms them.
- Native-speaker review. A native Korean speaker labeled the evaluation set and wrote 30 sentences before seeing the linter. The gate passed all 20 natural polite messages and refused all 10 casual ones (under the default policy). That is a small sample, so we report it as counts, not an accuracy rate.
What we learned
Deterministic checks and LLMs work well together when each does what it is good at. The model translates and plans; the server holds the rules that must not bend. Clear, machine-readable rejection messages let the model correct itself.
What's next for Nunchi Bridge
- Register policies for other languages with formal/informal forms (Japanese keigo, Spanish tú/usted, Hindi aap/tum).
- Voice confirmation via MCP elicitation, once Alexa+ documents how add-ons confirm state-changing actions.
- Per-family calibration of warnings, and a larger native-speaker evaluation.
Demo video: https://youtu.be/MXJBo56_VDk · Code: https://github.com/zadong12/nunchi-bridge
Log in or sign up for Devpost to join the conversation.