Skip to main content
Glama

Server Details

French public-data MCP: cross-ref health, demographics, business, geo & real-estate.

Ownership verified
Status
Healthy
Last Tested
Transport
Streamable HTTP
URL
Repository
cturkieh/france-data-mcp
GitHub Stars
3
Server Listing
France Data MCP

Available Tools

36 tools
autocomplete_communeA
Read-onlyIdempotent
Inspect

Recherche de communes françaises par nom, code postal ou code INSEE. Idéal pour autocomplétion. Source : geo.api.gouv.fr (DINUM/Etalab).

Un (au moins) parmi nom, codePostal, code est requis. Alias acceptés : q/query/searchnom, codepostal/postal_codecodePostal, code_insee/inseecode.

ParametersJSON Schema
NameRequiredDescriptionDefault
nomNoRecherche par nom (autocomplétion). Ex: "Villeneuve d'Ascq", "Lyon".
codeNoCode INSEE exact (5 caractères). Ex: "59009".
limitNoNombre max de résultats (1-30, défaut 10).
codePostalNoCode postal exact (5 chiffres). Ex: "59650".
boostPopulationNoTrier par population décroissante. Recommandé pour les noms ambigus (ex: 'Charleville').

TDQS

A3.6/5.0
Behavior4/5

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

Annotations already indicate read-only, idempotent, and non-destructive behavior. The description adds value by stating that at least one of nom, codePostal, or code is required, which is a key behavioral constraint not fully captured in the input schema (no required parameters).

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 three sentences long, front-loaded with purpose and source, then constraints, then aliases. Every sentence adds value with no redundancy or fluff.

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

Completeness3/5

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

The description covers purpose, constraints, and aliases well, but with no output schema, it could mention what the tool returns (e.g., a list of communes with basic fields). This omission slightly reduces completeness for a tool with 5 parameters.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline is 3. The description adds semantic value beyond the schema by providing aliases (e.g., q/query → nom) and explicitly stating the requirement for at least one parameter. The schema also includes examples, but the description's aliases enhance discoverability.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool searches French communes by name, postal code, or INSEE code, and is ideal for autocomplete. It is specific but does not explicitly differentiate from sibling get_commune_by_code, which might be more appropriate for exact code lookup.

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

Usage Guidelines2/5

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

The description provides minimal usage guidance: it notes the tool is ideal for autocomplete and mentions the data source. However, it does not specify when to use this tool over siblings like get_commune_by_code, nor does it state when not to use it.

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

centres_sante_by_finessA
Read-onlyIdempotent
Inspect

Récupère le détail d'un Centre de Santé (CDS) par son numéro FINESS. Différenciateur métier vs etablissement_by_finess : expose carte_vitale, APCV, et spécialités exercées sur place (Annexe A CNAM). Retourne un LookupResult discriminé par found.

found: true → payload CDS complet (raison sociale, accepte_carte_vitale/apcv, specialites.codes/libelles alignés, type_etab 124/125, adresse, coords centroïde commune, telephone). found: false{found: false, key, lookupStatus: 'not_found', message} quand le numéro FINESS pointe vers une structure non-CDS (hôpital, EHPAD, labo) ou un CDS très récent (CNAM latence ~1 sem).

Source : Annuaire santé Ameli, Assurance Maladie (sync hebdomadaire CNAM, mention obligatoire L.1461-2 CSP). Pour les structures non-CDS, utiliser etablissement_by_finess.

Alias acceptés : numFiness/finess/etab_finessnum_finess.

ParametersJSON Schema
NameRequiredDescriptionDefault
num_finessYesNuméro FINESS exact 9 chiffres. Ex: '750000123'.
include_freshnessNoSi true, ajoute un champ `data_freshness` au payload (dans `query_metadata` si présent, sinon à la racine) listant, par source (FINESS, Ameli, RPPS, CDS, IRIS), la dernière ingestion réussie (`last_success_at`, `staleness_days`) ET la dernière fois que la donnée a réellement changé (`last_data_change_at`, `data_age_days` — un run court-circuité « fichier amont identique » compte comme succès mais ne rajeunit pas la donnée ; c'est `data_age_days` qui dit l'âge réel de ce qui est servi). Opt-in pour ne pas alourdir les payloads par défaut. Cache 5min côté serveur — coût négligeable.

Output Schema

ParametersJSON Schema
NameRequiredDescription
keyNoClé recherchée (SIREN, num_finess, code INSEE, …).
foundYes
messageNoExplication actionnable quand `found=false` (cause probable + remédiation).
lookupStatusYes

TDQS

A5/5.0
Behavior5/5

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

The annotations already declare readOnlyHint, openWorldHint, idempotentHint, and destructiveHint false, but the description adds substantial behavioral context beyond those: discriminated LookupResult with found true/false, the exact not_found payload shape, the CNAM weekly sync latency, data source attribution, and the optional freshness metadata behavior. This goes well beyond what annotations alone communicate.

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 dense but well-organized and front-loaded. The core purpose and differentiator appear in the first sentence, followed by structured payload details, edge cases, source attribution, routing advice, and aliases. Every section earns its place and the formatting makes it easy for an agent to parse.

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?

Context is complete for a lookup tool. It covers purpose, scope, edge cases, source, freshness behavior, aliases, and explicitly routes the caller to the correct sibling for non-CDS structures. The output schema exists, so the description does not need to re-document the return type, and the found true/false branches are already explained in prose.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Even though the input schema has 100% description coverage, the description adds meaningful parameter semantics: accepted aliases for num_finess ('numFiness'/'finess'/'etab_finess') and a detailed explanation of include_freshness, including what fields it adds, the distinction between last_success_at and last_data_change_at, and the opt-in performance rationale. This is valuable information not fully captured by the schema.

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 opens with a specific verb and resource: 'Récupère le détail d'un Centre de Santé (CDS) par son numéro FINESS.' It immediately distinguishes itself from the sibling etablissement_by_finess by naming the differentiating fields (carte_vitale, APCV, spécialités), so an agent can unambiguously identify the tool's purpose.

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?

The description explicitly states when to use this tool versus the alternative: 'Pour les structures non-CDS, utiliser etablissement_by_finess.' It also explains the edge cases where a valid FINESS number returns not_found, such as non-CDS structures or recent CDS registrations with CNAM latency, giving clear guidance on expected resolution outcomes.

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

centres_sante_in_radiusA
Read-onlyIdempotent
Inspect

Recherche des Centres de Santé (CDS) dans un rayon géographique (PostGIS ST_DWithin). Source : Annuaire santé Ameli, Assurance Maladie (mention obligatoire L.1461-2 CSP — sync hebdomadaire CNAM). Différenciateur métier vs etablissements_finess_in_radius filtré famille=124 : expose carte_vitale, APCV, spécialités exercées sur place (Annexe A nomenclature CNAM, ~70 codes).

CDS = structures de soins ambulatoires non lucratives encadrées L.6323-1 CSP (associations, mutuelles, communes, hôpitaux). Volume ~3K en France. Filtres :

  • specialite_codes : array Annexe A (ex: ['01'] médecine générale, ['53'] dentaire). Match any-of — retourne les CDS qui exercent AU MOINS UNE des spécialités demandées.

  • accepte_carte_vitale : true / false / omis. Quasi-totalité accepte CV en pratique → filtre surtout utile en false pour audits.

  • type_etab_codes : ['124'] CDS standard, ['125'] CDS dentaire (deprecated CNAM, en voie d'extinction).

Coords = centroïde commune (~3 km moyenne) — pour précision adresse, pivoter via etab_finess retourné avec etablissement_by_finess. PAS d'horaires/tarifs/secteur 1/2 (retirés du nouvel annuaire CNAM post-2025).

Alias acceptés : radius/radius_metersradius_km, latitude/longitudelat/lon.

ParametersJSON Schema
NameRequiredDescriptionDefault
latYesLatitude du centre (WGS84). Ex: 48.872 (Paris).
lonYesLongitude du centre (WGS84). Ex: 2.317 (Paris).
limitNoNombre max de résultats (1-500, défaut 100).
radius_kmNoRayon en km (0.1-50, défaut 5).
type_etab_codesNoCodes type établissement Annexe B : ['124'] CDS standard (défaut implicite), ['125'] CDS dentaire deprecated. Vide = tous types.
specialite_codesNoCodes spécialité CNAM Annexe A (ex: ['01'] médecine générale, ['53'] chirurgien-dentiste). Match any-of. Vide = pas de filtre spécialité.
include_freshnessNoSi true, ajoute un champ `data_freshness` au payload (dans `query_metadata` si présent, sinon à la racine) listant, par source (FINESS, Ameli, RPPS, CDS, IRIS), la dernière ingestion réussie (`last_success_at`, `staleness_days`) ET la dernière fois que la donnée a réellement changé (`last_data_change_at`, `data_age_days` — un run court-circuité « fichier amont identique » compte comme succès mais ne rajeunit pas la donnée ; c'est `data_age_days` qui dit l'âge réel de ce qui est servi). Opt-in pour ne pas alourdir les payloads par défaut. Cache 5min côté serveur — coût négligeable.
accepte_carte_vitaleNoFiltre par acceptation carte Vitale. true = uniquement CDS qui acceptent CV, false = uniquement ceux qui ne l'acceptent pas. Omis = pas de filtre.

Output Schema

ParametersJSON Schema
NameRequiredDescription
countYesNombre d'entrées retournées dans `results` (post-troncature).
totalNoEffectif réel avant troncature. Présent sur les tools de nomenclature paginés (lister_*) : `count` = échantillon, `total` = total réel, re-appeler avec un `limit` supérieur si `truncated`.
resultsYesEntrées métier (shape spécifique au tool, cf. description du tool).
freshnessNoFraîcheur des sources (présent si `include_freshness: true`).
perimetreNoLentille de la source : ce que le comptage inclut/exclut. Lire `completeness_note` et la restituer au lecteur final.
truncatedNotrue si le total réel dépasse `limit` (re-paginer via `offset` si supporté, ou augmenter `limit` sur les lister_*). Optional sur les tools de listing exhaustif (lister_*).
query_metadataNoMetadata de la query (radius_km, departement, filtres appliqués, …).
activite_hebergeeNoCompte juxtaposé des sites hébergeant l'activité correspondant à la famille filtrée, sous une autre catégorie FINESS. Distinct du `count` principal — lire `note` pour comprendre la sémantique et ne JAMAIS additionner les deux comptes sans préciser leur nature.

TDQS

A4.9/5.0
Behavior5/5

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

Annotations already declare readOnly/idempotent/non-destructive, and the description adds substantial behavioral context: data source (Ameli, sync hebefamadaire CNAM), legal mention, coarseness caveat (centroid commune ~3 km mean), match any-of semantics, deprecated type 125, and the note that hour/tarifs were removed post-2025. No contradiction with annotations.

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?

The description is dense, but every section earns its place: source/legal, differentiator, filter semantics, limitation, exclusions, aliases. It is well-structured with clear line breaks, though slightly longer than strictly necessary. Still, no filler or redundancy — a strong 4.

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?

For an 8-parameter tool nested among 35 siblings, it covers purpose, sibling alternatives, filter behavior, data coarseness, freshness semantics, exclusions, and aliases. Return details are covered by the output schema, so nothing critical is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, but the description goes well beyond: it explains that `specialite_codes` matches any-of, that `accepte_carte_vitale=false` is mainly useful for audits, that `type_etab_codes` includes a deprecated CNAM code, and it lists accepted aliases (`radius`, `radius_meters`, `lat`, `lon`). This materially helps agents build correct calls.

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 opens with a precise verb+resource+scope: 'Recherche des Centres de Santé (CDS) dans un rayon géographique'. It further differentiates from the sibling `etablissements_finess_in_radius` by listing the exclusive fields (carte_vitale, APCV, spécialités sur place), so an agent can confidently identify what this tool uniquely provides.

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?

It explicitly names the sibling alternative (`etablissements_finess_in_radius`) and states when this tool is the better choice du to CDS-specific fields. It also routes to `etablissement_by_finess` for precise address-level data and clearly lists exclusions (no hour/tarifs/secteur 1-2). This gives an agent actionable when-to-use versus when-not-to-use guidance.

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

compare_adresse_cnam_vs_finessA
Read-onlyIdempotent
Inspect

Compare l'adresse d'un centre de santé côté CNAM (Annuaire santé Ameli) vs FINESS DREES pour un même num_finess. Primitive brute SANS interprétation métier — retourne les deux adresses, un score_dice (0..1, informatif ; null si non comparable car finess_absent) et un statut. Le caller décide quoi faire de la divergence.

Utilité : signaler un déménagement propagé par une source mais pas (encore) par l'autre (ex: CNAM '5 RUE DE L'ARQUEBUSE AUTUN' vs FINESS '15 BD BERNARD GIBERSTEIN AUTUN' pour le même FINESS). Équivalent côté centre de santé de compare_raison_sociale_finess_vs_rpps.

Statut (présent uniquement sur found: true) :

  • match : adresses strictement égales après normalisation

  • match_after_abbreviation_normalization : égales après expansion des abréviations de voie FR (R/RUE, BD/BOULEVARD, AV/AVENUE…) — MÊME adresse, simple abréviation DREES vs CNAM, PAS un déménagement

  • divergent_after_normalization : adresses réellement différentes (déménagement non synchronisé entre sources)

  • finess_absent : le CDS existe côté CNAM mais le num_finess est absent de FINESS DREES (latence sync bimensuelle)

Format : objet LookupResult discriminé par found. Si le num_finess n'est PAS un centre de santé CNAM, le tool retourne {found: false, lookupStatus: 'not_found', message} (utiliser etablissement_by_finess pour un établissement non-CDS).

ParametersJSON Schema
NameRequiredDescriptionDefault
num_finessYesNuméro FINESS exact (9 chiffres).

Output Schema

ParametersJSON Schema
NameRequiredDescription
keyNoClé recherchée (SIREN, num_finess, code INSEE, …).
foundYes
messageNoExplication actionnable quand `found=false` (cause probable + remédiation).
lookupStatusYes

TDQS

A4.6/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true and destructiveHint=false, so the tool is known safe. Description adds detailed behavior: returns two addresses, score_dice (with null case), statut with four cases explaining divergence, and handles not_found for non-CDS. No contradictions.

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?

Description is long but well-structured with bullet points for statut cases and clear examples. Could be slightly more concise, but the detail is justified given the tool's complexity.

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?

Given output schema exists and the tool has multiple status cases, description fully explains each statut, score_dice behavior, and the not_found scenario with alternative guidance. Very complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Only one parameter num_finess, with schema description covering format. Description adds semantics that the finess must correspond to a CDS, which is not in the schema, enriching understanding.

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?

Description clearly states it compares addresses from CNAM vs FINESS for a given num_finess, and distinguishes itself by noting it is the 'equivalent côté centre de santé de compare_raison_sociale_finess_vs_rpps'.

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 says when to use (signal a move propagated by one source but not the other), provides an example, and states when not to use (non-CDS finess) with an alternative tool (etablissement_by_finess).

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

compare_raison_sociale_finess_vs_rppsA
Read-onlyIdempotent
Inspect

Compare la raison sociale FINESS DREES vs RPPS / Annuaire Santé ANS pour un même num_finess. Primitive brute SANS interprétation métier — retourne juste les deux libellés + un statut de comparaison. Le caller décide quoi faire de la divergence.

Utilité : RPPS reflète souvent plus rapidement les rebrandings post-M&A que FINESS DREES (ex: un site racheté reste 'DIAGNOVIE' chez DREES alors qu'il est déjà 'BIOGROUP NORD' chez l'ANS). Ce tool expose la divergence factuelle ; il NE DIT PAS qui a racheté qui (ça repose sur de la connaissance d'enseignes commerciales non publique).

Statut renvoyé (champ statut présent uniquement sur la branche found: true) :

  • exact_match : FINESS et ≥1 RPPS sont strictement égaux après normalisation

  • divergent_after_normalization : aucune RPPS ne matche FINESS — vraie divergence

  • rpps_absent : aucune RPPS n'a déclaré ce FINESS (pivot impossible)

Format : objet LookupResult discriminé par found. Quand num_finess est absent de FINESS DREES, le tool retourne {found: false, lookupStatus: 'not_found', message, ...} — il n'y a PAS de champ statut dans ce cas.

ParametersJSON Schema
NameRequiredDescriptionDefault
num_finessYesNuméro FINESS exact (9 chiffres).

Output Schema

ParametersJSON Schema
NameRequiredDescription
keyNoClé recherchée (SIREN, num_finess, code INSEE, …).
foundYes
messageNoExplication actionnable quand `found=false` (cause probable + remédiation).
lookupStatusYes

TDQS

A4.6/5.0
Behavior5/5

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

Annotations set readOnlyHint, openWorldHint, idempotentHint, destructiveHint. The description adds detailed behavioral context: it returns two labels and a comparison status, describes the three possible statut values ('exact_match', 'divergent_after_normalization', 'rpps_absent'), and explains the not_found case. No contradictions.

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?

The description is well-structured with a clear introductory sentence, bullet-pointed statut explanations, and no redundant text. It could be slightly more concise, but each sentence adds value.

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?

Given the presence of an output schema, the description still covers all essential aspects: use case, return format, edge cases (not found), and statut details. It is complete for a simple tool with one parameter.

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?

The input schema has 100% coverage with a clear description for num_finess ('exact 9-digit number'). The description does not add new parameter information beyond that, but schema coverage is high, so baseline score of 3 is appropriate.

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 compares 'raison sociale' between FINESS DREES and RPPS/Annuaire Santé ANS for a given num_finess. It uses a specific verb ('compare') and resource, and distinguishes itself from sibling tools like compare_adresse_cnam_vs_finess by focusing on name comparison.

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?

The description explicitly states it is a 'primitive brute SANS interprétation métier' and explains when to use it (e.g., to detect rebranding after M&A). It also clarifies what it does not do (does not indicate acquisitions) and provides alternative context.

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

cout_foncierA
Read-onlyIdempotent
Inspect

Coût du foncier d'une zone (point + rayon) : prix médian au m² RÉSIDENTIEL bâti — maisons + appartements UNIQUEMENT, PAS les locaux commerciaux/professionnels (+ quartiles p25/p75), volume de ventes, période couverte. Source DGFiP DVF (ventes réelles géolocalisées). Pour un local pro (labo, cabinet), ce prix résidentiel est un PROXY indicatif, pas le prix d'un local commercial. INFORMATION pour le business case d'implantation — NE PAS intégrer à une note d'attractivité : le coût d'installation est distinct du potentiel de marché.

ParametersJSON Schema
NameRequiredDescriptionDefault
latYesLatitude du centre (WGS84).
lonYesLongitude du centre (WGS84).
rayon_kmNoRayon en km (0.1-10, défaut 3).

Output Schema

ParametersJSON Schema
NameRequiredDescription
sourceNoToujours 'DGFiP DVF'.
periodeNoAnnées couvertes (ex: '2019–2024').
n_ventesYesVolume de ventes dans le rayon.
couvertureYesStatut : 'ok' = données disponibles, 'indisponible:no_data' = pas de ventes DVF dans le rayon.
prix_m2_p25No1er quartile prix au m².
prix_m2_p75No3ème quartile prix au m².
prix_m2_medianNoPrix médian au m² bâti.

TDQS

A4.4/5.0
Behavior5/5

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

Beyond annotations (readOnlyHint, idempotentHint, etc.), the description adds significant behavioral detail: the data source (DGFiP DVF actual geolocated sales), that it returns quartiles and volume, the exclusion of commercial properties, and the proxy nature for professional premises. No contradiction with annotations.

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?

The description is dense but well-structured: first sentence defines main output, then exclusions, then source, then proxy note, then usage caveat. It is slightly long but every sentence adds value. Front-loaded with the core function and key constraints.

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?

Given the tool returns multiple statistics (median, quartiles, volume) and has an output schema, the description sufficiently covers what the tool does, its limitations, source, and appropriate usage. It is complete for an AI agent to select and invoke correctly.

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?

The input schema already has 100% description coverage for all parameters (lat, lon, rayon_km). The description does not add new parameter-specific information; it only describes the overall output. Baseline score of 3 is appropriate as the schema does the heavy lifting.

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 returns median residential property price per m², quartiles, sales volume, and period for a given point and radius. It explicitly distinguishes itself by specifying 'RÉSIDENTIEL bâti — maisons + appartements UNIQUEMENT, PAS les locaux commerciaux/professionnels', differentiating from tools that might return commercial prices or other real estate data. The verb 'coût du foncier' plus 'prix médian au m²' is specific and unambiguous.

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

Usage Guidelines4/5

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

The description provides clear context: it is for business case implantation but warns not to integrate into an attractiveness note. It also notes that for professional premises, the residential price is a proxy. However, it does not explicitly mention when to use this tool over siblings like 'dynamique_immobiliere' or others, though the exclusion of commercial properties implicitly guides usage.

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

data_freshnessA
Read-only
Inspect

Retourne la fraîcheur des dumps de données ingérés côté serveur : FINESS / ANS (flux quotidien, ingéré le 1er et le 15 du mois), Annuaire Santé Ameli (hebdomadaire), RPPS / Annuaire Santé ANS (mensuel), Centres de Santé CNAM (hebdomadaire), IRIS INSEE (annuel). Pour chaque source : last_data_change_at + data_age_days (dernier run ayant RÉELLEMENT changé la donnée servie, et son âge en jours — C'EST LE CHAMP À LIRE), last_success_at + staleness_days (dernier run réussi, y compris un run court-circuité « fichier amont identique » — ne mesure PAS l'âge de la donnée), last_success_row_count, last_attempt_at, last_attempt_status, cadence_hint (cadence attendue).

Usage typique : avant un audit territorial ou une analyse temporelle, le caller appelle ce tool pour savoir si les données sont à jour. Juger sur data_age_days, JAMAIS sur staleness_days seul : en 2026 la source FINESS s'est tarie 4 mois pendant que staleness_days restait à quelques jours (runs « fichier identique » comptés comme succès). Règle d'alerte : data_age_days > expected_max_age_days (seuil par source, exposé dans chaque ligne — ne pas le recopier) ; data_age_days: null = jamais ingéré.

Les sources LIVE (DINUM Recherche Entreprises, INSEE SIRENE V3.11, ANS FHIR live) ne sont PAS listées ici puisqu'elles n'ont pas de cycle d'ingestion — leur fraîcheur est celle des API amont (live, ~secondes).

Cache serveur : 5 minutes. Coût : 1 SELECT sur ingest_log au pire (sinon hit cache).

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
sourcesYes

TDQS

A4.9/5.0
Behavior5/5

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

Annotations mark the tool read-only and non-destructive, and the description goes much further: it clarifies the semantic difference between `data_age_days` and `staleness_days`, the meaning of `null`, the 5-minute server cache, and the worst-case SQL cost of 1 SELECT. No contradiction with annotations.

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?

Although long, the description is dense and well-structured: purpose first, then source cadences, field definitions, a concrete alert rule, a historical caveat, exclusions, and cache/cost. Every sentence carries operational value and none is redundant.

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?

For a zero-parameter tool, the description fully covers purpose, return-field semantics, the correct metric to judge freshness, the alert threshold rule, cavats from real incidents, excluded sources, and performance characteristics. The output schema exists and the description complements it with rich operational context.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so the input schema is trivially fully covered and the baseline is 4. The description adds no parameter docs because none are needed, but compensates by thoroughly documenting the meaning of every returned field.

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 opens with a precise verb and object: 'Retourne la fraîcheur des dumps de données ingérés côté serveur', then enumerates the exact data sources and fields returned. This clearly distinguishes the tool from all sibling data-lookup and geospatial tools by framing it as a metadata/freshness query.

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?

It explicitly states when to call the tool ('avant un audit territorial ou une analyse temporelle'), defines the alert rule, warns against misusing `staleness_days`, and explicitly lists which sources are excluded (LIVE APIs). This gives the agent both positive and negative usage guidance.

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

densite_santeA
Read-onlyIdempotent
Inspect

Densité de santé pour 100 000 habitants — cible: professionnels (RPPS) OU cible: etablissements (FINESS). Niveau département (code_dept) OU commune (code_insee / nom_commune). Exactement un scope des trois requis. Croise le count (RPPS ou FINESS) et INSEE Melodi (population municipale PMUN, recensement 2023).

cible='professionnels' (RPPS) — méthodo DREES par défaut : médecins (profession_code='10') en activité régulière (mode_exercice L, S, M), hors étudiants. Filtres : profession_code (60 infirmier, 21 pharmacien, 50 sage-femme…), savoir_faire_code (ex 'SM04' Cardiologie — 'SM02' = Anesthésie-réanimation ; voir lister_nomenclature referentiel rpps_savoir_faire), mode_exercice_codes (['L'] = libéraux seuls).

cible='etablissements' (FINESS) — famille OBLIGATOIRE : labo, pharmacie, ehpad, mco, ssr, psychiatrie, dialyse, imagerie, had, msp_cpts, handicap_enfants, handicap_adultes, addictologie, pmi, prevention_sante, etc. Sans famille le ratio mélangerait labos/hôpitaux/EHPAD → non-sens.

Sémantique conditionnelle de code_dept : seul = scope de calcul (dept entier) ; combiné avec nom_commune = hint de résolution UNIQUEMENT (filtre les homonymes), le calcul reste sur la commune résolue.

Paris/Marseille/Lyon : densité par code_insee INDISPONIBLE (RPPS/FINESS rattachés aux arrondissements, INSEE n'expose la population qu'à la commune entière) → RangeError ; utiliser code_dept (75, 13, 69).

compare_national: true ajoute la densité France entière (DOM inclus) + écart en % (positif = sur-doté, négatif = sous-doté).

Alias : dept/departementcode_dept, codeInsee/inseecode_insee. Ne renvoie AUCUNE interprétation métier (pas de seuil "désert médical" auto). Catégorie par défaut : Civil (C, ~97 % — libéraux, salariés privés, hospitaliers contractuels). Opt-in : include_agents_publics: true ajoute Agents publics (M, ~0,3 % — PH titulaires, ARS, CNAM, Éducation nationale, PMI, militaires SSA) ; include_etudiants: true ajoute Étudiants (E, ~2,5 % — internes, externes, élèves IDE/SF). Réf : https://mos.esante.gouv.fr/NOS/TRE_R09-CategorieProfessionnelle/. ATTENTION nomenclatures : les codes ANS (profession_code, savoir_faire_code) sont une nomenclature DISTINCTE des codes Ameli (specialite_code, type_ps_code) — un même nombre désigne des choses différentes (ex: '10' = Médecin côté ANS, Neurochirurgien côté Ameli). Ne JAMAIS passer un code Ameli à un paramètre ANS : le filtre renverrait vide sans erreur. Découvrir les codes ANS via lister_nomenclature(referentiel:'rpps_savoir_faire'). Source : Annuaire Santé, Agence du Numérique en Santé (ANS) — Licence Ouverte v2.0

ParametersJSON Schema
NameRequiredDescriptionDefault
cibleYes`professionnels` = densité de PS (RPPS, filtres profession_code/savoir_faire_code/mode_exercice_codes) ; `etablissements` = densité d'établissements (FINESS, `famille` obligatoire).
familleNocible='etablissements' UNIQUEMENT (obligatoire) : famille FINESS à compter (labo, pharmacie, ehpad, mco, ssr, psychiatrie, dialyse, imagerie, had, msp_cpts, handicap_enfants, handicap_adultes, addictologie, pmi, prevention_sante, etc.).
code_deptNoCode INSEE du département 2-3 caractères. Ex: "75" Paris, "59" Nord, "2A" Corse-du-Sud, "971" Guadeloupe. Sémantique conditionnelle : seul = scope dept entier ; combiné avec `nom_commune` = hint resolver pour désambiguer les homonymes. XOR avec `code_insee`.
code_inseeNoCode INSEE de la commune 5 caractères. Ex: "59009" Villeneuve-d'Ascq, "33063" Bordeaux, "2A004" Ajaccio. Paris/Lyon/Marseille NON supporté au niveau commune (densité indisponible — voir description) : utiliser code_dept. XOR avec `code_dept` et `nom_commune`.
nom_communeNoNom officiel de commune (alternative à `code_insee`). Ex: "Lille", "Villeneuve-d'Ascq". Le serveur résout en interne via geo.api.gouv.fr. Combinable avec `code_dept` comme hint de désambiguïsation pour homonymes (ex "Saint-Martin" + dept "65"). XOR avec `code_insee`.
profession_codeNocible='professionnels' UNIQUEMENT : code profession ANS (TRE_R94). Default '10' (Médecin). Ex : '60' Infirmier, '21' Pharmacien, '50' Sage-femme, '40' Chirurgien-dentiste, '70' Masseur-kinésithérapeute.
compare_nationalNoAjoute le calcul France entière + écart relatif en % (recommandé pour qualifier 'sous-doté'/'sur-doté').
include_etudiantsNo
savoir_faire_codeNocible='professionnels' UNIQUEMENT : code spécialité (savoir_faire). Pertinent surtout pour profession_code=10 (médecin). Ex : 'SM04' Cardiologie, 'SM15' Dermatologie et vénéréologie, 'SM02' Anesthésie-réanimation, 'SM26' Médecine générale. Voir lister_nomenclature(referentiel:'rpps_savoir_faire') pour la liste exhaustive.
mode_exercice_codesNocible='professionnels' UNIQUEMENT : codes mode_exercice ANS à inclure. Default ['L','S','M'] (libéral + salarié + mixte = activité régulière DREES). Passer ['L'] pour libéraux seuls. Codes mode_exercice ANS : L libéral, S salarié, M mixte, R remplaçant, B bénévole, A autre.
include_agents_publicsNo

TDQS

A4.3/5.0
Behavior5/5

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

Annotations already declare read-only, idempotent, and non-destructive. The description adds significant behavioral details: no automatic business interpretation, empty results without error if ANS/Ameli codes are confused, default category (Civil), and the source data license. This provides a clear operational understanding beyond the annotations.

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?

The description is long but well-structured with sections for different targets and warnings. It is front-loaded with the core purpose and uses bold for emphasis on critical points. Every sentence adds value given the tool's complexity, though it is not minimal.

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

Completeness3/5

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

Given the tool's complexity (11 parameters, no output schema), the description covers input semantics, constraints, and data sources. However, it does not describe the output structure (e.g., fields in the response, whether it returns density value, population, raw counts). This is a gap as the agent cannot infer the return format from the lack of output schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 82% schema description coverage, the baseline is 3, but the description substantially enriches parameter semantics. It explains conditional logic (code_dept alone vs with nom_commune), unsupported codes for Paris/Marseille/Lyon, aliases for parameter names, and cross-field dependencies (e.g., famille required when cible=etablissements). The description compensates for the remaining 18% undocumented parameters by providing context that the schema lacks.

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 computes health density per 100,000 inhabitants by cross-referencing counts (RPPS or FINESS) with INSEE population data. It distinguishes itself from sibling tools by focusing on aggregation at department or commune level, which is a unique capability among the sibling tools (e.g., professionnels_in_radius returns individual professionals).

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 provides extensive internal usage guidance (required parameters, conditional semantics, warnings about Paris/Marseille/Lyon and code mismatches) but does not explicitly compare this tool to sibling alternatives. While it implies the tool is for density calculations, it lacks explicit 'when to use this instead of other tools' advice.

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

dynamique_immobiliereA
Read-onlyIdempotent
Inspect

Dynamique immobilière et potentiel de croissance d'une zone (point + rayon). Combine 3 sources officielles : permis de construire (Sit@del/SDES, maille COMMUNE — logements autorisés/commencés récents → habitants attendus), zones AU du PLU (Géoportail de l'Urbanisme/IGN — futurs quartiers réservés, géolocalisés), ventes de terrains à bâtir (DGFiP DVF, géolocalisées). Sortie en 2 registres : 'note' = VOLUME (logements autorisés/commencés, nombre et immédiateté des zones AU) destiné au scoring de potentiel ; 'info' = quartiers concernés (nommés), habitants attendus, prix indicatifs (contexte, hors score). En ville dense les permis-commune sont grossiers → s'appuyer sur zones AU + terrains (géolocalisés). Point côtier/isolé sans commune au géocodage inverse → couverture.permis='indisponible:commune_introuvable' et meta.code_commune=null, MAIS zones AU + terrains restent servis (calcul par rayon) — l'outil ne plante jamais pour ça. 'geojson' = polygones des zones AU pour la carte. Sources : SDES, IGN/GPU, DGFiP.

ParametersJSON Schema
NameRequiredDescriptionDefault
latYesLatitude du centre (WGS84).
lonYesLongitude du centre (WGS84).
rayon_kmNoRayon en km (0.1-10, défaut 3).

Output Schema

ParametersJSON Schema
NameRequiredDescription
infoNoContexte non-scorable : habitants_attendus, quartiers_au (libellés), prix_m2_median, terrains. Ne PAS intégrer à une note d'attractivité.
noteNoDonnées de VOLUME — à utiliser pour le scoring LLM. logements_autorises_recent, logements_commences_recent, zones_au_nombre, zones_au_immediates, signal.
geojsonNoFeatureCollection GeoJSON des polygones des zones AU (pour la carte).
couvertureYesStatut de dégradation par section : 'ok' | 'indisponible:<raison>'. Lire avant d'interpréter note/info.

TDQS

A4.4/5.0
Behavior5/5

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

Annotations already indicate readOnly, idempotent, non-destructive. The description adds significant behavioral context: the tool never fails for missing commune data, it combines multiple sources, and it mentions coarse permit data in dense areas. This goes beyond annotation information.

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?

The description is reasonably concise for its complexity, front-loaded with the main purpose. It could be slightly more structured, but it effectively communicates the tool's functionality without unnecessary verbosity.

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?

Given the tool's complexity (multiple sources, edge cases, two output registers) and the presence of an output schema, the description is very complete. It covers the overall approach, edge cases, and output contents, leaving no major gaps.

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% with clear descriptions for all three parameters. The description adds minimal extra detail (e.g., radius used for 'calcul par rayon'), meeting the baseline for high schema coverage.

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: assessing real estate dynamics and growth potential of a zone. It specifies the three official sources combined and the two output registers ('note' and 'info'), distinguishing it from siblings which likely focus on single sources.

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

Usage Guidelines4/5

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

The description provides situational guidance, such as relying on AU zones and land sales in dense cities due to coarse building permit data. It also explains behavior when the commune is not found. However, it lacks explicit 'when not to use' instructions or comparisons to sibling tools.

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

enrichir_concurrentsA
Read-onlyIdempotent
Inspect

Enquête approfondie sur le top concurrents (V0.23). Pour chaque FINESS : statut actif + taille d'équipe + historique récent (inspect_site), signal M&A — rebranding en cours — (compare raison sociale FINESS vs RPPS), groupe parent (entreprise_by_siren : Biogroup/Cerballiance/… + est_grand_groupe).

Cap dur max=3 (inspect_site ~7 K tokens/appel — JAMAIS 10+). Drapeau couverture PAR concurrent ("ok" | "partiel:<raison>") : un concurrent qui échoue n'annule pas les autres.

Typiquement appelé sur concurrents.top[0..2].finess renvoyés par panorama_implantation_complet.

Sources : FINESS/ANS, RPPS/ANS, SIRENE/DINUM.

ParametersJSON Schema
NameRequiredDescriptionDefault
maxNoCap dur du nombre de concurrents enquêtés. Défaut 3.
finessYesNuméros FINESS à enquêter (typiquement le top 3 concurrents par distance).

TDQS

A4.5/5.0
Behavior4/5

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

Annotations already declare readOnlyHint, idempotentHint, destructiveHint=false, so safety is clear. The description adds behavioral details: it calls inspect_site (costly, cap at 3), checks M&A signals via entreprise_by_siren, and produces a couverture flag per competitor. However, it does not describe return format or pagination, so slightly less than perfect.

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?

The description is well-structured with lists and bold terms. It is informative but not overly verbose; every sentence adds value. A minor improvement could be trimming redundancy (e.g., 'Cap dur') but overall efficient.

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?

Given the tool's complexity (combines multiple internal tools) and no output schema, the description fairly complete. It covers what checks are performed, the cap, error handling, typical inputs, and data sources. Missing explicit output structure, but the couverture flag is mentioned.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% with descriptions. The description adds context: 'max' default is 3, and 'finess' are typically the top 3 from another tool. It also explains the token cost cap ties to 'max'. This adds meaningful guidance beyond the schema.

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 performs an in-depth investigation of top competitors, specifying what it checks (status, team size, history, M&A, parent group). It distinguishes itself from siblings like inspect_site and entreprise_by_siren by being a composite tool that calls them internally. The verb 'enquête' and the enumeration of checks provide a precise purpose.

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 states when to use: 'Typiquement appelé sur concurrents.top[0..2].finess renvoyés par panorama_implantation_complet.' Also provides constraints: hard cap max=3, token cost warning, and error handling (one failing competitor doesn't cancel others). This is excellent guidance.

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

entreprise_by_sirenA
Read-onlyIdempotent
Inspect

Récupère le détail d'une entreprise française par son SIREN (9 chiffres) : raison sociale, NAF, finances historiques, dirigeants, établissements. Source : DINUM Recherche Entreprises.

Format de retour : objet LookupResult discriminé par found.

  • found: true → l'entreprise est retournée à plat (champs siren, nomComplet, etablissements, enrichmentStatus, …)

  • found: false{ found: false, key, lookupStatus: 'not_found' | 'ambiguous', message }. not_found : SIREN non indexé par DINUM (souvent diffusion partielle INSEE — l'entreprise peut quand même exister dans SIRENE). ambiguous : régression API à signaler.

⚠️ Quand found: true, la liste etablissements peut être tronquée. Le champ nombreEtablissements (compté SIRENE) reflète le total réel. Lire enrichmentStatus pour savoir si la liste est complète :

  • success : etablissements contient tous les sites

  • partial : sites manquants (multi-département ou NAF différent du siège) — voir enrichmentWarning

  • failed : l'enrichissement a échoué (rate limit, panne API) — seul le siège est listé

  • not_attempted : entreprise monosite ou data SIRENE manquante

Pour énumération exhaustive multi-département, utiliser entreprises_in_radius par zone géographique. Coût : 1 ou 2 appels API DINUM par invocation (rate limit ~1 req/s effectif).

ParametersJSON Schema
NameRequiredDescriptionDefault
sirenYesSIREN exact, 9 chiffres.

Output Schema

ParametersJSON Schema
NameRequiredDescription
keyNoClé recherchée (SIREN, num_finess, code INSEE, …).
foundYes
messageNoExplication actionnable quand `found=false` (cause probable + remédiation).
lookupStatusYes

TDQS

A4.6/5.0
Behavior5/5

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

Annotations already provide readOnlyHint, openWorldHint, etc. The description adds significant behavioral context: return type (LookupResult discriminated), possible etablissements truncation, meaning of enrichmentStatus values, and that 1-2 API calls are made. No contradiction with annotations.

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?

The description is well-structured with sections for purpose, output format, and warnings. It is somewhat long but every sentence adds value. Could be slightly more concise, but front-loads key info.

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?

Given the output schema exists, the description fully explains the discriminated union (found: true/false), all relevant fields (nombreEtablissements, enrichmentStatus, etc.), and edge cases (not_found, ambiguous, truncation). Comprehensive coverage.

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 describes the single parameter 'siren' as 'SIREN exact, 9 chiffres.' with 100% coverage. The description repeats 'SIREN (9 chiffres)' but adds no extra meaning beyond the schema. Baseline 3 is appropriate.

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 retrieves French company details by SIREN, listing key fields (raison sociale, NAF, finances, dirigeants, établissements) and the data source (DINUM). It distinguishes itself from siblings like 'etablissement_by_siret' (by SIRET) and 'entreprises_in_radius' (exhaustive enumeration).

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?

The description explicitly advises when to use alternatives: 'Pour énumération exhaustive multi-département, utiliser `entreprises_in_radius`'. It also mentions the rate limit (~1 req/s) and recommends reading 'enrichmentStatus' for completeness.

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

entreprises_in_radiusA
Read-onlyIdempotent
Inspect

Recherche d'entreprises françaises avec filtres NAF, code postal, département ou rayon géographique. Couvre tous secteurs (santé via NAF 8690B, 4773Z, 8710A, 8621Z, etc.). Source : DINUM Recherche Entreprises (SIRENE + RNE). Renvoie CA, dirigeants, tranches d'effectif et dates de création.

Deux modes EXCLUSIFs (endpoints DINUM distincts) : (1) proximité — lat+lon+radiusKm (optionnellement + naf), résolu nativement via /near_point ; (2) administratif — q (texte libre) et/ou naf + codePostal/departement, via /search. La recherche de proximité ne supporte PAS q ni codePostal/departement (combinaison rejetée avec une erreur explicite : choisir un seul mode). radiusKm borné à 50 km.

Réduction de payload (V0.13) : includeDirigeants: false strip la liste des dirigeants RNE de chaque entreprise du résultat — utile en énumération volume (Geo Intel) où les dirigeants ne sont pas exploités et où les groupes type Biogroup peuvent en lister 20+ par entité (gonflement inutile du payload). Défaut true pour préserver le contrat V0.12 (backward-compat strict).

ParametersJSON Schema
NameRequiredDescriptionDefault
qNoRecherche textuelle libre (raison sociale, dirigeant…).
latNoLatitude du centre du cercle de recherche.
lonNoLongitude du centre du cercle de recherche.
nafNoCode NAF principal (ex: '8690B' = labos, '4773Z' = pharmacies, '8710A' = EHPAD, '8621Z' = MG).
pageNoPage (1-indexed).
perPageNoRésultats par page (1-25, défaut 10).
radiusKmNoRayon en km (1-50).
codePostalNoFiltre alternatif : code postal exact.
departementNoFiltre alternatif : code département.
includeDirigeantsNoInclure la liste des dirigeants RNE dans chaque entreprise (défaut true). `false` strip `dirigeants: []` côté handler — utile en énumération volume où les dirigeants ne sont pas exploités (économie de tokens, groupes type Biogroup peuvent lister 20+ dirigeants par entité).

Output Schema

ParametersJSON Schema
NameRequiredDescription
pageYes
totalYesTotal d'entreprises matchant la query côté DINUM.
perPageYes
totalPagesYes
entreprisesYesEntreprises retournées (SIREN, nomComplet, NAF, finances, etablissements).

TDQS

A4.8/5.0
Behavior5/5

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

Annotations (readOnlyHint=true, etc.) are already provided, and the description adds significant context: source (DINUM Recherche Entreprises), what is returned (CA, dirigeants, etc.), the behavior of the two modes, the constraint that proximity mode does not support administrative filters, and the effect of includeDirigeants. No contradictions.

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?

The description is well-structured into three paragraphs: general purpose, mode details, and parameter note. It is front-loaded with the main action. While it is fairly long, every sentence adds value and no information is redundant. Slightly more conciseness could be achieved, but it is acceptable.

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?

Given the complexity (10 parameters, two modes, output schema exists), the description covers all necessary aspects: mode exclusivity, parameter combinations, limits (radius 50 km), a specific performance optimization (includeDirigeants), and the data sources. An agent can correctly select and invoke this tool without ambiguity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% with inline descriptions, so baseline is 3. The description adds value beyond the schema by explaining which parameters belong to which mode, that q and codePostal/departement are exclusive with lat/lon/radiusKm, and the practical use of includeDirigeants for payload reduction. This extra context raises the score.

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 it searches French companies with filters (NAF, postal code, department, geographic radius), specifies the two exclusive modes (proximity and administrative), and lists the data returned (CA, dirigeants, etc.). It distinguishes from siblings like entreprise_by_siren or etablissements_in_radius by focusing on companies and the dual-mode search.

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?

The description explicitly details two exclusive modes: proximity (lat+lon+radiusKm, optionally naf) and administrative (q and/or naf+codePostal/departement). It states that mixing modes is rejected with an error, provides radius limit (50 km), and explains the payload reduction option (includeDirigeants). This gives clear when-to-use guidance.

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

etablissement_by_finessA
Read-onlyIdempotent
Inspect

Récupère le détail complet d'un établissement de santé par son numéro FINESS (9 chiffres) : raison sociale, catégorie + famille, adresse complète (voie + CP + ville + code INSEE + département), coordonnées GPS, téléphone. Retourne un objet LookupResult discriminé par found. found: true → champs FINESS à plat. found: false{ found: false, key, lookupStatus: 'not_found', message }. Le référentiel DREES a 1-2 mois de retard sur le terrain : pour des structures émergentes (CPTS récentes, MSP en agrément), cross-check ARS / Service Public. Source : FINESS / DREES. Note : champ email toujours null (non exposé par FINESS public). Note : raison_sociale provient du dump DREES qui abrège les libellés longs (~38 car. max, ex 'CERBALLIANCE HA' pour 'CERBALLIANCE HAZEBROUCK'). Pour le nom légal complet, cross-check via SIREN/SIRET (entreprise_by_siren / etablissement_by_siret).

ParametersJSON Schema
NameRequiredDescriptionDefault
num_finessYesNuméro FINESS exact (9 chiffres).
include_freshnessNoSi true, ajoute un champ `data_freshness` au payload (dans `query_metadata` si présent, sinon à la racine) listant, par source (FINESS, Ameli, RPPS, CDS, IRIS), la dernière ingestion réussie (`last_success_at`, `staleness_days`) ET la dernière fois que la donnée a réellement changé (`last_data_change_at`, `data_age_days` — un run court-circuité « fichier amont identique » compte comme succès mais ne rajeunit pas la donnée ; c'est `data_age_days` qui dit l'âge réel de ce qui est servi). Opt-in pour ne pas alourdir les payloads par défaut. Cache 5min côté serveur — coût négligeable.

Output Schema

ParametersJSON Schema
NameRequiredDescription
keyNoClé recherchée (SIREN, num_finess, code INSEE, …).
foundYes
messageNoExplication actionnable quand `found=false` (cause probable + remédiation).
lookupStatusYes

TDQS

A4.7/5.0
Behavior5/5

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

Beyond the readOnly/idempotent annotations, the description discloses return-shape details (LookupResult discriminated by found), the not-found payload, DREES lag, abbreviation behavior of raison_sociale, and the always-null email field. These are substantive behavioral disclosures not present in annotations or schema.

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 long but every sentence earns its place: purpose, return behavior, data-lag warning, source, two field caveats, and cross-check advice. It is front-loaded with the core action and structured with clear notes, so an agent can extract the important constraints efficiently.

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?

For a lookup tool with an output schema and rich annotations, the description still adds necessary real-world context: staleness, legal-name truncation, email unavailability, and fallback sources. Nothing needed to call this tool correctly or interpret its output is missing.

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%, so the baseline is 3. The schema already documents num_finess as exact 9 digits and describes include_freshness in detail. The description adds data-quality caveats but not new field-level semantic instructions beyond what the schema provides.

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?

Description states a specific action ('Récupère le détail complet') on a specific resource ('établissement de santé par son numéro FINESS'), making its target unmistakable. It also differentiates from sibling tools by identifier type: this is by FINESS, while etablissement_by_siret and entreprise_by_siren are named as alternatives for legal-name lookup.

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?

The description explicitly says when to cross-check (‘structures émergentes... cross-check ARS / Service Public') and names exact alternative tools for legal-name completness (‘entreprise_by_siren / etablissement_by_siret'). It also warns that email is always null, preventing wasted calls for that field.

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

etablissement_by_siretA
Read-onlyIdempotent
Inspect

Récupère le détail d'un établissement par son SIRET (14 chiffres) via l'API SIRENE INSEE V3.11 : raison sociale de l'unité légale, enseigne commerciale, NAF de l'établissement, dates de création/fermeture, statut administratif actif/fermé, adresse complète, tranche d'effectif. Source : SIRENE INSEE V3.11 (api.insee.fr).

Format de retour : objet LookupResult discriminé par found.

  • found: true → établissement à plat (siret, siren, actif, dateFermeture, enseigne, adresse, …)

  • found: false{ found: false, key, lookupStatus: 'not_found', message }. Cas typiques : clé INSEE_SIRENE_API_KEY non configurée côté serveur (message explicite), SIRET inexistant SIRENE, diffusion partielle INSEE.

⚠️ Différence avec entreprise_by_siren : ce tool renvoie UN établissement précis (un site), alors que entreprise_by_siren renvoie l'unité légale + sa liste d'établissements. Pour détecter un SIRET fermé encore listé actif côté FINESS, lire actif: false + dateFermeture.

Pas de coords : l'endpoint INSEE /siret/<siret> ne renvoie pas les coordonnées GPS. Pour géolocaliser, croiser avec geocode_adresse côté caller ou utiliser entreprises_in_radius.

Rate limit INSEE : 30 req/min (retry-after géré côté serveur).

ParametersJSON Schema
NameRequiredDescriptionDefault
siretYesSIRET exact, 14 chiffres.

Output Schema

ParametersJSON Schema
NameRequiredDescription
keyNoClé recherchée (SIREN, num_finess, code INSEE, …).
foundYes
messageNoExplication actionnable quand `found=false` (cause probable + remédiation).
lookupStatusYes

TDQS

A4.8/5.0
Behavior5/5

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

Annotations already declare readOnly=true, idempotent=true, non-destructive. Description adds significant behavioral context: the tool queries INSEE V3.11 API, returns a discriminated LookupResult (found true/false with specific fields), describes two not_found scenarios (API key missing, SIRET not found in SIRENE or diffusion partielle), explicitly states no GPS coordinates are returned, and explains rate limiting behavior. No contradictions with annotations.

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?

Description is detailed with well-structured sections (return format, error cases, sibling distinction, limitations, rate limit). However, it is somewhat verbose (multiple paragraphs); some sentences could be condensed. Front-loaded with purpose and key details, earning a 4.

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?

Given the tool's simplicity (1 param, output schema present, rich annotations), the description covers all essential aspects: return type, error handling, source, limitations (no coords), rate limit, and comparison with sibling tool. No gaps for an AI agent to misunderstand usage.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema has 100% coverage for the single parameter 'siret' (string, 14 digits). Description reinforces that SIRET must be exact 14 digits and adds context about format expectations. While schema already documents the parameter, the description provides meaningful usage context (exactness) justifying a score above baseline 3.

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 it retrieves details of an establishment by SIRET (14 digits) via the INSEE SIRENE API, listing specific fields returned (e.g., raison sociale, NAF, address, status). It explicitly differentiates from sibling 'entreprise_by_siren' by noting that this tool returns a single establishment site while the sibling returns the legal unit plus its establishments.

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?

Provides explicit when-to-use: retrieving details of a specific establishment by SIRET. Contrasts with 'entreprise_by_siren' for legal unit vs. establishment. Advises on detecting closed SIRET still active on FINESS by checking 'actif' and 'dateFermeture'. Notes rate limit (30 req/min) with server-side retry handling. Offers alternative tools for geocoding ('geocode_adresse', 'entreprises_in_radius').

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

etablissements_finess_by_categorieA
Read-onlyIdempotent
Inspect

Liste des établissements FINESS par famille, avec filtre département ou commune optionnel. Pas de rayon — pour énumération exhaustive d'une zone administrative. 24 familles disponibles : mco, ssr, sld, had, psychiatrie, dialyse, ambulatoire, labo, imagerie, pharmacie, msp_cpts, ehpad, residence_autonomie, senior_accompagnement, ssiad, aide_domicile, handicap_enfants, handicap_adultes, addictologie, enfance_protection, pmi, hebergement_social, prevention_sante, groupement.

V0.19.0 : accepte nom_commune (string) comme alternative à code_insee (résolu via geo.api.gouv.fr). XOR strict — passer SOIT departement SOIT code_insee SOIT nom_commune (combinable avec departement qui agit alors comme hint de désambiguïsation pour homonymes type "Saint-Martin"). Aucun param zone = France entière (acceptée).

Source : FINESS / DREES. Note : champ email toujours null (non exposé par FINESS public). Note : raison_sociale provient du dump DREES qui abrège les libellés longs (~38 car. max, ex 'CERBALLIANCE HA' pour 'CERBALLIANCE HAZEBROUCK'). Pour le nom légal complet, cross-check via SIREN/SIRET (entreprise_by_siren / etablissement_by_siret). Lentille : un filtre familles compte les établissements par leur catégorie FINESS principale. Les activités hébergées dans un site d'une autre catégorie (ex. plateau de biologie d'un hôpital sous famille=labo) ne sont pas comptées — voir le champ perimetre de la réponse. La famille imagerie renvoie le plus souvent 0 résultat (FINESS ne répertorie pas les cabinets d'imagerie).

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoNombre max de résultats (1-500, défaut 100).
categorieYesFamille FINESS recherchée (24 valeurs disponibles, voir enum).
code_inseeNoCode INSEE de commune (5 caractères). Optionnel. XOR strict avec `departement` et `nom_commune`.
departementNoCode département INSEE (ex: '75', '2A', '2B', '971'). Métropole 2 caractères (Corse '2A'/'2B', pas '20'), DOM/TOM 3 caractères. Optionnel. Combinable avec `nom_commune` comme hint resolver (filtre les homonymes), sinon XOR strict avec `code_insee` et `nom_commune`.
nom_communeNoNom officiel de commune (alternative à `code_insee`, V0.19). Ex: "Lille", "Saint-Étienne". Le serveur résout en interne via geo.api.gouv.fr. Si ambigu (ex "Saint-Martin" → 5 villes), retourne une erreur structurée avec candidates. Combinable avec `departement` comme hint de désambiguïsation. Abréviations type "St-Martin" non reconnues — utiliser le nom officiel complet.
include_freshnessNoSi true, ajoute un champ `data_freshness` au payload (dans `query_metadata` si présent, sinon à la racine) listant, par source (FINESS, Ameli, RPPS, CDS, IRIS), la dernière ingestion réussie (`last_success_at`, `staleness_days`) ET la dernière fois que la donnée a réellement changé (`last_data_change_at`, `data_age_days` — un run court-circuité « fichier amont identique » compte comme succès mais ne rajeunit pas la donnée ; c'est `data_age_days` qui dit l'âge réel de ce qui est servi). Opt-in pour ne pas alourdir les payloads par défaut. Cache 5min côté serveur — coût négligeable.

Output Schema

ParametersJSON Schema
NameRequiredDescription
countYesNombre d'entrées retournées dans `results` (post-troncature).
totalNoEffectif réel avant troncature. Présent sur les tools de nomenclature paginés (lister_*) : `count` = échantillon, `total` = total réel, re-appeler avec un `limit` supérieur si `truncated`.
resultsYesEntrées métier (shape spécifique au tool, cf. description du tool).
freshnessNoFraîcheur des sources (présent si `include_freshness: true`).
perimetreNoLentille de la source : ce que le comptage inclut/exclut. Lire `completeness_note` et la restituer au lecteur final.
truncatedNotrue si le total réel dépasse `limit` (re-paginer via `offset` si supporté, ou augmenter `limit` sur les lister_*). Optional sur les tools de listing exhaustif (lister_*).
query_metadataNoMetadata de la query (radius_km, departement, filtres appliqués, …).
activite_hebergeeNoCompte juxtaposé des sites hébergeant l'activité correspondant à la famille filtrée, sous une autre catégorie FINESS. Distinct du `count` principal — lire `note` pour comprendre la sémantique et ne JAMAIS additionner les deux comptes sans préciser leur nature.

TDQS

A4.6/5.0
Behavior5/5

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

Annotations already mark the tool as read-only and idempotent, and the description adds rich non-obvious behavior: `email` is always null, `raison_sociale` is truncated, category counting uses the principal FINESS category, `imagerie` usually returns 0, and `nom_commune` is resolved via geo.api.gouv.fr. This goes well beyond the annotations and materially helps an agent interpret results correctly.

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?

The description is long but dense and front-loaded with purpose before diving into caveats. Each warning, truncation note, resolution behavior, and freshness explanation earns its place for a tool with this complexity; however, the inline list of 24 families partially duplicates the schema enum and adds prose length.

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?

Given the output schema exists, return values need not be explained. The description covers data source, parameter constraints, geo-resolution, XOR semantics, known data quality issues, and even freshness metadata behavior. An agent has enough to select, invoke, and interpret this tool correctly without external information.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3. The description adds real value by explaining that a `familles` filter counts establishments by principal FINESS category rather than every hosted activity, and warns that `imagerie` typically returns no results. It also clarifies the semantics of combining `nom_commune` with `departement` for disambiguation.

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?

States a specific verb and resource: listing FINESS establishments by family, with optional department/commune filters. It explicitly distinguishes itself from radius-based tools with 'Pas de rayon — pour énumération exhaustive d'une zone administrative.' This makes the tool's scope immediately clear.

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

Usage Guidelines4/5

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

The description tells the agent when this tool is appropriate: exhaustive enumeration of an administrative zone rather than a radius search. It also explains the strict XOR between zone parameters and how `departement` can act as a disambiguation hint, giving practical selection guidance even if it does not explicitly name alternative sibling tools.

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

etablissements_finess_in_radiusA
Read-onlyIdempotent
Inspect

Recherche d'établissements de santé FINESS dans un rayon géographique (PostGIS ST_DWithin). Filtrable par familles. 24 valeurs disponibles : mco, ssr, sld, had, psychiatrie, dialyse, ambulatoire, labo, imagerie, pharmacie, msp_cpts, ehpad, residence_autonomie, senior_accompagnement, ssiad, aide_domicile, handicap_enfants, handicap_adultes, addictologie, enfance_protection, pmi, hebergement_social, prevention_sante, groupement. Source : FINESS / DREES (dump CSV ingéré localement). Note : champ email toujours null (non exposé par FINESS public). Note : raison_sociale provient du dump DREES qui abrège les libellés longs (~38 car. max, ex 'CERBALLIANCE HA' pour 'CERBALLIANCE HAZEBROUCK'). Pour le nom légal complet, cross-check via SIREN/SIRET (entreprise_by_siren / etablissement_by_siret). Lentille : un filtre familles compte les établissements par leur catégorie FINESS principale. Les activités hébergées dans un site d'une autre catégorie (ex. plateau de biologie d'un hôpital sous famille=labo) ne sont pas comptées — voir le champ perimetre de la réponse. La famille imagerie renvoie le plus souvent 0 résultat (FINESS ne répertorie pas les cabinets d'imagerie).

ParametersJSON Schema
NameRequiredDescriptionDefault
latYesLatitude du centre (WGS84).
lonYesLongitude du centre (WGS84).
limitNoNombre max de résultats (1-500, défaut 100).
famillesNoFamilles FINESS à inclure (24 valeurs disponibles, voir enum). Si omis, toutes catégories.
radius_kmNoRayon en km (0.1-50, défaut 5).
include_freshnessNoSi true, ajoute un champ `data_freshness` au payload (dans `query_metadata` si présent, sinon à la racine) listant, par source (FINESS, Ameli, RPPS, CDS, IRIS), la dernière ingestion réussie (`last_success_at`, `staleness_days`) ET la dernière fois que la donnée a réellement changé (`last_data_change_at`, `data_age_days` — un run court-circuité « fichier amont identique » compte comme succès mais ne rajeunit pas la donnée ; c'est `data_age_days` qui dit l'âge réel de ce qui est servi). Opt-in pour ne pas alourdir les payloads par défaut. Cache 5min côté serveur — coût négligeable.

Output Schema

ParametersJSON Schema
NameRequiredDescription
countYesNombre d'entrées retournées dans `results` (post-troncature).
totalNoEffectif réel avant troncature. Présent sur les tools de nomenclature paginés (lister_*) : `count` = échantillon, `total` = total réel, re-appeler avec un `limit` supérieur si `truncated`.
resultsYesEntrées métier (shape spécifique au tool, cf. description du tool).
freshnessNoFraîcheur des sources (présent si `include_freshness: true`).
perimetreNoLentille de la source : ce que le comptage inclut/exclut. Lire `completeness_note` et la restituer au lecteur final.
truncatedNotrue si le total réel dépasse `limit` (re-paginer via `offset` si supporté, ou augmenter `limit` sur les lister_*). Optional sur les tools de listing exhaustif (lister_*).
query_metadataNoMetadata de la query (radius_km, departement, filtres appliqués, …).
activite_hebergeeNoCompte juxtaposé des sites hébergeant l'activité correspondant à la famille filtrée, sous une autre catégorie FINESS. Distinct du `count` principal — lire `note` pour comprendre la sémantique et ne JAMAIS additionner les deux comptes sans préciser leur nature.

TDQS

A4.3/5.0
Behavior5/5

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

The description goes far beyond the annotations by disclosing key behavioral caveats: email is always null, raison_sociale is truncated, family filtering counts only by principal FINESS category, imagerie typically returns 0, and the source is a local FINESS/DREES dump. These are exactly the non-obvious behaviors an agent needs to interpret results correctly.

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

Conciseness3/5

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

The description is front-loaded with the main action and the caveats are labeled clearly, but it redundantly lists all 24 family values that already appear in the schema enum. That list adds length without information value, making the overall text less concise than it could be.

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?

Despite high schema and annotation coverage, the description covers the important contextual gaps: data source, legal-name truncation and cross-checking, family-filter semantics, and a known data limitation. With an output schema present, return-value details do not need to be repeated here, so the description is sufficiently complete for an agent to invoke and interpret this tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3. The description adds genuine value for the familles parameter by explaining the principal-category lens and the imagerie limitation, which are not inferable from the enum. Other parameters are already well described in the schema.

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 opens with a specific verb and resource: searching FINESS health establishments within a geographic radius, which clearly distinguishes it from exact-match and by-category siblings. The explicit radius scope and the family-filter concept make the tool's identity unambiguous.

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 establishes a clear use case: radius-based FINESS search with optional family filtering. It mentions a relevant cross-check path to SIREN/SIRET tools for legal names, but it does not explicitly state when to prefer this tool over related siblings such as etablissements_finess_by_categorie, leaving sibling selection partially implicit.

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

finess_sirene_coverage_in_radiusA
Read-onlyIdempotent
Inspect

Compare la couverture du référentiel FINESS DREES (sites physiques agréés LBM/pharmacie/etc.) au référentiel SIRENE DINUM (SIRET physiques actifs au NAF cible) dans un rayon géographique. Métrique : ratio sites FINESS / SIRET SIRENE. Utile pour détecter une sur-déclaration FINESS (sites encore listés mais SIRET fermés) ou une sous-déclaration DREES (sites SIRENE non agréés FINESS). Inclut une méthodologie explicite + caveats. V0.13.2 : si familles n'est pas passé, le scope FINESS est auto-dérivé du NAF cible (garantit un ratio cohérent — sinon finess_sites mélangerait toutes les familles co-localisées dans le rayon). Le matching FINESS↔SIRET est gaté par activité NAF↔famille (cas Hôpital Franco-Britannique : IFSI et labo au 4 rue Kléber ne sont plus confondus). Source : FINESS DREES + DINUM Recherche Entreprises + SIRENE INSEE.

ParametersJSON Schema
NameRequiredDescriptionDefault
latYesLatitude WGS84 du centre de la zone.
lonYesLongitude WGS84 du centre de la zone.
nafYesCode NAF SIRENE à comparer (ex: '8690B' labos d'analyses médicales, '4773Z' pharmacies, '8621Z' médecine générale).
famillesNoFamilles FINESS à inclure côté DREES. V0.13.2 : si omis, auto-dérivé du NAF cible via la table naf-finess-mapping (ex: naf=8690B → familles=[labo] ; naf=8610Z → multi-familles hospitalières). Passer explicitement si vous voulez restreindre davantage le scope. Valeurs : mco, ssr, sld, had, psychiatrie, dialyse, ambulatoire, labo, imagerie, pharmacie, msp_cpts, ehpad, residence_autonomie, senior_accompagnement, ssiad, aide_domicile, handicap_enfants, handicap_adultes, addictologie, enfance_protection, pmi, hebergement_social, prevention_sante, groupement.
radius_kmNoRayon de la zone en km (0.1-50, défaut 5).
max_unites_legalesNoNombre maximum d'unités légales DINUM à déplier (1-25, défaut 10). Au-delà : truncated_unites_legales=true.

Output Schema

ParametersJSON Schema
NameRequiredDescription
caveatsNoLimitations méthodologiques explicites (discipline zéro overclaim).
perimetreNoLentille de la source : ce que le comptage inclut/exclut. Lire `completeness_note` et la restituer au lecteur final.
methodologyYesDescription LLM-friendly de l'algorithme appliqué.
finess_sitesYesNombre de sites FINESS dans le rayon (référentiel DREES).
matched_countNoNombre de matchs greedy Dice ≥ 0.7.
sirene_siretsYesNombre de SIRET physiques actifs au NAF cible dans le rayon (DINUM/SIRENE).
coverage_ratioYesmatched / finess_sites ∈ [0, 1]. null si `sirene_sirets === 0` (zone rurale + NAF rare → ratio non calculable).
coverage_statusYesStatut typé du calcul (toujours présent). `computed` = calcul nominal (finess_sites peut être 0 sur rayon vide). `scope_empty_unknown_naf` = NAF non mappé, court-circuit (corriger le NAF ou compléter naf-finess-mapping). `scope_empty_familles_incompatible` = `familles` toutes incompatibles avec le NAF (réviser le couple ou omettre `familles` pour auto-derive). Le `caveats[]` reste exposé en parallèle pour lecture humaine — ce champ fait foi pour le routage.
matched_samplesNo
finess_only_countNo
sirene_only_countNo
finess_only_samplesNo
sirene_only_samplesNo
familles_excluees_nafNoFamilles passées en input mais incompatibles avec le `naf` cible, exclues du périmètre FINESS (V0.13.2 couche 2). Absent si tout est cohérent ou si `familles` n'a pas été passé.
familles_auto_deriveesYesFamilles FINESS auto-dérivées du `naf` cible quand `familles` n'est pas passé (V0.13.2 couche 1 — garantit un ratio cohérent). `null` si le caller a passé `familles` explicitement.
truncated_unites_legalesNotrue si le cap `maxUnitesLegales` a été atteint avant énumération complète.

TDQS

A4.3/5.0
Behavior4/5

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

Annotations declare readOnlyHint=true and destructiveHint=false, matching the description's non-destructive nature. Description adds value by detailing data sources, matching logic, version-specific behavior, and caveats beyond what annotations provide.

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?

Description is detailed but not overly verbose. Every sentence provides useful information (purpose, methodology, version notes). Could be slightly more concise, but front-loading core purpose is effective.

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?

Given 6 params (100% schema coverage) and presence of output schema, the description covers purpose, metric, usage, methodology, caveats, and version behavior. It is contextually complete for a complex tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% with clear descriptions. Description adds significant context, especially for familles (auto-derivation, relationship to NAF) and naf (examples). This goes beyond Schema alone.

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?

Description clearly states the tool compares FINESS DREES and SIRENE DINUM coverage in a radius, providing a ratio. It specifies use cases (over/under-declaration) and distinguishes from siblings like etablissements_finess_in_radius by focusing on coverage ratio rather than listing.

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

Usage Guidelines4/5

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

Explains when to use (detect discrepancies) and includes methodology, caveats, and parameter guidance (auto-derivation of familles). However, it does not explicitly mention when not to use or list alternative sibling tools.

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

geocode_adresseA
Read-onlyIdempotent
Inspect

Géocode une adresse française en coordonnées GPS. Source : IGN Géoplateforme (data.geopf.fr). Précision au numéro de rue.

Le champ score (0-1) qualifie la fiabilité du match : >= 0.8 fiable, < 0.5 = match douteux (souvent un fallback rue/commune sans rapport avec l'adresse demandée). Le champ booléen confidence_low vaut true dans ce cas : ne PAS utiliser point pour une décision quand confidence_low: true. Le champ type indique aussi la granularité (housenumber > street > locality > municipality).

ParametersJSON Schema
NameRequiredDescriptionDefault
adresseYesAdresse complète à géocoder.
codePostalNoOptionnel — limiter le résultat à un code postal pour désambiguïser.
codeCommuneNoOptionnel — limiter au code INSEE de commune.

TDQS

A4.3/5.0
Behavior4/5

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

Les annotations indiquent déjà que l'outil est en lecture seule et idempotent. La description ajoute des informations comportementales importantes : source des données, précision, et signification des champs de sortie (score, confidence_low, type). Aucune contradiction avec les annotations.

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?

Deux phrases concises qui commencent par l'essentiel : l'action principale. Aucun mot superflu, chaque phrase apporte une information utile.

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?

Malgré l'absence de schéma de sortie, la description explique suffisamment le format des résultats (score, confidence_low, type) pour qu'un agent puisse les interpréter. Elle couvre également la source et la précision, ce qui est complet pour un outil de géocodage en lecture seule.

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?

La couverture du schéma est de 100 % : chaque paramètre a une description. La description de l'outil n'ajoute pas d'information supplémentaire sur les paramètres au-delà de ce qui figure déjà dans le schéma. Note de base de 3 justifiée.

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?

La description indique clairement que l'outil géocode une adresse française en coordonnées GPS, précise la source (IGN Géoplateforme) et la précision (numéro de rue). Cela le distingue de son outil frère 'reverse_geocode' qui fait l'inverse.

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

Usage Guidelines4/5

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

La description explique comment interpréter les résultats : fiabilité selon le score, champ confidence_low pour les correspondances douteuses, et granularité via le type. Cependant, elle ne donne pas de contexte explicite sur quand utiliser cet outil plutôt que des alternatives comme 'reverse_geocode'.

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

get_commune_by_codeA
Read-onlyIdempotent
Inspect

Récupère une commune par son code INSEE. Retourne un objet LookupResult discriminé par found. found: true → champs commune à plat (nom, codesPostaux, centre…). found: false{ found: false, key, lookupStatus: 'not_found', message } orientant vers autocomplete_commune pour disambiguer.

Alias acceptés : code_insee/codeInsee/inseecode.

ParametersJSON Schema
NameRequiredDescriptionDefault
codeYesCode INSEE 5 caractères. Ex: "75056" Paris, "59009" Villeneuve-d'Ascq, "2A004" Ajaccio.

Output Schema

ParametersJSON Schema
NameRequiredDescription
keyNoClé recherchée (SIREN, num_finess, code INSEE, …).
foundYes
messageNoExplication actionnable quand `found=false` (cause probable + remédiation).
lookupStatusYes

TDQS

A4.7/5.0
Behavior4/5

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

Annotations already declare readOnlyHint, openWorldHint, idempotentHint, destructiveHint. The description adds value by detailing the discriminated return type and the not_found behavior with a suggestion for alternative tool, but does not contradict annotations.

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 very concise with four lines, front-loaded with the core purpose, and each sentence adds necessary information without redundancy.

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?

Given the low complexity, high annotation coverage, and presence of output schema, the description fully covers the return behavior and fallback, leaving no gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% with examples. The description adds alias information (code_insee/codeInsee/insee) that is not in the schema, enhancing understanding beyond the schema definition.

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 verb 'Récupère' and the resource 'commune par son code INSEE'. It distinguishes from sibling 'autocomplete_commune' by mentioning it for disambiguation.

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?

The description explicitly tells the agent what to do when the commune is not found (use autocomplete_commune), providing clear guidance on fallback behavior.

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

historique_etablissementA
Read-onlyIdempotent
Inspect

Reconstitue la timeline complète d'un établissement de santé (ouvertures, fermetures, changements de NAF/enseigne) en croisant FINESS DREES ↔ resolver SIRET (RPPS + DINUM) ↔ SIRENE INSEE V3.11. Lit les periodesEtablissement complètes pour chaque SIRET candidat.

V0.7.0 : SIRET candidats élargis via le resolver — inclut désormais les SIRET fermés du SIREN parent qui matchent l'adresse FINESS (invisibles côté RPPS seul). Permet de tracer la fermeture exacte d'un site même quand FINESS le liste encore actif.

Usage typique :

  • Tracer l'historique d'un site après une fusion-acquisition

  • Identifier la date de fermeture exacte d'un SIRET encore listé actif côté FINESS

  • Comprendre une cascade de rebrandings via les changements de enseigne1Etablissement au fil des périodes

Format : objet LookupResult. Quand found: true, retourne finess (vue DREES synthétique) + siret_timelines (1 entrée par SIRET candidat avec periodes chronologiques).

Coût : 1 RPC FINESS + 1 SELECT rpps + N appels DINUM + N appels INSEE en parallèle (N ≤ 5 typiquement). Pas de cache.

ParametersJSON Schema
NameRequiredDescriptionDefault
num_finessYesNuméro FINESS exact (9 chiffres).

Output Schema

ParametersJSON Schema
NameRequiredDescription
keyNoClé recherchée (SIREN, num_finess, code INSEE, …).
foundYes
messageNoExplication actionnable quand `found=false` (cause probable + remédiation).
lookupStatusYes

TDQS

A4.4/5.0
Behavior5/5

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

Annotations already indicate read-only and idempotent behavior. The description adds detailed behavioral context: it reads multiple sources, mentions the cross-referencing approach, version details (V0.7.0), and cost breakdown (RPC, SELECT, parallel calls). No contradiction with annotations.

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?

The description is well-structured with sections for purpose, version details, usage examples, output format, and cost. While slightly long, it front-loads the key purpose and provides valuable context without unnecessary verbosity.

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?

Given that an output schema exists and the input parameter is fully covered, the description provides complete context: explains the output structure (LookupResult with found flag, finess view, siret_timelines), addresses versioning, and mentions cost and lack of caching. The tool's complexity is well-handled.

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?

With 100% schema coverage, the description adds no additional parameter semantics beyond what the schema provides (exact 9-digit FINESS number). The parameter description in the schema is sufficient, so the baseline score of 3 is appropriate.

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 reconstructs the complete timeline of a healthcare establishment by cross-referencing multiple data sources (FINESS, RPPS, DINUM, INSEE). It distinguishes from sibling tools like 'etablissement_by_finess' by focusing on historical reconstruction rather than just current data.

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

Usage Guidelines4/5

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

The description provides three typical use cases (tracing history after merger/acquisition, identifying exact closure dates, understanding rebranding cascades), which helps identify when to use the tool. However, it does not explicitly contrast with alternatives or state when not to use it.

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

inspect_siteA
Read-onlyIdempotent
Inspect

Vue 360 d'un établissement de santé en 1 appel (V0.10). Pendant naturel de panorama_sante_territoire côté site : agrège en parallèle (a) identification FINESS DREES (raison sociale, adresse, téléphone), (b) statut administratif SIRENE via le resolver SIRET (verdicts site + groupe, best_match, SIREN explorés, dinum_errors, explication LLM-friendly), (c) professionnels rattachés via num_finess (sample borné + flag truncated si le site a plus de PS — PAS un count total), (d) historique INSEE (timeline périodes administratives par SIRET candidat).

Remplace 3 appels MCP individuels (verifier_site_actif + rpps_dans_etablissement + historique_etablissement) par 1 seul. Utile pour : prospection (qualifier un site avant outreach), audit territorial (cross-check rapide d'un FINESS suspect), enrichissement CRM en batch.

Format de retour : objet LookupResult. Quand found: true, payload avec 4 sections (finess, statut_site, professionnels, historique). La section historique peut être available: false quand le FINESS existe mais qu'aucun SIRET candidat n'a été identifié (RPPS vide + DINUM 0 match) — dans ce cas le message reprend celui de historique_etablissement. Quand num_finess est absent de FINESS DREES, retourne {found: false, lookupStatus: 'not_found', message}.

Coût : 3 sous-appels parallèles. Cache PostgreSQL absorbe la duplication FINESS-RPC ; le pivot RPPS→DINUM est exécuté en double (verifier + historique partagent la cascade), surcoût p95 ≤ 600 ms — acceptable pour un agrégateur. Pour les besoins ciblés (juste le verdict, juste l'historique), préférer les tools individuels. Payload lourd (~7K tokens) : passer historique_detail: false pour un retour allégé (résumé au lieu des timelines SIRENE complètes) en usage batch.

Alias acceptés : numFiness/finess/idnum_finess.

ParametersJSON Schema
NameRequiredDescriptionDefault
num_finessYesNuméro FINESS exact 9 chiffres. Ex: '590048997'.
rpps_limitNoNombre max de PS dans `professionnels.sample`. `professionnels.count` = taille du sample (≤ cette borne), pas le total du site ; `truncated: true` signale qu'il y a davantage de PS. Borné [1, 50]. Défaut 10.
historique_detailNoInclure les timelines SIRENE détaillées dans `historique.siret_timelines` (défaut true). `false` = payload allégé (~7K tokens en moins) : `historique` ne porte qu'un `resume` (counts) + un pointeur vers `historique_etablissement`.

Output Schema

ParametersJSON Schema
NameRequiredDescription
keyNoClé recherchée (SIREN, num_finess, code INSEE, …).
foundYes
messageNoExplication actionnable quand `found=false` (cause probable + remédiation).
lookupStatusYes

TDQS

A4.6/5.0
Behavior4/5

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

Annotations already declare readOnlyHint, destructiveHint=false, and idempotentHint. The description adds valuable context: it's an aggregator with parallel sub-calls, returns LookupResult with sections, handles truncation for professionals (not count), and describes edge cases (missing FINESS, unavailable historique). No contradictions with annotations.

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?

The description is relatively long but well-structured with sections and bullet points. It includes examples and explicit guidance. While not extremely concise, every sentence adds value.

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?

Given the tool's complexity (aggregator with multiple sub-calls, optional parameters, edge cases) and the presence of an output schema, the description fully covers return format, failure modes, performance considerations, and aliases. It leaves no critical gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline is 3. The description adds significant value: explains that rpps_limit is a sample (not total count) with truncated flag, that historique_detail reduces payload by ~7K tokens, and mentions aliases for num_finess. This enhances understanding beyond the schema.

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 explicitly states it provides a '360 view of a health establishment in 1 call' and aggregates four types of data (identification, administrative status, professionals, history). It distinguishes from siblings by noting it replaces three individual tools (verifier_site_actif, rpps_dans_etablissement, historique_etablissement) with a single call.

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?

The description clearly states when to use (prospection, audit territorial, CRM enrichment) and when not (for specific needs like just verdict or history, prefer individual tools). It also provides guidance on payload weight and suggests setting historique_detail=false for batch usage.

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

lister_nomenclatureA
Read-onlyIdempotent
Inspect

Découverte des nomenclatures de codes du serveur (tool unique paramétré par referentiel) — à appeler avant de filtrer un autre tool plutôt que deviner les codes. ⚠️ Les 3 nomenclatures sont DISTINCTES : un même nombre y désigne des choses différentes (ex '10' = Médecin côté ANS, Neurochirurgien côté Ameli). Ne JAMAIS passer un code d'un référentiel à un paramètre d'un autre — le filtre renverrait vide sans erreur.

referentiel :

  • ameli_specialites — codes specialite_code Ameli (libéraux conventionnés Assurance Maladie / CNAM) : libellé natif, type_ps_code de rattachement, count, libelle_clarifie (désambigüise les libellés partagés, ex "Médecin généraliste" = 01/22/23 ; "Psychiatre" = 33/75), is_libelle_partage. Pour filtrer professionnels_in_radius / professionnels_par_specialite_dept (param specialite_code(s)).

  • ameli_types_ps — codes type_ps Ameli : libelle_source, libelle_clarifie (résout l'ambiguïté du code "2" fourre-tout), count, et specialites_presentes (spécialités regroupées). Payload léger via include_specialites: false (→ nb_specialites).

  • rpps_savoir_faire — spécialités médicales savoir_faire_code RPPS / Annuaire Santé ANS (ex 'SM04' Cardiologie). Pour filtrer densite_sante (cible professionnels) / professionnels_rpps_*. Filtre par profession_code (défaut '10' Médecin ; string vide ou 'null' = tous savoir_faire).

Paginé : limit (défaut 50), réponse expose total et truncated. PÉRIMÈTRE : libéraux conventionnés UNIQUEMENT. HORS PÉRIMÈTRE : médecins exclusivement hospitaliers/salariés, biologistes médicaux salariés en LBM, anatomopathologistes hospitaliers, médecins du travail, médecine légale. Pour effectifs tous statuts, voir Annuaire Santé ANS (RPPS, esante.gouv.fr) — non couvert par ce serveur. Source : Annuaire santé Ameli (Assurance Maladie), MAJ hebdomadaire. Réutilisation soumise à l'art. L.1461-2 CSP — citer la source et la date de sync.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoNombre max de résultats (défaut 50, max 1000). Triés par fréquence décroissante. La réponse expose `total` (effectif réel) et `truncated` — re-appeler avec un `limit` supérieur pour la liste complète.
referentielYesNomenclature à lister. `ameli_specialites` / `ameli_types_ps` = Ameli (libéraux conventionnés) ; `rpps_savoir_faire` = spécialités médicales ANS/RPPS (nomenclature DISTINCTE).
profession_codeNoRéférentiel `rpps_savoir_faire` UNIQUEMENT : code profession ANS (TRE_R94). Défaut '10' (Médecin). String vide ou 'null' = tous savoir_faire, toutes professions.
include_freshnessNoSi true, ajoute un champ `data_freshness` au payload (dans `query_metadata` si présent, sinon à la racine) listant, par source (FINESS, Ameli, RPPS, CDS, IRIS), la dernière ingestion réussie (`last_success_at`, `staleness_days`) ET la dernière fois que la donnée a réellement changé (`last_data_change_at`, `data_age_days` — un run court-circuité « fichier amont identique » compte comme succès mais ne rajeunit pas la donnée ; c'est `data_age_days` qui dit l'âge réel de ce qui est servi). Opt-in pour ne pas alourdir les payloads par défaut. Cache 5min côté serveur — coût négligeable.
include_specialitesNoRéférentiel `ameli_types_ps` UNIQUEMENT : inclure le sous-tableau `specialites_presentes` détaillé (défaut true). `false` → remplacé par `nb_specialites` (compteur), ~6K tokens économisés.

Output Schema

ParametersJSON Schema
NameRequiredDescription
countYesNombre d'entrées retournées dans `results` (post-troncature).
totalNoEffectif réel avant troncature. Présent sur les tools de nomenclature paginés (lister_*) : `count` = échantillon, `total` = total réel, re-appeler avec un `limit` supérieur si `truncated`.
resultsYesEntrées métier (shape spécifique au tool, cf. description du tool).
freshnessNoFraîcheur des sources (présent si `include_freshness: true`).
perimetreNoLentille de la source : ce que le comptage inclut/exclut. Lire `completeness_note` et la restituer au lecteur final.
truncatedNotrue si le total réel dépasse `limit` (re-paginer via `offset` si supporté, ou augmenter `limit` sur les lister_*). Optional sur les tools de listing exhaustif (lister_*).
query_metadataNoMetadata de la query (radius_km, departement, filtres appliqués, …).
activite_hebergeeNoCompte juxtaposé des sites hébergeant l'activité correspondant à la famille filtrée, sous une autre catégorie FINESS. Distinct du `count` principal — lire `note` pour comprendre la sémantique et ne JAMAIS additionner les deux comptes sans préciser leur nature.

TDQS

A4.8/5.0
Behavior5/5

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

Beyond the readOnlyHint/destructiveHint annotations, it discloses silent empty results for mismatched codes, the scoped perimeter with a detailed hors-périmètre list, pagination via total/truncated, and source freshness/legal reuse conditions. This gives an agent a realistic model of failure and scope without invoking the tool.

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?

The purpose and the critical warning are front-loaded, and the rest is organized into référentiel bullets plus scope/source blocks. It is long, but most sentences carry distinct operational value; a slight redundancy with the scheama's paraméter docs prevents a 5.

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?

With no output scheama and three référentiels, the description still covers per-réferentiel response fields, pagination, edge cases (empty/null profession_code, shared libellés), out-of-scope populations, data source, and MAJ cadence. An agent has enough to call it correctly and interpret results without guessing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input scheama already provides detailed descriptions and enum for every paraméter, so the baseline is 3; the description adds cross-réferentiel warnings (e.g. '10' means Médecin vs Neurochirurgien) and payload-size consequences for include_specialites/include_freshness. That extra mapping to downstream parameter names justifies one point above baseline.

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 states a specific purpose ('Découverte des nomenclatures de codes du serveur') and positions it as the tool to call before filtering another tool, so an agent knows exactly what it lists and why. The three référentiel branches are individually described with examples, which distinguishes this discovery tool from the many filter siblings.

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?

It explicitly says when to call it ('à appeler avant de filtrer un autre tool plutôt que deviner les codes') and maps each référentiel to the downstream tools that consume it. It also gives an exclusion: for all-status headcounts, use the external Annuaire Santé ANS because the server only covers libéraux conventionnés.

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

panorama_implantation_completA
Read-onlyIdempotent
Inspect

Étude d'implantation labo en 1 appel (V0.23). Géocode l'adresse cible puis agrège EN PARALLÈLE 7 sections : territoire (densités PS commune vs national + établissements), demande (profil démographique du BASSIN — rayon — via profil_iris : âge, CSP, revenu pondéré), concurrents (labos FINESS), pourvoyeurs (MCO/EHPAD/SSR/dialyse — drivers écosystémiques), prescripteurs (médecins RPPS + IDEL Ameli), cds (centres de santé), referentiels (qualité couverture FINESS↔SIRENE).

Remplace ~15 appels MCP individuels par 1. Renvoie des RÉSUMÉS (count / top-N / moyenne), JAMAIS de listes brutes. AUCUNE interprétation métier (pas de 'désert médical' ni de verdict GO/NO-GO) — le caller LLM applique sa grille.

DÉGRADATION (lis couverture — 1 drapeau par section) : "ok" | "partiel:<raison>" | "indisponible:<raison>". Si une source est down, SA section est flaggée et le RESTE est renvoyé — comble alors le trou via l'outil unitaire correspondant (etablissements_finess_in_radius, professionnels_rpps_in_radius, densite_sante, centres_sante_in_radius…). Échec d'ANCRAGE (géocodage KO / adresse douteuse / code INSEE indérivable) = rejet total (RangeError).

Pièges internalisés : Paris/Lyon/Marseille basculés sur le département (meta.plm_mode=true) ; prescripteurs expose precis_count (PS géolocalisés à l'adresse, pas au centroïde commune) ; cds sans distance individuelle (centroïde commune).

WORKFLOW : appelle CET outil pour DÉMARRER une étude, puis creuse les sections partiel/indisponible via les unitaires, puis enrichir_concurrents sur le top 3 de concurrents.top.

Sources : IGN (géocodage), FINESS DREES, RPPS/ANS, Ameli/CNAM, INSEE/FILOSOFI, SIRENE/DINUM.

ParametersJSON Schema
NameRequiredDescriptionDefault
pointNoCoordonnées { lat, lon } si déjà connues (skip géocodage). Fournir `code_insee` avec.
adresseNoAdresse cible, géocodée en interne via IGN. Ex: "12 rue Nationale, Lille". XOR avec `point`.
rayon_kmNoRayon du bassin de l'étude (km). Défaut 5.
code_inseeNoCode INSEE commune (avec `point`, quand le géocodage est déjà fait).

TDQS

A4.9/5.0
Behavior5/5

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

Annotations already indicate readOnly, openWorld, idempotent, non-destructive. Description adds parallel aggregation, degradation flags ('ok', 'partiel', 'indisponible'), internalized pitfalls (PLM mode for big cities, precise count for prescripteurs), and source references. No contradiction with annotations.

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?

The description is dense and well-structured with section list and workflow steps. Minor redundancy (e.g., 'Renvoie des RÉSUMÉS...' restates, but key info). Front-loaded with purpose.

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?

Despite no output schema, the description fully covers return values (summaries, degradation flags), edge cases (partial failure, anchorage failure), and internal logic (parallel execution, pitfalls). Sufficient for an agent to use correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

All 4 parameters have descriptions in schema (100% coverage). Description adds critical context: XOR relationship between point and adresse, code_insee with point, default rayon_km=5, and behavior when point is used (skip geocoding).

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 it's an 'étude d'implantation labo' that aggregates 7 sections in parallel, replacing 15 individual MCP calls. It lists each section and explicitly distinguishes from sibling tools by being the orchestration entry point.

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?

Explicit workflow: call this tool to start, then handle partial/indisponible sections with unitary tools, then enrich top 3 concurrents. Also specifies when total failure occurs (anchorage failure) and that it returns summaries, not raw lists, and no business interpretation.

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

panorama_sante_territoireA
Read-onlyIdempotent
Inspect

Panorama santé d'une commune française en 1 appel (V0.9). Agrège en parallèle : population (INSEE Melodi), densités médecins + infirmiers + pharmaciens avec comparaison nationale (méthodo DREES), nombre d'établissements FINESS par famille (default ["labo","pharmacie","ehpad","mco","msp_cpts"]), et un bloc DEMANDE (V0.22.0 — profil démographique de la commune agrégé depuis ses IRIS : âge, CSP, familles, revenu pondéré, à CROISER avec l'OFFRE ci-dessus pour l'aide à l'implantation ; demande: null si commune hors couverture IRIS (DOM non ingéré) — pour le détail au quartier ou un bassin par rayon, utiliser profil_iris).

Remplace 7-10 appels MCP individuels par 1 seul. Ne renvoie AUCUNE interprétation métier (pas de qualification automatique 'désert médical') — le caller LLM applique sa grille.

V0.19.0 : accepte nom_commune (string) comme alternative à code_insee. departement (V0.19) = hint resolver UNIQUEMENT (panorama ne calcule pas par dept ; un departement seul lève une erreur explicite).

Granularité mixte : les densités professionnels et la population sont calculées au niveau commune ; le décompte FINESS est agrégé au niveau département dérivé du code INSEE (limitation V0.9 — pas de RPC count_finess_by_commune encore). Le champ niveauEtablissements du résultat indique "departement" (succès), "indisponible" (dept indérivable, ex code DOM tronqué) — utiliser cette information pour ne pas confondre ratios commune et dept.

Paris/Marseille/Lyon NON supporté : le panorama par commune dépend de la densité par commune, indisponible pour ces villes (INSEE n'expose la population qu'à la commune entière, les praticiens RPPS aux arrondissements). Un code PLM (commune-mère 75056 ou arrondissement) lève une RangeError. Pour ces villes, interroger les tools individuels au niveau code_dept (75/69/13).

Alias acceptés : codeInsee/insee/codecode_insee.

Sources : RPPS / Annuaire Santé ANS (mensuel), FINESS DREES (bimensuel), INSEE Melodi (PMUN 2023).

ParametersJSON Schema
NameRequiredDescriptionDefault
code_inseeNoCode INSEE de la commune 5 caractères. Ex: "59009" Villeneuve-d'Ascq, "33063" Bordeaux, "2A004" Ajaccio. Paris/Lyon/Marseille NON supporté (voir description). XOR avec `nom_commune`.
departementNoCode département INSEE (V0.19, hint resolver UNIQUEMENT). À utiliser EN COMBINAISON avec `nom_commune` pour désambiguer les homonymes. Seul, lève une erreur (panorama = calcul commune uniquement, utiliser `code_insee` ou `nom_commune`).
nom_communeNoNom officiel de commune (alternative à `code_insee`, V0.19). Ex: "Lille", "Saint-Étienne". Combinable avec `departement` comme hint de désambiguïsation pour homonymes (ex "Saint-Martin" + dept "65"). Abréviations type "St-Martin" non reconnues.
finess_famillesNoFamilles FINESS à inclure dans le décompte établissements. Default ["labo","pharmacie","ehpad","mco","msp_cpts"]. Passer [] pour omettre le décompte FINESS (renvoie uniquement population + densités PS).

TDQS

A4.9/5.0
Behavior5/5

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

Description adds significant behavioral context: returns no business interpretation (no 'désert médical'), granularity mix (commune vs department), PLM cities unsupported, 'demande' block null for DOM communes, and sources/update frequency. Annotations already indicate readonly, idempotent, non-destructive, but description enriches with these details.

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?

Description is long but well-structured: summary first, then version updates, granularity mix, PLM warning, aliases, sources. Could be slightly more concise (version numbers may be unnecessary for agent), but front-loaded purpose.

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?

Given complexity (multiple data sources, mixed granularity, special cases) and no output schema, description covers result blocks (population, densities, FINESS, demande) and null cases, error conditions (PLM, departement alone), and version behavior. It is complete enough for agent to use effectively.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, but description adds meaning: 'code_insee' notes PLM unsupported, 'departement' is hint only, 'nom_commune' combinable with departement, no abbreviations, 'finess_familles' explains default and effect of empty array. These details go beyond schema.

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 aggregates multiple data sources into one call for a French commune, replacing 7-10 individual MCP calls. It distinguishes from siblings like 'profil_iris' and 'densite_sante' by providing a holistic overview.

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 states when to use (single commune, replaces many calls) and when not to (Paris/Lyon/Marseille not supported, use individual tools at department level). Also explains parameter usage: 'departement' as hint only, error if used alone; granularity mix warns against confusing commune and department ratios.

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

populationA
Read-onlyIdempotent
Inspect

Population d'une COMMUNE (code INSEE 5 car.), d'un DÉPARTEMENT (2-3 car.) OU d'un IRIS infracommunal (9 car.) — granularité auto-détectée par la longueur du code. Retourne un LookupResult discriminé par found.

  • IRIS (9 car., ex 751103701 = commune 75110 + IRIS 3701) : population totale du quartier au Recensement 2022 (champ population, comptes bruts), + libelle, code_commune, type_iris (H/A/D/Z). Source : INSEE RP 2022 (table ingérée, géo 01/01/2024). Maille la plus fine (quartier) pour les villes ; en zone peu dense la commune = 1 IRIS (type_iris Z, code COM+0000). Pour le profil démographique détaillé d'un îlot ou d'un bassin (âge, CSP, familles, revenu), utiliser profil_iris.

  • Commune (5 car., ex 75056 Paris, 13055 Marseille, 2A004 Ajaccio) : PMUN/PCAP/PTOT. Source INSEE Melodi (DS_POPULATIONS_REFERENCE). PMUN = base légale DREES. Commune fusionnée → found: false + orientation autocomplete_commune. INSEE n'expose PAS les arrondissements PLM (75101-75120, 13201-13216, 69381-69389) → passer la commune-mère ou le département.

  • Département (2-3 car., ex 75, 59, 2A, 971) : Mayotte (976) ABSENTE de Melodi → lookupNotFound.

Alias acceptés : code_insee/codeInsee/insee, code_dept/dept/departement/code_departement, code_iris/iriscode.

ParametersJSON Schema
NameRequiredDescriptionDefault
codeYesCode INSEE — 5 caractères = commune (ex "75056"), 2-3 caractères = département (ex "75", "971", "2A"). Granularité auto-détectée par la longueur.

Output Schema

ParametersJSON Schema
NameRequiredDescription
keyNoClé recherchée (SIREN, num_finess, code INSEE, …).
foundYes
messageNoExplication actionnable quand `found=false` (cause probable + remédiation).
lookupStatusYes

TDQS

A4.9/5.0
Behavior5/5

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

The description goes well beyond annotations by explaining auto-detection of granularity, return type (LookupResult), data sources (INSEE RP 2022, Melodi), and specific behaviors for communes fusionnées, IRIS types, and missing departments. No contradiction with annotations.

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?

The description is detailed and well-structured with bullet points, but slightly verbose. However, it front-loads the core purpose and uses formatting for readability.

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?

Given the complexity of multiple granularities and edge cases, the description is comprehensive. It covers all scenarios (commune, department, IRIS, special cases like PLM, Mayotte) and references the output schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% for the single parameter 'code', but the description greatly enriches it by explaining length-based auto-detection, providing examples, and detailing the IRIS code structure (e.g., '751103701'). Adds substantial meaning beyond the schema.

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: population lookup for communes, departments, or IRIS by INSEE code. It explicitly names the French administrative levels and distinguishes from sibling tools like 'profil_iris'.

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?

Provides explicit when-to-use guidance for population counts at various granularities and when-not-to-use (detailed demographic profiles -> 'profil_iris'). Also warns about edge cases like PLM arrondissements and Mayotte absence.

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

professionnel_by_rppsA
Read-onlyIdempotent
Inspect

Récupère la fiche complète d'un PS par identifiant national (rpps_id / IDNPS, 11 ou 12 chiffres — IDs émis depuis 2020 ont un préfixe "81" = 12 chars ; anciens IDs = 11 chars). Renvoie N entrées quand le PS exerce sur plusieurs sites (1 par site, chacun avec sa propre geo_precision — un même PS peut donc cumuler un site précis FINESS et un site au centroïde commune).

Chaque résultat géolocalisé porte geo_precision ∈ {"adresse", "etablissement_finess", "centroide_commune"} — lire ce champ pour évaluer la fiabilité des coords (précise BAN/FINESS au m près vs centroïde commune ~3 km, non discriminant intra-commune).

Fallback automatique sur l'API FHIR ANS live (gateway.api.esante.gouv.fr/fhir/v2) si non trouvé en base locale (snapshot mensuel J-30 max). Le champ source distingue db (base locale) de ans_fhir (live). include_freshness n'affecte que source: "db". Source : Annuaire Santé, Agence du Numérique en Santé (ANS) — Licence Ouverte v2.0

ParametersJSON Schema
NameRequiredDescriptionDefault
rpps_idYes
include_freshnessNoSi true, ajoute un champ `data_freshness` au payload (dans `query_metadata` si présent, sinon à la racine) listant, par source (FINESS, Ameli, RPPS, CDS, IRIS), la dernière ingestion réussie (`last_success_at`, `staleness_days`) ET la dernière fois que la donnée a réellement changé (`last_data_change_at`, `data_age_days` — un run court-circuité « fichier amont identique » compte comme succès mais ne rajeunit pas la donnée ; c'est `data_age_days` qui dit l'âge réel de ce qui est servi). Opt-in pour ne pas alourdir les payloads par défaut. Cache 5min côté serveur — coût négligeable.

Output Schema

ParametersJSON Schema
NameRequiredDescription
keyNoClé recherchée (SIREN, num_finess, code INSEE, …).
foundYes
messageNoExplication actionnable quand `found=false` (cause probable + remédiation).
lookupStatusYes

TDQS

A4.7/5.0
Behavior5/5

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

Beyond the readOnly/openWorld/idempotent annotations, the description adds meaningfully rich behavior: automatic fallback to the live ANS FHIR API, multi-site result behavior (N entries per site), geo_precision semantics with accuracy implications, source field distinction (db vs ans_fhir), and the exact scope of include_freshness. This is far beyond what annotations alone provide and does not contradict them.

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?

The description is fairly long but densely informative and front-loaded with the core purpose. Each sentence contributes value (format, multi-site behavior, geo_precision, fallback, source semantics, freshness). It could be slightly tighter, but it is well-structured and readable.

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?

Given the output schema exists and annotations cover the safety/idempotency profile, the description provides nearly everything an agent needs: exact input format, multi-site return semantics, geolocation reliability interpretation, fallback behavior, and source/freshness semantics. No critical invocation detail appears missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is only 50%, and the description compensates strongly: it explains the rpps_id format (11/12 digits, 81 prefix for post-2020 IDs) beyond the regex pattern, and it adds behavioral context to include_freshness by clarifying it only affects source: db. This gives an agent much more operational meaning than the bare boolean schema.

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 retrieves a complete professional record by national identifier (rpps_id / IDNPS), with precise number-format rules. It distinguishes this exact-ID lookup from sibling tools such as search-by-name or radius-based tools, even though it does not name them explicitly.

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

Usage Guidelines4/5

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

The intended usage is clear: use this tool when you have an RPPS/IDNPS identifier and need the full record. It does not explicitly state when not to use it or point to alternatives like rpps_search_by_name, but the exact-ID scope provides adequate context without exclusions.

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

professionnels_in_radiusA
Read-onlyIdempotent
Inspect

Recherche de professionnels de santé libéraux conventionnés dans un rayon géographique. Précision géo HYBRIDE depuis le géocodage BAN (Chantier C) : ~77 % des PS sont géolocalisés à l'adresse précise (rue/bâtiment, distance_km exacte au m près), ~23 % restent au centroïde commune (~3 km, repli pour adresses non géocodables — DROM, Monaco, CEDEX, lieux-dits). Lire geo_precision PAR résultat — ne pas présumer une précision uniforme. Codes type_ps Ameli présents en base (3) : '1' médecins, '2' auxiliaires médicaux (fourre-tout : IDE, kinés, sages-femmes, podologues, orthophonistes, orthoptistes, IPA), '5' chirurgiens-dentistes. Pour cibler une profession précise (ex: IDE seuls, kinés seuls, podologues seuls), passer par specialite_codes plutôt que type_ps_codes qui ratisse plus large. Liste exhaustive des codes spécialité disponibles via le tool lister_nomenclature(referentiel:'ameli_specialites'). Multi-sites : par défaut un PS exerçant sur N adresses apparaît N fois — utiliser dedupe_by_ps=true pour regrouper par praticien et lister les sites en sous-objet. Distance retournée en km vol d'oiseau (haversine PostGIS) — pour distance routière, croiser avec un service externe (OSRM, ORS). Chaque PS géolocalisé porte geo_precision ∈ {"adresse", "centroide_commune"} : "adresse" = coords BAN précises, distance_km exacte, classement individuel fiable ; "centroide_commune" = ~3 km, distance_km IDENTIQUE pour tous les PS d'une même commune (non discriminante intra-commune — filtre de zone uniquement, pas de classement/choix d'un PS individuel). Param precise_only (défaut false) : à true, exclut les PS au centroïde commune et ne renvoie que les ~77 % géocodés à l'adresse BAN (distance_km exacte) — recommandé pour les rayons courts (<3 km) et le classement intra-commune. PÉRIMÈTRE : libéraux conventionnés UNIQUEMENT. HORS PÉRIMÈTRE : médecins exclusivement hospitaliers/salariés, biologistes médicaux salariés en LBM, anatomopathologistes hospitaliers, médecins du travail, médecine légale. Pour effectifs tous statuts, voir Annuaire Santé ANS (RPPS, esante.gouv.fr) — non couvert par ce serveur. Source : Annuaire santé Ameli (Assurance Maladie), MAJ hebdomadaire. Réutilisation soumise à l'art. L.1461-2 CSP — citer la source et la date de sync.

ParametersJSON Schema
NameRequiredDescriptionDefault
latYesLatitude du centre (WGS84).
lonYesLongitude du centre (WGS84).
limitNoNombre max de résultats (1-500, défaut 100). Appliqué AVANT déduplication.
radius_kmNoRayon en km (0.1-50, défaut 5).
dedupe_by_psNoRegrouper les entrées par praticien (nom + prénom + code spécialité) et lister chaque adresse d'exercice dans `sites[]`. Défaut false (comportement V0.4 historique : un PS multi-sites = N entrées).
precise_onlyNoSi true, exclut les PS au centroïde commune et ne renvoie que ceux géocodés à l'adresse BAN, à `distance_km` exacte (cf. description du tool pour la sémantique complète). Défaut false.
type_ps_codesNoListe de codes type PS Ameli (3 valeurs présentes en base : '1' médecins, '2' auxiliaires médicaux fourre-tout — IDE/kinés/sages-femmes/podologues/orthophonistes/orthoptistes/IPA, '5' chirurgiens-dentistes). Pour cibler une seule profession, préférer `specialite_codes`. Si omis, tous types.
specialite_codesNoListe de codes spécialité Ameli (ex: ['01'] MG, ['03'] cardio). Si omis, toutes spécialités.
include_freshnessNoSi true, ajoute un champ `data_freshness` au payload (dans `query_metadata` si présent, sinon à la racine) listant, par source (FINESS, Ameli, RPPS, CDS, IRIS), la dernière ingestion réussie (`last_success_at`, `staleness_days`) ET la dernière fois que la donnée a réellement changé (`last_data_change_at`, `data_age_days` — un run court-circuité « fichier amont identique » compte comme succès mais ne rajeunit pas la donnée ; c'est `data_age_days` qui dit l'âge réel de ce qui est servi). Opt-in pour ne pas alourdir les payloads par défaut. Cache 5min côté serveur — coût négligeable.

Output Schema

ParametersJSON Schema
NameRequiredDescription
countYesNombre d'entrées retournées dans `results` (post-troncature).
totalNoEffectif réel avant troncature. Présent sur les tools de nomenclature paginés (lister_*) : `count` = échantillon, `total` = total réel, re-appeler avec un `limit` supérieur si `truncated`.
resultsYesEntrées métier (shape spécifique au tool, cf. description du tool).
freshnessNoFraîcheur des sources (présent si `include_freshness: true`).
perimetreNoLentille de la source : ce que le comptage inclut/exclut. Lire `completeness_note` et la restituer au lecteur final.
truncatedNotrue si le total réel dépasse `limit` (re-paginer via `offset` si supporté, ou augmenter `limit` sur les lister_*). Optional sur les tools de listing exhaustif (lister_*).
query_metadataNoMetadata de la query (radius_km, departement, filtres appliqués, …).
activite_hebergeeNoCompte juxtaposé des sites hébergeant l'activité correspondant à la famille filtrée, sous une autre catégorie FINESS. Distinct du `count` principal — lire `note` pour comprendre la sémantique et ne JAMAIS additionner les deux comptes sans préciser leur nature.

TDQS

A4.9/5.0
Behavior5/5

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

Beyond the annotations (readOnly, openWorld, idempotent), the description richly discloses behavioral nuances: ~77% address-level geocoding vs ~23% commune centroid fallback, identical `distance_km` for centroid results, multi-site duplication behavior, `limit` applied before deduplication, freshness semantics, and cache behavior. These are critical operational traits an agent cannot infer from annotations alone.

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?

The description is long but appropriately densely packed for a tool with nine parameters and significant geocoding subtleties. It is front-loaded with the core purpose and precision caveat, and uses bolding/caps for key distinctions. Some repetition occurs around precision percentages and `distance_km` semantics, which slightly reduces structural economy, but every major section earns its place.

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?

For a complex geographic-health-data tool, the description covers purpose, perimeter exclusions, paramer semantics, geocoding precision behavior, deduplication, distance semantics, data freshness, source, and legal reuse. The presence of an output schema also means return fields do not need to be re-explained. An agent has enough context to call and interpret this tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Although schema coverage is 100%, the description substantially enriches parameter meaning: it clarifies that `type_ps_codes` is a catch-all compared to `specialite_codes`, explains the exact semantics and use cases of `precise_only`, details how `dedupe_by_ps` groups multi-site practitioners, and explains the practical interpretation of `include_freshness` fields (`data_age_days` vs `staleness_days`). This goes well beyond the baseline parameter descriptions.

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 identifies a precise verb-resource pair: searching liberal conventioned health professionals within a geographic radius, with the source (Annuaire santé Améli) and perimeter stated up front. It also distinguishes the tool from sibling tools by explicitly excluding hospital-based and salaried professionals and noting that all-status counts are not covered by this server.

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?

Provides explicit situational guidance: use `specialite_codes` instead of broad `type_ps_codes` for single professions, use `precise_only=true` for short radii and intra-commune sorting, use external services for road distance, and consult an external source for all-status counts. The PÉRIMÈTRE/HORS PÉRIMÈTRE block also clearly states what this tool is and is not for.

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

professionnels_par_specialite_deptA
Read-onlyIdempotent
Inspect

Liste des professionnels de santé libéraux conventionnés d'un département, avec filtres optionnels par spécialité ou type de PS. Pour énumération administrative — pas de rayon. Codes type_ps Ameli présents en base (3) : '1' médecins, '2' auxiliaires médicaux (fourre-tout : IDE, kinés, sages-femmes, podologues, orthophonistes, orthoptistes, IPA), '5' chirurgiens-dentistes. Pour cibler une profession précise (ex: IDE seuls), passer par specialite_code plutôt que type_ps_code qui ratisse plus large. Liste exhaustive des codes spécialité disponibles via le tool lister_nomenclature(referentiel:'ameli_specialites'). Pagination : utiliser offset pour récupérer les pages suivantes quand truncated=true. Multi-sites : utiliser dedupe_by_ps=true pour regrouper par praticien. PÉRIMÈTRE : libéraux conventionnés UNIQUEMENT. HORS PÉRIMÈTRE : médecins exclusivement hospitaliers/salariés, biologistes médicaux salariés en LBM, anatomopathologistes hospitaliers, médecins du travail, médecine légale. Pour effectifs tous statuts, voir Annuaire Santé ANS (RPPS, esante.gouv.fr) — non couvert par ce serveur. Source : Annuaire santé Ameli (Assurance Maladie), MAJ hebdomadaire. Réutilisation soumise à l'art. L.1461-2 CSP — citer la source et la date de sync.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoNombre max de résultats (1-500, défaut 100). Appliqué AVANT déduplication.
offsetNoDécalage de pagination (≥ 0, défaut 0). Combiner avec `limit` pour énumérer un département à fort effectif. Re-paginer tant que `truncated=true`.
departementYesCode département INSEE : 2 caractères métropole/Corse ('01'-'95', '2A'/'2B'), 3 caractères DOM ('971'-'978').
dedupe_by_psNoRegrouper les entrées par praticien (nom + prénom + code spécialité) et lister chaque adresse d'exercice dans `sites[]`. Défaut false.
type_ps_codeNoCode type PS Ameli ('1' médecins, '2' auxiliaires médicaux, '5' chirurgiens-dentistes). Optionnel — préférer `specialite_code` pour un ciblage précis. Liste complète via `lister_nomenclature(referentiel:'ameli_types_ps')`.
specialite_codeNoCode spécialité Ameli (ex: '01' MG, '24' IDE, '26' kiné, '03' cardio). Optionnel. Liste complète via `lister_nomenclature(referentiel:'ameli_specialites')`.
include_freshnessNoSi true, ajoute un champ `data_freshness` au payload (dans `query_metadata` si présent, sinon à la racine) listant, par source (FINESS, Ameli, RPPS, CDS, IRIS), la dernière ingestion réussie (`last_success_at`, `staleness_days`) ET la dernière fois que la donnée a réellement changé (`last_data_change_at`, `data_age_days` — un run court-circuité « fichier amont identique » compte comme succès mais ne rajeunit pas la donnée ; c'est `data_age_days` qui dit l'âge réel de ce qui est servi). Opt-in pour ne pas alourdir les payloads par défaut. Cache 5min côté serveur — coût négligeable.

Output Schema

ParametersJSON Schema
NameRequiredDescription
countYesNombre d'entrées retournées dans `results` (post-troncature).
totalNoEffectif réel avant troncature. Présent sur les tools de nomenclature paginés (lister_*) : `count` = échantillon, `total` = total réel, re-appeler avec un `limit` supérieur si `truncated`.
resultsYesEntrées métier (shape spécifique au tool, cf. description du tool).
freshnessNoFraîcheur des sources (présent si `include_freshness: true`).
perimetreNoLentille de la source : ce que le comptage inclut/exclut. Lire `completeness_note` et la restituer au lecteur final.
truncatedNotrue si le total réel dépasse `limit` (re-paginer via `offset` si supporté, ou augmenter `limit` sur les lister_*). Optional sur les tools de listing exhaustif (lister_*).
query_metadataNoMetadata de la query (radius_km, departement, filtres appliqués, …).
activite_hebergeeNoCompte juxtaposé des sites hébergeant l'activité correspondant à la famille filtrée, sous une autre catégorie FINESS. Distinct du `count` principal — lire `note` pour comprendre la sémantique et ne JAMAIS additionner les deux comptes sans préciser leur nature.

TDQS

A4.7/5.0
Behavior5/5

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

Annotations already declare readOnly, openWorld, idempotent, and non-destructive behavior, so the bar is lower, and the description adds meaningful context: data source (Annuaire santé Ameli), weekly refresh, legal reuse constraints, strict perimeter details, and pagination behavior via `truncated=true`. This goes well beyond the structured annotations.

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 long but dense and every section earns its place: purpose, filtering guidance, pagination, deduplication, scope, exclusions, alternative sources, and legal constraints. It is front-loaded with the core purpose and organized with clear markers like PÉRIMÈTRE/HORS PÉRIMÈTRE, making it easy to scan.

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?

For a tool with 7 parameters, an output schema, and no enums, the description is complete: it covers scope, exclusions, pagination, deduplication, source freshness, and legal reuse requirements. The output schema handles return-value documentation, so the description does not need to repeat that, and the remaining guidance is sufficient for correct invocation.

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%, so baseline is 3. Most parameter guidance in the description repeats what the schema already says, e.g., preferring `specialite_code` over `type_ps_code` and pagination via `offset`. It adds the useful 'fourre-tout' nuance for `type_ps_code`, but this is a marginal increment rather than substantial new parameter semantics.

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 states a specific verb and resource: listing liberal health professionals in a department with optional specialty/type filters. It clearly distinguishes itself from radius-based tools with 'Pour énumération administrative — pas de rayon' and gives concrete exclusion boundaries, so an agent can tell what this tool is for.

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?

The description gives explicit when-to-use and when-not-to-use guidance: administrative enumeration, not geolocation; precise professions should use `specialite_code` rather than `type_ps_code`; hospital-only and salaried professionals are excluded; for all-status counts it points to Annuaire Santé ANS. It also tells the agent to use `lister_nomenclature` for exhaustive codes, which is a concrete routing decision.

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

professionnels_rpps_in_radiusA
Read-onlyIdempotent
Inspect

Trouve les PS dans un rayon via RPPS (Annuaire Santé ANS — tous statuts : libéraux + salariés + mixtes + remplaçants ; vs professionnels_in_radius Ameli = libéraux conventionnés seuls).

Param critique precise_only — Défaut false (mode hybride). À true : ne renvoie que les PS géolocalisés précisément (distance_km exacte au m près) — recommandé pour rayons courts (<3 km), classement intra-commune, "PS à <500 m d'une adresse".

Chaque résultat porte geo_precision ∈ :

  • "adresse" — coords BAN rue/lieu-dit/bâtiment, distance_km exacte.

  • "etablissement_finess" — coords du site FINESS (via num_finess), distance_km exacte au site.

  • "centroide_commune" — centroïde commune (~3 km), distance_km IDENTIQUE pour tous les PS de la commune — ne PAS l'utiliser pour classer individuellement, seulement comme filtre de zone.

Couverture actuelle : ~68,5 % précis, ~31,5 % centroide_commune résiduel. Mode hybride = précis (granularité adresse) + centroïde (granularité commune) fusionnés et triés globalement par distance_km.

Filtres : profession_codes (ex: ["10"] Médecin, ["60"] Infirmier), savoir_faire_codes (spécialité fine DES/DESC), mode_exercice_codes. Codes mode_exercice ANS : L libéral, S salarié, M mixte, R remplaçant, B bénévole, A autre. Catégorie par défaut : Civil (C, ~97 % — libéraux, salariés privés, hospitaliers contractuels). Opt-in : include_agents_publics: true ajoute Agents publics (M, ~0,3 % — PH titulaires, ARS, CNAM, Éducation nationale, PMI, militaires SSA) ; include_etudiants: true ajoute Étudiants (E, ~2,5 % — internes, externes, élèves IDE/SF). Réf : https://mos.esante.gouv.fr/NOS/TRE_R09-CategorieProfessionnelle/. ATTENTION nomenclatures : les codes ANS (profession_code, savoir_faire_code) sont une nomenclature DISTINCTE des codes Ameli (specialite_code, type_ps_code) — un même nombre désigne des choses différentes (ex: '10' = Médecin côté ANS, Neurochirurgien côté Ameli). Ne JAMAIS passer un code Ameli à un paramètre ANS : le filtre renverrait vide sans erreur. Découvrir les codes ANS via lister_nomenclature(referentiel:'rpps_savoir_faire'). Source : Annuaire Santé, Agence du Numérique en Santé (ANS) — Licence Ouverte v2.0

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoNombre max de résultats retournés (défaut serveur 100).
centerYesCentre du cercle de recherche (coordonnées WGS84).
radius_kmYesRayon en km (0.1-50).
precise_onlyNoSi true, exclut les PS au centroïde commune et ne renvoie que ceux à `distance_km` exacte (cf. description du tool pour la sémantique complète et le seuil d'usage recommandé). Défaut false.
profession_codesNoCodes profession ANS (ex: ['10'] Médecin, ['60'] Infirmier). Si omis, toutes professions.
include_etudiantsNo
include_freshnessNoSi true, ajoute un champ `data_freshness` au payload (dans `query_metadata` si présent, sinon à la racine) listant, par source (FINESS, Ameli, RPPS, CDS, IRIS), la dernière ingestion réussie (`last_success_at`, `staleness_days`) ET la dernière fois que la donnée a réellement changé (`last_data_change_at`, `data_age_days` — un run court-circuité « fichier amont identique » compte comme succès mais ne rajeunit pas la donnée ; c'est `data_age_days` qui dit l'âge réel de ce qui est servi). Opt-in pour ne pas alourdir les payloads par défaut. Cache 5min côté serveur — coût négligeable.
savoir_faire_codesNoCodes savoir-faire ANS (spécialités fines DES/DESC). Si omis, tous savoir-faire.
mode_exercice_codesNoCodes mode d'exercice ANS (libéral / salarié / mixte). Si omis, tous modes.
include_agents_publicsNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
countYesNombre d'entrées retournées dans `results` (post-troncature).
totalNoEffectif réel avant troncature. Présent sur les tools de nomenclature paginés (lister_*) : `count` = échantillon, `total` = total réel, re-appeler avec un `limit` supérieur si `truncated`.
resultsYesEntrées métier (shape spécifique au tool, cf. description du tool).
freshnessNoFraîcheur des sources (présent si `include_freshness: true`).
perimetreNoLentille de la source : ce que le comptage inclut/exclut. Lire `completeness_note` et la restituer au lecteur final.
truncatedNotrue si le total réel dépasse `limit` (re-paginer via `offset` si supporté, ou augmenter `limit` sur les lister_*). Optional sur les tools de listing exhaustif (lister_*).
query_metadataNoMetadata de la query (radius_km, departement, filtres appliqués, …).
activite_hebergeeNoCompte juxtaposé des sites hébergeant l'activité correspondant à la famille filtrée, sous une autre catégorie FINESS. Distinct du `count` principal — lire `note` pour comprendre la sémantique et ne JAMAIS additionner les deux comptes sans préciser leur nature.

TDQS

A4.9/5.0
Behavior5/5

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

Annotations already declare readOnly, idempotent, openWorld, and non-destructive, and the description adds substantial behavioral context beyond that: `geo_précision` semantics for adresse vs étabissement_finess vs centroïde_commune, coverage percentages (~68.5% precise, ~31.5% centroïde), hybrid-mode merging behavior, and the warning that passing an Ameli code returns empty without error. No contradiction with annotations.

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?

The description is long but well-structured with bold headers, bullets, and clear separation of concepts. It is front-loaded with the purpose and the critical `precise_only` parameter. A few trailing details (source URL, license, freshness internals) are less essential for invocation, so it is not maximally concise, but every major block earns its place.

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?

For a 10-parameter tool with nested objects, output schema, and multiple subtle filtering behaviors, the description is remarkably complete: it covers purpose, alternatives, parameter semantics, geo_precision interpretation, code-nomenclature risks, default vs opt-in categories, and freshness behavior. Nothing an agent needs to call it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Despite 80% schema coverage, the description significantly extends parameter understanding: it explains `precise_only` semantics and thresholds, gives examples for `profession_codes` ('10' Médecin, '60' Infirmier), details `mode_exercice_codes` values, and clarifies opt-in flags `include_agents_publics` and `include_etudiants` with category percentages. The nomenclature warning about ANS vs Ameli codes is critical and not present in the schema.

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 opens with a specific verb and resource: 'Trouve les PS dans un rayon via RPPS' and immediately contrasts with `professionnels_in_radius` Ameli = libéraux conventionnés seuls. The scope is fully unambiguous: it covers all statuses (libéraux, salariés, mixtes, remplaçants) via Annuaire Santé ANS.

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?

The description explicitly names the sibling alternative `professionnels_in_radius` and states the distinguishing condition (Ameli = libéraux conventionnés only vs RPPS = all statuses). It also gives concrete usage guidance for `précise_only`: recommended for short radii (<3 km), intra-commune ranking, and 'PS à <500 m', plus a warning not to use centroïde results for individual ranking.

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

professionnels_rpps_par_deptA
Read-onlyIdempotent
Inspect

Liste tous les PS d'un département via RPPS (libéraux + salariés). Pour les libéraux conventionnés uniquement, préférer professionnels_par_specialite_dept (Ameli). Re-paginer via offset tant que truncated=true.

Chaque résultat géolocalisé porte geo_precision ∈ {"adresse", "etablissement_finess", "centroide_commune"} — lire ce champ pour évaluer la fiabilité des coords (précise BAN/FINESS au m près vs centroïde commune ~3 km, non discriminant intra-commune).

Filtres optionnels : profession_code, savoir_faire_code, mode_exercice_code. Catégorie par défaut : Civil (C, ~97 % — libéraux, salariés privés, hospitaliers contractuels). Opt-in : include_agents_publics: true ajoute Agents publics (M, ~0,3 % — PH titulaires, ARS, CNAM, Éducation nationale, PMI, militaires SSA) ; include_etudiants: true ajoute Étudiants (E, ~2,5 % — internes, externes, élèves IDE/SF). Réf : https://mos.esante.gouv.fr/NOS/TRE_R09-CategorieProfessionnelle/. ATTENTION nomenclatures : les codes ANS (profession_code, savoir_faire_code) sont une nomenclature DISTINCTE des codes Ameli (specialite_code, type_ps_code) — un même nombre désigne des choses différentes (ex: '10' = Médecin côté ANS, Neurochirurgien côté Ameli). Ne JAMAIS passer un code Ameli à un paramètre ANS : le filtre renverrait vide sans erreur. Découvrir les codes ANS via lister_nomenclature(referentiel:'rpps_savoir_faire'). Source : Annuaire Santé, Agence du Numérique en Santé (ANS) — Licence Ouverte v2.0

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoNombre max de résultats par page (défaut serveur 100).
offsetNoOffset pour pagination (défaut 0). Re-paginer tant que `truncated=true`.
departementYesCode département INSEE (ex: '75', '2A', '2B', '971'). Métropole 2 caractères (Corse '2A'/'2B', pas '20'), DOM/TOM 3 caractères.
profession_codeNoCode profession ANS (ex: '10' Médecin, '60' Infirmier). Optionnel.
include_etudiantsNo
include_freshnessNoSi true, ajoute un champ `data_freshness` au payload (dans `query_metadata` si présent, sinon à la racine) listant, par source (FINESS, Ameli, RPPS, CDS, IRIS), la dernière ingestion réussie (`last_success_at`, `staleness_days`) ET la dernière fois que la donnée a réellement changé (`last_data_change_at`, `data_age_days` — un run court-circuité « fichier amont identique » compte comme succès mais ne rajeunit pas la donnée ; c'est `data_age_days` qui dit l'âge réel de ce qui est servi). Opt-in pour ne pas alourdir les payloads par défaut. Cache 5min côté serveur — coût négligeable.
savoir_faire_codeNoCode savoir-faire ANS (spécialité fine DES/DESC). Optionnel.
mode_exercice_codeNoCode mode d'exercice ANS (libéral / salarié / mixte). Optionnel.
include_agents_publicsNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
countYesNombre d'entrées retournées dans `results` (post-troncature).
totalNoEffectif réel avant troncature. Présent sur les tools de nomenclature paginés (lister_*) : `count` = échantillon, `total` = total réel, re-appeler avec un `limit` supérieur si `truncated`.
resultsYesEntrées métier (shape spécifique au tool, cf. description du tool).
freshnessNoFraîcheur des sources (présent si `include_freshness: true`).
perimetreNoLentille de la source : ce que le comptage inclut/exclut. Lire `completeness_note` et la restituer au lecteur final.
truncatedNotrue si le total réel dépasse `limit` (re-paginer via `offset` si supporté, ou augmenter `limit` sur les lister_*). Optional sur les tools de listing exhaustif (lister_*).
query_metadataNoMetadata de la query (radius_km, departement, filtres appliqués, …).
activite_hebergeeNoCompte juxtaposé des sites hébergeant l'activité correspondant à la famille filtrée, sous une autre catégorie FINESS. Distinct du `count` principal — lire `note` pour comprendre la sémantique et ne JAMAIS additionner les deux comptes sans préciser leur nature.

TDQS

A4.9/5.0
Behavior5/5

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

Annotations already declare readOnly/openWorld/idempotent/non-destructive behavior, but the description adds consequential behavioral details: pagination semantics, `geo_precision` reliability for `coords`, default category composition (~97% Civil), opt-in categories, and the ANS-vs-Ameli code pitfall that silently returns empty results. This goes well beyond what annotations convey.

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 long but each sentence carries a distinct fact: scope, preferred alternative, pagination, geo_precision, filters, category defaults, opt-in behavior, nomenclature warning, and source/license. It's structured with the core purpose and distinguishing alternative front-loaded, and the caveats follow logically. There is no filler.

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 already exists, so the description doesn't need to document the full return shape, yet it still adds crucial info about `geo_precision`, source, license, and the ANS/Ameli code conflict. The annotations cover safety and idempotency, and the description covers pagination, filters, defaults, and categories. An agent has enough context to call it correctly in the right situation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 78% schema coverage, the baseline is 3, and the description adds meaningful extra semantics: it clarifies that `profession_code` and `savoir_faire_code` are ANS codes distinct from Ameli codes, explains the default category behavior, and describes what `include_etudiants` and `include_agents_publics` actually change. It doesn't exhaustively augment every parameter, but it covers the non-obvious and error-prone ones, which is the highest-value contribution.

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 opens with a precise verb-object phrase: 'Liste tous les PS d'un département via RPPS (libéraux + salariés).' It explicitly names the sibling `professionnels_par_specialite_dept` as the Ameli-based alternative, which disambiguates the tool immediately. The RPPS source and population scope together separate it cleanly from the other sibling tools.

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?

The description gives explicit routing guidance: for libéraux conventionnés only, it says to prefer `professionnels_par_specialite_dept` instead. It also supplies operational usage conventions, such as re-paginating via `offset` until `truncated=true`, and explains optional filters and opt-in categories. This is model when-to-use-vs-alternatives guidance.

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

profil_irisA
Read-onlyIdempotent
Inspect

Profil démographique au grain QUARTIER (IRIS) — la « demande » d'un territoire (âge, CSP, familles, revenu), à croiser avec l'offre de soins pour l'aide à l'implantation. Source : INSEE RP 2022 + FILOSOFI 2021 (tables ingérées, géo 01/01/2024). Retourne un LookupResult discriminé par found.

Entrée : EXACTEMENT un de point (lat+lon) OU code_iris (9 car.). rayon_km optionnel (0 < r ≤ 10) → DEUX modes :

  • SANS rayon_km → profil de l'ÎLOT seul (~2000 hab) sous le point / du code. mode: "ilot", revenu_median = médiane réelle de l'îlot.

  • AVEC rayon_km → AGRÉGAT du BASSIN = îlots dont le CENTROÏDE est dans le disque (chaque îlot compté 1 fois). mode: "bassin", population_bassin, nb_iris_agreges, et revenu_median_pondere = PROXY (moyenne pondérée population des médianes des îlots couverts — PAS une vraie médiane de bassin) + couverture {revenu_pct_population, iris_revenu_manquants} car FILOSOFI ne couvre que les communes ≥5000 hab.

Les parts age (part_65_plus/75_plus) et csp (cadres, prof_interm, employés, ouvriers, agriculteurs, artisans_comm, retraités, autres) sont des ratios sur comptes bruts (Σ/Σ). Pour une simple population de commune/dept, utiliser population. not_found motivé si code absent ou point hors métropole / en mer.

ParametersJSON Schema
NameRequiredDescriptionDefault
latNoLatitude du point (mode point).
lonNoLongitude du point (mode point).
rayon_kmNoRayon du bassin en km (0 < r ≤ 10). Absent = profil de l'îlot seul.
code_irisNoCode IRIS 9 caractères (ex `751103701`) — alternatif au point.

Output Schema

ParametersJSON Schema
NameRequiredDescription
keyNoClé recherchée (SIREN, num_finess, code INSEE, …).
foundYes
messageNoExplication actionnable quand `found=false` (cause probable + remédiation).
lookupStatusYes

TDQS

A4.8/5.0
Behavior5/5

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

Annotations already indicate safe, idempotent read. Description adds that output is a LookupResult discriminated by 'found', details proxy calculation for revenu_median_pondere, data sources (INSEE RP 2022, FILOSOFI 2021), and coverage limitations (communes ≥5000 hab). No contradiction.

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?

Well-structured with clear separation of modes via bullet points. Slightly long but every sentence adds essential information. Front-loaded with purpose.

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?

Covers all aspects: dual modes, input constraints, output structure (LookupResult), data provenance, coverage caveats, and proxy calculations. No missing context despite complexity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema covers 100% with concise descriptions. Description adds behavioral context: lat+lon vs code_iris exclusivity, rayon_km modes, and the meaning of computed fields (e.g., revenu_median_pondere as proxy). Exceeds baseline of 3.

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 it provides demographic profiles at the IRIS (neighborhood) level for location assistance, distinguishing between single-IRIS and basin modes. It contrasts with siblings like 'population' (simple commune/department counts).

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 explains two modes (with/without rayon_km), specifies input constraints (exactly one of point or code_iris), and advises using 'population' for simpler population needs. Covers invalid cases (not_found).

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

reconcilier_finess_sireneA
Read-onlyIdempotent
Inspect

Croise FINESS DREES ↔ SIRENE INSEE V3.11 et calcule un score de cohérence (Sørensen-Dice sur bigrammes) pour chaque SIRET candidat. Utile pour confirmer/infirmer un appariement num_finess ↔ SIRET avant prospection ou cross-check qualité.

Logique :

  1. Récupère FINESS (raison sociale + adresse libellée)

  2. Récupère SIRET candidats via la table RPPS

  3. Pour chaque SIRET, lookup SIRENE puis calcule 3 sous-scores :

    • nom : Dice sur raison sociale (FINESS vs SIRENE.uniteLegale)

    • adresse : Dice sur adresse complète

    • telephone : binaire 0/1 (toujours 0 actuellement : SIRENE n'expose pas le tel)

  4. Score global = pondération (nom 0.5, adresse 0.4, tel 0.1)

  5. Verdict brut : match (≥0.8) / partial (0.5..0.8) / mismatch (<0.5)

Algorithme PUBLIC (Sørensen-Dice est dans la littérature depuis 1948). Aucune valeur ajoutée Unilabs ici — c'est une primitive ouverte. La connaissance propriétaire (mapping enseignes ↔ SELAS) reste côté Geo Intel.

Format : objet LookupResult. Quand found: true, retourne { num_finess, candidates, skipped } :

  • candidates : tableau trié par score_global décroissant (meilleur match en premier)

  • skipped : SIRET candidats qu'on n'a PAS pu réconcilier (lookup SIRENE rejected ou not_found) avec la reason. Permet au caller de distinguer 'aucun SIRET candidat trouvé' (found: false LookupResult.not_found) de 'N SIRETs candidats mais tous rejetés par SIRENE' (candidates: [] + skipped: [...]).

ParametersJSON Schema
NameRequiredDescriptionDefault
num_finessYesNuméro FINESS exact (9 chiffres).

Output Schema

ParametersJSON Schema
NameRequiredDescription
keyNoClé recherchée (SIREN, num_finess, code INSEE, …).
foundYes
messageNoExplication actionnable quand `found=false` (cause probable + remédiation).
lookupStatusYes

TDQS

A4.4/5.0
Behavior5/5

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

The description extensively details behavioral traits: algorithm (Sørensen-Dice on bigrams), score computation, verdict thresholds, and output format including the `skipped` field. Annotations already indicate read-only, open-world, idempotent, non-destructive; the description adds value with the internal logic and edge cases.

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?

The description is well-structured with clear sections and bullet points, making it easy to read. It is slightly lengthy (four paragraphs) but each part serves a purpose. Some algorithmic details could be condensed, but overall it is efficient.

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?

Given the tool's complexity and the presence of an output schema, the description provides a complete picture: input, algorithm, output format (including handling of null cases like 'not_found' vs empty candidates). Nothing essential is missing.

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?

The single parameter 'num_finess' is fully described in the schema (9-digit string). The description adds context about how it is used to fetch FINESS data, but does not provide additional semantic constraints beyond the schema. With 100% schema coverage, a score of 3 is appropriate.

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: cross-referencing FINESS and SIRENE data and computing a coherence score for FINESS-SIRET matching. It uses specific verbs ('Croise', 'calcule') and identifies the resource (FINESS, SIRENE). The tool is distinct from siblings, none of which perform this reconciliation.

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

Usage Guidelines4/5

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

The description explicitly says the tool is useful 'pour confirmer/infirmer un appariement num_finess ↔ SIRET avant prospection ou cross-check qualité', providing clear context. It does not, however, mention when not to use it or suggest alternative tools, but the specificity is sufficient.

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

reverse_geocodeA
Read-onlyIdempotent
Inspect

Géocodage inverse : à partir de coordonnées GPS, retrouve l'adresse la plus proche. Source : IGN Géoplateforme. Couverture France métropolitaine + DOM uniquement : des coordonnées hors zone (ex. New York) ou en pleine mer renvoient null (pas une erreur — c'est l'absence de résultat, pas une panne).

ParametersJSON Schema
NameRequiredDescriptionDefault
latYesLatitude (WGS84).
lonYesLongitude (WGS84).

TDQS

A4.4/5.0
Behavior5/5

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

Annotations already declare readOnlyHint, openWorldHint, idempotentHint true, and destructiveHint false. Description adds valuable behavioral context: coverage limitation, null return meaning 'no result not error', and data source attribution. No contradictions.

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?

Description is two sentences, concise, and front-loaded with the primary purpose. Every sentence adds value (purpose, source, coverage, special return behavior). No wasted words.

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?

Given no output schema, description mentions that out-of-zone coordinates return null, which partially addresses return behavior. However, it does not specify the format of the returned address. Still, for a simple tool with good annotations, it is nearly complete.

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?

Input schema has 100% description coverage for both parameters (lat and lon with WGS84). Description does not add additional semantics beyond what the schema provides. Baseline 3 is appropriate since schema already explains parameters.

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?

Description clearly states 'reverse geocoding' and retrieves nearest address from GPS coordinates. Specifies data source (IGN Géoplateforme) and coverage, distinguishing it from sibling tool geocode_adresse which does forward geocoding.

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

Usage Guidelines4/5

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

Provides clear context on coverage (France métropolitaine + DOM) and behavior for out-of-zone coordinates (returns null). Does not explicitly state when to use versus alternatives, but the tool's purpose is self-evident and no other sibling does reverse geocoding.

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

rpps_dans_etablissementA
Read-onlyIdempotent
Inspect

Liste les PS rattachés à un établissement FINESS (num_finess 9 chiffres). Pivot RPPS↔FINESS — répond à "qui travaille dans ce labo / hôpital / clinique ?". Le mode_exercice distingue les libéraux exerçant sur place (vacations) des salariés. Couverture : RPPS expose ce lien quand le PS l'a déclaré ; salariés CH/CHU/cliniques bien couverts.

Sortie compacte : coords et distance_km sont null (le tool est par établissement, pas spatial — pour la géoloc, pivoter via etablissement_by_finess sur le num_finess). Catégorie par défaut : Civil (C, ~97 % — libéraux, salariés privés, hospitaliers contractuels). Opt-in : include_agents_publics: true ajoute Agents publics (M, ~0,3 % — PH titulaires, ARS, CNAM, Éducation nationale, PMI, militaires SSA) ; include_etudiants: true ajoute Étudiants (E, ~2,5 % — internes, externes, élèves IDE/SF). Réf : https://mos.esante.gouv.fr/NOS/TRE_R09-CategorieProfessionnelle/. Source : Annuaire Santé, Agence du Numérique en Santé (ANS) — Licence Ouverte v2.0

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
num_finessYes
include_etudiantsNo
include_freshnessNoSi true, ajoute un champ `data_freshness` au payload (dans `query_metadata` si présent, sinon à la racine) listant, par source (FINESS, Ameli, RPPS, CDS, IRIS), la dernière ingestion réussie (`last_success_at`, `staleness_days`) ET la dernière fois que la donnée a réellement changé (`last_data_change_at`, `data_age_days` — un run court-circuité « fichier amont identique » compte comme succès mais ne rajeunit pas la donnée ; c'est `data_age_days` qui dit l'âge réel de ce qui est servi). Opt-in pour ne pas alourdir les payloads par défaut. Cache 5min côté serveur — coût négligeable.
include_agents_publicsNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
countYesNombre d'entrées retournées dans `results` (post-troncature).
totalNoEffectif réel avant troncature. Présent sur les tools de nomenclature paginés (lister_*) : `count` = échantillon, `total` = total réel, re-appeler avec un `limit` supérieur si `truncated`.
resultsYesEntrées métier (shape spécifique au tool, cf. description du tool).
freshnessNoFraîcheur des sources (présent si `include_freshness: true`).
perimetreNoLentille de la source : ce que le comptage inclut/exclut. Lire `completeness_note` et la restituer au lecteur final.
truncatedNotrue si le total réel dépasse `limit` (re-paginer via `offset` si supporté, ou augmenter `limit` sur les lister_*). Optional sur les tools de listing exhaustif (lister_*).
query_metadataNoMetadata de la query (radius_km, departement, filtres appliqués, …).
activite_hebergeeNoCompte juxtaposé des sites hébergeant l'activité correspondant à la famille filtrée, sous une autre catégorie FINESS. Distinct du `count` principal — lire `note` pour comprendre la sémantique et ne JAMAIS additionner les deux comptes sans préciser leur nature.

TDQS

A4.7/5.0
Behavior5/5

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

Even with readOnlyHint and idempotentHint annotations, the description discloses meaningful behavioral details: `coords` and `distance_km` are null, output is compact, coverage depends on RPPS declarations, and category membership is not uniform across populations. This goes well beyond what the annotations express.

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 dense but every sentence earns its place: purpose, coverage caveats, output nulls, category defaults and opt-ins, reference, and license. The main use case is front-loaded, and the paragraphs are logically organized.

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?

For a tool with five parameters and low schema coverage, the description provides enough context for an agent to call it correctly: required identifier format, output behavior, category filters, coverage limitations, and an alternative for spatial use. The output schema existence covers return-value detail, so no critical operational context is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 20%, but the tool description compensates well for `num_finess`, `include_agents_publics`, and `include_etudiants` by explaining their exact effect and category breakdowns. The one gap is `limit`, which receives no semantic explanation either in the schema or the description.

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 opens with a specific verb and resource: 'Liste les PS rattachés à un établissement FINESS', clarifying exactly what the tool returns. It also frames the tool as a 'Pivot RPPS↔FINESS' answering 'qui travaille dans ce labo / hôpital / clinique ?', which clearly distinguishes it from spatial or facility-only siblings.

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

Usage Guidelines4/5

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

The description gives a clear question the tool answers and explicitly says that for geolocation the agent should pivot via `etablissement_by_finess` instead. It also explains coverage and opt-in category behavior, though it does not enumerate alternative search tools like `professionnel_by_rpps` or `rpps_search_by_name`.

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

rpps_search_by_nameA
Read-onlyIdempotent
Inspect

Trouve un PS par identité (matching trigram tolérant aux accents/typos). Usage : "Dr Martin à Paris" → nom: "Martin", departement: "75". Nom obligatoire ; prenom et departement affinent.

Tri par match_score ∈ [0..1] décroissant (score trigram pg_trgm). Un score <0.5 = homonymie partielle à confirmer côté caller. Sans departement, des homonymes exacts ("Pierre Martin") ont TOUS le même score ~1.0 et ne sont pas départagés — toujours filtrer par dept ou prénom sur un nom commun.

truncated: true = d'autres résultats existent (restreindre, ne pas parcourir).

Chaque résultat géolocalisé porte geo_precision ∈ {"adresse", "etablissement_finess", "centroide_commune"} — lire ce champ pour évaluer la fiabilité des coords (précise BAN/FINESS au m près vs centroïde commune ~3 km, non discriminant intra-commune).

Catégorie par défaut : Civil (C, ~97 % — libéraux, salariés privés, hospitaliers contractuels). Opt-in : include_agents_publics: true ajoute Agents publics (M, ~0,3 % — PH titulaires, ARS, CNAM, Éducation nationale, PMI, militaires SSA) ; include_etudiants: true ajoute Étudiants (E, ~2,5 % — internes, externes, élèves IDE/SF). Réf : https://mos.esante.gouv.fr/NOS/TRE_R09-CategorieProfessionnelle/.

Source : Annuaire Santé, Agence du Numérique en Santé (ANS) — Licence Ouverte v2.0

ParametersJSON Schema
NameRequiredDescriptionDefault
nomYesNom de famille (non vide).
limitNoNombre max de résultats (1-500, défaut 100).
prenomNoPrénom du PS.
departementNoCode département INSEE (ex: '75', '2A', '2B', '971'). Métropole 2 caractères (Corse '2A'/'2B', pas '20'), DOM/COM 3 caractères.
include_etudiantsNo
include_freshnessNoSi true, ajoute un champ `data_freshness` au payload (dans `query_metadata` si présent, sinon à la racine) listant, par source (FINESS, Ameli, RPPS, CDS, IRIS), la dernière ingestion réussie (`last_success_at`, `staleness_days`) ET la dernière fois que la donnée a réellement changé (`last_data_change_at`, `data_age_days` — un run court-circuité « fichier amont identique » compte comme succès mais ne rajeunit pas la donnée ; c'est `data_age_days` qui dit l'âge réel de ce qui est servi). Opt-in pour ne pas alourdir les payloads par défaut. Cache 5min côté serveur — coût négligeable.
include_agents_publicsNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
countYesNombre d'entrées retournées dans `results` (post-troncature).
totalNoEffectif réel avant troncature. Présent sur les tools de nomenclature paginés (lister_*) : `count` = échantillon, `total` = total réel, re-appeler avec un `limit` supérieur si `truncated`.
resultsYesEntrées métier (shape spécifique au tool, cf. description du tool).
freshnessNoFraîcheur des sources (présent si `include_freshness: true`).
perimetreNoLentille de la source : ce que le comptage inclut/exclut. Lire `completeness_note` et la restituer au lecteur final.
truncatedNotrue si le total réel dépasse `limit` (re-paginer via `offset` si supporté, ou augmenter `limit` sur les lister_*). Optional sur les tools de listing exhaustif (lister_*).
query_metadataNoMetadata de la query (radius_km, departement, filtres appliqués, …).
activite_hebergeeNoCompte juxtaposé des sites hébergeant l'activité correspondant à la famille filtrée, sous une autre catégorie FINESS. Distinct du `count` principal — lire `note` pour comprendre la sémantique et ne JAMAIS additionner les deux comptes sans préciser leur nature.

TDQS

A5/5.0
Behavior5/5

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

Annotations declare readOnly/openWorld/idempotent, and the description goes beyond them by revealing: ordering by match_score with pg_trgm semantics, the homonymy problem when no department is given, the meaning of truncated flag, geo_precision values with physical distance implications, category distribution percentages, and data freshness behavior for include_freshness. This is rich behavioral disclosure that materially changes how an agent should interpret results.

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 long but each sentence carries operational weight: search semantics, scoring, truncation, geo-precision, category opt-ins, source and license. Critical facts are front-loaded (what the tool does, the example), with secondary concerns (freshness, license) later. No filler or repetition of schema details.

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?

For a complex search tool with 7 parameters, an output schema, and no enums, the description covers matching behavior, ordering, confidence interpretation, geo-precision, category semantics, freshness opt-in, truncation handling, and source reliability. An agent has everything it needs to decide when to call this tool, which parameters to use, and how to interpret the response, including edge cases.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 71% and the description adds substantial semantic value: it explains the fuzzy matching behavior of nom, the disambiguation role of prenom and departement, the exact format of departement codes including the Corsica and DOM/COM edge cases, and the meaning and trade-offs of include_agents_publics and include_etudiants (percentages, examples, categories). The description fills the gaps left by the two schema parameters that have no description and clarifies the others beyond basic identifiers.

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 opens with a concrete verb and resource: finds a health professional (PS) by identity using trigram matching tolerant to accents/typos, with a clear search example. It distinguishes itself from sibling tools like professionnel_by_rpps (lookup by exact RPPS number) and rpps_dans_etablissement (search within an establishment), making it unambiguous what this tool searches for.

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?

The description gives explicit usage guidance: when to add prenom/departement, why filtering by department is important for common names, what a score <0.5 means, and when to interpret truncation. It also explains the opt-in categories, which is effectively guidance on when to include additional parameters and the trade-offs. No alternative tool is named but the tool-specific search semantics are thoroughly explained.

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

verifier_site_actifA
Read-onlyIdempotent
Inspect

Vérifie si un établissement de santé FINESS est encore en activité en croisant FINESS DREES ↔ RPPS (pivot SIRET) ↔ DINUM (liste complète des SIRET du SIREN, incluant les fermés). Détecte les SIRET fermés encore listés actifs côté FINESS (DREES a 1-2 mois de retard).

V0.16 — fix succession M&A : quand un site a changé d'exploitant (rachat), l'ancien SIRET fermé et le repreneur actif coexistent à la même adresse. Le resolver privilégie désormais le SIRET ACTIF co-localisé avec le FINESS (distance géodésique ≤ 100 m, recalibré V0.16.1 — le géocodage DREES place le point FINESS à plusieurs dizaines de mètres de l'adresse réelle) — avant, le verdict pouvait être ferme à tort, le best_match étant choisi sur la seule ressemblance d'adresse. Parmi les co-localisés, seul l'actif de la bande la plus proche prime : un voisin actif d'une autre adresse ne bascule pas le verdict. Un site RÉELLEMENT fermé reste ferme (aucun SIRET actif co-localisé).

Logique :

  1. Lookup FINESS pour récupérer raison sociale + adresse + téléphone DREES

  2. SIRET candidats via le resolver : pivot RPPS, puis fallback géo DINUM /near_point (récupère TOUS les SIRET autour de l'adresse FINESS, actifs ET fermés — capte le repreneur invisible côté RPPS)

  3. best_match = le SIRET ACTIF co-localisé avec le FINESS s'il en existe un ; sinon le meilleur candidat (possiblement fermé). La co-localisation est une distance géo, pas un score textuel.

  4. 2 verdicts distincts :

  • verdict_site (actif / ferme / indetermine) : basé sur best_match.actif. C'est le verdict qui compte pour un audit territorial.

  • verdict_groupe (actif / ferme / indetermine) : basé sur l'état admin de l'UL parente (champ actif DINUM). Une UL active peut très bien avoir un site fermé.

Format de retour : objet LookupResult discriminé par found. Quand found: true, le payload contient finess (vue DREES), candidates (liste enrichie — chaque candidat porte distance_finess_m), best_match, sirens_explored, verdict_site, verdict_groupe, succession ({ detected, exploitants_precedents } — les SIRET fermés co-localisés avec le repreneur ; fait brut, le tool ne qualifie PAS de « rachat »), explication. Quand num_finess est absent de FINESS DREES, le tool retourne {found: false, lookupStatus: 'not_found', message, ...}.

Coût : 1 RPC FINESS + 1 SELECT rpps + N appels DINUM (N = nombre de SIREN distincts, typiquement 1). DINUM gère son propre fallback INSEE V3.11 pour les SIREN diffusion partielle.

ParametersJSON Schema
NameRequiredDescriptionDefault
num_finessYesNuméro FINESS exact (9 chiffres).

Output Schema

ParametersJSON Schema
NameRequiredDescription
keyNoClé recherchée (SIREN, num_finess, code INSEE, …).
foundYes
messageNoExplication actionnable quand `found=false` (cause probable + remédiation).
lookupStatusYes

TDQS

A4.4/5.0
Behavior5/5

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

Annotations declare readOnlyHint, idempotentHint, destructiveHint false. Description adds cost details (RPC, SELECT, DINUM calls) and explains version-specific fixes and edge cases. No contradiction.

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?

The description is well-organized with paragraphs and bullet points, but quite verbose with technical details like version numbers and distances. Could be more concise without losing key information.

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?

Given the complexity (multi-source, two verdicts, output schema), the description covers all important aspects: logic, edge cases (succession, collocation), cost, and output format. Very complete.

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?

Only one parameter 'num_finess' with schema description 'Numéro FINESS exact (9 chiffres).' Description does not add further semantics. Since schema coverage is 100%, baseline is 3.

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 explicitly states it 'Vérifie si un établissement de santé FINESS est encore en activité' and details cross-referencing multiple sources. This distinguishes it from sibling tools like 'etablissement_by_finess' which likely returns general info.

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

Usage Guidelines4/5

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

The description provides extensive logic (lookup steps, two verdicts, handling of successions) but does not explicitly state when to use this tool vs alternatives. The detailed algorithm helps the agent infer correct usage.

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

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

  1. 14 tool updates
    • Changedcentres_sante_by_finess1 field changed
      • changedInput schema / properties / include_freshness / description
        Previous value: -"Si true, ajoute un champ `data_freshness` au payload (dans `query_metadata` si présent, sinon à la racine) listant la dernière ingestion réussie par source (FINESS, Ameli, RPPS, CDS) avec `staleness_days`. Opt-in pour ne pas alourdir les payloads par défaut. Cache 5min côté serveur — coût négligeable."New value: +"Si true, ajoute un champ `data_freshness` au payload (dans `query_metadata` si présent, sinon à la racine) listant, par source (FINESS, Ameli, RPPS, CDS, IRIS), la dernière ingestion réussie (`last_success_at`, `staleness_days`) ET la dernière fois que la donnée a réellement changé (`last_data_change_at`, `data_age_days` — un run court-circuité « fichier amont identique » compte comme succès mais ne rajeunit pas la donnée ; c'est `data_age_days` qui dit l'âge réel de ce qui est servi). Opt-in pour ne pas alourdir les payloads par défaut. Cache 5min côté serveur — coût négligeable."
    • Changedcentres_sante_in_radius1 field changed
      • changedInput schema / properties / include_freshness / description
        Previous value: -"Si true, ajoute un champ `data_freshness` au payload (dans `query_metadata` si présent, sinon à la racine) listant la dernière ingestion réussie par source (FINESS, Ameli, RPPS, CDS) avec `staleness_days`. Opt-in pour ne pas alourdir les payloads par défaut. Cache 5min côté serveur — coût négligeable."New value: +"Si true, ajoute un champ `data_freshness` au payload (dans `query_metadata` si présent, sinon à la racine) listant, par source (FINESS, Ameli, RPPS, CDS, IRIS), la dernière ingestion réussie (`last_success_at`, `staleness_days`) ET la dernière fois que la donnée a réellement changé (`last_data_change_at`, `data_age_days` — un run court-circuité « fichier amont identique » compte comme succès mais ne rajeunit pas la donnée ; c'est `data_age_days` qui dit l'âge réel de ce qui est servi). Opt-in pour ne pas alourdir les payloads par défaut. Cache 5min côté serveur — coût négligeable."
    • Changeddata_freshness5 fields changed
      • addedOutput schema / properties / sources / items / properties / data_age_days
        Added value: +{
        +  "description": "Âge de la donnée servie, en jours, depuis last_data_change_at. C'est CE champ qui dit si la donnée est périmée (post-mortem FINESS 2026-09 : staleness_days=4 pour une donnée de 113 jours).",
        +  "type": [
        +    "number",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / sources / items / properties / expected_max_age_days
        Added value: +{
        +  "description": "Âge maximal attendu de la donnée pour cette source, en jours. Règle d'alerte : data_age_days > expected_max_age_days.",
        +  "type": "number"
        +}
      • addedOutput schema / properties / sources / items / properties / last_data_change_at
        Added value: +{
        +  "description": "ISO timestamp du dernier run ayant RÉELLEMENT changé la donnée servie (success/partial sans court-circuit). null si aucune ingestion réelle n'a jamais abouti.",
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • changedOutput schema / properties / sources / items / properties / last_success_at / description
        Previous value: -"ISO timestamp dernière ingestion OK. null si aucun succès enregistré (1er déploiement)."New value: +"ISO timestamp du dernier run dont le swap a réussi — statut `success` OU `partial` (swap OK, couche secondaire matview/canary en échec : la donnée est servie). null si aucun succès enregistré (1er déploiement)."
      • changedOutput schema / properties / sources / items / properties / staleness_days / description
        Previous value: -"null si la source n'a jamais été synchronisée (signal alarmant à propager au caller)."New value: +"Jours depuis le dernier run réussi — y compris un run court-circuité « fichier amont identique ». NE mesure PAS l'âge de la donnée : utiliser data_age_days. null si la source n'a jamais été synchronisée (signal alarmant à propager au caller)."
    • Changedetablissement_by_finess1 field changed
      • changedInput schema / properties / include_freshness / description
        Previous value: -"Si true, ajoute un champ `data_freshness` au payload (dans `query_metadata` si présent, sinon à la racine) listant la dernière ingestion réussie par source (FINESS, Ameli, RPPS, CDS) avec `staleness_days`. Opt-in pour ne pas alourdir les payloads par défaut. Cache 5min côté serveur — coût négligeable."New value: +"Si true, ajoute un champ `data_freshness` au payload (dans `query_metadata` si présent, sinon à la racine) listant, par source (FINESS, Ameli, RPPS, CDS, IRIS), la dernière ingestion réussie (`last_success_at`, `staleness_days`) ET la dernière fois que la donnée a réellement changé (`last_data_change_at`, `data_age_days` — un run court-circuité « fichier amont identique » compte comme succès mais ne rajeunit pas la donnée ; c'est `data_age_days` qui dit l'âge réel de ce qui est servi). Opt-in pour ne pas alourdir les payloads par défaut. Cache 5min côté serveur — coût négligeable."
    • Changedetablissements_finess_by_categorie1 field changed
      • changedInput schema / properties / include_freshness / description
        Previous value: -"Si true, ajoute un champ `data_freshness` au payload (dans `query_metadata` si présent, sinon à la racine) listant la dernière ingestion réussie par source (FINESS, Ameli, RPPS, CDS) avec `staleness_days`. Opt-in pour ne pas alourdir les payloads par défaut. Cache 5min côté serveur — coût négligeable."New value: +"Si true, ajoute un champ `data_freshness` au payload (dans `query_metadata` si présent, sinon à la racine) listant, par source (FINESS, Ameli, RPPS, CDS, IRIS), la dernière ingestion réussie (`last_success_at`, `staleness_days`) ET la dernière fois que la donnée a réellement changé (`last_data_change_at`, `data_age_days` — un run court-circuité « fichier amont identique » compte comme succès mais ne rajeunit pas la donnée ; c'est `data_age_days` qui dit l'âge réel de ce qui est servi). Opt-in pour ne pas alourdir les payloads par défaut. Cache 5min côté serveur — coût négligeable."
    • Changedetablissements_finess_in_radius1 field changed
      • changedInput schema / properties / include_freshness / description
        Previous value: -"Si true, ajoute un champ `data_freshness` au payload (dans `query_metadata` si présent, sinon à la racine) listant la dernière ingestion réussie par source (FINESS, Ameli, RPPS, CDS) avec `staleness_days`. Opt-in pour ne pas alourdir les payloads par défaut. Cache 5min côté serveur — coût négligeable."New value: +"Si true, ajoute un champ `data_freshness` au payload (dans `query_metadata` si présent, sinon à la racine) listant, par source (FINESS, Ameli, RPPS, CDS, IRIS), la dernière ingestion réussie (`last_success_at`, `staleness_days`) ET la dernière fois que la donnée a réellement changé (`last_data_change_at`, `data_age_days` — un run court-circuité « fichier amont identique » compte comme succès mais ne rajeunit pas la donnée ; c'est `data_age_days` qui dit l'âge réel de ce qui est servi). Opt-in pour ne pas alourdir les payloads par défaut. Cache 5min côté serveur — coût négligeable."
    • Changedlister_nomenclature1 field changed
      • changedInput schema / properties / include_freshness / description
        Previous value: -"Si true, ajoute un champ `data_freshness` au payload (dans `query_metadata` si présent, sinon à la racine) listant la dernière ingestion réussie par source (FINESS, Ameli, RPPS, CDS) avec `staleness_days`. Opt-in pour ne pas alourdir les payloads par défaut. Cache 5min côté serveur — coût négligeable."New value: +"Si true, ajoute un champ `data_freshness` au payload (dans `query_metadata` si présent, sinon à la racine) listant, par source (FINESS, Ameli, RPPS, CDS, IRIS), la dernière ingestion réussie (`last_success_at`, `staleness_days`) ET la dernière fois que la donnée a réellement changé (`last_data_change_at`, `data_age_days` — un run court-circuité « fichier amont identique » compte comme succès mais ne rajeunit pas la donnée ; c'est `data_age_days` qui dit l'âge réel de ce qui est servi). Opt-in pour ne pas alourdir les payloads par défaut. Cache 5min côté serveur — coût négligeable."
    • Changedprofessionnel_by_rpps1 field changed
      • changedInput schema / properties / include_freshness / description
        Previous value: -"Si true, ajoute un champ `data_freshness` au payload (dans `query_metadata` si présent, sinon à la racine) listant la dernière ingestion réussie par source (FINESS, Ameli, RPPS, CDS) avec `staleness_days`. Opt-in pour ne pas alourdir les payloads par défaut. Cache 5min côté serveur — coût négligeable."New value: +"Si true, ajoute un champ `data_freshness` au payload (dans `query_metadata` si présent, sinon à la racine) listant, par source (FINESS, Ameli, RPPS, CDS, IRIS), la dernière ingestion réussie (`last_success_at`, `staleness_days`) ET la dernière fois que la donnée a réellement changé (`last_data_change_at`, `data_age_days` — un run court-circuité « fichier amont identique » compte comme succès mais ne rajeunit pas la donnée ; c'est `data_age_days` qui dit l'âge réel de ce qui est servi). Opt-in pour ne pas alourdir les payloads par défaut. Cache 5min côté serveur — coût négligeable."
    • Changedprofessionnels_in_radius1 field changed
      • changedInput schema / properties / include_freshness / description
        Previous value: -"Si true, ajoute un champ `data_freshness` au payload (dans `query_metadata` si présent, sinon à la racine) listant la dernière ingestion réussie par source (FINESS, Ameli, RPPS, CDS) avec `staleness_days`. Opt-in pour ne pas alourdir les payloads par défaut. Cache 5min côté serveur — coût négligeable."New value: +"Si true, ajoute un champ `data_freshness` au payload (dans `query_metadata` si présent, sinon à la racine) listant, par source (FINESS, Ameli, RPPS, CDS, IRIS), la dernière ingestion réussie (`last_success_at`, `staleness_days`) ET la dernière fois que la donnée a réellement changé (`last_data_change_at`, `data_age_days` — un run court-circuité « fichier amont identique » compte comme succès mais ne rajeunit pas la donnée ; c'est `data_age_days` qui dit l'âge réel de ce qui est servi). Opt-in pour ne pas alourdir les payloads par défaut. Cache 5min côté serveur — coût négligeable."
    • Changedprofessionnels_par_specialite_dept1 field changed
      • changedInput schema / properties / include_freshness / description
        Previous value: -"Si true, ajoute un champ `data_freshness` au payload (dans `query_metadata` si présent, sinon à la racine) listant la dernière ingestion réussie par source (FINESS, Ameli, RPPS, CDS) avec `staleness_days`. Opt-in pour ne pas alourdir les payloads par défaut. Cache 5min côté serveur — coût négligeable."New value: +"Si true, ajoute un champ `data_freshness` au payload (dans `query_metadata` si présent, sinon à la racine) listant, par source (FINESS, Ameli, RPPS, CDS, IRIS), la dernière ingestion réussie (`last_success_at`, `staleness_days`) ET la dernière fois que la donnée a réellement changé (`last_data_change_at`, `data_age_days` — un run court-circuité « fichier amont identique » compte comme succès mais ne rajeunit pas la donnée ; c'est `data_age_days` qui dit l'âge réel de ce qui est servi). Opt-in pour ne pas alourdir les payloads par défaut. Cache 5min côté serveur — coût négligeable."
    • Changedprofessionnels_rpps_in_radius1 field changed
      • changedInput schema / properties / include_freshness / description
        Previous value: -"Si true, ajoute un champ `data_freshness` au payload (dans `query_metadata` si présent, sinon à la racine) listant la dernière ingestion réussie par source (FINESS, Ameli, RPPS, CDS) avec `staleness_days`. Opt-in pour ne pas alourdir les payloads par défaut. Cache 5min côté serveur — coût négligeable."New value: +"Si true, ajoute un champ `data_freshness` au payload (dans `query_metadata` si présent, sinon à la racine) listant, par source (FINESS, Ameli, RPPS, CDS, IRIS), la dernière ingestion réussie (`last_success_at`, `staleness_days`) ET la dernière fois que la donnée a réellement changé (`last_data_change_at`, `data_age_days` — un run court-circuité « fichier amont identique » compte comme succès mais ne rajeunit pas la donnée ; c'est `data_age_days` qui dit l'âge réel de ce qui est servi). Opt-in pour ne pas alourdir les payloads par défaut. Cache 5min côté serveur — coût négligeable."
    • Changedprofessionnels_rpps_par_dept1 field changed
      • changedInput schema / properties / include_freshness / description
        Previous value: -"Si true, ajoute un champ `data_freshness` au payload (dans `query_metadata` si présent, sinon à la racine) listant la dernière ingestion réussie par source (FINESS, Ameli, RPPS, CDS) avec `staleness_days`. Opt-in pour ne pas alourdir les payloads par défaut. Cache 5min côté serveur — coût négligeable."New value: +"Si true, ajoute un champ `data_freshness` au payload (dans `query_metadata` si présent, sinon à la racine) listant, par source (FINESS, Ameli, RPPS, CDS, IRIS), la dernière ingestion réussie (`last_success_at`, `staleness_days`) ET la dernière fois que la donnée a réellement changé (`last_data_change_at`, `data_age_days` — un run court-circuité « fichier amont identique » compte comme succès mais ne rajeunit pas la donnée ; c'est `data_age_days` qui dit l'âge réel de ce qui est servi). Opt-in pour ne pas alourdir les payloads par défaut. Cache 5min côté serveur — coût négligeable."
    • Changedrpps_dans_etablissement1 field changed
      • changedInput schema / properties / include_freshness / description
        Previous value: -"Si true, ajoute un champ `data_freshness` au payload (dans `query_metadata` si présent, sinon à la racine) listant la dernière ingestion réussie par source (FINESS, Ameli, RPPS, CDS) avec `staleness_days`. Opt-in pour ne pas alourdir les payloads par défaut. Cache 5min côté serveur — coût négligeable."New value: +"Si true, ajoute un champ `data_freshness` au payload (dans `query_metadata` si présent, sinon à la racine) listant, par source (FINESS, Ameli, RPPS, CDS, IRIS), la dernière ingestion réussie (`last_success_at`, `staleness_days`) ET la dernière fois que la donnée a réellement changé (`last_data_change_at`, `data_age_days` — un run court-circuité « fichier amont identique » compte comme succès mais ne rajeunit pas la donnée ; c'est `data_age_days` qui dit l'âge réel de ce qui est servi). Opt-in pour ne pas alourdir les payloads par défaut. Cache 5min côté serveur — coût négligeable."
    • Changedrpps_search_by_name1 field changed
      • changedInput schema / properties / include_freshness / description
        Previous value: -"Si true, ajoute un champ `data_freshness` au payload (dans `query_metadata` si présent, sinon à la racine) listant la dernière ingestion réussie par source (FINESS, Ameli, RPPS, CDS) avec `staleness_days`. Opt-in pour ne pas alourdir les payloads par défaut. Cache 5min côté serveur — coût négligeable."New value: +"Si true, ajoute un champ `data_freshness` au payload (dans `query_metadata` si présent, sinon à la racine) listant, par source (FINESS, Ameli, RPPS, CDS, IRIS), la dernière ingestion réussie (`last_success_at`, `staleness_days`) ET la dernière fois que la donnée a réellement changé (`last_data_change_at`, `data_age_days` — un run court-circuité « fichier amont identique » compte comme succès mais ne rajeunit pas la donnée ; c'est `data_age_days` qui dit l'âge réel de ce qui est servi). Opt-in pour ne pas alourdir les payloads par défaut. Cache 5min côté serveur — coût négligeable."
  2. 2 tool updates
    • Addedcout_foncier
    • Addeddynamique_immobiliere
  3. 2 tool updates
    • Addedenrichir_concurrents
    • Addedpanorama_implantation_complet
  4. 1 tool update
    • Addedprofil_iris
  5. 11 tool updates
    • Removeddensite_etablissements_sante
    • Removeddensite_professionnels_sante
    • Addeddensite_sante
    • Addedlister_nomenclature
    • Removedlister_specialites_ameli
    • Removedlister_specialites_medicales
    • Removedlister_types_ps_ameli
    • Addedpopulation
    • Removedpopulation_par_commune
    • Removedpopulation_par_departement
    • Changedprofessionnels_par_specialite_dept2 fields changed
      • changedInput schema / properties / specialite_code / description
        Previous value: -"Code spécialité Ameli (ex: '01' MG, '24' IDE, '26' kiné, '03' cardio). Optionnel. Liste complète via `lister_specialites_ameli`."New value: +"Code spécialité Ameli (ex: '01' MG, '24' IDE, '26' kiné, '03' cardio). Optionnel. Liste complète via `lister_nomenclature(referentiel:'ameli_specialites')`."
      • changedInput schema / properties / type_ps_code / description
        Previous value: -"Code type PS Ameli ('1' médecins, '2' auxiliaires médicaux, '5' chirurgiens-dentistes). Optionnel — préférer `specialite_code` pour un ciblage précis. Liste complète via `lister_types_ps_ameli`."New value: +"Code type PS Ameli ('1' médecins, '2' auxiliaires médicaux, '5' chirurgiens-dentistes). Optionnel — préférer `specialite_code` pour un ciblage précis. Liste complète via `lister_nomenclature(referentiel:'ameli_types_ps')`."
  6. 1 tool update
    • Changeddensite_etablissements_sante4 fields changed
      • changedInput schema / properties / code_dept / description
        Previous value: -"Code INSEE du département 2-3 caractères. Ex: \"75\" Paris, \"59\" Nord, \"2A\" Corse-du-Sud, \"971\" Guadeloupe."New value: +"Code INSEE du département 2-3 caractères. Ex: \"75\" Paris, \"59\" Nord, \"2A\" Corse-du-Sud, \"971\" Guadeloupe. Sémantique conditionnelle (V0.20) : seul = scope dept entier ; combiné avec `nom_commune` = hint resolver pour désambiguer les homonymes. XOR avec `code_insee`."
      • addedInput schema / properties / code_insee
        Added value: +{
        +  "description": "Code INSEE de la commune 5 caractères (V0.20). Ex: \"59009\" Villeneuve-d'Ascq, \"33063\" Bordeaux, \"2A004\" Ajaccio. Paris/Lyon/Marseille NON supporté au niveau commune (densité indisponible — voir description) : utiliser code_dept. XOR avec `code_dept` et `nom_commune`.",
        +  "type": "string"
        +}
      • addedInput schema / properties / nom_commune
        Added value: +{
        +  "description": "Nom officiel de commune (alternative à `code_insee`, V0.20). Ex: \"Lille\", \"Villeneuve-d'Ascq\". Le serveur résout en interne via geo.api.gouv.fr. Combinable avec `code_dept` comme hint de désambiguïsation pour homonymes (ex \"Saint-Martin\" + dept \"65\"). XOR avec `code_insee` (paramètres redondants).",
        +  "type": "string"
        +}
      • changedInput schema / required
        Previous value: -[
        -  "code_dept",
        -  "famille"
        -]New value: +[
        +  "famille"
        +]
  7. 3 tool updates
    • Changeddensite_professionnels_sante3 fields changed
      • changedInput schema / properties / code_dept / description
        Previous value: -"Code INSEE du département 2-3 caractères. Ex: \"75\" Paris, \"59\" Nord, \"2A\" Corse-du-Sud, \"971\" Guadeloupe. Exclusif avec code_insee."New value: +"Code INSEE du département 2-3 caractères. Ex: \"75\" Paris, \"59\" Nord, \"2A\" Corse-du-Sud, \"971\" Guadeloupe. Sémantique conditionnelle (V0.19) : seul = scope dept entier ; combiné avec `nom_commune` = hint resolver pour désambiguer les homonymes. XOR avec `code_insee`."
      • changedInput schema / properties / code_insee / description
        Previous value: -"Code INSEE de la commune 5 caractères (V0.9). Ex: \"59009\" Villeneuve-d'Ascq, \"33063\" Bordeaux, \"2A004\" Ajaccio. Paris/Lyon/Marseille NON supporté au niveau commune (densité indisponible — voir description) : utiliser code_dept. Exclusif avec code_dept."New value: +"Code INSEE de la commune 5 caractères (V0.9). Ex: \"59009\" Villeneuve-d'Ascq, \"33063\" Bordeaux, \"2A004\" Ajaccio. Paris/Lyon/Marseille NON supporté au niveau commune (densité indisponible — voir description) : utiliser code_dept. XOR avec `code_dept` et `nom_commune`."
      • addedInput schema / properties / nom_commune
        Added value: +{
        +  "description": "Nom officiel de commune (alternative à `code_insee`, V0.19). Ex: \"Lille\", \"Villeneuve-d'Ascq\". Le serveur résout en interne via geo.api.gouv.fr. Combinable avec `code_dept` comme hint de désambiguïsation pour homonymes (ex \"Saint-Martin\" + dept \"65\"). XOR avec `code_insee` (paramètres redondants).",
        +  "type": "string"
        +}
    • Changedetablissements_finess_by_categorie3 fields changed
      • changedInput schema / properties / code_insee / description
        Previous value: -"Code INSEE de commune (5 caractères). Optionnel."New value: +"Code INSEE de commune (5 caractères). Optionnel. XOR strict avec `departement` et `nom_commune`."
      • changedInput schema / properties / departement / description
        Previous value: -"Code département INSEE (ex: '75', '2A', '2B', '971'). Métropole 2 caractères (Corse '2A'/'2B', pas '20'), DOM/TOM 3 caractères. Optionnel."New value: +"Code département INSEE (ex: '75', '2A', '2B', '971'). Métropole 2 caractères (Corse '2A'/'2B', pas '20'), DOM/TOM 3 caractères. Optionnel. Combinable avec `nom_commune` comme hint resolver (filtre les homonymes), sinon XOR strict avec `code_insee` et `nom_commune`."
      • addedInput schema / properties / nom_commune
        Added value: +{
        +  "description": "Nom officiel de commune (alternative à `code_insee`, V0.19). Ex: \"Lille\", \"Saint-Étienne\". Le serveur résout en interne via geo.api.gouv.fr. Si ambigu (ex \"Saint-Martin\" → 5 villes), retourne une erreur structurée avec candidates. Combinable avec `departement` comme hint de désambiguïsation. Abréviations type \"St-Martin\" non reconnues — utiliser le nom officiel complet.",
        +  "type": "string"
        +}
    • Changedpanorama_sante_territoire4 fields changed
      • changedInput schema / properties / code_insee / description
        Previous value: -"Code INSEE de la commune 5 caractères. Ex: \"59009\" Villeneuve-d'Ascq, \"33063\" Bordeaux, \"2A004\" Ajaccio. Paris/Lyon/Marseille NON supporté (voir description)."New value: +"Code INSEE de la commune 5 caractères. Ex: \"59009\" Villeneuve-d'Ascq, \"33063\" Bordeaux, \"2A004\" Ajaccio. Paris/Lyon/Marseille NON supporté (voir description). XOR avec `nom_commune`."
      • addedInput schema / properties / departement
        Added value: +{
        +  "description": "Code département INSEE (V0.19, hint resolver UNIQUEMENT). À utiliser EN COMBINAISON avec `nom_commune` pour désambiguer les homonymes. Seul, lève une erreur (panorama = calcul commune uniquement, utiliser `code_insee` ou `nom_commune`).",
        +  "type": "string"
        +}
      • addedInput schema / properties / nom_commune
        Added value: +{
        +  "description": "Nom officiel de commune (alternative à `code_insee`, V0.19). Ex: \"Lille\", \"Saint-Étienne\". Combinable avec `departement` comme hint de désambiguïsation pour homonymes (ex \"Saint-Martin\" + dept \"65\"). Abréviations type \"St-Martin\" non reconnues.",
        +  "type": "string"
        +}
      • removedInput schema / required
        Removed value: -[
        -  "code_insee"
        -]
  8. 11 tool updates
    • Changedcentres_sante_in_radius1 field changed
      • addedOutput schema / properties / activite_hebergee
        Added value: +{
        +  "description": "Compte juxtaposé des sites hébergeant l'activité correspondant à la famille filtrée, sous une autre catégorie FINESS. Distinct du `count` principal — lire `note` pour comprendre la sémantique et ne JAMAIS additionner les deux comptes sans préciser leur nature.",
        +  "properties": {
        +    "activite": {
        +      "type": "string"
        +    },
        +    "count": {
        +      "type": "integer"
        +    },
        +    "densite_pour_100k_hab": {
        +      "type": "number"
        +    },
        +    "note": {
        +      "type": "string"
        +    },
        +    "sites_apercu": {
        +      "items": {
        +        "properties": {
        +          "categorie_code": {
        +            "type": "string"
        +          },
        +          "categorie_libelle": {
        +            "type": "string"
        +          },
        +          "num_finess": {
        +            "type": "string"
        +          },
        +          "raison_sociale": {
        +            "type": "string"
        +          }
        +        },
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "truncated": {
        +      "type": "boolean"
        +    }
        +  },
        +  "type": "object"
        +}
    • Changedetablissements_finess_by_categorie1 field changed
      • addedOutput schema / properties / activite_hebergee
        Added value: +{
        +  "description": "Compte juxtaposé des sites hébergeant l'activité correspondant à la famille filtrée, sous une autre catégorie FINESS. Distinct du `count` principal — lire `note` pour comprendre la sémantique et ne JAMAIS additionner les deux comptes sans préciser leur nature.",
        +  "properties": {
        +    "activite": {
        +      "type": "string"
        +    },
        +    "count": {
        +      "type": "integer"
        +    },
        +    "densite_pour_100k_hab": {
        +      "type": "number"
        +    },
        +    "note": {
        +      "type": "string"
        +    },
        +    "sites_apercu": {
        +      "items": {
        +        "properties": {
        +          "categorie_code": {
        +            "type": "string"
        +          },
        +          "categorie_libelle": {
        +            "type": "string"
        +          },
        +          "num_finess": {
        +            "type": "string"
        +          },
        +          "raison_sociale": {
        +            "type": "string"
        +          }
        +        },
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "truncated": {
        +      "type": "boolean"
        +    }
        +  },
        +  "type": "object"
        +}
    • Changedetablissements_finess_in_radius1 field changed
      • addedOutput schema / properties / activite_hebergee
        Added value: +{
        +  "description": "Compte juxtaposé des sites hébergeant l'activité correspondant à la famille filtrée, sous une autre catégorie FINESS. Distinct du `count` principal — lire `note` pour comprendre la sémantique et ne JAMAIS additionner les deux comptes sans préciser leur nature.",
        +  "properties": {
        +    "activite": {
        +      "type": "string"
        +    },
        +    "count": {
        +      "type": "integer"
        +    },
        +    "densite_pour_100k_hab": {
        +      "type": "number"
        +    },
        +    "note": {
        +      "type": "string"
        +    },
        +    "sites_apercu": {
        +      "items": {
        +        "properties": {
        +          "categorie_code": {
        +            "type": "string"
        +          },
        +          "categorie_libelle": {
        +            "type": "string"
        +          },
        +          "num_finess": {
        +            "type": "string"
        +          },
        +          "raison_sociale": {
        +            "type": "string"
        +          }
        +        },
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "truncated": {
        +      "type": "boolean"
        +    }
        +  },
        +  "type": "object"
        +}
    • Changedlister_specialites_ameli1 field changed
      • addedOutput schema / properties / activite_hebergee
        Added value: +{
        +  "description": "Compte juxtaposé des sites hébergeant l'activité correspondant à la famille filtrée, sous une autre catégorie FINESS. Distinct du `count` principal — lire `note` pour comprendre la sémantique et ne JAMAIS additionner les deux comptes sans préciser leur nature.",
        +  "properties": {
        +    "activite": {
        +      "type": "string"
        +    },
        +    "count": {
        +      "type": "integer"
        +    },
        +    "densite_pour_100k_hab": {
        +      "type": "number"
        +    },
        +    "note": {
        +      "type": "string"
        +    },
        +    "sites_apercu": {
        +      "items": {
        +        "properties": {
        +          "categorie_code": {
        +            "type": "string"
        +          },
        +          "categorie_libelle": {
        +            "type": "string"
        +          },
        +          "num_finess": {
        +            "type": "string"
        +          },
        +          "raison_sociale": {
        +            "type": "string"
        +          }
        +        },
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "truncated": {
        +      "type": "boolean"
        +    }
        +  },
        +  "type": "object"
        +}
    • Changedlister_types_ps_ameli1 field changed
      • addedOutput schema / properties / activite_hebergee
        Added value: +{
        +  "description": "Compte juxtaposé des sites hébergeant l'activité correspondant à la famille filtrée, sous une autre catégorie FINESS. Distinct du `count` principal — lire `note` pour comprendre la sémantique et ne JAMAIS additionner les deux comptes sans préciser leur nature.",
        +  "properties": {
        +    "activite": {
        +      "type": "string"
        +    },
        +    "count": {
        +      "type": "integer"
        +    },
        +    "densite_pour_100k_hab": {
        +      "type": "number"
        +    },
        +    "note": {
        +      "type": "string"
        +    },
        +    "sites_apercu": {
        +      "items": {
        +        "properties": {
        +          "categorie_code": {
        +            "type": "string"
        +          },
        +          "categorie_libelle": {
        +            "type": "string"
        +          },
        +          "num_finess": {
        +            "type": "string"
        +          },
        +          "raison_sociale": {
        +            "type": "string"
        +          }
        +        },
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "truncated": {
        +      "type": "boolean"
        +    }
        +  },
        +  "type": "object"
        +}
    • Changedprofessionnels_in_radius1 field changed
      • addedOutput schema / properties / activite_hebergee
        Added value: +{
        +  "description": "Compte juxtaposé des sites hébergeant l'activité correspondant à la famille filtrée, sous une autre catégorie FINESS. Distinct du `count` principal — lire `note` pour comprendre la sémantique et ne JAMAIS additionner les deux comptes sans préciser leur nature.",
        +  "properties": {
        +    "activite": {
        +      "type": "string"
        +    },
        +    "count": {
        +      "type": "integer"
        +    },
        +    "densite_pour_100k_hab": {
        +      "type": "number"
        +    },
        +    "note": {
        +      "type": "string"
        +    },
        +    "sites_apercu": {
        +      "items": {
        +        "properties": {
        +          "categorie_code": {
        +            "type": "string"
        +          },
        +          "categorie_libelle": {
        +            "type": "string"
        +          },
        +          "num_finess": {
        +            "type": "string"
        +          },
        +          "raison_sociale": {
        +            "type": "string"
        +          }
        +        },
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "truncated": {
        +      "type": "boolean"
        +    }
        +  },
        +  "type": "object"
        +}
    • Changedprofessionnels_par_specialite_dept1 field changed
      • addedOutput schema / properties / activite_hebergee
        Added value: +{
        +  "description": "Compte juxtaposé des sites hébergeant l'activité correspondant à la famille filtrée, sous une autre catégorie FINESS. Distinct du `count` principal — lire `note` pour comprendre la sémantique et ne JAMAIS additionner les deux comptes sans préciser leur nature.",
        +  "properties": {
        +    "activite": {
        +      "type": "string"
        +    },
        +    "count": {
        +      "type": "integer"
        +    },
        +    "densite_pour_100k_hab": {
        +      "type": "number"
        +    },
        +    "note": {
        +      "type": "string"
        +    },
        +    "sites_apercu": {
        +      "items": {
        +        "properties": {
        +          "categorie_code": {
        +            "type": "string"
        +          },
        +          "categorie_libelle": {
        +            "type": "string"
        +          },
        +          "num_finess": {
        +            "type": "string"
        +          },
        +          "raison_sociale": {
        +            "type": "string"
        +          }
        +        },
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "truncated": {
        +      "type": "boolean"
        +    }
        +  },
        +  "type": "object"
        +}
    • Changedprofessionnels_rpps_in_radius1 field changed
      • addedOutput schema / properties / activite_hebergee
        Added value: +{
        +  "description": "Compte juxtaposé des sites hébergeant l'activité correspondant à la famille filtrée, sous une autre catégorie FINESS. Distinct du `count` principal — lire `note` pour comprendre la sémantique et ne JAMAIS additionner les deux comptes sans préciser leur nature.",
        +  "properties": {
        +    "activite": {
        +      "type": "string"
        +    },
        +    "count": {
        +      "type": "integer"
        +    },
        +    "densite_pour_100k_hab": {
        +      "type": "number"
        +    },
        +    "note": {
        +      "type": "string"
        +    },
        +    "sites_apercu": {
        +      "items": {
        +        "properties": {
        +          "categorie_code": {
        +            "type": "string"
        +          },
        +          "categorie_libelle": {
        +            "type": "string"
        +          },
        +          "num_finess": {
        +            "type": "string"
        +          },
        +          "raison_sociale": {
        +            "type": "string"
        +          }
        +        },
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "truncated": {
        +      "type": "boolean"
        +    }
        +  },
        +  "type": "object"
        +}
    • Changedprofessionnels_rpps_par_dept1 field changed
      • addedOutput schema / properties / activite_hebergee
        Added value: +{
        +  "description": "Compte juxtaposé des sites hébergeant l'activité correspondant à la famille filtrée, sous une autre catégorie FINESS. Distinct du `count` principal — lire `note` pour comprendre la sémantique et ne JAMAIS additionner les deux comptes sans préciser leur nature.",
        +  "properties": {
        +    "activite": {
        +      "type": "string"
        +    },
        +    "count": {
        +      "type": "integer"
        +    },
        +    "densite_pour_100k_hab": {
        +      "type": "number"
        +    },
        +    "note": {
        +      "type": "string"
        +    },
        +    "sites_apercu": {
        +      "items": {
        +        "properties": {
        +          "categorie_code": {
        +            "type": "string"
        +          },
        +          "categorie_libelle": {
        +            "type": "string"
        +          },
        +          "num_finess": {
        +            "type": "string"
        +          },
        +          "raison_sociale": {
        +            "type": "string"
        +          }
        +        },
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "truncated": {
        +      "type": "boolean"
        +    }
        +  },
        +  "type": "object"
        +}
    • Changedrpps_dans_etablissement1 field changed
      • addedOutput schema / properties / activite_hebergee
        Added value: +{
        +  "description": "Compte juxtaposé des sites hébergeant l'activité correspondant à la famille filtrée, sous une autre catégorie FINESS. Distinct du `count` principal — lire `note` pour comprendre la sémantique et ne JAMAIS additionner les deux comptes sans préciser leur nature.",
        +  "properties": {
        +    "activite": {
        +      "type": "string"
        +    },
        +    "count": {
        +      "type": "integer"
        +    },
        +    "densite_pour_100k_hab": {
        +      "type": "number"
        +    },
        +    "note": {
        +      "type": "string"
        +    },
        +    "sites_apercu": {
        +      "items": {
        +        "properties": {
        +          "categorie_code": {
        +            "type": "string"
        +          },
        +          "categorie_libelle": {
        +            "type": "string"
        +          },
        +          "num_finess": {
        +            "type": "string"
        +          },
        +          "raison_sociale": {
        +            "type": "string"
        +          }
        +        },
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "truncated": {
        +      "type": "boolean"
        +    }
        +  },
        +  "type": "object"
        +}
    • Changedrpps_search_by_name1 field changed
      • addedOutput schema / properties / activite_hebergee
        Added value: +{
        +  "description": "Compte juxtaposé des sites hébergeant l'activité correspondant à la famille filtrée, sous une autre catégorie FINESS. Distinct du `count` principal — lire `note` pour comprendre la sémantique et ne JAMAIS additionner les deux comptes sans préciser leur nature.",
        +  "properties": {
        +    "activite": {
        +      "type": "string"
        +    },
        +    "count": {
        +      "type": "integer"
        +    },
        +    "densite_pour_100k_hab": {
        +      "type": "number"
        +    },
        +    "note": {
        +      "type": "string"
        +    },
        +    "sites_apercu": {
        +      "items": {
        +        "properties": {
        +          "categorie_code": {
        +            "type": "string"
        +          },
        +          "categorie_libelle": {
        +            "type": "string"
        +          },
        +          "num_finess": {
        +            "type": "string"
        +          },
        +          "raison_sociale": {
        +            "type": "string"
        +          }
        +        },
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "truncated": {
        +      "type": "boolean"
        +    }
        +  },
        +  "type": "object"
        +}
  9. 12 tool updates
    • Changedcentres_sante_in_radius1 field changed
      • addedOutput schema / properties / perimetre
        Added value: +{
        +  "description": "Lentille de la source : ce que le comptage inclut/exclut. Lire `completeness_note` et la restituer au lecteur final.",
        +  "properties": {
        +    "completeness_note": {
        +      "type": "string"
        +    },
        +    "compte": {
        +      "type": "string"
        +    },
        +    "exclut": {
        +      "type": "string"
        +    },
        +    "lens": {
        +      "type": "string"
        +    },
        +    "source": {
        +      "type": "string"
        +    }
        +  },
        +  "type": "object"
        +}
    • Changedetablissements_finess_by_categorie1 field changed
      • addedOutput schema / properties / perimetre
        Added value: +{
        +  "description": "Lentille de la source : ce que le comptage inclut/exclut. Lire `completeness_note` et la restituer au lecteur final.",
        +  "properties": {
        +    "completeness_note": {
        +      "type": "string"
        +    },
        +    "compte": {
        +      "type": "string"
        +    },
        +    "exclut": {
        +      "type": "string"
        +    },
        +    "lens": {
        +      "type": "string"
        +    },
        +    "source": {
        +      "type": "string"
        +    }
        +  },
        +  "type": "object"
        +}
    • Changedetablissements_finess_in_radius1 field changed
      • addedOutput schema / properties / perimetre
        Added value: +{
        +  "description": "Lentille de la source : ce que le comptage inclut/exclut. Lire `completeness_note` et la restituer au lecteur final.",
        +  "properties": {
        +    "completeness_note": {
        +      "type": "string"
        +    },
        +    "compte": {
        +      "type": "string"
        +    },
        +    "exclut": {
        +      "type": "string"
        +    },
        +    "lens": {
        +      "type": "string"
        +    },
        +    "source": {
        +      "type": "string"
        +    }
        +  },
        +  "type": "object"
        +}
    • Changedfiness_sirene_coverage_in_radius1 field changed
      • addedOutput schema / properties / perimetre
        Added value: +{
        +  "description": "Lentille de la source : ce que le comptage inclut/exclut. Lire `completeness_note` et la restituer au lecteur final.",
        +  "properties": {
        +    "completeness_note": {
        +      "type": "string"
        +    },
        +    "compte": {
        +      "type": "string"
        +    },
        +    "exclut": {
        +      "type": "string"
        +    },
        +    "lens": {
        +      "type": "string"
        +    },
        +    "source": {
        +      "type": "string"
        +    }
        +  },
        +  "type": "object"
        +}
    • Changedlister_specialites_ameli1 field changed
      • addedOutput schema / properties / perimetre
        Added value: +{
        +  "description": "Lentille de la source : ce que le comptage inclut/exclut. Lire `completeness_note` et la restituer au lecteur final.",
        +  "properties": {
        +    "completeness_note": {
        +      "type": "string"
        +    },
        +    "compte": {
        +      "type": "string"
        +    },
        +    "exclut": {
        +      "type": "string"
        +    },
        +    "lens": {
        +      "type": "string"
        +    },
        +    "source": {
        +      "type": "string"
        +    }
        +  },
        +  "type": "object"
        +}
    • Changedlister_types_ps_ameli1 field changed
      • addedOutput schema / properties / perimetre
        Added value: +{
        +  "description": "Lentille de la source : ce que le comptage inclut/exclut. Lire `completeness_note` et la restituer au lecteur final.",
        +  "properties": {
        +    "completeness_note": {
        +      "type": "string"
        +    },
        +    "compte": {
        +      "type": "string"
        +    },
        +    "exclut": {
        +      "type": "string"
        +    },
        +    "lens": {
        +      "type": "string"
        +    },
        +    "source": {
        +      "type": "string"
        +    }
        +  },
        +  "type": "object"
        +}
    • Changedprofessionnels_in_radius1 field changed
      • addedOutput schema / properties / perimetre
        Added value: +{
        +  "description": "Lentille de la source : ce que le comptage inclut/exclut. Lire `completeness_note` et la restituer au lecteur final.",
        +  "properties": {
        +    "completeness_note": {
        +      "type": "string"
        +    },
        +    "compte": {
        +      "type": "string"
        +    },
        +    "exclut": {
        +      "type": "string"
        +    },
        +    "lens": {
        +      "type": "string"
        +    },
        +    "source": {
        +      "type": "string"
        +    }
        +  },
        +  "type": "object"
        +}
    • Changedprofessionnels_par_specialite_dept1 field changed
      • addedOutput schema / properties / perimetre
        Added value: +{
        +  "description": "Lentille de la source : ce que le comptage inclut/exclut. Lire `completeness_note` et la restituer au lecteur final.",
        +  "properties": {
        +    "completeness_note": {
        +      "type": "string"
        +    },
        +    "compte": {
        +      "type": "string"
        +    },
        +    "exclut": {
        +      "type": "string"
        +    },
        +    "lens": {
        +      "type": "string"
        +    },
        +    "source": {
        +      "type": "string"
        +    }
        +  },
        +  "type": "object"
        +}
    • Changedprofessionnels_rpps_in_radius1 field changed
      • addedOutput schema / properties / perimetre
        Added value: +{
        +  "description": "Lentille de la source : ce que le comptage inclut/exclut. Lire `completeness_note` et la restituer au lecteur final.",
        +  "properties": {
        +    "completeness_note": {
        +      "type": "string"
        +    },
        +    "compte": {
        +      "type": "string"
        +    },
        +    "exclut": {
        +      "type": "string"
        +    },
        +    "lens": {
        +      "type": "string"
        +    },
        +    "source": {
        +      "type": "string"
        +    }
        +  },
        +  "type": "object"
        +}
    • Changedprofessionnels_rpps_par_dept1 field changed
      • addedOutput schema / properties / perimetre
        Added value: +{
        +  "description": "Lentille de la source : ce que le comptage inclut/exclut. Lire `completeness_note` et la restituer au lecteur final.",
        +  "properties": {
        +    "completeness_note": {
        +      "type": "string"
        +    },
        +    "compte": {
        +      "type": "string"
        +    },
        +    "exclut": {
        +      "type": "string"
        +    },
        +    "lens": {
        +      "type": "string"
        +    },
        +    "source": {
        +      "type": "string"
        +    }
        +  },
        +  "type": "object"
        +}
    • Changedrpps_dans_etablissement1 field changed
      • addedOutput schema / properties / perimetre
        Added value: +{
        +  "description": "Lentille de la source : ce que le comptage inclut/exclut. Lire `completeness_note` et la restituer au lecteur final.",
        +  "properties": {
        +    "completeness_note": {
        +      "type": "string"
        +    },
        +    "compte": {
        +      "type": "string"
        +    },
        +    "exclut": {
        +      "type": "string"
        +    },
        +    "lens": {
        +      "type": "string"
        +    },
        +    "source": {
        +      "type": "string"
        +    }
        +  },
        +  "type": "object"
        +}
    • Changedrpps_search_by_name1 field changed
      • addedOutput schema / properties / perimetre
        Added value: +{
        +  "description": "Lentille de la source : ce que le comptage inclut/exclut. Lire `completeness_note` et la restituer au lecteur final.",
        +  "properties": {
        +    "completeness_note": {
        +      "type": "string"
        +    },
        +    "compte": {
        +      "type": "string"
        +    },
        +    "exclut": {
        +      "type": "string"
        +    },
        +    "lens": {
        +      "type": "string"
        +    },
        +    "source": {
        +      "type": "string"
        +    }
        +  },
        +  "type": "object"
        +}
  10. 1 tool update
    • Changedprofessionnels_in_radius1 field changed
      • addedInput schema / properties / precise_only
        Added value: +{
        +  "default": false,
        +  "description": "Si true, exclut les PS au centroïde commune et ne renvoie que ceux géocodés à l'adresse BAN, à `distance_km` exacte (cf. description du tool pour la sémantique complète). Défaut false.",
        +  "type": "boolean"
        +}

Frequently Asked Questions

Discussions

No comments yet. Be the first to start the discussion!

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    MCP server for exploring French public open data via APIs like data.gouv.fr, geo.api.gouv.fr, INSEE Sirene, and Radio France.
    -
  • A
    license
    Not graded
    quality
    C
    maintenance
    Access 17M+ geocoded French property transactions (DVF), 22M+ DPE energy ratings, and 20M+ building records via MCP or REST API. Search transactions, market stats, comparables, price trends, rental yield, flip detection, and more.
    MIT
Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

TDQS

A4/5.0
Disambiguation3/5

While tools have distinct purposes, there is overlap among several similar tools (e.g., multiple professional and establishment search tools). The detailed descriptions help differentiate, but an agent may struggle to choose correctly among them.

Naming Consistency2/5

Naming mixes French and English, with no consistent pattern (e.g., 'enrichir_concurrents' vs 'inspect_site', 'etablissement_by_finess' vs 'etablissements_finess_in_radius'). This inconsistency makes the toolset harder to navigate.

Tool Count3/5

36 tools is high but justified given the broad domain. However, there are multiple tools for similar tasks (e.g., four professional search tools), suggesting some redundancy. The scope is borderline but acceptable.

Completeness4/5

The toolset covers a wide range of needs for French health data analysis: establishments, professionals, population, geocoding, demographics, and composite analyses. Few obvious gaps exist, though some specialized tasks might require additional integration.