validate_nif_es
Validates Spanish tax IDs (NIF, NIE, CIF) by automatically detecting the document type and returning a boolean validity flag, type, and normalized ID.
Instructions
Validates Spanish tax identification numbers — NIF (DNI, 8 digits + check letter, for Spanish citizens), NIE (Número de Identidad de Extranjero, starts with X/Y/Z, for foreign residents), and CIF (Código de Identificación Fiscal, letter + 7 digits + control, for companies). Automatically detects the document type. Returns { valid: boolean, type: 'NIF'|'NIE'|'CIF', id: string }.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Spanish NIF, NIE or CIF. Examples: '12345678Z' (NIF), 'X1234567L' (NIE), 'B12345678' (CIF) |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| valid | Yes | ||
| type | No | ||
| id | No | ||
| reason | No |
Implementation Reference
- index.js:166-196 (handler)The handler function for the 'validate_nif_es' tool. It validates Spanish tax identification numbers: NIF (DNI - 8 digits + check letter using TRWAGMYFPDXBNJZSQVHLCKE algorithm), NIE (starts with X/Y/Z mapped to 0/1/2 + 7 digits + check letter), and CIF (letter + 7 digits + control digit using the official weighted sum algorithm). Returns {valid, type: 'NIF'|'NIE'|'CIF', id} or {valid: false, reason}.
server.registerTool("validate_nif_es", { description: "Validates Spanish tax identification numbers — NIF (DNI, 8 digits + check letter, for Spanish citizens), NIE (Número de Identidad de Extranjero, starts with X/Y/Z, for foreign residents), and CIF (Código de Identificación Fiscal, letter + 7 digits + control, for companies). Automatically detects the document type. Returns { valid: boolean, type: 'NIF'|'NIE'|'CIF', id: string }.", inputSchema: { id: z.string().describe("Spanish NIF, NIE or CIF. Examples: '12345678Z' (NIF), 'X1234567L' (NIE), 'B12345678' (CIF)") }, outputSchema: { valid: z.boolean(), type: z.enum(["NIF","NIE","CIF"]).optional(), id: z.string().optional(), reason: z.string().optional() }, annotations: { title: "Validate Spanish NIF / NIE / CIF", readOnlyHint: true, idempotentHint: true, openWorldHint: false } }, async ({ id }) => { const clean = id.replace(/\s/g, "").toUpperCase(); const nifLetters = "TRWAGMYFPDXBNJZSQVHLCKE"; if (/^\d{8}[A-Z]$/.test(clean)) { const valid = clean[8] === nifLetters[parseInt(clean.slice(0, 8)) % 23]; return { content: [{ type: "text", text: JSON.stringify({ valid, type: "NIF", id: clean }) }] }; } if (/^[XYZ]\d{7}[A-Z]$/.test(clean)) { const nieMap = { X: "0", Y: "1", Z: "2" }; const valid = clean[8] === nifLetters[parseInt(nieMap[clean[0]] + clean.slice(1, 8)) % 23]; return { content: [{ type: "text", text: JSON.stringify({ valid, type: "NIE", id: clean }) }] }; } if (/^[ABCDEFGHJKLMNPQRSUVW]\d{7}[0-9A-J]$/.test(clean)) { const letters = "JABCDEFGHI"; let sumOdd = 0, sumEven = 0; for (let i = 1; i <= 7; i++) { const digit = parseInt(clean[i]); if (i % 2 === 0) sumEven += digit; else { const d = digit * 2; sumOdd += d > 9 ? d - 9 : d; } } const controlDigit = (10 - ((sumOdd + sumEven) % 10)) % 10; const valid = clean[8] === controlDigit.toString() || clean[8] === letters[controlDigit]; return { content: [{ type: "text", text: JSON.stringify({ valid, type: "CIF", id: clean }) }] }; } return { content: [{ type: "text", text: JSON.stringify({ valid: false, reason: "Format not recognized. Expected NIF (8 digits + letter), NIE (X/Y/Z + 7 digits + letter) or CIF (letter + 7 digits + control)" }) }] }; }); - index.js:166-196 (registration)The registration of the 'validate_nif_es' tool via server.registerTool() on line 166, including its input schema (z.string() for 'id'), output schema (valid, type enum, id, reason), description, and annotations.
server.registerTool("validate_nif_es", { description: "Validates Spanish tax identification numbers — NIF (DNI, 8 digits + check letter, for Spanish citizens), NIE (Número de Identidad de Extranjero, starts with X/Y/Z, for foreign residents), and CIF (Código de Identificación Fiscal, letter + 7 digits + control, for companies). Automatically detects the document type. Returns { valid: boolean, type: 'NIF'|'NIE'|'CIF', id: string }.", inputSchema: { id: z.string().describe("Spanish NIF, NIE or CIF. Examples: '12345678Z' (NIF), 'X1234567L' (NIE), 'B12345678' (CIF)") }, outputSchema: { valid: z.boolean(), type: z.enum(["NIF","NIE","CIF"]).optional(), id: z.string().optional(), reason: z.string().optional() }, annotations: { title: "Validate Spanish NIF / NIE / CIF", readOnlyHint: true, idempotentHint: true, openWorldHint: false } }, async ({ id }) => { const clean = id.replace(/\s/g, "").toUpperCase(); const nifLetters = "TRWAGMYFPDXBNJZSQVHLCKE"; if (/^\d{8}[A-Z]$/.test(clean)) { const valid = clean[8] === nifLetters[parseInt(clean.slice(0, 8)) % 23]; return { content: [{ type: "text", text: JSON.stringify({ valid, type: "NIF", id: clean }) }] }; } if (/^[XYZ]\d{7}[A-Z]$/.test(clean)) { const nieMap = { X: "0", Y: "1", Z: "2" }; const valid = clean[8] === nifLetters[parseInt(nieMap[clean[0]] + clean.slice(1, 8)) % 23]; return { content: [{ type: "text", text: JSON.stringify({ valid, type: "NIE", id: clean }) }] }; } if (/^[ABCDEFGHJKLMNPQRSUVW]\d{7}[0-9A-J]$/.test(clean)) { const letters = "JABCDEFGHI"; let sumOdd = 0, sumEven = 0; for (let i = 1; i <= 7; i++) { const digit = parseInt(clean[i]); if (i % 2 === 0) sumEven += digit; else { const d = digit * 2; sumOdd += d > 9 ? d - 9 : d; } } const controlDigit = (10 - ((sumOdd + sumEven) % 10)) % 10; const valid = clean[8] === controlDigit.toString() || clean[8] === letters[controlDigit]; return { content: [{ type: "text", text: JSON.stringify({ valid, type: "CIF", id: clean }) }] }; } return { content: [{ type: "text", text: JSON.stringify({ valid: false, reason: "Format not recognized. Expected NIF (8 digits + letter), NIE (X/Y/Z + 7 digits + letter) or CIF (letter + 7 digits + control)" }) }] }; }); - index.js:168-169 (schema)Input and output Zod schemas for the validate_nif_es tool. Input: {id: z.string()} - the Spanish NIF/NIE/CIF string. Output: {valid: z.boolean(), type: z.enum(['NIF','NIE','CIF']), id: z.string(), reason: z.string()}.
inputSchema: { id: z.string().describe("Spanish NIF, NIE or CIF. Examples: '12345678Z' (NIF), 'X1234567L' (NIE), 'B12345678' (CIF)") }, outputSchema: { valid: z.boolean(), type: z.enum(["NIF","NIE","CIF"]).optional(), id: z.string().optional(), reason: z.string().optional() },