Skip to main content
Glama

Read a letter

read_letter

Read a photo of an old handwritten letter, postcard or document with FamilyLore: the transcription in its own script, a translation and notes on what it meant then. Use it when the person attaches a photo of a handwritten page and asks what it says. It reads pre-1918 Russian and Ukrainian cursive, German Kurrent and Sütterlin, Yiddish, and old English cursive. It needs the person's FamilyLore account and uses one page of the account's allowance. It starts the reading and answers at once with the page id; a reading takes about a minute and a half. If the photo can't be attached here, call it without one: it answers with a one-time link where the person sends the photo to FamilyLore, and the page id to pass to get_reading once they have.

Input Schema

NameRequiredDescriptionDefault
yearNoThe year it was written, if the person knows it roughly (1912 for 'about 1912')
photoNoThe photo of the page the person attached
page_idNoA page already on FamilyLore that hasn't been read, from FamilyLore's own photo upload
languageNoThe letter's language, if the person says it or it is plain: ru_uk = Russian or Ukrainian, de_kurrent = German (Kurrent or Sütterlin), yi = Yiddish, en = English (old cursive). Leave it out and FamilyLore tells.
target_languageNoThe language to translate it into: en (English), de (German), ru (Russian), pl (Polish), it (Italian), fr (French), uk (Ukrainian). English if left out.

Output Schema

NameRequiredDescriptionDefault
statusYesreading: started (about a minute and a half); read: the page already has its reading; waiting_for_photo: the person sends the photo at upload_link, then FamilyLore reads it
page_idYesThe page's id on FamilyLore
page_urlYesThe page on familylore.ai, with the person's other pages
allowanceNoPages left, as the Account page counts them
upload_linkNowaiting_for_photo: where the person sends the photo, once
link_expires_atNoWhen upload_link stops working (UTC)
converted_from_heicNoThe photo was an iPhone HEIC, read as a JPEG

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed2 schema fields changed
    • changedInput schema / properties / target_language / anyOf
      Previous value: -[
      -  {
      -    "enum": [
      -      "en",
      -      "de",
      -      "ru"
      -    ],
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "enum": [
      +      "en",
      +      "de",
      +      "ru",
      +      "pl",
      +      "it",
      +      "fr",
      +      "uk"
      +    ],
      +    "type": "string"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • changedInput schema / properties / target_language / description
      Previous value: -"The language to translate it into: en (English), de (German), ru (Russian). English if left out."New value: +"The language to translate it into: en (English), de (German), ru (Russian), pl (Polish), it (Italian), fr (French), uk (Ukrainian). English if left out."
  2. Changed2 schema fields changed
    • changedInput schema / properties / language / anyOf
      Previous value: -[
      -  {
      -    "enum": [
      -      "ru_uk",
      -      "de_kurrent",
      -      "yi"
      -    ],
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "enum": [
      +      "ru_uk",
      +      "de_kurrent",
      +      "yi",
      +      "en"
      +    ],
      +    "type": "string"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • changedInput schema / properties / language / description
      Previous value: -"The letter's language, if the person says it or it is plain: ru_uk = Russian or Ukrainian, de_kurrent = German (Kurrent or Sütterlin), yi = Yiddish. Leave it out and FamilyLore tells."New value: +"The letter's language, if the person says it or it is plain: ru_uk = Russian or Ukrainian, de_kurrent = German (Kurrent or Sütterlin), yi = Yiddish, en = English (old cursive). Leave it out and FamilyLore tells."
  3. First observed

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations it discloses prerequisites (the person's FamilyLore account), cost (one page of the account's allowance), and timing semantics (returns immediately with a page id, reading completes in about a minute and a half). The no-photo branch with a one-time upload link is behavioral context an agent could not infer from readOnlyHint=false and openWorldHint=true.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The core action, trigger and cost constraints are front-loaded, and each later sentence carries operational detail. It runs long, and the list of supported scripts could be trimmed, but no sentence is pure filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For an asynchronous, allowance-consuming, account-gated tool with a fallback upload path, the description covers the account requirement, cost, latency, and the two-step page-id flow into get_reading. An output schema exists, so return-value explanation is correctly left out.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents year, photo, page_id, language and target_language with enums and defaults. The description reinforces the photo-optional path and the page id handoff but adds no new meaning for individual parameters such as target_language or the year hint.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description gives a specific verb and resource ('Read a photo of an old handwritten letter, postcard or document') and enumerates what comes back: transcription in the original script, a translation, and notes on period meaning. It is clearly distinguishable from siblings such as get_reading and reading_status, which it names as the follow-up step.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It states the trigger plainly ('Use it when the person attaches a photo of a handwritten page and asks what it says') and supplies an explicit fallback path when no photo can be attached, including the handoff to get_reading. It stops short of contrasting itself with ask_letter or reading_status, so the sibling routing is only partly covered.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources