Skip to main content
Glama
cmendezs

mcp-facturacion-electronica-es

es__get_compliance_status

Retrieve current electronic invoicing compliance deadlines and operating system for a Spanish company profile based on entity type, province, turnover, and SII status.

Instructions

Devuelve los plazos de mandato vigentes y el sistema operativo para un perfil de empresa. Refleja el RD-ley 15/2025 — sujeto a cambios por legislación posterior.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
entity_typeYesTipo de obligado tributario.
province_codeYesCódigo de provincia INE de dos dígitos.
annual_turnover_eurNoVolumen anual de operaciones IVA en EUR (para umbral SII > €6M).
enrolled_in_siiNoInscripción en el SII.

Implementation Reference

  • Tool definition (schema) for 'es__get_compliance_status' — defines name, description, and inputSchema with parameters entity_type, province_code, annual_turnover_eur, and enrolled_in_sii.
    TOOL_ES_GET_COMPLIANCE_STATUS = types.Tool(
        name="es__get_compliance_status",
        description=(
            "Devuelve los plazos de mandato vigentes y el sistema operativo para un perfil de empresa. "
            "Refleja el RD-ley 15/2025 — sujeto a cambios por legislación posterior."
        ),
        inputSchema={
            "type": "object",
            "properties": {
                "entity_type": {
                    "type": "string",
                    "enum": ["IS", "IRPF"],
                    "description": "Tipo de obligado tributario.",
                },
                "province_code": {
                    "type": "string",
                    "description": "Código de provincia INE de dos dígitos.",
                    "pattern": "^[0-9]{1,2}$",
                },
                "annual_turnover_eur": {
                    "type": "number",
                    "description": "Volumen anual de operaciones IVA en EUR (para umbral SII > €6M).",
                },
                "enrolled_in_sii": {
                    "type": "boolean",
                    "description": "Inscripción en el SII.",
                    "default": False,
                },
            },
            "required": ["entity_type", "province_code"],
        },
    )
  • Handler function 'handle_es_get_compliance_status' — determines mandate deadlines and applicable e-invoicing systems (Facturae/FACe, Crea y Crece B2B, TicketBAI, NaTicket, SII, VERI*FACTU) for a company profile based on entity type, province code, turnover, and SII enrolment. Calls _detect_regime and uses _MANDATE_DATES constants.
    async def handle_es_get_compliance_status(
        arguments: dict[str, Any],
    ) -> list[types.TextContent]:
        """Return mandate deadlines and applicable systems for a company profile."""
        try:
            entity_type_str = arguments.get("entity_type", "IS")
            province_code = str(arguments.get("province_code", "28")).strip()
            turnover = arguments.get("annual_turnover_eur")
            enrolled = bool(arguments.get("enrolled_in_sii", False))
    
            try:
                entity_type = EntityType(entity_type_str)
            except ValueError:
                return err(f"Invalid entity_type: {entity_type_str!r}. Must be 'IS' or 'IRPF'.")
    
            regime = _detect_regime(province_code, enrolled, annual_turnover_eur=turnover)
    
            applicable_systems: list[dict[str, Any]] = []
    
            # Facturae/FACe always applies for B2G
            applicable_systems.append({
                "system": "Facturae / FACe",
                "scope": "B2G (facturas al sector público)",
                **_MANDATE_DATES["FACTURAE_FACE"],
            })
    
            # Crea y Crece B2B (pending decree)
            applicable_systems.append({
                "system": "Crea y Crece B2B",
                "scope": "B2B (todas las empresas)",
                **_MANDATE_DATES["B2B_CREA_Y_CRECE"],
            })
    
            # Regime-specific system
            if regime == SpanishRegime.TICKETBAI:
                applicable_systems.append({
                    "scope": "Todas las facturas (sustituye a VERI*FACTU en el País Vasco)",
                    **_MANDATE_DATES["TICKETBAI"],
                })
            elif regime == SpanishRegime.NATICKET:
                applicable_systems.append({
                    "scope": "Todas las facturas en Navarra",
                    **_MANDATE_DATES["NATICKET"],
                })
            elif regime == SpanishRegime.VERIFACTU_SII:
                applicable_systems.append({
                    "scope": "Grandes empresas / grupos IVA / REDEME",
                    **_MANDATE_DATES["SII"],
                })
            else:
                # VERIFACTU
                key = "VERIFACTU_IS" if entity_type == EntityType.IS else "VERIFACTU_IRPF"
                applicable_systems.append({
                    "scope": (
                        "Impuesto sobre Sociedades"
                        if entity_type == EntityType.IS
                        else "IRPF / autónomos y otros no-SII"
                    ),
                    **_MANDATE_DATES[key],
                })
    
            result: dict[str, Any] = {
                "entity_type": entity_type.value,
                "province_code": province_code,
                "enrolled_in_sii": enrolled,
                "detected_regime": regime.value,
                "applicable_systems": applicable_systems,
                "disclaimer": (
                    "Fechas de mandato según RD-ley 15/2025 (diciembre 2025). "
                    "Sujetas a cambios por legislación posterior o instrucciones de la AEAT. "
                    "Este software no constituye asesoramiento jurídico ni fiscal."
                ),
            }
            if turnover is not None:
                result["annual_turnover_eur"] = turnover
                if turnover > _SII_TURNOVER_THRESHOLD_EUR:
                    result["sii_threshold_note"] = (
                        f"Facturación ({turnover:,.2f} EUR) supera el umbral SII (€6M). "
                        "Considere inscripción voluntaria en el SII."
                    )
    
            return ok(result)
    
        except Exception as exc:
            logger.exception("es__get_compliance_status failed")
            return err(str(exc))
  • Tool handler registration mapping: 'es__get_compliance_status' is mapped to 'handle_es_get_compliance_status' in the _TOOL_HANDLERS dictionary within server.py.
    _TOOL_HANDLERS: dict[str, Any] = {
        # VERI*FACTU
        "es__generate_verifactu_record":      handle_es_generate_verifactu_record,
        "es__validate_verifactu_record":      handle_es_validate_verifactu_record,
        "es__submit_verifactu_to_aeat":       handle_es_submit_verifactu_to_aeat,
        "es__generate_qr_verifactu":          handle_es_generate_qr_verifactu,
        "es__cancel_verifactu_record":        handle_es_cancel_verifactu_record,
        # Facturae / FACe
        "es__generate_facturae_xml":          handle_es_generate_facturae_xml,
        "es__sign_facturae_xades":            handle_es_sign_facturae_xades,
        "es__submit_to_face":                 handle_es_submit_to_face,
        "es__get_face_invoice_status":        handle_es_get_face_invoice_status,
        "es__validate_facturae_schema":       handle_es_validate_facturae_schema,
        # SII
        "es__build_sii_invoice_record":       handle_es_build_sii_invoice_record,
        "es__submit_sii_batch":               handle_es_submit_sii_batch,
        "es__query_sii_status":               handle_es_query_sii_status,
        "es__generate_sii_correction":        handle_es_generate_sii_correction,
        # TicketBAI
        "es__generate_ticketbai_xml":         handle_es_generate_ticketbai_xml,
        "es__submit_ticketbai":               handle_es_submit_ticketbai,
        "es__validate_ticketbai_schema":      handle_es_validate_ticketbai_schema,
        # Crea y Crece / B2B
        "es__generate_b2b_einvoice_es":       handle_es_generate_b2b_einvoice_es,
        "es__check_b2b_mandate_applicability": handle_es_check_b2b_mandate_applicability,
        # Utilities
        "es__detect_regional_regime":         handle_es_detect_regional_regime,
        "es__get_compliance_status":          handle_es_get_compliance_status,
        "es__parse_aeat_response":            handle_es_parse_aeat_response,
    }
  • Helper function '_detect_regime' — pure-logic regime detection from province code, SII enrolment, and turnover. Used by the compliance status handler to determine the applicable regime.
    def _detect_regime(
        province_code: str,
        enrolled_in_sii: bool,
        annual_turnover_eur: float | None = None,
    ) -> SpanishRegime:
        """Pure-logic regime detection from province code and SII enrolment."""
        code = str(province_code).strip().zfill(2)
        if code in _TICKETBAI_INE_CODES:
            return SpanishRegime.TICKETBAI
        if code == _NATICKET_INE_CODE:
            return SpanishRegime.NATICKET
        if enrolled_in_sii:
            return SpanishRegime.VERIFACTU_SII
        if annual_turnover_eur is not None and annual_turnover_eur > _SII_TURNOVER_THRESHOLD_EUR:
            # Large turnover may trigger voluntary SII; regime is still VERIFACTU
            # until formally enrolled (enrollment is what triggers the exclusion)
            pass
        return SpanishRegime.VERIFACTU
  • Helper constants '_MANDATE_DATES' — maps system keys to deadline info (system name, deadline date, description) for all six systems (VERIFACTU_IS, VERIFACTU_IRPF, SII, FACTURAE_FACE, TICKETBAI, NATICKET, B2B_CREA_Y_CRECE). Used by the handler.
    _MANDATE_DATES: dict[str, dict[str, str]] = {
        "VERIFACTU_IS": {
            "system": "VERI*FACTU",
            "deadline": "2027-01-01",
            "description": (
                "Obligatorio para contribuyentes del Impuesto sobre Sociedades (IS) "
                "desde el 1 de enero de 2027 (RD-ley 15/2025)."
            ),
        },
        "VERIFACTU_IRPF": {
            "system": "VERI*FACTU",
            "deadline": "2027-07-01",
            "description": (
                "Obligatorio para autónomos en régimen de IRPF y otros obligados no-SII "
                "desde el 1 de julio de 2027 (RD-ley 15/2025)."
            ),
        },
        "SII": {
            "system": "SII",
            "deadline": "already_mandatory",
            "description": (
                "Ya obligatorio para grandes empresas (facturación > €6M), "
                "grupos de IVA y REDEME (RD 596/2016). "
                "Excluye la obligación de VERI*FACTU (RD 254/2025)."
            ),
        },
        "FACTURAE_FACE": {
            "system": "Facturae / FACe",
            "deadline": "already_mandatory",
            "description": (
                "Ya obligatorio para todos los proveedores del sector público "
                "desde 2015 (Ley 25/2013)."
            ),
        },
        "TICKETBAI": {
            "system": "TicketBAI",
            "deadline": "already_mandatory",
            "description": (
                "Ya obligatorio en el País Vasco (Álava, Gipuzkoa, Bizkaia) "
                "con implantación sectorial escalonada entre 2022 y 2023."
            ),
        },
        "NATICKET": {
            "system": "NaTicket",
            "deadline": "rolling",
            "description": (
                "Mandato foral de la Hacienda Foral de Navarra con implantación escalonada. "
                "VERI*FACTU no aplica en Navarra."
            ),
        },
        "B2B_CREA_Y_CRECE": {
            "system": "Crea y Crece B2B",
            "deadline": "pending_decree",
            "description": (
                "Reglamento de desarrollo de la Ley 18/2022 pendiente de publicación. "
                "El umbral y el calendario definitivos están por determinar."
            ),
        },
    }
Behavior2/5

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

No annotations are provided, so the description carries full burden. It only states what the tool returns and references a law, but fails to disclose behavioral traits such as read-only nature, authentication requirements, or rate limits. The description is too brief to cover transparency needs.

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 extremely concise with two sentences, no unnecessary words, and prioritizes the core purpose. 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?

Given the lack of annotations and output schema, the description is relatively complete for a simple getter. It explains the returned data and cites legal context. However, it could mention if any return values are conditional, but overall it is satisfactory.

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?

All 4 parameters have descriptions in the input schema (100% coverage). The description adds no additional meaning beyond what the schema provides; it only repeats the overall purpose. Baseline score of 3 is appropriate.

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 returns 'mandate terms and operating system' for a company profile, using a specific verb ('Devuelve') and resource ('plazos de mandato vigentes y sistema operativo'). It is distinct from sibling tools, which are primarily submission, generation, or validation tools.

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

Usage Guidelines3/5

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

The description provides no explicit guidance on when to use this tool versus alternatives, or any prerequisites. While the purpose is clear, there is no mention of context or exclusions, making it merely implied.

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-facturacion-electronica-es'

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