Skip to main content
Glama

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
ERP2PDF_API_KEYYesAPI token from the erp2pdf.com cabinet, issued with "Allow Template API".
ERP2PDF_BASE_URLNoBase URL of the erp2pdf.com deployment to talk to.https://erp2pdf.com
ERP2PDF_OUTPUT_DIRNoWhere `render_preview` saves PDF and PNG previews. Created if missing, readable only by you.~/.cache/erp2pdf-studio-mcp (%LOCALAPPDATA%\erp2pdf-studio-mcp on Windows)

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

CapabilityDetails
tools
{
  "listChanged": false
}
prompts
{
  "listChanged": false
}
resources
{
  "subscribe": false,
  "listChanged": false
}

Tools

Functions exposed to the LLM to take actions

NameDescription
list_modelsA

List the Odoo models a template can bind to (live from the customer's Odoo when a connector is configured, else bundled samples). Use the model value as layout.bind_model.

get_fieldsC

Fields of an Odoo model, plus paths: dotted paths one relation deep (partner_id.name, order_line.price_subtotal). A path with in_table belongs inside a table (repeater) bound to that value, where you write it as row_path (e.g. {{ price_subtotal }}).

search_recordsA

Search real records in the customer's Odoo (needs a configured connector) to pick a record_id for get_values / render_preview.

get_sample_recordD

The record previews are rendered with (real when a connector is configured, else the bundled sample): shows the data shape.

list_templatesA

List the account's templates (id, name, bind_model, slot_count).

get_templateB

Get one template with its full layout and mapping.

create_templateB

Create a template from a Studio layout {bind_model, slots[], master_refs?, translations?}. The layout is validated first; on errors nothing is saved and the errors carry JSON paths.

update_templateA

Change a template. Either send a whole new layout, or edit in place: upsert_slots adds slots or replaces those with the same id, delete_slots removes top-level slots by id, layout_set sets top-level keys such as master_refs or translations (null removes).

delete_templateC

Delete a template.

duplicate_templateC

Copy a template (default name: ' (copy)').

validate_layoutA

Validate a layout without saving: returns {ok, errors[], warnings[], stats}. Each issue has a JSON path (slots[3].row_template[1].content), a code and a message. With evaluate=true every expression is also run against a sample record; runtime failures come back as warnings.

get_valuesA

What every {{ }} expression prints for one record, per slot (slots: path, template, value/error) and per table row (tables). Pass template_id for a saved template or layout for a draft. The cheapest way to check expressions without reading a PDF. language picks formatDate's "short"/"long"/"datetime" presets; timezone (IANA, Europe/Kyiv) is where datetimes print, unless the live record brings the document's own.

render_previewB

Render a preview (PREVIEW watermark, no credits) of a saved template (template_id) or an unsaved layout. output=html returns the HTML inline; pdf/png are saved to a local file and the path is returned (png = page 1). With output=png and show=true (default) the image itself comes back too: look at it to judge the design (alignment, overlaps, clipped text, contrast) and iterate.

list_startersB

Starting points: blank, quotation, invoice, purchase, product, each with the styles it comes in (classic, folder, wave, diagonal, sidebar, bigtotal) and whether a style uses the shared header/footer.

create_from_starterA

Create a template from a starter layout (same as Studio's New template dialog). style picks the look (default classic): folder = light band with a folder tab, wave = dark wave header, diagonal = dark band with a slanted edge, sidebar = coloured column, bigtotal = the amount to pay set large. Every colour is a theme reference, so update_template(layout_set={"theme": {...}}) rebrands it. theme picks a palette and fonts at creation: a palette key ("ocean"), or {"palette": "ocean", "fonts": "editorial", } (list_starters lists presets.palettes and presets.fonts). Classic reuses the shared 'Company header'/'Company footer' parts (created on first use); the bold styles draw their own letterhead. model is only for the blank starter.

get_capabilitiesA

Read this before designing. Everything a layout can hold, from the same rules the validator applies: slot kinds and their keys with types and allowed values (text: letterSpacing, lineHeight, textTransform, valign, bgColor...; image: mask, grayscale; every slot: opacity, shadow, rotation, blendMode), the paint format (hex, theme., or a linear/radial gradient object), the path kind (free vector drawing: viewBox + paths[{d, fill, gradient, stroke, ...}]), page background, theme keys, bundled fonts, page sizes, limits, and ready path_recipes (folder tab, wave, diagonal band, chevron, hexagon, blob, corner arc) to copy into a path slot.

import_svgA

Turn an SVG (a logo, an illustration, a shape drawn elsewhere) into a path slot body: returns {viewBox, paths, warnings, box, keepAspect}. Pass the markup as svg, or path to a local .svg file (max 1 MB). Create the slot as {"kind": "path", "x", "y", "w": box.w, "h": box.h, "viewBox", "keepAspect", "paths"}, or pass w/h for the size you will place it at (stroke widths are in pt for that size). Text, images, filters and masks are dropped and listed in warnings.

preview_starterA

Look at a starter style before creating anything: page 1 on a fixed sample document, re-skinned by a palette and a font pairing (preset keys from list_starters), as an image. Width 240-960 px. Use it to compare styles and palettes with the user, then create_from_starter(starter, name, style=..., theme=palette).

list_partsA

List the shared header/footer parts (templates use them through layout.master_refs = {header: id, footer: id}).

create_partC

Create a header or footer part: {slots[]} in page coordinates (a header near the top, a footer near the bottom of the A4 page).

update_partB

Update a part's name, description and/or layout. Every template that uses the part changes with it.

delete_partA

Delete a part. Refused (part_in_use) while templates use it, unless force=true.

get_translationsA

Every translatable string of a PDF template (kind=pdf, header and footer parts included) or an email template (kind=email: subject and body text), with its translation per target language, a status per language (translated, inherited, override, invalid, missing), glossary suggestions for missing cells and missing counts per language. A string that prints values keeps them as {{ placeholders }}; an email string keeps its inline tags (b, strong, i, em, u, a, span, code, br) as numbered placeholders <1>...</1> and <2/>, listed in placeholders (the element each stands for in tags).

set_translationsA

Translate a template, many languages in one call. translations = {lang: {source string: text}} (lang: de, de_DE, fr_CH...; source strings exactly as get_translations lists them; null deletes a cell). A translation must keep exactly the source's {{ expressions }} and, in an email, its numbered tags <1>...</1>, <2/> (any order, each tag closed after it opens), else nothing is saved and the errors say which. replace=true replaces each language sent as a whole (PUT); default merges (PATCH). fill_from_glossary fills empty cells of the given languages from the built-in glossary. Returns the updated report plus changed and warnings.

list_email_templatesA

List the account's HTML email templates (sent from Odoo by the connector's 'Send by email' wizard).

get_email_templateB

Get one email template: subject, body_html, translations and the record fields it reads.

create_email_templateB

Create an email template. Subject and body use the PDF templates' expressions: {{ expr }} prints a value HTML-escaped, {{{ expr }}} inserts it as cleaned HTML. Use inline styles and tables (email clients). {{ odoo_url }} is the connected Odoo's https address: {{ odoo_url }}/logo.png?company={{ company_id.id }} is the company logo. attach_template_id = a PDF template to attach when sent.

update_email_templateC

Change an email template; only the fields given change. remove_attachment=true stops attaching a PDF.

delete_email_templateD

Delete an email template.

preview_emailA

Render an email for one record: a saved one (email_template_id) or a draft (subject + body_html, optional translations). language (de_DE, fr...) shows it as a customer with that language gets it; timezone (IANA) is where its datetimes print. Returns {subject, html, errors, source, record}; no credits.

Prompts

Interactive templates invoked by user choice

NameDescription

No prompts

Resources

Contextual data attached and managed by the client

NameDescription

No resources

TDQS

B3/5.0

Scored across 30 tools

Disambiguation4/5

The surface splits cleanly into sub-domains (models/records, PDF templates, parts, starters, email templates, translations, preview/validation), and the descriptions explicitly cross-reference which tool to use when. A few boundaries blur: three creation paths (create_template, create_from_starter, duplicate_template) and three preview tools whose names invert verb placement (render_preview vs preview_starter/preview_email) could still cause misselection, as could the family of get_* tools (get_fields, get_capabilities, get_values, get_sample_record), which all mean different kinds of 'get'.

Naming Consistency4/5

Nearly everything is snake_case with a leading verb, and the list_*/get_*/create_*/update_*/delete_* families are uniform across templates, parts, and email templates. The deviation is verb ordering in the preview trio (render_preview vs preview_starter, preview_email) and in create_from_starter, where the verb is followed by a preposition rather than a noun.

Tool Count3/5

At 30 tools this sits above the comfortable band and is heavy for an agent to hold in working memory. The breadth is real (PDF design, shared parts, starters, SVG import, translations, email templates, preview, validation), and nearly every tool maps to a distinct operation, but some could consolidate — e.g. list_starters/preview_starter and create_template/create_from_starter.

Completeness4/5

CRUD is complete for PDF templates, shared parts, and email templates, and the design loop is closed by validate_layout, get_values, render_preview, and preview_email. Minor gaps remain: there is no get_part for fetching a single part, no duplicate for email templates, and no tool to inspect or edit existing translations per-cell beyond the bulk get/set pair, but these are workable.

Maintenance

ActivityMaintained
ResponsivenessNo recent community issues