Skip to main content
Glama
BeeL MCP server

BeeL MCP server

Official
by beel-es

beel_get_invoice_pdf

Read-onlyIdempotent

Retrieves a temporary pre-signed URL to download an issued invoice PDF, waiting up to 10 seconds for asynchronous generation so you can download it without polling.

Instructions

Returns a temporary pre-signed URL to download the invoice PDF.

  • URL: expires in five minutes and only allows GET.

  • Waiting: a PDF is produced asynchronously, so this request waits for it (up to ten seconds) instead of handing you a polling loop to write. Bound the wait with Prefer: wait=N, or opt out with Prefer: wait=0.

  • 202: only when the wait elapsed with the PDF still in flight. No body is returned; ask again after Retry-After.

  • Drafts: a draft has no fiscal PDF and answers 400 INVOICE_NOT_ISSUED_NO_PDF immediately — that one never waits. Issue it, or render it with GET …/{invoice_id}/pdf/preview.

  • Not registered with the AEAT: under VeriFactu the PDF carries the QR code of the invoice's registration. An invoice whose registration was rejected before reaching the AEAT, or that was voided without ever being registered, has no PDF and answers 400 INVOICE_NOT_REGISTERED_NO_PDF immediately. Its verifactu.error_message says why.

  • Never modified: the PDF of an issued invoice is generated once — with its VeriFactu QR when it applies — and stays the document you delivered. Voiding the invoice or issuing a corrective against it does not change the PDF: read the invoice's status to know it.

BeeL API endpoint: GET /v1/companies/{company_id}/invoices/{invoice_id}/pdf (reference: https://docs.beel.es)

Tool call template

Replace each placeholder with a value matching the input schema. Only required parameters are included; add optional parameters as needed.

{
  "id": 1,
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "arguments": {
      "company_id": "<company_id>",
      "invoice_id": "<invoice_id>"
    },
    "name": "beel_get_invoice_pdf"
  }
}

Input Schema

NameRequiredDescriptionDefault
company_idYesUnique identifier (UUID) of the company the operation acts on — its identifier, not its NIF. It is the only source of context: the account that owns it is derived from it, and the `BeeL-Active-Company` header plays no part. A company you do not reach answers `403`, and so does a company that does not exist, so the existence of a company in another account is never disclosed.
invoice_idYesInvoice ID

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changedv0.10.0
    • addedInput schema / properties / invoice_id / type
      Added value: +"string"
  2. Changed3 schema fields changedv0.5.0
    • removedInput schema / $defs / UUID / example
      Removed value: -"550e8400-e29b-41d4-a716-446655440000"
    • addedInput schema / additionalProperties
      Added value: +false
    • changedInput schema / properties / company_id / description
      Previous value: -"NIF (company) the operation acts on. It is the only source of context: the account that owns it is derived from it, and the `BeeL-Active-Company` header plays no part. A NIF you do not reach answers `403`, and so does a NIF that does not exist, so the existence of a NIF in another account is never disclosed."New value: +"Unique identifier (UUID) of the company the operation acts on — its identifier, not its NIF. It is the only source of context: the account that owns it is derived from it, and the `BeeL-Active-Company` header plays no part. A company you do not reach answers `403`, and so does a company that does not exist, so the existence of a company in another account is never disclosed."
  3. First observedv0.3.1

TDQS

A4.1/5.0
Behavior3/5

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

Even though annotations already declare readOnly/idempotent/non-destructive, the description adds substantial behavioral context: 5-minute URL expiry, GET-only, an async generation that blocks up to ten seconds, a 202-with-Retry-After outcome, two specific 400 error codes, and the fact that the PDF is generated once and never changes after voiding or corrections. That is rich disclosure beyond the annotations, so it sits above the midpoint; the small deduction is for the `Prefer: wait` header not appearing in the schema at all. The description still doesn't say what the response body looks like, but the URL contract matters more here and is covered.

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

Conciseness4/5

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

Front-loads the core answer in one sentence, then uses bolded labels (URL, Waiting, 202, Drafts, Not registered with the AEAT, Never modified) so each bullet maps to one failure mode or trait. It is on the long side for a two-parameter read, and the wait/202 material could be trimmed slightly, but almost every sentence earns its place.

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

Completeness4/5

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

There is no output schema, so the description correctly supplies the return contract itself: a temporary pre-signed URL, its five-minute lifetime, and its GET-only restriction. Combined with the 400/202/Retry-After paths, an agent has everything it needs to call and handle the result. The gap is minor: with `additionalProperties: false`, it never states how the `Prefer: wait` header is actually transmitted.

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

Parameters3/5

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

Schema coverage is 100%, so both `company_id` and `invoice_id` are already documented in the schema, including the 403 behavior for out-of-scope companies. The description adds nothing about either parameter. The one behavioral knob it does document, `Prefer: wait`, is an HTTP header rather than an input property, and the schema declares `additionalProperties: false`, so the agent has to assume the header is handled out-of-band. With the schema carrying the parameter weight, baseline 3 applies.

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

Purpose5/5

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

Opens with a specific verb and resource: 'Returns a temporary pre-signed URL to download the invoice PDF.' An agent can immediately tell this apart from sibling readers like beel_get_invoice (metadata) and beel_get_invoice_preview (rendering of drafts), and the distinction is made explicit in the Drafts bullet.

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

Usage Guidelines5/5

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

Gives concrete when-to-use and when-not-to-use rules: drafts answer 400 INVOICE_NOT_ISSUED_NO_PDF and should be issued or rendered via the preview endpoint instead; unregistered invoices answer 400 INVOICE_NOT_REGISTERED_NO_PDF. It also tells the agent how to control waiting via `Prefer: wait=N` or `wait=0`, so no inference is required.

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

Deploy Server

Other Tools