mcp-translation
Tools at a glance
Section titled “Tools at a glance”| Tool | What it takes | What it returns | Why your brain cares |
|---|---|---|---|
translate_incoming | { text, channel?, thread_context?, target_language? } | explicit ask, ranked subtext hypotheses, ambiguity spans, recommended next action | reads the “happy to discuss further” you’ve been staring at for ten minutes and tells you whether it’s a soft no or a real opening — without you having to mask-rehearse seven interpretations |
check_tone | { text, baseline_messages?, target_register?, channel? } | scores on directness, warmth, urgency; flagged phrases | shows you that your draft reads as 92/100 urgent when your usual baseline is 40 — useful when the social-meter in your head is offline |
rewrite_outgoing | { text, target_register, preserve_terms? } | rewritten text, preserved/unpreserved terms, diff summary | lets you keep the ticket IDs and jargon verbatim while a tool handles the register shift you find exhausting |
brief_meeting | { transcript, me, project?, speakers? } | my asks / others’ asks / decisions / ambiguous items (with verbatim quotes) | turns ninety minutes of transcript into the four lists you actually need; ambiguous items are quoted character-for-character so nothing is invented |
mcp-translation decodes corporate ambiguity. It is the substrate’s communication-layer server: it scores tone, rewrites for register, decodes incoming subtext, and briefs meeting transcripts. The server itself contains no LLM SDK — every tool returns a deterministic baseline plus a structured prompt the caller’s MCP client executes against its configured model.
- Package:
packages/mcp-translation/ - Version:
0.0.2 - Schemas:
packages/mcp-translation/schemas/*.schema.json - ADR: 0005 — Translation tool design
- Schema
$idprefix:https://schemas.neurodock.org/mcp-translation/v0.1.0/
Design framing
Section titled “Design framing”Per ADR 0005 §2, the server imports no anthropic, no openai, no ollama. The substrate is vendor-neutral by construction. Each tool returns an envelope:
{ "deterministic_analysis": { /* v0.1.0 output shape, populated heuristically */ }, "prompt_for_llm_refinement": { "role": "user", "content": "<rendered prompt template>", "output_schema_ref": "packages/mcp-translation/schemas/<tool>.schema.json" }, "eval_corpus_slice": "packages/evals/corpora/translation/<slice>.jsonl"}The caller MAY use the deterministic analysis alone (no LLM required) or feed prompt_for_llm_refinement.content to its configured model and replace the deterministic block with the refined response. This makes the server useful without a connected LLM and vendor-neutral when one is connected.
Tools (detailed contract)
Section titled “Tools (detailed contract)”| Tool | Input | Output |
|---|---|---|
translate_incoming | { text, channel?, thread_context?, target_language? } | { explicit_ask, likely_subtext[], ambiguity, recommended_next_action, model_provenance, eval_corpus_slice } |
check_tone | { text, baseline_messages?, target_register?, channel? } | { axes, axes_target?, baseline_delta, flagged_phrases[], suggested_rewrite_hint, model_provenance, eval_corpus_slice } |
rewrite_outgoing | { text, target_register, preserve_terms?, channel?, preserve_intent? } | { rewritten, preserved_terms[], unpreserved_terms[], diff_summary, model_provenance, eval_corpus_slice } |
brief_meeting | { transcript, me, project?, speakers? } | { my_asks[], others_asks[], decisions[], ambiguous_items[], model_provenance, eval_corpus_slice } |
translate_incoming
Section titled “translate_incoming”Decode subtext, ambiguity, and the likely implicit ask in an incoming corporate message. Returns the explicit ask (or null if there is none), a ranked list of likely subtext hypotheses with confidence scores, ambiguity spans with character offsets, and a recommended next action.
channelis an enum:email | slack | linear | github | notion | gdocs | outlook | generic. Influences register expectations.thread_contextaccepts up to twenty prior messages, oldest first.target_languageis BCP-47 (en,en-IE,de,ja). Used to select a language pack when one is registered.
check_tone
Section titled “check_tone”Score an outgoing message on three axes — directness, warmth, urgency — on a 0..100 scale. 50 is neutral, <30 is notably low, >70 is notably high. When baseline_messages is supplied (at least three), baseline_delta reports how each axis diverges from the sender’s usual register in signed percentage points.
- Does not rewrite. Pair with
rewrite_outgoingto actually shift register. flagged_phrasesuse{start_char, end_char, reason}— the same shape astranslate_incoming.ambiguity.spansandbrief_meeting.*.quoted_spanfor shared rendering.
rewrite_outgoing
Section titled “rewrite_outgoing”Rewrite an outgoing message toward a target_register while preserving caller-named technical terms and the message’s underlying intent.
target_registerenum:direct | warm | formal | concise | clarifying.preserve_termsis a caller-supplied list of exact substrings (jargon, system names, ticket ids) that MUST appear verbatim in the rewrite. The server checks this with exact substring match and reports gaps inunpreserved_terms— but does not auto-retry. A non-emptyunpreserved_termsis a soft signal the caller may surface or chain another rewrite.preserve_intentdefaults totrueand SHOULD be left at the default.
brief_meeting
Section titled “brief_meeting”Convert a transcript into a four-section brief: asks of the recipient, asks the recipient is making of others, concrete decisions, and ambiguous items quoted verbatim from the transcript.
transcriptis 20–200,000 characters (roughly a 90-minute meeting). Longer transcripts MUST be chunked by the caller; the tool returnsTRANSCRIPT_TOO_LONGotherwise.meis required. Without a speaker label that identifies the recipient, the four-section partition is ill-defined; the tool returnsME_REQUIREDrather than guessing.ambiguous_items[].quoted_span.textMUST equalinput.transcript[start_char:end_char]. The server validates this on every response (including its own deterministic output) and raisesVERBATIM_ANCHOR_FAILEDif the model fabricates a span. This is anti-hallucination armour — a fabricated “ambiguous item” not in the transcript is worse than no brief at all.
Error codes
Section titled “Error codes”| Code | Meaning |
|---|---|
VERBATIM_ANCHOR_FAILED | brief_meeting produced an ambiguous item whose quoted_span.text did not match transcript[start_char:end_char]. Caller MUST surface; never silently retry. |
TRANSCRIPT_TOO_LONG | brief_meeting transcript exceeded 200,000 characters. Caller chunks. |
ME_REQUIRED | brief_meeting was called without a me label. |
MODEL_UNAVAILABLE | The caller’s MCP client could not reach its configured LLM during refinement. The deterministic baseline is still returned; this error appears in the envelope only when the caller explicitly required refinement. |
INPUT_TOO_LARGE | An input string exceeded its per-field cap. Caller MUST truncate before retrying. |
Privacy
Section titled “Privacy”- The server stores no inputs. All text is in-memory for the call duration only.
- The server logs structured event names and outcomes, never input text.
- PII redaction is upstream (browser extension or caller). The server analyses whatever it is given.
model_provenanceis required output:{mode, provider, model}. Surfacescloudvslocalhonestly so a calling surface can render an accurate cloud-mode banner.brief_meetingoperates on third-party speech (meeting transcripts). Cloud-mode forbrief_meetingSHOULD prompt the user with a stronger consent surface; that is the calling skill or extension’s responsibility, not the server’s.
Versioning
Section titled “Versioning”- v0.0.2 envelopes wrap the v0.1.0 wire contract. The envelope collapses to the wire contract once Phase 2 LLM-refinement flow is the default path.
- Additive-only within the
v0.1.xline. Channel enum, target-register enum, and error codes are closed at v0.1.0; additions are minor bumps.
Known limitations (v0.0.2)
Section titled “Known limitations (v0.0.2)”- English-only deterministic heuristics. BCP-47
target_languageis accepted but only passed through to the prompt template. - No
model_provenancefrom a real LLM. The deterministic analysis setsmode="unknown"on every response; a connected MCP client populates this in the refined response. - No eval-corpus integration yet. The
eval_corpus_slicepaths are recorded on every response, but the slices themselves are owned byeval-curatorand land in Phase 2. - No streaming. Long meeting transcripts (>200k chars) must be chunked.
What’s next
Section titled “What’s next”- ADR 0005 for the four-tool decomposition rationale and the seventeen binding decisions.
asd-meeting-translator— the reference Phase 2 consumer ofbrief_meeting.- Contribute an eval example — the lowest-friction way to improve the translation corpus.