Loading...
0%
Loading application...
Documentation

MCP tool reference — input schemas and JSON output | yomeru.ai

Input contracts and output shapes for grammar_lab, grammar_lab_fast, word_lab, and example_sentences — plus error codes and rate limits.

Every MCP tool advertises a strict JSON Schema in tools/list. The server re-validates every call. Below: input contracts, output JSON, and error envelopes.

grammar_lab

Full LLM-backed Japanese sentence analysis.

Input

{
  "sentence": "string (2–200 chars, must contain Japanese)",
  "context":  "string (optional, max 500 chars)"
}

Output (success)

{
  "tool":               "grammar_lab",
  "sentence":           "今日は学校に行きました。",
  "normalizedSentence": "今日は学校に行きました。",
  "grammarAnalysis":    "<markdown breakdown produced by the generator>",
  "vocab": [
    { "word": "今日", "reading": "きょう",   "gloss": "today",            "jlpt": "N5", "source": "jmdict" },
    { "word": "学校", "reading": "がっこう", "gloss": "school",           "jlpt": "N5", "source": "jmdict" },
    { "word": "行きました", "reading": "いきました", "gloss": "went (polite past)", "jlpt": "N5", "source": "jmdict" }
  ],
  "modelUsed":   "<provider/model id>",
  "cached":      false,
  "status":      "pending",
  "slug":        "kyou-wa-gakkou-ni-ikimashita",
  "url":         "https://yomeru.ai/grammar-lab-fast/kyou-wa-gakkou-ni-ikimashita",
  "generatedAt": "2026-05-02T13:00:00Z"
}

Notes

  • cached: true + status: "approved" when the sentence has been reviewed and promoted to canonical.
  • cached: false + status: "pending" for fresh generations from MCP.

grammar_lab_fast

Same Grammar Lab analysis run on smaller AI models for speed — sub-second response, slightly less depth than the full grammar_lab pass. Same response shape on hit.

Input

{ "sentence": "string (2–200 chars, must contain Japanese)" }

Output (cache miss)

{
  "tool":          "grammar_lab_fast",
  "sentence":      "...",
  "status":        "queued",
  "queryHash":     "<hex>",
  "retryAfterSec": 5,
  "message":       "Generation queued. Re-call this tool with the same sentence in ~5 seconds."
}

word_lab

JMDict lookup with AI fallback for words outside the dictionary.

Input

{
  "word":     "string (1–50, must contain Japanese)",
  "reading":  "string (kana-only, max 50, optional)",
  "baseForm": "string (1–50, optional, must contain Japanese)",
  "context":  { "sentence": "string (max 200, mixed JA/non-JA accepted)" }
}

Output (hit)

{
  "tool":        "word_lab",
  "query":       "食べる",
  "slug":        "%E9%A3%9F%E3%81%B9%E3%82%8B",
  "url":         "https://yomeru.ai/word-lab?q=%E9%A3%9F%E3%81%B9%E3%82%8B",
  "primaryWord": "食べる",
  "entries": [
    {
      "word":                 "食べる",
      "reading":              "たべる",
      "alternateReadings":    [],
      "partOfSpeech":         ["v1", "vt"],
      "partOfSpeechDisplay":  "Ichidan verb · transitive verb",
      "meanings":             ["to eat", "to live on (e.g., a salary)", "to subsist on"],
      "jlpt":                 "N5",
      "common":               true,
      "frequencyRank":        266,
      "frequencyTier":        "TOP300",
      "tags":                 [],
      "source":               "jmdict",
      "status":               "approved",
      "entryId":              1546880,
      "details": {
        "kanji":      [ /* one entry per kanji in the word, with stroke order */ ],
        "examples":   [
          { "japanese": "毎日朝ごはんを食べる。", "english": "I eat breakfast every day.", "source": "tatoeba", "status": "approved" }
        ],
        "compounds":  [ /* compound words containing this term */ ],
        "inflections": {
          /* Discriminated by `kind`: "verb" | "i-adjective" | "na-adjective".
             Verb example shown; adjective shapes share `stem` + `conjugations[]`
             but use `irregular` (i-adj) instead of `verbType`. */
          "kind":     "verb",
          "verbType": "v1",
          "stem":     "食べ",
          "conjugations": [
            { "japanese": "食べて",   "english": "Te form",                  "category": "base" },
            { "japanese": "食べた",   "english": "Ta form (Past)",           "category": "base" },
            { "japanese": "食べます", "english": "I do X (Formal Present)",  "category": "formal" }
            /* …~20–35 rows depending on POS. For non-inflectable entries
               (nouns, adverbs, particles) `inflections` is omitted. */
          ]
        }
      }
    }
    /* additional entries (homonyms / alternate orthographies) follow with basic card data — `details` is present only on the primary entry above. */
  ],
  "totalCount": 1,
  "generating": false
}

Output (AI fallback queued)

{
  "tool":          "word_lab",
  "query":         "<word>",
  "generating":    true,
  "queryHash":     "<hex>",
  "retryAfterSec": 5
}

When the AI-generated entry resolves on a re-poll, the entry in entries[] carries source: "ai_generated", status: "pending", and an aiMeta block with model, promptVersion, and generatedAt.

example_sentences

1–5 example sentences per word: up to 4 from canonical sources + 1 freshly LLM-generated to round out short sets.

Input

{
  "word":  "string (1–50, must contain Japanese)",
  "limit": "integer 1–5 (optional, default 5)"
}

Output

{
  "tool": "example_sentences",
  "word": "食べる",
  "examples": [
    { "n": 1, "japanese": "毎日朝ごはんを食べる。",    "english": "I eat breakfast every day.", "source": "tatoeba",      "status": "approved" },
    { "n": 2, "japanese": "りんごを食べたい。",         "english": "I want to eat an apple.",     "source": "jmdict",       "status": "approved" },
    { "n": 3, "japanese": "彼はラーメンを食べている。", "english": "He is eating ramen.",         "source": "tatoeba",      "status": "approved" },
    { "n": 4, "japanese": "もう食べましたか。",         "english": "Have you already eaten?",      "source": "tatoeba",      "status": "approved" },
    { "n": 5, "japanese": "<AI-generated>",             "english": "<AI-generated translation>",  "source": "ai_generated", "status": "pending",
      "aiMeta": { "model": "<id>", "promptVersion": "v1", "generatedAt": "2026-05-02T13:00:00Z" }
    }
  ],
  "aiPadded":           true,
  "totalCount":         5,
  "circuitBreakerOpen": false
}

Behavior matrix

stored examplesrequested limitresponse
≥45 (default)4 stored + 1 AI = 5; aiPadded: true
5+55 stored only; aiPadded: false
0–35n stored + 1 AI = n+1
any< 5 (≤ stored)DB results capped at limit; AI padding skipped
051 AI only; totalCount: 1
anyLLM circuit openstored only, circuitBreakerOpen: true, no AI

Error envelope (every tool)

Tool-level errors come back as a spec-compliant CallToolResult with isError: true:

{
  "content": [{ "type": "text", "text": "Invalid input: 'sentence' must contain Japanese characters." }],
  "structuredContent": {
    "error": {
      "code":          "INVALID_INPUT",
      "field":         "sentence",
      "reason":        "must contain Japanese characters",
      "retryAfterSec": null,
      "limits": { "minLength": 2, "maxLength": 200, "scriptRequired": "ja" }
    }
  },
  "isError": true
}

Error codes

codewhen
INVALID_INPUTSchema or Japanese-gate validation failed
RATE_LIMITEDPer-IP, /64, or ASN cap exceeded
SYSTEM_BUSYLLM cost circuit breaker open
BUDGET_EXHAUSTEDDaily or monthly token / dollar cap hit
UPSTREAM_FAILURELLM provider or DB failure
NOT_READYAI generation queued; client should re-poll with the same input

JSON-RPC errors (malformed payloads, batched calls — batches are rejected in v1) come back through the standard JSON-RPC error path, not wrapped in a CallToolResult.

MCP tool reference — input schemas and JSON output | yomeru.ai | Documentation | yomeru.ai