Skip to main content
Glama
cmendezs

mcp-fattura-elettronica-it

validate_cedente_prestatore

Validates seller (CedentePrestatore) data for FatturaPA invoices: ensures valid name, fiscal regime code, and Italian VAT format. Outputs block for XML or error list.

Instructions

Validate and build the CedentePrestatore (seller) block for FatturaPA.

Use this as step 4 in the invoice generation workflow, after build_transmission_header() and before validate_cessionario(). Call get_regime_fiscale_codes() first if you need to look up the RF code.

Validates: either denominazione or both nome+cognome must be provided (mutually exclusive); regime_fiscale must be a valid RF01–RF19 code; Italian Partita IVA (id_paese='IT') must be exactly 11 digits.

On success returns {'CedentePrestatore': {...}} ready to pass to generate_fattura_xml(). On failure returns {'error': ''} listing all validation issues joined by '; '.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
id_paeseYesISO 3166-1 two-letter country code of the seller (e.g. 'IT').
id_codiceYesPartita IVA (11 digits) or foreign VAT number of the seller.
denominazioneNoCompany name (Denominazione). Mutually exclusive with nome+cognome.
nomeNoFirst name (Nome), for individual sellers.
cognomeNoLast name (Cognome), for individual sellers.
regime_fiscaleNoFiscal regime code RF01–RF19. Use get_regime_fiscale_codes() for the complete list. Most companies use RF01 (ordinary regime).RF01
indirizzoNoStreet address (via, piazza…) of the registered office.
capNoItalian postal code (5 digits) or foreign equivalent.
comuneNoCity/municipality of the registered office.
nazioneNoISO 3166-1 two-letter country code of the registered office.IT

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault

No arguments

Implementation Reference

  • Main handler for validate_cedente_prestatore — validates seller (CedentePrestatore) block: checks denominazione vs nome+cognome mutual exclusivity, regime_fiscale validity against REGIME_FISCALE dict, Italian Partita IVA must be 11 digits, returns structured CedentePrestatore dict or error.
    def validate_cedente_prestatore(
        id_paese: Annotated[
            str,
            Field(description="ISO 3166-1 two-letter country code of the seller (e.g. 'IT')."),
        ],
        id_codice: Annotated[
            str,
            Field(description="Partita IVA (11 digits) or foreign VAT number of the seller."),
        ],
        denominazione: Annotated[
            Optional[str],
            Field(
                default=None,
                description="Company name (Denominazione). Mutually exclusive with nome+cognome.",
            ),
        ] = None,
        nome: Annotated[
            Optional[str],
            Field(default=None, description="First name (Nome), for individual sellers."),
        ] = None,
        cognome: Annotated[
            Optional[str],
            Field(default=None, description="Last name (Cognome), for individual sellers."),
        ] = None,
        regime_fiscale: Annotated[
            str,
            Field(
                description=(
                    "Fiscal regime code RF01–RF19. Use get_regime_fiscale_codes() for the "
                    "complete list. Most companies use RF01 (ordinary regime)."
                )
            ),
        ] = "RF01",
        indirizzo: Annotated[
            str,
            Field(description="Street address (via, piazza…) of the registered office."),
        ] = "",
        cap: Annotated[
            str,
            Field(description="Italian postal code (5 digits) or foreign equivalent."),
        ] = "",
        comune: Annotated[
            str,
            Field(description="City/municipality of the registered office."),
        ] = "",
        nazione: Annotated[
            str,
            Field(description="ISO 3166-1 two-letter country code of the registered office."),
        ] = "IT",
    ) -> dict:
        """Validate and build the CedentePrestatore (seller) block for FatturaPA.
    
        Use this as step 4 in the invoice generation workflow, after
        build_transmission_header() and before validate_cessionario().
        Call get_regime_fiscale_codes() first if you need to look up the RF code.
    
        Validates: either denominazione or both nome+cognome must be provided (mutually
        exclusive); regime_fiscale must be a valid RF01–RF19 code; Italian Partita IVA
        (id_paese='IT') must be exactly 11 digits.
    
        On success returns {'CedentePrestatore': {...}} ready to pass to generate_fattura_xml().
        On failure returns {'error': '<reason>'} listing all validation issues joined by '; '.
        """
        errors: list[str] = []
    
        if not denominazione and not (nome and cognome):
            errors.append("Either 'denominazione' or both 'nome' and 'cognome' are required.")
    
        if denominazione and (nome or cognome):
            errors.append("'denominazione' is mutually exclusive with 'nome'/'cognome'.")
    
        if regime_fiscale not in REGIME_FISCALE:
            errors.append(
                f"Invalid regime_fiscale '{regime_fiscale}'. "
                f"Valid codes: {', '.join(REGIME_FISCALE.keys())}."
            )
    
        if id_paese == "IT" and not re.match(r"^\d{11}$", id_codice):
            errors.append("Italian Partita IVA must be exactly 11 digits.")
    
        if errors:
            return {"error": "; ".join(errors)}
    
        anagrafica: dict = {}
        if denominazione:
            anagrafica["Denominazione"] = denominazione
        else:
            anagrafica["Nome"] = nome
            anagrafica["Cognome"] = cognome
    
        return {
            "CedentePrestatore": {
                "DatiAnagrafici": {
                    "IdFiscaleIVA": {"IdPaese": id_paese.upper(), "IdCodice": id_codice},
                    "Anagrafica": anagrafica,
                    "RegimeFiscale": regime_fiscale,
                },
                "Sede": {
                    "Indirizzo": indirizzo,
                    "CAP": cap,
                    "Comune": comune,
                    "Nazione": nazione.upper(),
                },
            }
        }
  • Pydantic Field-based input schema for the tool — defines parameters: id_paese, id_codice, denominazione, nome, cognome, regime_fiscale, indirizzo, cap, comune, nazione with descriptions and defaults.
    def validate_cedente_prestatore(
        id_paese: Annotated[
            str,
            Field(description="ISO 3166-1 two-letter country code of the seller (e.g. 'IT')."),
        ],
        id_codice: Annotated[
            str,
            Field(description="Partita IVA (11 digits) or foreign VAT number of the seller."),
        ],
        denominazione: Annotated[
            Optional[str],
            Field(
                default=None,
                description="Company name (Denominazione). Mutually exclusive with nome+cognome.",
            ),
        ] = None,
        nome: Annotated[
            Optional[str],
            Field(default=None, description="First name (Nome), for individual sellers."),
        ] = None,
        cognome: Annotated[
            Optional[str],
            Field(default=None, description="Last name (Cognome), for individual sellers."),
        ] = None,
        regime_fiscale: Annotated[
            str,
            Field(
                description=(
                    "Fiscal regime code RF01–RF19. Use get_regime_fiscale_codes() for the "
                    "complete list. Most companies use RF01 (ordinary regime)."
                )
            ),
        ] = "RF01",
        indirizzo: Annotated[
            str,
            Field(description="Street address (via, piazza…) of the registered office."),
        ] = "",
        cap: Annotated[
            str,
            Field(description="Italian postal code (5 digits) or foreign equivalent."),
        ] = "",
        comune: Annotated[
            str,
            Field(description="City/municipality of the registered office."),
        ] = "",
        nazione: Annotated[
            str,
            Field(description="ISO 3166-1 two-letter country code of the registered office."),
        ] = "IT",
    ) -> dict:
  • The function register_header_tools() that registers the tool via @mcp.tool() decorator on FastMCP instance.
    def register_header_tools(mcp: FastMCP) -> None:
        """Register the 7 FatturaElettronicaHeader tools on the FastMCP instance."""
  • REGIME_FISCALE constant dictionary mapping RF01–RF19 codes to descriptions, used for validating the regime_fiscale parameter.
    REGIME_FISCALE: dict[str, str] = {
        "RF01": "Regime ordinario",
        "RF02": "Regime contribuenti minimi (art. 1, c.96-117, L. 244/2007)",
        "RF04": "Agricoltura e attività connesse e pesca (artt. 34 e 34-bis, DPR 633/72)",
        "RF05": "Vendita sali e tabacchi (art. 74, c.1, DPR. 633/72)",
        "RF06": "Commercio fiammiferi (art. 74, c.1, DPR. 633/72)",
        "RF07": "Editoria (art. 74, c.1, DPR. 633/72)",
        "RF08": "Gestione servizi telefonia pubblica (art. 74, c.1, DPR. 633/72)",
        "RF09": "Rivendita documenti di trasporto pubblico e di sosta (art. 74, c.1, DPR. 633/72)",
        "RF10": "Intrattenimenti, giochi e altre attività (art. 74, c.6, DPR. 633/72)",
        "RF11": "Agenzie viaggi e turismo (art. 74-ter, DPR. 633/72)",
        "RF12": "Agriturismo (art. 5, c.2, L. 413/91)",
        "RF13": "Vendite a domicilio (art. 25-bis, c.6, DPR. 600/73)",
        "RF14": "Rivendita beni usati, oggetti d'arte, d'antiquariato o da collezione (art. 36, DL 41/95)",
        "RF15": "Agenzie di vendite all'asta di oggetti d'arte, antiquariato o da collezione (art. 40-bis, DL 41/95)",
        "RF16": "IVA per cassa P.A. (art. 6, c.5, DPR. 633/72)",
        "RF17": "IVA per cassa (art. 32-bis, DL 83/2012)",
        "RF18": "Altro",
        "RF19": "Regime forfettario (art. 1, c.54-89, L. 190/2014)",
    }
  • server.py:83-85 (registration)
    Top-level registration call: register_header_tools(mcp) invoked in server.py entry point.
    register_header_tools(mcp)
    register_body_tools(mcp)
    register_global_tools(mcp)
Behavior4/5

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

With no annotations, the description covers key behaviors: specifies validation rules (mutual exclusivity, regime code range, Partita IVA length) and return format (success dict or error with reasons). Lacks mention of side effects but validation tools are typically side-effect free.

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

Conciseness5/5

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

The description is well-structured: opens with purpose, then workflow placement, validation rules, and return format. Every sentence is informative and concise.

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

Completeness5/5

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

Given 10 parameters and output schema existence, the description adequately covers workflow context, validation logic, and error handling, making it complete for agent use.

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

Parameters4/5

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

Schema coverage is 100%, baseline 3. The description adds value by explaining mutual exclusivity of denominazione vs nome+cognome, regime_fiscale code format, and default values, which go beyond schema descriptions.

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

Purpose5/5

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

The description clearly states the tool validates and builds the CedentePrestatore (seller) block for FatturaPA, specifying it's for sellers and distinguishing it from sibling validate_cessionario.

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?

It explicitly provides workflow context: step 4 after build_transmission_header and before validate_cessionario, and recommends calling get_regime_fiscale_codes() first if needed.

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

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/cmendezs/mcp-fattura-elettronica-it'

If you have feedback or need assistance with the MCP directory API, please join our Discord server