Skip to main content
Glama
cmendezs

mcp-facturacion-electronica-es

es__get_face_invoice_status

Check the processing status of an invoice in FACe by providing its registration number. Retrieve codes for registered, recognized, rejected, or paid.

Instructions

Consulta el estado de tramitación de una factura en FACe. Códigos: 1200 Registrada, 2400 Reconocida, 3100 Rechazada, 4100 Pagada.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
invoice_idYesNúmero de registro FACe.

Implementation Reference

  • The handler function that executes the es__get_face_invoice_status tool logic. Retrieves OAuth2 config from env vars (FACE_CLIENT_ID, FACE_CLIENT_SECRET, FACE_ENV), instantiates a BaseEInvoicingClient, makes a GET request to /facturas/{invoice_id}, and maps FACe status codes (1200=Registrada, 2400=Reconocida, 3100=Rechazada, 4100=Pagada).
    async def handle_es_get_face_invoice_status(
        arguments: dict[str, Any],
    ) -> list[types.TextContent]:
        try:
            from mcp_einvoicing_core.http_client import AuthMode, BaseEInvoicingClient, OAuthConfig
    
            invoice_id = arguments.get("invoice_id", "")
            if not invoice_id:
                return err("invoice_id is required", "MISSING_PARAM")
    
            client_id = os.environ.get("FACE_CLIENT_ID", "")
            client_secret = os.environ.get("FACE_CLIENT_SECRET", "")
            if not client_id or not client_secret:
                return err("FACE_CLIENT_ID y FACE_CLIENT_SECRET son obligatorios.", "MISSING_CONFIG")
    
            env = face_env()
            base_url = FACE_BASE_URLS[env]
            oauth_cfg = OAuthConfig(
                token_url=f"{base_url}/oauth/token",
                client_id=client_id,
                client_secret=client_secret,
            )
            client = BaseEInvoicingClient(
                base_url=base_url,
                auth_mode=AuthMode.OAUTH2_CLIENT_CREDENTIALS,
                oauth_config=oauth_cfg,
            )
    
            response = await client._request("GET", f"/facturas/{invoice_id}")
            body = response.json() if response.headers.get("content-type", "").startswith("application/json") else {"raw": response.text}
    
            # Map known FACe status codes
            status_codes = {
                "1200": "Registrada",
                "2400": "Reconocida por la unidad tramitadora",
                "3100": "Rechazada",
                "4100": "Pagada",
            }
            raw_status = str(body.get("codigo", body.get("status", "")))
            return ok({
                "invoice_id": invoice_id,
                "status_code": raw_status,
                "status_description": status_codes.get(raw_status, "Desconocido"),
                "environment": env,
                "response": body,
            })
    
        except Exception as exc:
            logger.exception("es__get_face_invoice_status failed")
            return err(str(exc))
  • The Tool definition (schema) for es__get_face_invoice_status. Declares inputSchema requiring invoice_id (string). Description explains it consults the FACe invoice processing status with known status codes.
    TOOL_ES_GET_FACE_INVOICE_STATUS = types.Tool(
        name="es__get_face_invoice_status",
        description=(
            "Consulta el estado de tramitación de una factura en FACe. "
            "Códigos: 1200 Registrada, 2400 Reconocida, 3100 Rechazada, 4100 Pagada."
        ),
        inputSchema={
            "type": "object",
            "properties": {
                "invoice_id": {"type": "string", "description": "Número de registro FACe."},
            },
            "required": ["invoice_id"],
        },
    )
  • Registration of the tool in the _TOOL_HANDLERS dict, mapping name 'es__get_face_invoice_status' to handle_es_get_face_invoice_status.
    "es__get_face_invoice_status":        handle_es_get_face_invoice_status,
  • The Tool object imported and registered in the server's tools list (TOOL_ES_GET_FACE_INVOICE_STATUS).
    TOOL_ES_GET_FACE_INVOICE_STATUS,
  • FACe base URLs for sandbox and production environments, used by the handler to determine the API endpoint.
    FACE_BASE_URLS: dict[str, str] = {
        "sandbox": "https://se-face.redsara.es/factura-face-b2b-api/api/v2",
        "production": "https://face.gob.es/factura-face-b2b-api/api/v2",
        # [NEED: verify — FACe may have changed API base path in 2025]
    }
Behavior3/5

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

The description indicates a read-only query ('Consulta') and enumerates possible status codes, but it lacks details on error handling, authentication requirements, or output format. With no annotations, the description carries full burden but covers only basic behavior.

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: one sentence and a list of codes. Every word adds value, and the main action is front-loaded. No redundancy or unnecessary information.

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?

For a simple tool with one parameter and no output schema, the description covers the essential purpose and expected status codes. However, it does not describe the response structure or error scenarios, leaving minor gaps in completeness.

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 description coverage is 100%, and the description adds no extra meaning beyond the schema for the sole parameter. Baseline score of 3 applies as the schema already adequately documents the parameter.

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's purpose: consulting the processing status of an invoice in FACe. It also lists specific status codes, making the action unambiguous and distinguishing it from sibling tools that focus on invoice creation or submission.

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 implies usage for checking invoice status but does not explicitly state when to use this tool over alternatives or when not to use it. No guidance on prerequisites or alternatives is provided.

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