validate_nif
Validates Portuguese NIF (tax identification number) using modulo-11 checksum to confirm format and check digit, ensuring fiscal compliance for invoices, supplier onboarding, and user registration.
Instructions
Validates a Portuguese NIF (Número de Identificação Fiscal) — the 9-digit tax identification number issued by the Portuguese Tax Authority (AT) to individuals and companies. Applies the official modulo-11 checksum algorithm to verify the check digit. Returns { valid: true, nif: string } for valid NIFs, or { valid: false, reason: string } for invalid format or failed checksum. First-digit rules are enforced: 1–3 for individuals, 5 for corporations, 6 for public entities, 7–8 for other entities, 9 for occasional taxpayers. Use when processing Portuguese invoices (faturas), onboarding suppliers, validating user registrations, or any fiscal compliance workflow. Does not query the AT database — offline format and checksum validation only.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| nif | Yes | 9-digit Portuguese NIF, with or without spaces. Example: '123456789' |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| valid | Yes | Whether the NIF is valid | |
| nif | No | Normalized NIF without spaces | |
| reason | No | Reason for invalidity if valid is false |
Implementation Reference
- index.js:19-36 (registration)Registration of the validate_nif tool with description, input/output schemas, and annotations
server.registerTool("validate_nif", { description: "Validates a Portuguese NIF (Número de Identificação Fiscal) — the 9-digit tax identification number issued by the Portuguese Tax Authority (AT) to individuals and companies. Applies the official modulo-11 checksum algorithm to verify the check digit. Returns { valid: true, nif: string } for valid NIFs, or { valid: false, reason: string } for invalid format or failed checksum. First-digit rules are enforced: 1–3 for individuals, 5 for corporations, 6 for public entities, 7–8 for other entities, 9 for occasional taxpayers. Use when processing Portuguese invoices (faturas), onboarding suppliers, validating user registrations, or any fiscal compliance workflow. Does not query the AT database — offline format and checksum validation only.", inputSchema: { nif: z.string().describe("9-digit Portuguese NIF, with or without spaces. Example: '123456789'") }, outputSchema: { valid: z.boolean().describe("Whether the NIF is valid"), nif: z.string().optional().describe("Normalized NIF without spaces"), reason: z.string().optional().describe("Reason for invalidity if valid is false") }, annotations: { title: "Validate Portuguese NIF", readOnlyHint: true, idempotentHint: true, openWorldHint: false } }, async ({ nif }) => { const clean = nif.replace(/\s/g, ""); if (!/^\d{9}$/.test(clean)) { const r = { valid: false, reason: "NIF must have exactly 9 digits" }; return { content: [{ type: "text", text: JSON.stringify(r) }], structuredContent: r }; } const validFirst = [1,2,3,5,6,7,8,9]; if (!validFirst.includes(parseInt(clean[0]))) { const r = { valid: false, reason: "Invalid first digit" }; return { content: [{ type: "text", text: JSON.stringify(r) }], structuredContent: r }; } let sum = 0; for (let i = 0; i < 8; i++) sum += parseInt(clean[i]) * (9 - i); const remainder = sum % 11; const checkDigit = remainder < 2 ? 0 : 11 - remainder; const valid = checkDigit === parseInt(clean[8]); const r = { valid, nif: clean }; return { content: [{ type: "text", text: JSON.stringify(r) }], structuredContent: r }; }); - index.js:24-36 (handler)Handler function that validates a Portuguese NIF: strips spaces, checks 9-digit format, validates first digit, applies modulo-11 checksum algorithm, and returns result
}, async ({ nif }) => { const clean = nif.replace(/\s/g, ""); if (!/^\d{9}$/.test(clean)) { const r = { valid: false, reason: "NIF must have exactly 9 digits" }; return { content: [{ type: "text", text: JSON.stringify(r) }], structuredContent: r }; } const validFirst = [1,2,3,5,6,7,8,9]; if (!validFirst.includes(parseInt(clean[0]))) { const r = { valid: false, reason: "Invalid first digit" }; return { content: [{ type: "text", text: JSON.stringify(r) }], structuredContent: r }; } let sum = 0; for (let i = 0; i < 8; i++) sum += parseInt(clean[i]) * (9 - i); const remainder = sum % 11; const checkDigit = remainder < 2 ? 0 : 11 - remainder; const valid = checkDigit === parseInt(clean[8]); const r = { valid, nif: clean }; return { content: [{ type: "text", text: JSON.stringify(r) }], structuredContent: r }; }); - index.js:21-22 (schema)Input and output schema definitions for validate_nif using Zod validation
inputSchema: { nif: z.string().describe("9-digit Portuguese NIF, with or without spaces. Example: '123456789'") }, outputSchema: { valid: z.boolean().describe("Whether the NIF is valid"), nif: z.string().optional().describe("Normalized NIF without spaces"), reason: z.string().optional().describe("Reason for invalidity if valid is false") },