Skip to main content
Glama
iMark21

AEAT MCP Server

by iMark21

get_ccaa_deductions

Retrieve tax deductions for a specific Spanish autonomous community, including amounts, limits, requirements, and legal sources. Filter results by keywords like 'alquiler' or 'vivienda' to find relevant deductions.

Instructions

Returns all tax deductions available in a specific Spanish autonomous community (CCAA). Covers all 17 CCAA + Ceuta + Melilla. Each deduction includes amount/percentage, limits, income requirements, and legal source. Use common names: 'baleares', 'madrid', 'cataluna', 'valencia', etc. Source: AEAT Manual Practico Renta 2025, Parte 2 — Deducciones Autonomicas.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
ccaaYesAutonomous community name (e.g., 'baleares', 'madrid', 'cataluna', 'valencia', 'andalucia')
queryNoOptional keyword to filter deductions (e.g., 'alquiler', 'hijo', 'vivienda', 'donacion')

Implementation Reference

  • The handler logic for the 'get_ccaa_deductions' tool, which processes input parameters, loads regional data, filters it, and returns the result.
      async ({ ccaa, query }) => {
        const data = loadAllCcaa();
        if (Object.keys(data).length === 0) {
          return {
            content: [
              {
                type: "text" as const,
                text: JSON.stringify({
                  error: "no_data",
                  message: "CCAA deductions data not available.",
                }),
              },
            ],
          };
        }
    
        const key = CCAA_ALIASES[ccaa.toLowerCase().replace(/[\s-]/g, "_")] ?? ccaa.toLowerCase().replace(/[\s-]/g, "_");
        const ccaaData = data[key];
    
        if (!ccaaData) {
          const available = Object.keys(data).join(", ");
          return {
            content: [
              {
                type: "text" as const,
                text: JSON.stringify({
                  error: "not_found",
                  message: `CCAA '${ccaa}' not found. Available: ${available}`,
                  suggestion: "Try common names: baleares, madrid, cataluna, valencia, andalucia",
                }),
              },
            ],
          };
        }
    
        let deductions = ccaaData.deductions || [];
    
        if (query) {
          const keywords = query.toLowerCase().split(/\s+/).filter((k: string) => k.length >= 2);
          deductions = deductions.filter((d: any) => {
            const text = JSON.stringify(d).toLowerCase();
            return keywords.every((kw: string) => text.includes(kw));
          });
        }
    
        return {
          content: [
            {
              type: "text" as const,
              text: JSON.stringify(
                {
                  ccaa: ccaaData.name || key,
                  year: 2025,
                  total_deductions: deductions.length,
                  query: query ?? null,
                  deductions,
                  disclaimer:
                    "Informational only. Does not constitute tax advice.",
                },
                null,
                2
              ),
            },
          ],
        };
      }
    );
  • The Zod schema validation for the 'get_ccaa_deductions' tool input.
    {
      ccaa: z
        .string()
        .min(2)
        .describe(
          "Autonomous community name (e.g., 'baleares', 'madrid', 'cataluna', 'valencia', 'andalucia')"
        ),
      query: z
        .string()
        .optional()
        .describe(
          "Optional keyword to filter deductions (e.g., 'alquiler', 'hijo', 'vivienda', 'donacion')"
        ),
    },
  • The registration of the 'get_ccaa_deductions' tool on the McpServer.
    export function registerCcaaDeductionsTool(server: McpServer) {
      server.tool(
        "get_ccaa_deductions",
        "Returns all tax deductions available in a specific Spanish autonomous community (CCAA). " +
          "Covers all 17 CCAA + Ceuta + Melilla. Each deduction includes amount/percentage, " +
          "limits, income requirements, and legal source. " +
          "Use common names: 'baleares', 'madrid', 'cataluna', 'valencia', etc. " +
          "Source: AEAT Manual Practico Renta 2025, Parte 2 — Deducciones Autonomicas.",
        {
          ccaa: z
            .string()
            .min(2)
            .describe(
              "Autonomous community name (e.g., 'baleares', 'madrid', 'cataluna', 'valencia', 'andalucia')"
            ),
          query: z
            .string()
            .optional()
            .describe(
              "Optional keyword to filter deductions (e.g., 'alquiler', 'hijo', 'vivienda', 'donacion')"
            ),
        },
        async ({ ccaa, query }) => {
          const data = loadAllCcaa();
          if (Object.keys(data).length === 0) {
            return {
              content: [
                {
                  type: "text" as const,
                  text: JSON.stringify({
                    error: "no_data",
                    message: "CCAA deductions data not available.",
                  }),
                },
              ],
            };
          }
    
          const key = CCAA_ALIASES[ccaa.toLowerCase().replace(/[\s-]/g, "_")] ?? ccaa.toLowerCase().replace(/[\s-]/g, "_");
          const ccaaData = data[key];
    
          if (!ccaaData) {
            const available = Object.keys(data).join(", ");
            return {
              content: [
                {
                  type: "text" as const,
                  text: JSON.stringify({
                    error: "not_found",
                    message: `CCAA '${ccaa}' not found. Available: ${available}`,
                    suggestion: "Try common names: baleares, madrid, cataluna, valencia, andalucia",
                  }),
                },
              ],
            };
          }
    
          let deductions = ccaaData.deductions || [];
    
          if (query) {
            const keywords = query.toLowerCase().split(/\s+/).filter((k: string) => k.length >= 2);
            deductions = deductions.filter((d: any) => {
              const text = JSON.stringify(d).toLowerCase();
              return keywords.every((kw: string) => text.includes(kw));
            });
          }
    
          return {
            content: [
              {
                type: "text" as const,
                text: JSON.stringify(
                  {
                    ccaa: ccaaData.name || key,
                    year: 2025,
                    total_deductions: deductions.length,
                    query: query ?? null,
                    deductions,
                    disclaimer:
                      "Informational only. Does not constitute tax advice.",
                  },
                  null,
                  2
                ),
              },
            ],
          };
        }
      );
    }
  • Helper function to load and cache CCAA (autonomous community) data from JSON files.
    function loadAllCcaa(): Record<string, any> {
      if (allCcaaData) return allCcaaData;
    
      allCcaaData = {};
      const ccaaDir = join(__dirname, "..", "data", "irpf", "ccaa");
    
      try {
        for (const f of readdirSync(ccaaDir)) {
          if (f.endsWith(".json")) {
            const content = JSON.parse(readFileSync(join(ccaaDir, f), "utf-8"));
            if (content.ccaa) {
              Object.assign(allCcaaData, content.ccaa);
            }
          }
        }
      } catch {
        // Directory might not exist
      }
    
      return allCcaaData;
    }

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/iMark21/aeat-mcp'

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