InvoicePDFs MCP Server
OfficialServer Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| INVOICEPDFS_API_KEY | Yes | Your InvoicePDFs API key, created at https://invoicepdfs.com. Any key can do anything your account can, including deleting data. | |
| INVOICEPDFS_BASE_URL | No | Overrides the API host if you are pointing at a local server. |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| document_renderA | Render a document supplied inline, storing nothing but the PDF. The stateless path: pass the whole document in the body and get a PDF back,
with no customer, business profile or stored document required. To render a
document that already lives here, use Returns JSON with a signed This tool renders asynchronously and waits for the result, so it returns the finished render rather than a queued one. Rendering is CPU-bound and served by a single worker: prefer one call at a time over starting many renders in parallel. |
| document_render_storedA | Render a stored document to a PDF. Use this when the document lives here. To render one you hold yourself,
without storing it, use The response carries a signed |
| document_get_renderA | One render: its status, its totals, and how to download it.
|
| document_download_renderA | Fetch the PDF, by signature or by API key. Two ways in, and the signature is checked first — before the row is looked up — so a forged token cannot be used to tell a real render id from an invented one. It also means the token path costs no auth work at all, which matters because this is the one endpoint a browser hits directly. |
| document_calculateA | Compute the totals for a document without storing or rendering it. Returns the same breakdown — subtotal, discounts, tax, shipping, total — that a render would print, so a checkout page can show a figure before committing to one. |
| document_validateA | Check that a document body is well-formed, without pricing it. The cheapest of the three stateless operations: no totals are computed and no
PDF is produced. Use |
| document_createC | Create a document in Totals are computed and stored at creation, so the figures you read back are
the ones that were issued rather than a recalculation. Nothing is rendered —
use |
| document_getC | One document, with the totals stored when it was created. |
| document_listA | Every document on the account, newest first. Cursor-paginated: pass the |
| document_updateA | Change a document that is still a A finalized document is a record of what was issued and cannot be edited;
|
| document_duplicateA | Copy a document into a new The copy gets the next available number rather than the original's, so it can be finalized without colliding with the document it came from. |
| document_sendA | Queue the document to be emailed, with its PDF attached. The document must be finalized; sending a draft is a 409. Returns 202 with the delivery in |
| compliance_checkA | Check a document against an e-invoicing ruleset without rendering it. Costs no renders: nothing is stored and no PDF is produced, so a caller can check every invoice they are about to send rather than discovering the problem from a rejection weeks later. Two tiers run, and both are reported. The mandatory-field check names a field of the request you can go and change. Schematron then serializes the document and runs the published rules at a pinned version over the result — the same artefacts an access point runs — so a finding here quotes the rule id a rejection notice would quote. Read |
| compliance_xmlA | The e-invoicing XML for a document, without storing anything. Takes the same body as The syntax is not a parameter. It follows from the profile, because a profile already is a syntax plus a ruleset, and asking a caller for both is asking them to know that Peppol means UBL. |
| customer_listC | The people and companies you bill, newest first. Cursor-paginated. A customer is optional — the stateless render endpoints take a buyer inline — but storing one lets a document reference it by id. |
| customer_createB | Store a customer you can bill repeatedly.
|
| customer_getD | One stored customer. |
| customer_updateA | Change a stored customer. Only the fields you send are changed — omit one to leave it alone, send
|
| business_profile_listC | The identities you issue documents as, newest first. One per entity you bill from — a business with two trading names or two tax registrations needs two. For how documents look rather than who issues them, see the branding profiles. |
| business_profile_createB | Create an identity to issue documents as: the seller side.
|
| template_listA | The built-in templates every account can render with. Your own designs are listed separately by |
| recurring_createB | Set up a schedule that issues invoices on its own. Starts |
| recurring_listA | The schedules on this account, newest first. These are the recurring definitions, not the invoices they produce; for
those, use |
| recurring_pauseA | Stop a schedule issuing invoices, for now. Only an |
| recurring_resumeA | Start a paused schedule issuing again. Only a |
| recurring_cancelA | End a schedule permanently. Terminal: it cannot be resumed or edited afterwards, and cancelling twice
is refused with 409. To stop issuing temporarily, use
Invoices already issued are left alone. |
| recurring_generatedA | The invoices one schedule has actually issued, newest first. The documents produced by this schedule, as opposed to
|
| document_transitionA | Move a document through its lifecycle.
Each transition is only valid from certain states and is refused with 409 otherwise. To actually email a document to its customer, use |
| find_operationA | Search every InvoicePDFs API operation by what it does, and get back the full input schema of each match. Use this when no tool above covers what you need — most of the API is reachable this way. |
| call_operationB | Run any operation returned by find_operation, by name. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
TDQS
Scored across 30 tools
Most tools target a distinct resource+action, but a cluster of stateless operations (document_render, document_render_stored, document_calculate, document_validate, compliance_check, compliance_xml) all act on a document body and overlap conceptually, and document_send vs document_transition-to-'sent' needs the description to separate. The problem is compounded because descriptions point to tools that don't exist under those names (create_document_render, render_document, list_generated_invoices), which will actively mislead selection.
The tool names themselves mostly follow a consistent noun_verb pattern (document_create, customer_list, recurring_pause), which is readable. However, the descriptions repeatedly reference aliases that are not the actual tool names (render_document, calculate_document, resume_recurring_invoice, list_recurring_invoices), so the naming is not self-consistent across names and docs.
At 30 tools this is heavy for the scope, pushing past the point where an agent can comfortably scan the set. While the invoicing domain is genuinely broad, several render/validate/compliance variants and a generic find_operation/call_operation escape hatch could likely be consolidated.
Core lifecycle is well covered: document create/get/list/update/duplicate/transition, customers, recurring schedules, rendering, sending, and compliance. There are minor gaps (no customer or business_profile delete, business_profile only list/create, templates only list), but the find_operation/call_operation pair provides an escape hatch to the rest of the API.