Print and Mail Company
Server Details
Print and mail real letters worldwide from the EU, incl. registered mail. Quote, compose, send.
- Status
- Healthy
- Uptime
- 100.0% over 28 days
- Last Tested
- Transport
- Streamable HTTP · MCP 2025-11-25
- URL
- Repository
- Printandmailcompany/connector
- GitHub Stars
- 0
- ChatGPT
- –
- Claude
- –
TDQS
Scored across 14 tools
Most tools have clearly distinct purposes, but the PDF-related trio (check_pdf_margins, upload_document, fix_document_margins) and the two letter-creation paths (compose_letter vs create_letter) are adjacent enough that an agent must read descriptions carefully. The descriptions do clarify the split (pre-check vs stored upload, text vs PDF), so ambiguity is limited rather than systemic.
Every tool follows a consistent snake_case verb_noun pattern (get_letter, create_letter, list_letters, send_letter, fix_document_margins). The convention is predictable throughout with no mixed casing or vague one-word names.
14 tools is well within the appropriate range for a print-and-mail workflow and each tool covers a meaningful step: quoting, destinations, balance/top-up, upload, PDF checks/fixes, compose/create, send, cancel, and status lookup. No tool feels redundant enough to remove.
The surface covers the full letter lifecycle: price quote, destination lookup, balance check and top-up, PDF upload/check/fix, draft creation from text or PDF, send, cancel, and status listing/lookup. Minor gaps like editing an existing draft can be handled by cancelling and recreating, so there are no serious dead ends.
Available Tools
14 toolscancel_letterCancel letterADestructiveIdempotentInspect
Use this when the user wants to stop a letter they created here: cancels a draft, or a paid letter that has not gone into production yet, and returns the amount to the user's credit. Letters already printed or posted cannot be recalled. This cancels our letter, not a contract the user has with someone else (for that, compose_letter writes the cancellation letter). Ask the user before cancelling. Needs the user's account.
| Name | Required | Description | Default |
|---|---|---|---|
| letter_id | Yes | letter_id of the letter to cancel, from create_letter, compose_letter or list_letters, e.g. ltr_8f3k2m9q4x7v1c6b0n5p. Only drafts and paid letters not yet in production can be cancelled. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations by disclosing the refund-to-credit side effect, the irreversibility boundary for printed/posted letters, the account requirement, and a confirmation expectation. These are exactly the behavioral facts an agent needs for a destructiveHint=true operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the trigger condition and stays focused, with each sentence carrying a distinct instruction. There is minor overlap between 'drafts and paid letters not yet in production' and the schema's restatement of the same rule, but no real waste.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter mutation with no output schema, the description supplies the missing pieces: refund outcome, irreversibility limits, account requirement, and disambiguation from siblings. Nothing an agent needs to call it correctly is absent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the single letter_id parameter is fully documented in the schema, including its source tools and example format. The description restates the cancellable-state constraint but adds no syntax or format detail beyond what the schema already provides, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource (cancel a letter created via this service) and immediately scopes it to drafts and paid-but-unproduced letters. It also distinguishes itself from sibling compose_letter by clarifying that this cancels our letter, not a third-party contract.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly covers when to use it, when not to (letters already printed or posted cannot be recalled), the alternative tool for a different need (compose_letter for contract cancellation letters), and a prerequisite action (ask the user before cancelling).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
check_pdf_marginsCheck PDF for printingARead-onlyIdempotentInspect
Use this when the user has a PDF they want printed and posted and it should be checked first: verifies the page size (A4 or US Letter) and the required free margin on every side, and lists the pages that need changes. We print on the paper size uploaded (printed_on): A4 on A4, US Letter on US Letter (for a recipient outside the US, Canada and US territories the user may choose A4 instead when sending); a PDF mixing A4 and US Letter pages is printed on A4, its Letter pages centred at 100 % or scaled down slightly when content comes close to the edge (us_letter_note, pages[].scale_percent). Decide by compliant: all_pages_a4 is false for a US Letter PDF, which is printable. Accepts a public https URL or base64. The file is not stored and nothing is sent. Works without sign-in. To fix a failing PDF, upload it with upload_document and use fix_document_margins.
| Name | Required | Description | Default |
|---|---|---|---|
| pdf_url | No | Public https URL of the PDF (A4 or US Letter pages), e.g. https://example.com/letter.pdf. Pass pdf_url or pdf_base64. | |
| pdf_base64 | No | The PDF file as base64 (a data:application/pdf;base64, prefix is fine), for files up to about 3 MB. Pass pdf_url or pdf_base64. Larger files: pass pdf_url, or use create_upload_link. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark this read-only, idempotent and non-destructive, and the description still adds substantial context: the file is not stored, nothing is sent, and it works without sign-in. It also names the output fields (compliant, all_pages_a4, us_letter_note, pages[].scale_percent) that drive the decision, which is exactly what a no-output-schema tool needs.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the trigger and the verification behavior before the printing-rule detail, which is good ordering. However the middle section reads as dense run-on sentences about print paper selection that partly belong to the printing workflow rather than to a margin check.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the burden and does so: it explains the verification result, the all_pages_a4 pitfall (false for a printable US Letter PDF), and how to interpret scale_percent when pages are mixed. Auth, storage, and input-method concerns are all addressed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both parameters (pdf_url, pdf_base64) are already fully documented including the alternative and the size caveat. The description only restates 'accepts a public https URL or base64', adding no new syntax or constraint beyond the schema, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a concrete verb and resource: it verifies page size (A4/US Letter) and required free margins on every side, and lists pages needing changes. It also distinguishes itself from the sibling that remediates problems (fix_document_margins), so an agent can tell the two apart without reading either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives a clear trigger ('when the user has a PDF they want printed and posted and it should be checked first') and names the follow-up path via upload_document plus fix_document_margins. There is no explicit when-not-to-use case, so it stops just short of the top band.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
compose_letterCompose a letterAInspect
Use this when the user wants to write a new paper letter from text and post it, for example to cancel a contract, subscription or membership by letter, file a complaint or objection, or send a formal notice, by ordinary or registered mail. Renders an A4 letter (DIN 5008 layout: sender block with the user's own name and address, recipient, place and date, subject, body, closing, signature) that passes the print check, and creates a draft with the exact price. Nothing is sent or charged: show the user the draft and the total, ask for confirmation, then call send_letter. The sender can live in any country. For the account's first letter the sender block must carry the user's REAL full name (first and last name, no alias, nickname or pseudonym) and postal address: it is then saved as the account's sender details; without valid ones the call fails with SENDER_DETAILS_REQUIRED. Once the account has sender details, the sender block is printed as given and the saved details stay as they are (sender_details: on_file when the block matches them, kept when it differs): the user changes them in Settings → Your details. Body supports paragraphs (blank line), '- ' bullets, '1. ' lists and bold. Needs the user's account.
| Name | Required | Description | Default |
|---|---|---|---|
| body | Yes | Letter text including the salutation (e.g. 'Dear Sir or Madam,'), without closing or signature. Blank line = new paragraph; '- ' bullets, '1. ' numbered lists and **bold** work. Up to 20,000 characters. | |
| date | No | Date of the letter as an ISO date (YYYY-MM-DD), e.g. 2026-10-08. Default: today. | |
| color | No | "bw" = black and white, "color" = colour printing (costs more per page). Default "bw". | bw |
| place | No | Place printed before the date, usually the user's city, e.g. Berlin. Optional. | |
| duplex | No | true = print on both sides of the paper (fewer sheets, so a lighter letter); false = one side only. Default false. | |
| sender | Yes | The user's own name and address (any country), printed in the letter's sender block (the envelope always shows our return address). Use the user's REAL full name, not an alias, nickname or pseudonym: for an account without sender details yet, this block is checked and saved as them; once the account has them, they stay as they are. | |
| closing | No | Closing phrase, e.g. 'Kind regards'. Default: the usual closing in the letter's language. | |
| subject | Yes | Subject line printed above the body, e.g. Cancellation of my contract no. 12345 (up to 200 characters). | |
| envelope | No | "DL" (220×110 mm, letter folded twice), "C5" (229×162 mm, folded once) or "C4" (324×229 mm, flat). Omit to use the smallest envelope that holds the sheets (recommended); one too small for the page count is refused. | |
| language | No | Language of the letter as an ISO 639-1 code, e.g. en, de, fr, es, pt, it or nl; sets the date format and the default closing. Default "en". | en |
| recipient | Yes | Recipient's postal address, printed in the letter's address field and on the envelope. Ask the user for missing fields. | |
| signature | No | Name printed under the closing, e.g. Max Mustermann. Default: the sender's name. | |
| references | No | Up to 5 reference lines printed above the subject, e.g. ["Customer no. 12345", "Contract no. 987"]. Optional. | |
| registered | No | true = registered mail: tracking number and signature on delivery, for an extra fee (also what "certified" letters, Einschreiben, lettre recommandée and carta certificada mean here; not a US certified-mail product). false = ordinary mail. Default false. Often wanted for cancellations and deadlines. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations, it discloses that nothing is sent or charged, that a draft is created with an exact price, the SENDER_DETAILS_REQUIRED failure mode, and how sender details are saved or preserved on the account. It also covers body markup, print-check behavior, and that the sender can be in any country.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
It is front-loaded with the when-to-use and the draft-then-send workflow before the caveats. It is dense but justified for a 14-parameter tool, though the real-name requirement and body-formatting details are partially repeated in the schema, costing some conciseness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex nested 14-parameter mutation with no output schema, the description covers the workflow, pricing, confirmation requirement, error modes, sender-details persistence, and formatting rules. An agent has enough to invoke it correctly without guessing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds genuine meaning beyond the schema: the body formatting rules, the sender-block-as-account-details semantics, and which fields cause SENDER_DETAILS_REQUIRED. It does repeat some schema details rather than only adding new meaning.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description gives a specific verb and resource (compose a new paper letter from text, render an A4 DIN 5008 letter, create a draft) and lists concrete use cases like cancellations and formal notices. It clearly separates composing from sending by naming send_letter, but never addresses the sibling create_letter, which an agent could easily confuse with this tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It states when to use the tool with concrete scenarios, spells out the required follow-up workflow (show draft and total, ask for confirmation, call send_letter), and explains the first-letter sender-details prerequisite. The missing piece is guidance on how this differs from the create_letter sibling.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_letterCreate letter draftAInspect
Use this when the user has an uploaded PDF (document_id, or upload_id from create_upload_link) and a recipient address and wants it posted by ordinary or registered mail; registered mail is international registered mail with tracking and signature on delivery; "certified" letters, Einschreiben, lettre recommandée and carta certificada mean this here (not a US certified-mail product). Creates a draft with the exact total in the user's currency. Nothing is sent or charged; call send_letter only after the user confirms. Every envelope carries our company return address, so the user's own address belongs in the document. The account's first letter needs the user's sender details, their REAL full name (no alias, nickname or pseudonym) and postal address: pass them as sender; without them (and none saved before) the call fails with SENDER_DETAILS_REQUIRED. Once the account has them, the saved details are used (sender_details "on_file"; "kept" when a different sender was passed, which is not saved): the user changes them in Settings → Your details. A US Letter PDF to a recipient outside the US, Canada and US territories needs the user's paper choice (paper_size, same price): without it the draft says paper_choice_required. Needs the user's account.
| Name | Required | Description | Default |
|---|---|---|---|
| color | No | "bw" = black and white, "color" = colour printing (costs more per page). Default "bw". | bw |
| duplex | No | true = print on both sides of the paper (fewer sheets, so a lighter letter); false = one side only. Default false. | |
| sender | No | The user's own sender details: their REAL full name (first and last name, not an alias, nickname or pseudonym) and postal address, any country. Optional: needed only while the account has no sender details yet; they are then checked and saved to the account. Once the account has them, the saved details are used and this is not saved (the user changes them in Settings → Your details). | |
| envelope | No | "DL" (220×110 mm, letter folded twice), "C5" (229×162 mm, folded once) or "C4" (324×229 mm, flat). Omit to use the smallest envelope that holds the sheets (recommended); one too small for the page count is refused. | |
| recipient | Yes | Recipient's postal address, printed on the envelope. Ask the user for missing fields. | |
| upload_id | No | upload_id from create_upload_link, once the user has uploaded the PDF on that page. Pass document_id or upload_id. | |
| paper_size | No | Only for a US Letter PDF to a recipient outside US, CA, PR, VI, GU, AS, MP (the US, Canada and US territories): "a4" = shrink to A4 (recommended), "us_letter" = keep US Letter. Ask the user; same price. Ignored otherwise (A4 PDFs print on A4, US Letter PDFs to those countries on US Letter). No default: omit until the user has chosen. | |
| registered | No | true = registered mail: tracking number and signature on delivery, for an extra fee (also what "certified" letters, Einschreiben, lettre recommandée and carta certificada mean here; not a US certified-mail product). false = ordinary mail. Default false. | |
| document_id | No | The PDF to post: document_id from upload_document or compose_letter, e.g. doc_2h7k9m4q8x1v3c6b0n5p. Pass document_id or upload_id. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare non-read-only, non-destructive, non-idempotent, closed-world, so the bar is lower, yet the description adds real behavior: draft-only, no charge or dispatch, the exact total quoted in user currency, and named failure modes (SENDER_DETAILS_REQUIRED, paper_choice_required, INVALID_ADDRESS, refused too-small envelope). It also explains the saved-versus-kept sender state ('on_file'/'kept'). It stops short of describing what the draft object itself returns, but with no output schema that is a minor gap rather than a serious one.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well front-loaded: the trigger condition comes first, then the draft/no-charge contract, then prerequisites and the paper-size wrinkle. It is dense rather than padded, though it is long enough that the sender-details paragraph partly duplicates schema text and could be trimmed.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 9-parameter nested-object creation tool with no output schema, the description covers the pieces that actually cause failed calls: first-letter sender details, region-required countries, the US Letter to non-US paper choice, envelope sizing, and the confirmation handoff to send_letter. An agent can call this correctly without further discovery.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the nested sender/recipient blocks already document region rules, ISO codes and paper_size conditions, so the description mostly restates what structured data provides. It does add one genuinely non-schema insight — that every envelope carries the company return address, so the user's own address belongs in the document — which nudges it to the top of the baseline band.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a concrete precondition (uploaded PDF plus recipient address) and a specific verb (creates a draft for posting by ordinary or registered mail), and explicitly distinguishes the act from send_letter. It also pins down the ambiguous term 'certified' versus Einschreiben/lettre recommandée, so an agent knows exactly what this tool produces.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
States when to use it, names the upstream alternatives (document_id from upload_document/compose_letter, or upload_id from create_upload_link), and gives an explicit when-not: nothing is sent or charged, and send_letter is the follow-up call after the user confirms. The user-facing prerequisites (sender details, paper choice) are attached to the right moments.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_topup_linkCreate payment linkAIdempotentInspect
Use this when the user needs to add credit, or to pay one specific draft letter by card. Returns a link to the payment page on printandmailcompany.com; give it to the user, who pays there. The assistant cannot pay, and calling this tool charges nothing. Needs the user's account.
| Name | Required | Description | Default |
|---|---|---|---|
| letter_id | No | letter_id of a draft, e.g. ltr_8f3k2m9q4x7v1c6b0n5p: the link then pays that letter by card. Omit for a link to add prepaid credit. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations (readOnlyHint=false, destructiveHint=false, idempotentHint=true), the description discloses the key non-obvious traits: the link is handed to the user who pays externally, the assistant cannot pay, and calling the tool charges nothing. It also states the auth requirement ('Needs the user's account'), which the annotations do not cover.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences, front-loaded with the trigger condition, then the return behavior, then the safety/auth caveat. Every sentence earns its place and nothing is redundant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description steps in and describes the return value (a link to the payment page), plus the auth requirement and the no-charge guarantee. An agent has everything needed to call it and explain the result to the user.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the letter_id description already explains the two modes (pay a draft vs. omit for credit), so the schema carries the parameter burden. The description's phrasing 'add credit, or to pay one specific draft letter' mirrors that without adding new syntax or constraints, which is the expected baseline 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource ('Returns a link to the payment page') and scopes it precisely to two cases: adding prepaid credit or paying one draft letter by card. No sibling (create_upload_link, get_balance, send_letter) shares this resource, so an agent can identify it without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives an explicit trigger: 'Use this when the user needs to add credit, or to pay one specific draft letter by card.' That is clear context for invocation, but no alternatives or when-not conditions are named (e.g. when to use get_balance or get_price_quote instead), so it stops short of full routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_upload_linkCreate upload linkAInspect
Use this when the user wants to post a PDF that is on their own device and cannot be passed as a URL or base64. Creates a private upload page (valid 60 minutes); give the URL to the user, and once they have uploaded, pass upload_id to create_letter. Sends nothing. Needs the user's account.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare a non-read-only, non-destructive, non-idempotent, closed-world operation, so the bar is lower; the description still adds substantive context beyond them: the link is private, valid for 60 minutes, sends nothing, and requires the user's account. These are auth, lifecycle, and side-effect details the annotations do not convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three compact sentences, front-loaded with the trigger condition and followed by the lifecycle and handoff. No filler; every clause carries decision-relevant information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description covers the return artifacts (URL to give the user, upload_id for create_letter), validity window, side effects, and auth requirement. An agent has everything needed to call it and act on the result.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters and schema coverage is 100%, so there is nothing for the description to disambiguate; baseline is 4. It usefully explains what the caller supplies downstream (upload_id to create_letter) even though no input is required.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
It names a specific verb and resource ('Creates a private upload page') and precisely scopes it: a PDF resident on the user's own device that cannot be passed as URL or base64. This cleanly distinguishes it from sibling tools like upload_document and create_letter.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit trigger ('when the user wants to post a PDF that is on their own device and cannot be passed as a URL or base64') plus the downstream handoff ('pass upload_id to create_letter'). The agent knows both when to call it and what to do with the result.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fix_document_marginsFix document marginsADestructiveIdempotentInspect
Use this when an uploaded PDF fails the print check because content is too close to the edge or pages are neither A4 nor US Letter. mode "shrink" (default) scales the affected pages down slightly and centres them on their paper (US Letter for a US Letter PDF, else A4); nothing is lost. mode "crop" keeps pages at 100 % and removes everything inside the margin band, so that content is NOT printed (pages of other sizes are first fitted onto A4). The US Letter pages of a mixed PDF that already fit on A4 keep their placement. The original upload is kept; calling again with the other mode replaces the earlier fix. If content touches the edge, ask the user which mode they prefer and tell them what changed. Not possible once the letter is paid. Needs the user's account.
| Name | Required | Description | Default |
|---|---|---|---|
| mode | No | "shrink" = scale pages down slightly, nothing lost; "crop" = keep 100 % size and cut off everything inside the margin (that content is not printed). Default "shrink". | shrink |
| document_id | Yes | document_id returned by upload_document or compose_letter, e.g. doc_2h7k9m4q8x1v3c6b0n5p. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare destructiveHint=true and idempotentHint=true, and the description goes well beyond them: crop 'removes everything inside the margin band, so that content is NOT printed', the original upload is kept, and re-calling with the other mode replaces the earlier fix. It also discloses a lifecycle constraint not in annotations (fails once the letter is paid), which is exactly the kind of context the agent needs before invoking a destructive fix.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the triggering condition and mode semantics, and each sentence carries a distinct constraint (destruction, reversibility, lifecycle, escalation). It is dense — several clauses packed into long sentences — but no sentence is filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a destructive, non-read-only operation with no output schema, the description covers what gets removed, what is preserved, reversibility, the paid-letter precondition, and the auth requirement. Nothing an agent needs to call this correctly appears to be missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the mode enum is already fully documented in the schema, so the baseline is 3. The description earns extra credit by adding behaviour the schema does not: how shrink centres pages ('US Letter for a US Letter PDF, else A4') and how mixed PDFs that already fit on A4 keep their placement.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (fix) and resource (document margins) and pins the exact trigger condition: an uploaded PDF that fails the print check because content is too close to the edge or pages are not A4/US Letter. This distinguishes it from check_pdf_margins (the diagnostic) without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit when-to-use (print check failure), when-not-to-use (not possible once the letter is paid), and an escalation rule (ask the user which mode they prefer when content touches the edge). It also specifies the precondition 'Needs the user's account', leaving little to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_balanceGet credit balanceARead-onlyIdempotentInspect
Use this when the user asks how much prepaid credit they have, or to check before sending that the credit covers a letter. Returns the credit, the account currency and the minimum top-up. Changes nothing. Needs the user's account.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint and destructiveHint=false, so the safety profile is covered. The description still adds value by stating "Changes nothing" and the auth-ish precondition "Needs the user's account," plus listing the returned fields despite no output schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, front-loaded with the trigger condition, then output contents, then the side-effect/auth note. No filler and nothing redundant with the title.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a parameterless read with no output schema, the description supplies exactly the missing pieces: when to call it, what it returns (credit, currency, minimum top-up), and that it has no side effects. An agent has everything needed to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Zero parameters, so the baseline is 4. The description adds the only meaningful input context — that the user's account is needed — which is implicit scoping rather than a formal parameter. Nothing further is required.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource (get the prepaid credit balance) and enumerates what comes back: credit, account currency, minimum top-up. This is unmistakable against siblings like create_topup_link or get_price_quote, which serve different purposes.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives two concrete triggering conditions: the user asking about prepaid credit, and checking coverage before sending a letter. That is clear context, but there is no explicit when-not guidance or named alternative for the related money question (top-up vs. price quote).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_letterGet letterARead-onlyIdempotentInspect
Use this when the user asks about a letter they created here: status (draft, paid, in_production, printed, posted, cancelled, returned), tracking number for registered mail, and price. Look up by letter_id or reference (PM-XXXXXX). Changes nothing. Needs the user's account.
| Name | Required | Description | Default |
|---|---|---|---|
| letter_id | No | letter_id from create_letter, compose_letter or list_letters, e.g. ltr_8f3k2m9q4x7v1c6b0n5p. Pass letter_id or reference. | |
| reference | No | The letter's reference as shown to the user, format PM-XXXXXX, e.g. PM-7K3QH9. Pass letter_id or reference. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, and non-destructive, so the safety profile is covered; the description goes beyond them by asserting 'Changes nothing' and adding an auth requirement ('Needs the user's account') plus the return fields. It does not mention error behavior for an unknown reference or whether an unauthenticated call fails, so it is not exhaustive.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One dense sentence front-loads the usage trigger and then packs the return fields, with 'Changes nothing. Needs the user's account.' as short trailing constraints. Every clause earns its place; the long parenthetical status list makes it slightly heavy but still readable.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the return-value burden and does so by naming status (with its full value set), tracking number, and price. Combined with annotations covering safety and the 100%-covered schema, an agent has enough to call this correctly; only error/not-found behavior is unaddressed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and both parameter descriptions already state the formats and 'Pass letter_id or reference.' The description merely restates this optionality ('Look up by letter_id or reference (PM-XXXXXX)'), adding no precedence rule or extra meaning, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource (retrieve a letter) and enumerates exactly what is returned: status, tracking number, price. The singular, instance-scoped framing ('a letter they created here', looked up by letter_id or PM- reference) is clearly distinguishable from create_letter, compose_letter, and list_letters without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives a concrete trigger ('when the user asks about a letter they created here') and the two accepted lookup keys. It stops short of naming alternatives or stating exclusions (e.g., use list_letters for multiple letters, create_letter to make one), so it is clear context rather than a full routing rule.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_price_quoteGet price quoteARead-onlyIdempotentInspect
Use this when the user asks what it costs to send a physical letter by post (snail mail), including a registered letter. Returns the exact total incl. VAT (for a signed-in EU business customer with a confirmed VAT number: excl. VAT under the reverse charge), the line items, the envelope, the postal size class and zone and the typical delivery time for a page count, destination country and print options. Letters are printed and posted in Europe, so the sender can be anywhere in the world. Note: registered mail is international registered mail with tracking and signature on delivery; "certified" letters, Einschreiben, lettre recommandée and carta certificada mean this here (not a US certified-mail product). Works without sign-in. Set currency to get the total in USD, GBP or CHF (ECB rate plus currency margin). Does not cover email, fax, parcels or postcards.
| Name | Required | Description | Default |
|---|---|---|---|
| color | No | "bw" = black and white, "color" = colour printing (costs more per page). Default "bw". | bw |
| pages | Yes | Number of pages in the PDF, a whole number from 1 to 250, e.g. 2. | |
| duplex | No | true = print on both sides of the paper (fewer sheets, so a lighter letter); false = one side only. Default false. | |
| country | Yes | Destination country as an ISO 3166-1 alpha-2 code, e.g. DE, FR or US (list_destinations lists them all). | |
| currency | No | Currency for the total: "EUR", "USD", "GBP" or "CHF". Prices are set in EUR; for USD, GBP or CHF the result adds the total converted at the ECB rate plus a currency margin. Default "EUR". | EUR |
| envelope | No | "DL" (220×110 mm, letter folded twice), "C5" (229×162 mm, folded once) or "C4" (324×229 mm, flat). Omit to use the smallest envelope that holds the sheets (recommended); one too small for the page count is refused. | |
| registered | No | true = registered mail: tracking number and signature on delivery, for an extra fee (also what "certified" letters, Einschreiben, lettre recommandée and carta certificada mean here; not a US certified-mail product). false = ordinary mail. Default false. | |
| postal_code | No | Destination postcode, e.g. 07001. Optional: it only changes the price for the Spanish and Portuguese islands and enclaves (Balearic and Canary Islands, Ceuta, Melilla, Madeira, Azores). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark it read-only, idempotent and non-destructive, but the description goes well beyond: VAT treatment incl. reverse charge for EU business customers, works without sign-in, currency conversion via ECB rate plus margin, and the exact registered-mail semantics. These are meaningful behavioral details not derivable from annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the usage trigger, then packs return contents and caveats efficiently. It is dense and fairly long, but nearly every sentence (VAT, registered definition, currency, Europe posting) carries distinct information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, but the description enumerates what is returned: exact total incl. VAT, line items, envelope, postal size class and zone, and typical delivery time. Combined with the when-to-use framing, an agent has everything needed to invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description restates the currency conversion and registered-mail meaning, which mostly duplicates the schema's own parameter descriptions (e.g. postal_code island caveat, envelope recommendation), adding limited new value beyond the structured fields.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: a price quote for sending a physical letter by post, including registered mail. It explicitly excludes email, fax, parcels and postcards, and the scope (printed/posted in Europe) distinguishes it clearly from compose_letter, create_letter, send_letter and get_balance.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Front-loads the trigger condition ('Use this when the user asks what it costs to send a physical letter by post') and names out-of-scope cases (email, fax, parcels, postcards). It clarifies that no sign-in is needed and disambiguates 'certified'/Einschreiben/lettre recommandée/carta certificada, leaving little to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_destinationsList destinationsARead-onlyIdempotentInspect
Use this when the user asks whether a letter can be posted to a country, or which countries can be reached. Without country: all destination countries with their postage zone. With country: that country's zone, the price of a 1-page standard and registered letter, and the typical delivery time. Works without sign-in. Letters only, no parcels.
| Name | Required | Description | Default |
|---|---|---|---|
| country | No | ISO 3166-1 alpha-2 code of one country, e.g. DE: returns its zone, 1-page prices and delivery time. Omit to list every destination country. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent and closed-world, so the safety bar is low. The description adds real context beyond them: it works without sign-in and covers letters only, not parcels — useful constraints for an agent. It does not describe response format or pagination, but no output schema exists so this is a minor gap.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four short, front-loaded sentences: usage condition first, then the two parameter modes, then behavioral constraints. No filler and every sentence adds usable information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter read tool with no output schema, the description covers when to use it, both parameter modes, and the returned fields (zone, prices, delivery time). Return values are only sketched, but that is acceptable given the tool's simplicity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the single optional country parameter and its ISO alpha-2 format are fully documented in the schema. The description restates the behavioral consequence of omitting or providing the code, which is helpful but largely mirrors what the schema already says; baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource (list destination countries) and distinguishes itself from siblings like get_price_quote by describing the postal-eligibility question it answers. An agent can tell what it returns and how it differs from letter-composition or pricing tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit when-to-use triggers (user asks whether a letter can be posted to a country, or which countries are reachable) and clarifies the with/without-country split. It does not name alternative tools for related questions, but the usage context is unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_lettersList lettersARead-onlyIdempotentInspect
Use this when the user wants to see their recent letters, optionally filtered by status. Returns status, recipient, price and tracking number per letter. Changes nothing. Needs the user's account.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | How many letters to return, newest first: a whole number from 1 to 50. Default 10. | |
| status | No | Only letters with this status, e.g. draft or posted. Omit for letters in any status. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true and destructiveHint=false, so 'Changes nothing' is largely redundant. The description still adds value beyond the annotations by disclosing the authorization requirement ('Needs the user's account') and the per-letter return fields an agent can expect without an output schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four short sentences, zero filler, with the usage trigger front-loaded before the return, safety and auth notes. Nothing is repeated that the reader doesn't need at call time.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description compensates by naming the returned fields, and it covers the trigger, filter, safety profile and account requirement. An agent has everything needed to decide to call this and to interpret the result.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%: both limit (default 10, max 50) and the status enum are fully documented in the schema. The description only restates 'optionally filtered by status' and 'recent,' adding no format or semantics beyond what the schema already provides, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a concrete verb and resource with scope: seeing 'recent letters, optionally filtered by status,' and it enumerates the returned fields. It separates itself in spirit from get_letter (single letter) by emphasizing a plural, filtered listing, but it never names that sibling explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It states a clear trigger — 'Use this when the user wants to see their recent letters' — and notes the optional status filter. There is no explicit when-not guidance (e.g., use get_letter for one specific letter), so it stops short of the top band.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
send_letterSend letter (charges credit)ADestructiveInspect
Use this when the user has explicitly confirmed a specific draft letter (recipient, content and total price) and wants it printed and posted. Pays the letter from the user's prepaid credit and releases it to print; it can be cancelled with cancel_letter only until production starts. Only call this after that confirmation and after the user agreed to the Terms (https://printandmailcompany.com/en/legal/terms) and to printing starting immediately (which ends the consumer right of withdrawal once printed). If credit is too low, the result contains a payment link for the user; the assistant cannot pay. A US Letter PDF to a recipient outside the US, Canada and US territories needs paper_size (ask the user: shrink to A4, recommended, or keep US Letter; same price); without it the call fails with PAPER_CHOICE_REQUIRED and nothing is charged. While the account has no sender details (the user's REAL full name, no alias, and postal address) the call fails with SENDER_DETAILS_REQUIRED and nothing is charged: ask the user for them and call send_letter again with them as sender (saved to the account before paying; once the account has them, the saved details are used). Posts paper letters only: no email, fax or parcels. Needs the user's account.
| Name | Required | Description | Default |
|---|---|---|---|
| sender | No | The user's own sender details: their REAL full name (first and last name, not an alias, nickname or pseudonym) and postal address, any country. Optional: needed only while the account has no sender details yet (SENDER_DETAILS_REQUIRED); they are then checked and saved to the account before paying. Once the account has them, the saved details are used and this is not saved (the user changes them in Settings → Your details). | |
| confirm | Yes | Must be true: the user explicitly confirmed sending this letter (recipient, content and total price). | |
| letter_id | Yes | letter_id of the draft the user confirmed, from create_letter or compose_letter, e.g. ltr_8f3k2m9q4x7v1c6b0n5p. Sending charges its total to the user's prepaid credit. | |
| paper_size | No | The user's choice for a US Letter PDF to a recipient outside the US, Canada and US territories: "a4" = shrink to A4 (recommended), "us_letter" = keep US Letter. Same price. Saved on the draft before paying; ignored for other letters. No default: omit unless the user has chosen. | |
| user_accepted_terms | Yes | Must be true: the user agreed to the Terms and to the immediate start of printing. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations, it discloses that sending charges prepaid credit, releases the letter to print, and can only be cancelled before production starts. It also explains low-credit payment links, PAPER_CHOICE_REQUIRED and SENDER_DETAILS_REQUIRED failures, and that sender details are saved before paying.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the main use case and every sentence carries operational guidance for a high-stakes payment action. It is dense and could be structured with bullets, but it is appropriately sized for the complexity and is not padded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
It covers the essential behavior for a destructive, credit-charging, open-world tool: prerequisites, legal acceptance, payment handling, cancellation limits, print-channel limits, sender-detail collection, and failure modes. Given the absence of an output schema, it also explains that low credit returns a payment link in the result.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3, but the description adds operational meaning for paper_size and sender: when paper_size is required, the recommended A4 choice, and that sender details are only needed while the account lacks them. Much of this is already in the schema, but the failure-code context adds value.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first sentence states a specific verb and resource: send a confirmed draft letter for printing and posting, paid from prepaid credit. It clearly scopes the tool against siblings by mentioning cancel_letter for cancellation and excluding email, fax and parcels.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives explicit preconditions: the user must have confirmed the specific draft, agreed to the Terms, and agreed to immediate printing. It also states when not to proceed by requiring that confirmation and by restricting the tool to paper letters rather than other channels.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
upload_documentUpload a PDFAInspect
Use this when the user already has a PDF (public https URL or base64) that should be printed and posted. Stores the file in the user's account, runs the print check (A4 or US Letter, free margins; printed_on says the paper: US Letter PDFs are printed on US Letter, a PDF mixing A4 and US Letter pages on A4, see us_letter_note; decide by compliant, as all_pages_a4 is false for a US Letter PDF) and returns document_id for create_letter. If the check fails, call fix_document_margins or ask the user for a corrected file. For a file on the user's own device, use create_upload_link instead. Sends nothing. Needs the user's account.
| Name | Required | Description | Default |
|---|---|---|---|
| pdf_url | No | Public https URL of the PDF (A4 or US Letter pages), e.g. https://example.com/letter.pdf. Pass pdf_url or pdf_base64. | |
| file_name | No | Name to store the file under, e.g. cancellation.pdf. Default: the name from the URL, or "document.pdf". | |
| pdf_base64 | No | The PDF file as base64 (a data:application/pdf;base64, prefix is fine), for files up to about 3 MB. Pass pdf_url or pdf_base64. Larger files: pass pdf_url, or use create_upload_link. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare the mutation profile (readOnlyHint=false, openWorldHint=true, idempotentHint=false), but the description adds material context beyond them: it stores the file in the account, requires the user's account, 'Sends nothing' (clarifying no letter is dispatched), and returns document_id for the downstream create_letter step. The A4/US Letter print-check explanation is tangled but genuinely discloses what the tool computes.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The when-to-use and alternatives are front-loaded well, but the parenthetical about printed_on, compliant, all_pages_a4, and us_letter_note is dense, circular, and hard to parse. That clause costs more attention than it earns.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description still explains the return value (document_id for create_letter), the auth requirement, the no-send guarantee, the alternative tool, and the remediation path. Nothing an agent needs to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so pdf_url, file_name, and pdf_base64 are already fully documented in the schema. The description adds no syntax or format detail beyond that, so the baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('upload_document' stores a PDF in the user's account, runs a print check, and returns document_id for create_letter) and distinguishes itself from the sibling create_upload_link for on-device files. An agent can identify the tool's role without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly names the trigger ('when the user already has a PDF... that should be printed and posted'), the alternative for a different input source ('For a file on the user's own device, use create_upload_link instead'), and the failure path ('call fix_document_margins or ask the user for a corrected file'). This is the strongest kind of routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
2 tool updates
- Changed
create_letter1 field changed- changed
Input schema / properties / sender / descriptionPrevious value: -"The user's own sender details: their REAL full name (first and last name, not an alias, nickname or pseudonym) and postal address, any country. Optional: needed only while the account has no sender details yet; they are then checked and saved to the account, kept on record and never printed on the envelope or in the letter. Once the account has them, the saved details are used and this is not saved (the user changes them in Settings → Your details)."New value: +"The user's own sender details: their REAL full name (first and last name, not an alias, nickname or pseudonym) and postal address, any country. Optional: needed only while the account has no sender details yet; they are then checked and saved to the account. Once the account has them, the saved details are used and this is not saved (the user changes them in Settings → Your details)."
- Changed
send_letter1 field changed- changed
Input schema / properties / sender / descriptionPrevious value: -"The user's own sender details: their REAL full name (first and last name, not an alias, nickname or pseudonym) and postal address, any country. Optional: needed only while the account has no sender details yet (SENDER_DETAILS_REQUIRED); they are then checked and saved to the account before paying, kept on record and never printed on the envelope or in the letter. Once the account has them, the saved details are used and this is not saved (the user changes them in Settings → Your details)."New value: +"The user's own sender details: their REAL full name (first and last name, not an alias, nickname or pseudonym) and postal address, any country. Optional: needed only while the account has no sender details yet (SENDER_DETAILS_REQUIRED); they are then checked and saved to the account before paying. Once the account has them, the saved details are used and this is not saved (the user changes them in Settings → Your details)."
3 tool updates
- Changed
compose_letter3 fields changed- changed
Input schema / properties / sender / descriptionPrevious value: -"The user's own name and address (any country), printed in the letter's sender block (the envelope always shows our return address)"New value: +"The user's own name and address (any country), printed in the letter's sender block (the envelope always shows our return address). Use the user's REAL full name, not an alias, nickname or pseudonym: for an account without sender details yet, this block is checked and saved as them; once the account has them, they stay as they are." - changed
Input schema / properties / sender / properties / name / descriptionPrevious value: -"The user's full name, e.g. Max Mustermann."New value: +"The user's full name: their REAL first and last name, not an alias, nickname or pseudonym, e.g. Anna Schmidt." - changed
Input schema / properties / sender / properties / region / descriptionPrevious value: -"State, province or region where the user's country has one in addresses, e.g. CA (California, US), ON (Ontario, CA) or Madrid (ES). Optional in the sender block."New value: +"State, province or region where the user's country has one in addresses, e.g. CA (California, US), ON (Ontario, CA) or Madrid (ES). Required for addresses in AE, AS, AU, BR, CA, CN, CO, CR, ES, FM, HK, HN, ID, IN, IQ, IT, JM, JP, KN, KR, KY, MH, MP, MX, NR, PF, PG, PW, RU, SO, SV, TW, US, VE, VI, VN when this block is saved as the user's sender details (an account without them yet: SENDER_DETAILS_REQUIRED, fields.region); otherwise optional."
- Changed
create_letter1 field changed- added
Input schema / properties / senderAdded value: +{ + "description": "The user's own sender details: their REAL full name (first and last name, not an alias, nickname or pseudonym) and postal address, any country. Optional: needed only while the account has no sender details yet; they are then checked and saved to the account, kept on record and never printed on the envelope or in the letter. Once the account has them, the saved details are used and this is not saved (the user changes them in Settings → Your details).", + "properties": { + "city": { + "description": "City or town, e.g. Berlin.", + "maxLength": 50, + "minLength": 1, + "type": "string" + }, + "company": { + "description": "The user's company or organisation, e.g. Example GmbH. Optional.", + "maxLength": 60, + "type": "string" + }, + "country": { + "description": "Country as an ISO 3166-1 alpha-2 code, e.g. DE, FR or US.", + "maxLength": 2, + "minLength": 2, + "type": "string" + }, + "line1": { + "description": "Street and house number, or PO box, e.g. Hauptstraße 5.", + "maxLength": 60, + "minLength": 1, + "type": "string" + }, + "line2": { + "description": "Optional extra address line: c/o, apartment, floor or building, e.g. Apt 4B.", + "maxLength": 60, + "type": "string" + }, + "name": { + "description": "The user's full name: their REAL first and last name, not an alias, nickname or pseudonym, e.g. Anna Schmidt.", + "maxLength": 60, + "minLength": 1, + "type": "string" + }, + "postal_code": { + "description": "Postcode / ZIP code, e.g. 10115 or 94105. Required in countries that use postcodes.", + "maxLength": 16, + "type": "string" + }, + "region": { + "description": "State, province or region where the user's country has one in addresses, e.g. CA (California, US), ON (Ontario, CA) or Madrid (ES). Required for addresses in AE, AS, AU, BR, CA, CN, CO, CR, ES, FM, HK, HN, ID, IN, IQ, IT, JM, JP, KN, KR, KY, MH, MP, MX, NR, PF, PG, PW, RU, SO, SV, TW, US, VE, VI, VN when this block is saved as the user's sender details (an account without them yet: SENDER_DETAILS_REQUIRED, fields.region); otherwise optional.", + "maxLength": 50, + "type": "string" + } + }, + "required": [ + "name", + "line1", + "city", + "country" + ], + "type": "object" +}
- Changed
send_letter1 field changed- added
Input schema / properties / senderAdded value: +{ + "description": "The user's own sender details: their REAL full name (first and last name, not an alias, nickname or pseudonym) and postal address, any country. Optional: needed only while the account has no sender details yet (SENDER_DETAILS_REQUIRED); they are then checked and saved to the account before paying, kept on record and never printed on the envelope or in the letter. Once the account has them, the saved details are used and this is not saved (the user changes them in Settings → Your details).", + "properties": { + "city": { + "description": "City or town, e.g. Berlin.", + "maxLength": 50, + "minLength": 1, + "type": "string" + }, + "company": { + "description": "The user's company or organisation, e.g. Example GmbH. Optional.", + "maxLength": 60, + "type": "string" + }, + "country": { + "description": "Country as an ISO 3166-1 alpha-2 code, e.g. DE, FR or US.", + "maxLength": 2, + "minLength": 2, + "type": "string" + }, + "line1": { + "description": "Street and house number, or PO box, e.g. Hauptstraße 5.", + "maxLength": 60, + "minLength": 1, + "type": "string" + }, + "line2": { + "description": "Optional extra address line: c/o, apartment, floor or building, e.g. Apt 4B.", + "maxLength": 60, + "type": "string" + }, + "name": { + "description": "The user's full name: their REAL first and last name, not an alias, nickname or pseudonym, e.g. Anna Schmidt.", + "maxLength": 60, + "minLength": 1, + "type": "string" + }, + "postal_code": { + "description": "Postcode / ZIP code, e.g. 10115 or 94105. Required in countries that use postcodes.", + "maxLength": 16, + "type": "string" + }, + "region": { + "description": "State, province or region where the user's country has one in addresses, e.g. CA (California, US), ON (Ontario, CA) or Madrid (ES). Required for addresses in AE, AS, AU, BR, CA, CN, CO, CR, ES, FM, HK, HN, ID, IN, IQ, IT, JM, JP, KN, KR, KY, MH, MP, MX, NR, PF, PG, PW, RU, SO, SV, TW, US, VE, VI, VN when this block is saved as the user's sender details (an account without them yet: SENDER_DETAILS_REQUIRED, fields.region); otherwise optional.", + "maxLength": 50, + "type": "string" + } + }, + "required": [ + "name", + "line1", + "city", + "country" + ], + "type": "object" +}
12 tool updates
- Changed
cancel_letter1 field changed- added
Input schema / properties / letter_id / descriptionAdded value: +"letter_id of the letter to cancel, from create_letter, compose_letter or list_letters, e.g. ltr_8f3k2m9q4x7v1c6b0n5p. Only drafts and paid letters not yet in production can be cancelled."
- Changed
check_pdf_margins2 fields changed- changed
Input schema / properties / pdf_base64 / descriptionPrevious value: -"The PDF as base64, for files up to about 3 MB. Larger files: pass pdf_url, or use create_upload_link."New value: +"The PDF file as base64 (a data:application/pdf;base64, prefix is fine), for files up to about 3 MB. Pass pdf_url or pdf_base64. Larger files: pass pdf_url, or use create_upload_link." - added
Input schema / properties / pdf_url / descriptionAdded value: +"Public https URL of the PDF (A4 or US Letter pages), e.g. https://example.com/letter.pdf. Pass pdf_url or pdf_base64."
- Changed
compose_letter31 fields changed- changed
Input schema / properties / body / descriptionPrevious value: -"Letter text including the salutation (e.g. 'Dear Sir or Madam,'), without closing or signature"New value: +"Letter text including the salutation (e.g. 'Dear Sir or Madam,'), without closing or signature. Blank line = new paragraph; '- ' bullets, '1. ' numbered lists and **bold** work. Up to 20,000 characters." - changed
Input schema / properties / closing / descriptionPrevious value: -"e.g. 'Kind regards' (default by language)"New value: +"Closing phrase, e.g. 'Kind regards'. Default: the usual closing in the letter's language." - added
Input schema / properties / color / descriptionAdded value: +"\"bw\" = black and white, \"color\" = colour printing (costs more per page). Default \"bw\"." - changed
Input schema / properties / date / descriptionPrevious value: -"ISO date; defaults to today"New value: +"Date of the letter as an ISO date (YYYY-MM-DD), e.g. 2026-10-08. Default: today." - added
Input schema / properties / duplex / descriptionAdded value: +"true = print on both sides of the paper (fewer sheets, so a lighter letter); false = one side only. Default false." - added
Input schema / properties / envelope / descriptionAdded value: +"\"DL\" (220×110 mm, letter folded twice), \"C5\" (229×162 mm, folded once) or \"C4\" (324×229 mm, flat). Omit to use the smallest envelope that holds the sheets (recommended); one too small for the page count is refused." - changed
Input schema / properties / language / descriptionPrevious value: -"Language of the letter, e.g. en, de, fr — sets date format and default closing"New value: +"Language of the letter as an ISO 639-1 code, e.g. en, de, fr, es, pt, it or nl; sets the date format and the default closing. Default \"en\"." - changed
Input schema / properties / place / descriptionPrevious value: -"Place shown next to the date, e.g. the sender's city"New value: +"Place printed before the date, usually the user's city, e.g. Berlin. Optional." - added
Input schema / properties / recipient / descriptionAdded value: +"Recipient's postal address, printed in the letter's address field and on the envelope. Ask the user for missing fields." - added
Input schema / properties / recipient / properties / city / descriptionAdded value: +"City or town, e.g. Berlin." - changed
Input schema / properties / recipient / properties / company / descriptionPrevious value: -"Company or organisation (optional)"New value: +"Recipient's company or organisation, e.g. Example GmbH. Optional." - changed
Input schema / properties / recipient / properties / country / descriptionPrevious value: -"ISO 3166-1 alpha-2 country code, e.g. DE, FR, US"New value: +"Country as an ISO 3166-1 alpha-2 code, e.g. DE, FR or US." - changed
Input schema / properties / recipient / properties / line1 / descriptionPrevious value: -"Street and house number, or PO box"New value: +"Street and house number, or PO box, e.g. Hauptstraße 5." - changed
Input schema / properties / recipient / properties / line2 / descriptionPrevious value: -"Additional line: c/o, apartment, building"New value: +"Optional extra address line: c/o, apartment, floor or building, e.g. Apt 4B." - changed
Input schema / properties / recipient / properties / name / descriptionPrevious value: -"Recipient (person) name"New value: +"Recipient's name: a person, or a department such as Customer Service when writing to a company, e.g. Erika Mustermann." - changed
Input schema / properties / recipient / properties / postal_code / descriptionPrevious value: -"Postcode / ZIP (required in most countries)"New value: +"Postcode / ZIP code, e.g. 10115 or 94105. Required in countries that use postcodes." - changed
Input schema / properties / recipient / properties / region / descriptionPrevious value: -"State / province where the country uses it (e.g. US state code CA)"New value: +"State, province or region. Required for recipients in AE, AS, AU, BR, CA, CN, CO, CR, ES, FM, HK, HN, ID, IN, IQ, IT, JM, JP, KN, KR, KY, MH, MP, MX, NR, PF, PG, PW, RU, SO, SV, TW, US, VE, VI, VN (without it the draft is refused: INVALID_ADDRESS, fields.region); omit where addresses have none, e.g. DE, FR or GB. The code in US, CA, AU and BR, e.g. CA (California) or ON (Ontario); elsewhere the name or its usual abbreviation, e.g. Madrid (ES) or RM (Rome, IT)." - changed
Input schema / properties / references / descriptionPrevious value: -"Lines like 'Customer no. 12345'"New value: +"Up to 5 reference lines printed above the subject, e.g. [\"Customer no. 12345\", \"Contract no. 987\"]. Optional." - changed
Input schema / properties / registered / descriptionPrevious value: -"Registered mail (tracking + signature on delivery), e.g. for cancellations and deadlines"New value: +"true = registered mail: tracking number and signature on delivery, for an extra fee (also what \"certified\" letters, Einschreiben, lettre recommandée and carta certificada mean here; not a US certified-mail product). false = ordinary mail. Default false. Often wanted for cancellations and deadlines." - added
Input schema / properties / sender / properties / city / descriptionAdded value: +"City or town, e.g. Berlin." - changed
Input schema / properties / sender / properties / company / descriptionPrevious value: -"Company or organisation (optional)"New value: +"The user's company or organisation, e.g. Example GmbH. Optional." - changed
Input schema / properties / sender / properties / country / descriptionPrevious value: -"ISO 3166-1 alpha-2 country code, e.g. DE, FR, US"New value: +"Country as an ISO 3166-1 alpha-2 code, e.g. DE, FR or US." - added
Input schema / properties / sender / properties / email / descriptionAdded value: +"The user's email address, printed in the sender block, e.g. max@example.com. Optional." - changed
Input schema / properties / sender / properties / line1 / descriptionPrevious value: -"Street and house number, or PO box"New value: +"Street and house number, or PO box, e.g. Hauptstraße 5." - changed
Input schema / properties / sender / properties / line2 / descriptionPrevious value: -"Additional line: c/o, apartment, building"New value: +"Optional extra address line: c/o, apartment, floor or building, e.g. Apt 4B." - changed
Input schema / properties / sender / properties / name / descriptionPrevious value: -"Recipient (person) name"New value: +"The user's full name, e.g. Max Mustermann." - added
Input schema / properties / sender / properties / phone / descriptionAdded value: +"The user's phone number, printed in the sender block, e.g. +49 30 1234567. Optional." - changed
Input schema / properties / sender / properties / postal_code / descriptionPrevious value: -"Postcode / ZIP (required in most countries)"New value: +"Postcode / ZIP code, e.g. 10115 or 94105. Required in countries that use postcodes." - changed
Input schema / properties / sender / properties / region / descriptionPrevious value: -"State / province where the country uses it (e.g. US state code CA)"New value: +"State, province or region where the user's country has one in addresses, e.g. CA (California, US), ON (Ontario, CA) or Madrid (ES). Optional in the sender block." - changed
Input schema / properties / signature / descriptionPrevious value: -"Name under the closing; defaults to the sender name"New value: +"Name printed under the closing, e.g. Max Mustermann. Default: the sender's name." - added
Input schema / properties / subject / descriptionAdded value: +"Subject line printed above the body, e.g. Cancellation of my contract no. 12345 (up to 200 characters)."
- Changed
create_letter16 fields changed- added
Input schema / properties / color / descriptionAdded value: +"\"bw\" = black and white, \"color\" = colour printing (costs more per page). Default \"bw\"." - added
Input schema / properties / document_id / descriptionAdded value: +"The PDF to post: document_id from upload_document or compose_letter, e.g. doc_2h7k9m4q8x1v3c6b0n5p. Pass document_id or upload_id." - added
Input schema / properties / duplex / descriptionAdded value: +"true = print on both sides of the paper (fewer sheets, so a lighter letter); false = one side only. Default false." - added
Input schema / properties / envelope / descriptionAdded value: +"\"DL\" (220×110 mm, letter folded twice), \"C5\" (229×162 mm, folded once) or \"C4\" (324×229 mm, flat). Omit to use the smallest envelope that holds the sheets (recommended); one too small for the page count is refused." - changed
Input schema / properties / paper_size / descriptionPrevious value: -"Only for a US Letter PDF to a recipient outside US, CA, PR, VI, GU, AS, MP (the US, Canada and US territories): \"a4\" = shrink to A4 (recommended), \"us_letter\" = keep US Letter. Ask the user; same price. Ignored otherwise (A4 PDFs print on A4, US Letter PDFs to those countries on US Letter)."New value: +"Only for a US Letter PDF to a recipient outside US, CA, PR, VI, GU, AS, MP (the US, Canada and US territories): \"a4\" = shrink to A4 (recommended), \"us_letter\" = keep US Letter. Ask the user; same price. Ignored otherwise (A4 PDFs print on A4, US Letter PDFs to those countries on US Letter). No default: omit until the user has chosen." - added
Input schema / properties / recipient / descriptionAdded value: +"Recipient's postal address, printed on the envelope. Ask the user for missing fields." - added
Input schema / properties / recipient / properties / city / descriptionAdded value: +"City or town, e.g. Berlin." - changed
Input schema / properties / recipient / properties / company / descriptionPrevious value: -"Company or organisation (optional)"New value: +"Recipient's company or organisation, e.g. Example GmbH. Optional." - changed
Input schema / properties / recipient / properties / country / descriptionPrevious value: -"ISO 3166-1 alpha-2 country code, e.g. DE, FR, US"New value: +"Country as an ISO 3166-1 alpha-2 code, e.g. DE, FR or US." - changed
Input schema / properties / recipient / properties / line1 / descriptionPrevious value: -"Street and house number, or PO box"New value: +"Street and house number, or PO box, e.g. Hauptstraße 5." - changed
Input schema / properties / recipient / properties / line2 / descriptionPrevious value: -"Additional line: c/o, apartment, building"New value: +"Optional extra address line: c/o, apartment, floor or building, e.g. Apt 4B." - changed
Input schema / properties / recipient / properties / name / descriptionPrevious value: -"Recipient (person) name"New value: +"Recipient's name: a person, or a department such as Customer Service when writing to a company, e.g. Erika Mustermann." - changed
Input schema / properties / recipient / properties / postal_code / descriptionPrevious value: -"Postcode / ZIP (required in most countries)"New value: +"Postcode / ZIP code, e.g. 10115 or 94105. Required in countries that use postcodes." - changed
Input schema / properties / recipient / properties / region / descriptionPrevious value: -"State / province where the country uses it (e.g. US state code CA)"New value: +"State, province or region. Required for recipients in AE, AS, AU, BR, CA, CN, CO, CR, ES, FM, HK, HN, ID, IN, IQ, IT, JM, JP, KN, KR, KY, MH, MP, MX, NR, PF, PG, PW, RU, SO, SV, TW, US, VE, VI, VN (without it the draft is refused: INVALID_ADDRESS, fields.region); omit where addresses have none, e.g. DE, FR or GB. The code in US, CA, AU and BR, e.g. CA (California) or ON (Ontario); elsewhere the name or its usual abbreviation, e.g. Madrid (ES) or RM (Rome, IT)." - changed
Input schema / properties / registered / descriptionPrevious value: -"Registered mail (tracking + signature on delivery)"New value: +"true = registered mail: tracking number and signature on delivery, for an extra fee (also what \"certified\" letters, Einschreiben, lettre recommandée and carta certificada mean here; not a US certified-mail product). false = ordinary mail. Default false." - changed
Input schema / properties / upload_id / descriptionPrevious value: -"From create_upload_link, once the user has uploaded"New value: +"upload_id from create_upload_link, once the user has uploaded the PDF on that page. Pass document_id or upload_id."
- Changed
create_topup_link1 field changed- changed
Input schema / properties / letter_id / descriptionPrevious value: -"Pay this draft letter directly"New value: +"letter_id of a draft, e.g. ltr_8f3k2m9q4x7v1c6b0n5p: the link then pays that letter by card. Omit for a link to add prepaid credit."
- Changed
fix_document_margins2 fields changed- added
Input schema / properties / document_id / descriptionAdded value: +"document_id returned by upload_document or compose_letter, e.g. doc_2h7k9m4q8x1v3c6b0n5p." - changed
Input schema / properties / mode / descriptionPrevious value: -"shrink = scale pages down slightly, nothing lost; crop = keep 100 % size and cut off everything inside the margin (that content is not printed)"New value: +"\"shrink\" = scale pages down slightly, nothing lost; \"crop\" = keep 100 % size and cut off everything inside the margin (that content is not printed). Default \"shrink\"."
- Changed
get_letter2 fields changed- added
Input schema / properties / letter_id / descriptionAdded value: +"letter_id from create_letter, compose_letter or list_letters, e.g. ltr_8f3k2m9q4x7v1c6b0n5p. Pass letter_id or reference." - added
Input schema / properties / reference / descriptionAdded value: +"The letter's reference as shown to the user, format PM-XXXXXX, e.g. PM-7K3QH9. Pass letter_id or reference."
- Changed
get_price_quote8 fields changed- added
Input schema / properties / color / descriptionAdded value: +"\"bw\" = black and white, \"color\" = colour printing (costs more per page). Default \"bw\"." - changed
Input schema / properties / country / descriptionPrevious value: -"Destination ISO country code, e.g. DE"New value: +"Destination country as an ISO 3166-1 alpha-2 code, e.g. DE, FR or US (list_destinations lists them all)." - added
Input schema / properties / currency / descriptionAdded value: +"Currency for the total: \"EUR\", \"USD\", \"GBP\" or \"CHF\". Prices are set in EUR; for USD, GBP or CHF the result adds the total converted at the ECB rate plus a currency margin. Default \"EUR\"." - changed
Input schema / properties / duplex / descriptionPrevious value: -"Double-sided printing"New value: +"true = print on both sides of the paper (fewer sheets, so a lighter letter); false = one side only. Default false." - changed
Input schema / properties / envelope / descriptionPrevious value: -"Omit to use the smallest envelope that fits"New value: +"\"DL\" (220×110 mm, letter folded twice), \"C5\" (229×162 mm, folded once) or \"C4\" (324×229 mm, flat). Omit to use the smallest envelope that holds the sheets (recommended); one too small for the page count is refused." - changed
Input schema / properties / pages / descriptionPrevious value: -"Number of pages in the PDF"New value: +"Number of pages in the PDF, a whole number from 1 to 250, e.g. 2." - changed
Input schema / properties / postal_code / descriptionPrevious value: -"Destination postcode (matters for Spanish/Portuguese islands)"New value: +"Destination postcode, e.g. 07001. Optional: it only changes the price for the Spanish and Portuguese islands and enclaves (Balearic and Canary Islands, Ceuta, Melilla, Madeira, Azores)." - changed
Input schema / properties / registered / descriptionPrevious value: -"Registered mail with tracking and signature on delivery (also for 'certified', Einschreiben, lettre recommandée)"New value: +"true = registered mail: tracking number and signature on delivery, for an extra fee (also what \"certified\" letters, Einschreiben, lettre recommandée and carta certificada mean here; not a US certified-mail product). false = ordinary mail. Default false."
- Changed
list_destinations1 field changed- changed
Input schema / properties / country / descriptionPrevious value: -"ISO code for details of one country"New value: +"ISO 3166-1 alpha-2 code of one country, e.g. DE: returns its zone, 1-page prices and delivery time. Omit to list every destination country."
- Changed
list_letters2 fields changed- added
Input schema / properties / limit / descriptionAdded value: +"How many letters to return, newest first: a whole number from 1 to 50. Default 10." - added
Input schema / properties / status / descriptionAdded value: +"Only letters with this status, e.g. draft or posted. Omit for letters in any status."
- Changed
send_letter4 fields changed- changed
Input schema / properties / confirm / descriptionPrevious value: -"Must be true: the user explicitly confirmed sending this letter"New value: +"Must be true: the user explicitly confirmed sending this letter (recipient, content and total price)." - added
Input schema / properties / letter_id / descriptionAdded value: +"letter_id of the draft the user confirmed, from create_letter or compose_letter, e.g. ltr_8f3k2m9q4x7v1c6b0n5p. Sending charges its total to the user's prepaid credit." - changed
Input schema / properties / paper_size / descriptionPrevious value: -"The user's choice for a US Letter PDF to a recipient outside the US, Canada and US territories: \"a4\" = shrink to A4 (recommended), \"us_letter\" = keep US Letter. Same price. Saved on the draft before paying; ignored for other letters."New value: +"The user's choice for a US Letter PDF to a recipient outside the US, Canada and US territories: \"a4\" = shrink to A4 (recommended), \"us_letter\" = keep US Letter. Same price. Saved on the draft before paying; ignored for other letters. No default: omit unless the user has chosen." - changed
Input schema / properties / user_accepted_terms / descriptionPrevious value: -"Must be true: the user agreed to the Terms and to the immediate start of printing"New value: +"Must be true: the user agreed to the Terms and to the immediate start of printing."
- Changed
upload_document3 fields changed- added
Input schema / properties / file_name / descriptionAdded value: +"Name to store the file under, e.g. cancellation.pdf. Default: the name from the URL, or \"document.pdf\"." - changed
Input schema / properties / pdf_base64 / descriptionPrevious value: -"The PDF as base64, for files up to about 3 MB. Larger files: pass pdf_url, or use create_upload_link."New value: +"The PDF file as base64 (a data:application/pdf;base64, prefix is fine), for files up to about 3 MB. Pass pdf_url or pdf_base64. Larger files: pass pdf_url, or use create_upload_link." - added
Input schema / properties / pdf_url / descriptionAdded value: +"Public https URL of the PDF (A4 or US Letter pages), e.g. https://example.com/letter.pdf. Pass pdf_url or pdf_base64."
2 tool updates
- Changed
create_letter1 field changed- added
Input schema / properties / paper_sizeAdded value: +{ + "description": "Only for a US Letter PDF to a recipient outside US, CA, PR, VI, GU, AS, MP (the US, Canada and US territories): \"a4\" = shrink to A4 (recommended), \"us_letter\" = keep US Letter. Ask the user; same price. Ignored otherwise (A4 PDFs print on A4, US Letter PDFs to those countries on US Letter).", + "enum": [ + "a4", + "us_letter" + ], + "type": "string" +}
- Changed
send_letter1 field changed- added
Input schema / properties / paper_sizeAdded value: +{ + "description": "The user's choice for a US Letter PDF to a recipient outside the US, Canada and US territories: \"a4\" = shrink to A4 (recommended), \"us_letter\" = keep US Letter. Same price. Saved on the draft before paying; ignored for other letters.", + "enum": [ + "a4", + "us_letter" + ], + "type": "string" +}
2 tool updates
- Changed
check_pdf_margins1 field changed- added
Input schema / properties / pdf_base64 / descriptionAdded value: +"The PDF as base64, for files up to about 3 MB. Larger files: pass pdf_url, or use create_upload_link."
- Changed
upload_document1 field changed- added
Input schema / properties / pdf_base64 / descriptionAdded value: +"The PDF as base64, for files up to about 3 MB. Larger files: pass pdf_url, or use create_upload_link."
14 tool updates
- First observed
cancel_letter - First observed
check_pdf_margins - First observed
compose_letter - First observed
create_letter - First observed
create_topup_link - First observed
create_upload_link - First observed
fix_document_margins - First observed
get_balance - First observed
get_letter - First observed
get_price_quote - First observed
list_destinations - First observed
list_letters - First observed
send_letter - First observed
upload_document
Related MCP Connectors
Mail real paper letters (standard, registered, registered with receipt) worldwide. No account.
Send real, printed letters by post across Europe. Requires a free account; quote before sending.
Mail real US letters, postcards and certified mail from an agent, quoted before sending.
Your AI writes letters. We send them as real post to 31 countries, with status and e-mail updates.
Related MCP Servers
- AlicenseAqualityAmaintenanceEnables sending physical letters (including registered mail) from PDFs via the Pingen API, with tools to manage drafts, submit, track, and cancel letters.919 npmMIT
- AlicenseBqualityDmaintenanceCompare parcel and letter delivery prices across 60+ carriers in 27 European countries.1MIT
- FlicenseNot gradedqualityCmaintenanceEnables AI assistants to prepare, price, review, pay for, and send real physical letters and postcards via a hosted MCP server.-
- AlicenseAqualityDmaintenanceSend real physical postcards worldwide via AI agents. Supports single and bulk send (up to 500 recipients), balance checking, delivery tracking, and volume pricing from $0.72/card.5237 npm5MIT
Glama MCP Gateway
Add one secure layer between your agents and this server.