Skip to main content
Glama

Expat Living Italy

Does a comune meet a regime's geographic criteria?

check_tax_eligibility
Read-onlyIdempotent

For one regime slug (from list_tax_regimes) and one 6-digit ISTAT code (from search_comuni): qualifies, does_not_qualify or not_assessable, with a one-sentence reason to quote. not_assessable is never a no. This is about the place only; say so, and never present it as whether a person qualifies or as tax advice.

Input Schema

NameRequiredDescriptionDefault
slugYesA regime slug from /tax/regimes, e.g. "regime-7-percent-pensioners".
comuneYes6-digit ISTAT comune code. Find it with /comuni?q=.

Output Schema

NameRequiredDescriptionDefault
placeYes
reasonYesOne sentence on why, safe to quote.
regimeYes
headroomNoResidents between this comune and the ceiling, when it qualifies.
disclaimerYes
populationYes
attributionYes
maxPopulationNo
placesNotPeopleYes
ruleIsIncompleteYes
geographicEligibilityYesqualifies: the comune meets the regime's verified geographic criteria. does_not_qualify: it doesn't, and the rule has no unverified route that could admit it. not_assessable: no geographic answer can be given (see reason).

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed2 schema fields changed
    • addedOutput schema / properties / attribution / properties / license
      Added value: +{
      +  "additionalProperties": false,
      +  "description": "License of Expat Living Italy's own work only; upstream data keeps its own license, per dataset.",
      +  "properties": {
      +    "name": {
      +      "type": "string"
      +    },
      +    "url": {
      +      "type": "string"
      +    }
      +  },
      +  "required": [
      +    "name",
      +    "url"
      +  ],
      +  "type": "object"
      +}
    • changedOutput schema / properties / attribution / required
      Previous value: -[
      -  "publisher",
      -  "url",
      -  "citeAs",
      -  "request"
      -]New value: +[
      +  "publisher",
      +  "url",
      +  "citeAs",
      +  "request",
      +  "license"
      +]
  2. Changed1 schema field changed
    • changedOutput schema / (root)
      Previous value: -nullNew value: +{
      +  "$schema": "http://json-schema.org/draft-07/schema#",
      +  "additionalProperties": false,
      +  "properties": {
      +    "attribution": {
      +      "additionalProperties": false,
      +      "properties": {
      +        "citeAs": {
      +          "description": "A ready-made citation line.",
      +          "type": "string"
      +        },
      +        "page": {
      +          "description": "The expatliving.it page these figures come from — link it when you quote them.",
      +          "type": "string"
      +        },
      +        "publisher": {
      +          "type": "string"
      +        },
      +        "request": {
      +          "type": "string"
      +        },
      +        "url": {
      +          "type": "string"
      +        }
      +      },
      +      "required": [
      +        "publisher",
      +        "url",
      +        "citeAs",
      +        "request"
      +      ],
      +      "type": "object"
      +    },
      +    "disclaimer": {
      +      "type": "string"
      +    },
      +    "geographicEligibility": {
      +      "description": "qualifies: the comune meets the regime's verified geographic criteria. does_not_qualify: it doesn't, and the rule has no unverified route that could admit it. not_assessable: no geographic answer can be given (see reason).",
      +      "enum": [
      +        "qualifies",
      +        "does_not_qualify",
      +        "not_assessable"
      +      ],
      +      "type": "string"
      +    },
      +    "headroom": {
      +      "description": "Residents between this comune and the ceiling, when it qualifies.",
      +      "type": "number"
      +    },
      +    "maxPopulation": {
      +      "type": "number"
      +    },
      +    "place": {
      +      "additionalProperties": false,
      +      "properties": {
      +        "istatCode": {
      +          "description": "6-digit ISTAT comune code, e.g. 075029.",
      +          "type": "string"
      +        },
      +        "lat": {
      +          "type": "number"
      +        },
      +        "lng": {
      +          "type": "number"
      +        },
      +        "name": {
      +          "type": "string"
      +        },
      +        "page": {
      +          "description": "This comune's profile page on expatliving.it — link it when you quote any figure below.",
      +          "type": "string"
      +        },
      +        "province": {
      +          "type": "string"
      +        },
      +        "provinceCode": {
      +          "type": "string"
      +        },
      +        "provinceSlug": {
      +          "type": "string"
      +        },
      +        "region": {
      +          "type": "string"
      +        },
      +        "regionSlug": {
      +          "type": "string"
      +        },
      +        "slug": {
      +          "description": "Stable URL slug for /data/comune/{slug} — never changes, even if a comune merges.",
      +          "type": "string"
      +        }
      +      },
      +      "required": [
      +        "istatCode",
      +        "slug",
      +        "name",
      +        "province",
      +        "provinceCode",
      +        "provinceSlug",
      +        "region",
      +        "regionSlug",
      +        "lat",
      +        "lng",
      +        "page"
      +      ],
      +      "type": "object"
      +    },
      +    "placesNotPeople": {
      +      "const": true,
      +      "type": "boolean"
      +    },
      +    "population": {
      +      "additionalProperties": false,
      +      "properties": {
      +        "coverage": {
      +          "additionalProperties": false,
      +          "description": "How many of Italy's places this dataset covers at all, e.g. 7587 of 7894 comuni.",
      +          "properties": {
      +            "in": {
      +              "maximum": 9007199254740991,
      +              "minimum": -9007199254740991,
      +              "type": "integer"
      +            },
      +            "of": {
      +              "maximum": 9007199254740991,
      +              "minimum": -9007199254740991,
      +              "type": "integer"
      +            }
      +          },
      +          "required": [
      +            "in",
      +            "of"
      +          ],
      +          "type": "object"
      +        },
      +        "extractedOn": {
      +          "description": "ISO date this value was extracted from the source.",
      +          "type": "string"
      +        },
      +        "license": {
      +          "type": "string"
      +        },
      +        "method": {
      +          "description": "URL to the methodology page for this dataset.",
      +          "type": "string"
      +        },
      +        "reason": {
      +          "description": "Present only when value is null: why this place has no figure.",
      +          "type": "string"
      +        },
      +        "source": {
      +          "type": "string"
      +        },
      +        "unit": {
      +          "type": "string"
      +        },
      +        "value": {
      +          "type": [
      +            "number",
      +            "null"
      +          ]
      +        },
      +        "vintage": {
      +          "description": "The period the value describes, e.g. \"2025H2\" or \"2025\" — not when it was fetched.",
      +          "type": "string"
      +        }
      +      },
      +      "required": [
      +        "value",
      +        "unit",
      +        "source",
      +        "vintage",
      +        "extractedOn",
      +        "method",
      +        "license"
      +      ],
      +      "type": "object"
      +    },
      +    "reason": {
      +      "description": "One sentence on why, safe to quote.",
      +      "type": "string"
      +    },
      +    "regime": {
      +      "additionalProperties": false,
      +      "properties": {
      +        "criteria": {
      +          "description": "geographic: some comuni qualify and others don't. person: turns on who you are, not where you live; no per-comune answer exists.",
      +          "enum": [
      +            "geographic",
      +            "person"
      +          ],
      +          "type": "string"
      +        },
      +        "label": {
      +          "type": "string"
      +        },
      +        "page": {
      +          "description": "The regime's page on expatliving.it.",
      +          "type": "string"
      +        },
      +        "slug": {
      +          "description": "The regime's id, e.g. \"regime-7-percent-pensioners\".",
      +          "type": "string"
      +        },
      +        "status": {
      +          "description": "draft: encoded but not yet checked against the legislation. A draft regime's eligibility is never served.",
      +          "enum": [
      +            "verified",
      +            "draft"
      +          ],
      +          "type": "string"
      +        }
      +      },
      +      "required": [
      +        "slug",
      +        "label",
      +        "status",
      +        "criteria",
      +        "page"
      +      ],
      +      "type": "object"
      +    },
      +    "ruleIsIncomplete": {
      +      "type": "boolean"
      +    }
      +  },
      +  "required": [
      +    "regime",
      +    "place",
      +    "geographicEligibility",
      +    "reason",
      +    "population",
      +    "ruleIsIncomplete",
      +    "placesNotPeople",
      +    "disclaimer",
      +    "attribution"
      +  ],
      +  "type": "object"
      +}
  3. Added

TDQS

A4.6/5.0
Behavior5/5

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

Annotations already cover read-only/idempotent/closed-world, and the description adds the semantic traits annotations cannot: the three outcome values, the critical rule that 'not_assessable is never a no', and that a one-sentence reason is returned for quoting. That is exactly the interpretive context needed to avoid misreading a null-ish result.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences plus a caveat clause, with the outcome enum front-loaded before the interpretive warnings. The clipped phrasing ('for one regime slug ... and one 6-digit ISTAT code') is dense but every clause carries instruction; nothing is padding.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists so return shape needs no explanation, and annotations cover the safety profile. The description supplies what structured fields cannot: input provenance, the three-state semantics, the not_assessable caveat, and the place-only framing — leaving no material ambiguity for a two-parameter read tool.

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 coverage is 100% and both properties already document format and provenance ('regime slug from /tax/regimes', '6-digit ISTAT code ... /comuni?q='). The description restates the same sourcing hints without adding syntax, constraints, or edge cases beyond the schema, so the baseline 3 applies.

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?

Names a specific operation (evaluate geographic eligibility) over two precisely identified inputs and enumerates the exact three-valued outcome. It also scopes itself against adjacent concerns ('about the place only'), so an agent can separate it from person-level or advice-oriented questions.

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

Usage Guidelines5/5

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

Explicitly routes the agent to the two sibling tools that supply each input ('from list_tax_regimes', 'from search_comuni') and states when-not to use the result ('never present it as whether a person qualifies or as tax advice'). Both the positive path and the exclusions are spelled out.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources