이 MCP로 할 수 있는 일
Queries French public data on healthcare facilities and professionals, companies, demographics, geography, and real estate for territorial analysis.
도구
입력 스키마
{'type': 'object', 'properties': {'nom': {'type': 'string', 'description': 'Recherche par nom (autocomplétion). Ex: "Villeneuve d\'Ascq", "Lyon".'}, 'code': {'type': 'string', 'description': 'Code INSEE exact (5 caractères). Ex: "59009".'}, 'limit': {'type': 'number', 'default': 10, 'description': 'Nombre max de résultats (1-30, défaut 10).'}, 'codePostal': {'type': 'string', 'description': 'Code postal exact (5 chiffres). Ex: "59650".'}, 'boostPopulation': {'type': 'boolean', 'default': True, 'description': "Trier par population décroissante. Recommandé pour les noms ambigus (ex: 'Charleville')."}}}
입력 스키마
{'type': 'object', 'required': ['num_finess'], 'properties': {'num_finess': {'type': 'string', 'description': "Numéro FINESS exact 9 chiffres. Ex: '750000123'."}, 'include_freshness': {'type': 'boolean', 'default': False, 'description': "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."}}}
출력 스키마
{'type': 'object', 'required': ['found', 'lookupStatus'], 'properties': {'key': {'type': 'string', 'description': 'Clé recherchée (SIREN, num_finess, code INSEE, …).'}, 'found': {'type': 'boolean'}, 'message': {'type': 'string', 'description': 'Explication actionnable quand `found=false` (cause probable + remédiation).'}, 'lookupStatus': {'enum': ['found', 'not_found', 'ambiguous'], 'type': 'string'}}, 'description': 'LookupResult discriminé par `found`. true → payload métier à plat (siren, nomComplet, etc.). false → `lookupStatus`/`key`/`message` actionnables. `lookupStatus` est toujours présent runtime (validé par tests).'}
입력 스키마
{'type': 'object', 'required': ['lon', 'lat'], 'properties': {'lat': {'type': 'number', 'description': 'Latitude du centre (WGS84). Ex: 48.872 (Paris).'}, 'lon': {'type': 'number', 'description': 'Longitude du centre (WGS84). Ex: 2.317 (Paris).'}, 'limit': {'type': 'number', 'default': 100, 'maximum': 500, 'minimum': 1, 'description': 'Nombre max de résultats (1-500, défaut 100).'}, 'radius_km': {'type': 'number', 'default': 5, 'maximum': 50, 'minimum': 0.1, 'description': 'Rayon en km (0.1-50, défaut 5).'}, 'type_etab_codes': {'type': 'array', 'items': {'type': 'string'}, 'description': "Codes type établissement Annexe B : ['124'] CDS standard (défaut implicite), ['125'] CDS dentaire deprecated. Vide = tous types."}, 'specialite_codes': {'type': 'array', 'items': {'type': 'string'}, 'description': "Codes 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_freshness': {'type': 'boolean', 'default': False, 'description': "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."}, 'accepte_carte_vitale': {'type': 'boolean', 'description': "Filtre par acceptation carte Vitale. true = uniquement CDS qui acceptent CV, false = uniquement ceux qui ne l'acceptent pas. Omis = pas de filtre."}}}
출력 스키마
{'type': 'object', 'required': ['count', 'results'], 'properties': {'count': {'type': 'number', 'description': "Nombre d'entrées retournées dans `results` (post-troncature)."}, 'total': {'type': 'number', 'description': 'Effectif 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`.'}, 'results': {'type': 'array', 'items': {'type': 'object'}, 'description': 'Entrées métier (shape spécifique au tool, cf. description du tool).'}, 'freshness': {'type': 'object', 'description': 'Fraîcheur des sources (présent si `include_freshness: true`).'}, 'perimetre': {'type': 'object', 'properties': {'lens': {'type': 'string'}, 'compte': {'type': 'string'}, 'exclut': {'type': 'string'}, 'source': {'type': 'string'}, 'completeness_note': {'type': 'string'}}, 'description': 'Lentille de la source : ce que le comptage inclut/exclut. Lire `completeness_note` et la restituer au lecteur final.'}, 'truncated': {'type': 'boolean', 'description': 'true 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_metadata': {'type': 'object', 'description': 'Metadata de la query (radius_km, departement, filtres appliqués, …).'}, 'activite_hebergee': {'type': 'object', 'properties': {'note': {'type': 'string'}, 'count': {'type': 'integer'}, 'activite': {'type': 'string'}, 'truncated': {'type': 'boolean'}, 'sites_apercu': {'type': 'array', 'items': {'type': 'object', 'properties': {'num_finess': {'type': 'string'}, 'categorie_code': {'type': 'string'}, 'raison_sociale': {'type': 'string'}, 'categorie_libelle': {'type': 'string'}}}}, 'densite_pour_100k_hab': {'type': 'number'}}, '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."}}, 'description': 'Résultat de query avec metadata. `results` est tronqué à `limit` côté serveur (cf. `truncated` quand applicable).'}
입력 스키마
{'type': 'object', 'required': ['num_finess'], 'properties': {'num_finess': {'type': 'string', 'description': 'Numéro FINESS exact (9 chiffres).'}}}
출력 스키마
{'type': 'object', 'required': ['found', 'lookupStatus'], 'properties': {'key': {'type': 'string', 'description': 'Clé recherchée (SIREN, num_finess, code INSEE, …).'}, 'found': {'type': 'boolean'}, 'message': {'type': 'string', 'description': 'Explication actionnable quand `found=false` (cause probable + remédiation).'}, 'lookupStatus': {'enum': ['found', 'not_found', 'ambiguous'], 'type': 'string'}}, 'description': 'LookupResult discriminé par `found`. true → payload métier à plat (siren, nomComplet, etc.). false → `lookupStatus`/`key`/`message` actionnables. `lookupStatus` est toujours présent runtime (validé par tests).'}
입력 스키마
{'type': 'object', 'required': ['num_finess'], 'properties': {'num_finess': {'type': 'string', 'description': 'Numéro FINESS exact (9 chiffres).'}}}
출력 스키마
{'type': 'object', 'required': ['found', 'lookupStatus'], 'properties': {'key': {'type': 'string', 'description': 'Clé recherchée (SIREN, num_finess, code INSEE, …).'}, 'found': {'type': 'boolean'}, 'message': {'type': 'string', 'description': 'Explication actionnable quand `found=false` (cause probable + remédiation).'}, 'lookupStatus': {'enum': ['found', 'not_found', 'ambiguous'], 'type': 'string'}}, 'description': 'LookupResult discriminé par `found`. true → payload métier à plat (siren, nomComplet, etc.). false → `lookupStatus`/`key`/`message` actionnables. `lookupStatus` est toujours présent runtime (validé par tests).'}
입력 스키마
{'type': 'object', 'required': ['lat', 'lon'], 'properties': {'lat': {'type': 'number', 'description': 'Latitude du centre (WGS84).'}, 'lon': {'type': 'number', 'description': 'Longitude du centre (WGS84).'}, 'rayon_km': {'type': 'number', 'default': 3, 'maximum': 10, 'minimum': 0.1, 'description': 'Rayon en km (0.1-10, défaut 3).'}}}
출력 스키마
{'type': 'object', 'required': ['couverture', 'n_ventes'], 'properties': {'source': {'type': 'string', 'description': "Toujours 'DGFiP DVF'."}, 'periode': {'type': ['string', 'null'], 'description': "Années couvertes (ex: '2019–2024')."}, 'n_ventes': {'type': 'number', 'description': 'Volume de ventes dans le rayon.'}, 'couverture': {'enum': ['ok', 'indisponible:no_data'], 'type': 'string', 'description': "Statut : 'ok' = données disponibles, 'indisponible:no_data' = pas de ventes DVF dans le rayon."}, 'prix_m2_p25': {'type': ['number', 'null'], 'description': '1er quartile prix au m².'}, 'prix_m2_p75': {'type': ['number', 'null'], 'description': '3ème quartile prix au m².'}, 'prix_m2_median': {'type': ['number', 'null'], 'description': 'Prix médian au m² bâti.'}}, 'description': "Prix foncier DVF dans le rayon. couverture='indisponible:no_data' si aucune vente."}
입력 스키마
{'type': 'object', 'properties': {}, 'additionalProperties': False}
출력 스키마
{'type': 'object', 'required': ['sources'], 'properties': {'sources': {'type': 'array', 'items': {'type': 'object', 'required': ['source'], 'properties': {'source': {'type': 'string', 'description': 'Identifiant source (finess, ameli_ps, rpps).'}, 'cadence_hint': {'type': 'string'}, 'data_age_days': {'type': ['number', 'null'], '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)."}, 'staleness_days': {'type': ['number', 'null'], 'description': "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)."}, 'last_attempt_at': {'type': ['string', 'null']}, 'last_success_at': {'type': ['string', 'null'], 'description': '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).'}, 'last_attempt_status': {'type': ['string', 'null']}, 'last_data_change_at': {'type': ['string', 'null'], '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."}, 'expected_max_age_days': {'type': 'number', 'description': "Âge maximal attendu de la donnée pour cette source, en jours. Règle d'alerte : data_age_days > expected_max_age_days."}, 'last_success_row_count': {'type': ['number', 'null']}}}}}}
입력 스키마
{'type': 'object', 'required': ['cible'], 'properties': {'cible': {'enum': ['professionnels', 'etablissements'], 'type': 'string', 'description': "`professionnels` = densité de PS (RPPS, filtres profession_code/savoir_faire_code/mode_exercice_codes) ; `etablissements` = densité d'établissements (FINESS, `famille` obligatoire)."}, 'famille': {'type': 'string', 'description': "cible='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_dept': {'type': 'string', 'description': 'Code 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_insee': {'type': 'string', 'description': 'Code 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_commune': {'type': 'string', 'description': 'Nom 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_code': {'type': 'string', 'description': "cible='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_national': {'type': 'boolean', 'default': False, 'description': "Ajoute le calcul France entière + écart relatif en % (recommandé pour qualifier 'sous-doté'/'sur-doté')."}, 'include_etudiants': {'type': 'boolean'}, 'savoir_faire_code': {'type': 'string', 'description': "cible='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_codes': {'type': 'array', 'items': {'type': 'string'}, 'description': "cible='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_publics': {'type': 'boolean'}}}
입력 스키마
{'type': 'object', 'required': ['lat', 'lon'], 'properties': {'lat': {'type': 'number', 'description': 'Latitude du centre (WGS84).'}, 'lon': {'type': 'number', 'description': 'Longitude du centre (WGS84).'}, 'rayon_km': {'type': 'number', 'default': 3, 'maximum': 10, 'minimum': 0.1, 'description': 'Rayon en km (0.1-10, défaut 3).'}}}
출력 스키마
{'type': 'object', 'required': ['couverture'], 'properties': {'info': {'type': 'object', 'description': "Contexte non-scorable : habitants_attendus, permis { annees_pleines, annee_en_cours: { annee, mois_couverts, logements_autorises, logements_commences } | null }, quartiers_au (libellés), prix_m2_median, terrains. Ne PAS intégrer à une note d'attractivité."}, 'note': {'type': 'object', 'description': 'Données de VOLUME — à utiliser pour le scoring LLM. logements_autorises_recent, logements_commences_recent, zones_au_nombre, zones_au_immediates, signal.'}, 'geojson': {'type': 'object', 'description': 'FeatureCollection GeoJSON des polygones des zones AU (pour la carte).'}, 'couverture': {'type': 'object', 'description': "Statut de dégradation par section : 'ok' | 'partiel:<raison>' | 'indisponible:<raison>'. Un 'partiel:' signifie que le chiffre est SERVI mais NON comparable et NON scoré ('partiel:ville_entiere_plm' = chiffre de la ville entière ; 'partiel:fenetre_courte' = moins de 5 années pleines ; 'partiel:annees_incompletes' = une année de la fenêtre a moins de 12 mois publiés ; 'partiel:lignes_illisibles'). Lire avant d'interpréter note/info."}}, 'description': 'Résultat de dynamique immobilière à 2 registres (note = scoring, info = contexte) + couverture de dégradation par section.'}
입력 스키마
{'type': 'object', 'required': ['finess'], 'properties': {'max': {'type': 'number', 'description': 'Cap dur du nombre de concurrents enquêtés. Défaut 3.'}, 'finess': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Numéros FINESS à enquêter (typiquement le top 3 concurrents par distance).'}}}
입력 스키마
{'type': 'object', 'required': ['siren'], 'properties': {'siren': {'type': 'string', 'description': 'SIREN exact, 9 chiffres.'}}}
출력 스키마
{'type': 'object', 'required': ['found', 'lookupStatus'], 'properties': {'key': {'type': 'string', 'description': 'Clé recherchée (SIREN, num_finess, code INSEE, …).'}, 'found': {'type': 'boolean'}, 'message': {'type': 'string', 'description': 'Explication actionnable quand `found=false` (cause probable + remédiation).'}, 'lookupStatus': {'enum': ['found', 'not_found', 'ambiguous'], 'type': 'string'}}, 'description': 'LookupResult discriminé par `found`. true → payload métier à plat (siren, nomComplet, etc.). false → `lookupStatus`/`key`/`message` actionnables. `lookupStatus` est toujours présent runtime (validé par tests).'}
입력 스키마
{'type': 'object', 'properties': {'q': {'type': 'string', 'description': 'Recherche textuelle libre (raison sociale, dirigeant…).'}, 'lat': {'type': 'number', 'description': 'Latitude du centre du cercle de recherche.'}, 'lon': {'type': 'number', 'description': 'Longitude du centre du cercle de recherche.'}, 'naf': {'type': 'string', 'description': "Code NAF principal (ex: '8690B' = labos, '4773Z' = pharmacies, '8710A' = EHPAD, '8621Z' = MG)."}, 'page': {'type': 'number', 'default': 1, 'description': 'Page (1-indexed).'}, 'perPage': {'type': 'number', 'default': 10, 'description': 'Résultats par page (1-25, défaut 10).'}, 'radiusKm': {'type': 'number', 'description': 'Rayon en km (1-50).'}, 'codePostal': {'type': 'string', 'description': 'Filtre alternatif : code postal exact.'}, 'departement': {'type': 'string', 'description': 'Filtre alternatif : code département.'}, 'includeDirigeants': {'type': 'boolean', 'default': True, 'description': 'Inclure 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é).'}}}
출력 스키마
{'type': 'object', 'required': ['total', 'page', 'perPage', 'totalPages', 'entreprises'], 'properties': {'page': {'type': 'number'}, 'total': {'type': 'number', 'description': "Total d'entreprises matchant la query côté DINUM."}, 'perPage': {'type': 'number'}, 'totalPages': {'type': 'number'}, 'entreprises': {'type': 'array', 'items': {'type': 'object'}, 'description': 'Entreprises retournées (SIREN, nomComplet, NAF, finances, etablissements).'}}, 'description': 'Résultat de recherche DINUM avec pagination native (total, page, perPage, totalPages, entreprises).'}
입력 스키마
{'type': 'object', 'required': ['num_finess'], 'properties': {'num_finess': {'type': 'string', 'description': 'Numéro FINESS exact (9 chiffres).'}, 'include_freshness': {'type': 'boolean', 'default': False, 'description': "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."}}}
출력 스키마
{'type': 'object', 'required': ['found', 'lookupStatus'], 'properties': {'key': {'type': 'string', 'description': 'Clé recherchée (SIREN, num_finess, code INSEE, …).'}, 'found': {'type': 'boolean'}, 'message': {'type': 'string', 'description': 'Explication actionnable quand `found=false` (cause probable + remédiation).'}, 'lookupStatus': {'enum': ['found', 'not_found', 'ambiguous'], 'type': 'string'}}, 'description': 'LookupResult discriminé par `found`. true → payload métier à plat (siren, nomComplet, etc.). false → `lookupStatus`/`key`/`message` actionnables. `lookupStatus` est toujours présent runtime (validé par tests).'}
입력 스키마
{'type': 'object', 'required': ['siret'], 'properties': {'siret': {'type': 'string', 'description': 'SIRET exact, 14 chiffres.'}}}
출력 스키마
{'type': 'object', 'required': ['found', 'lookupStatus'], 'properties': {'key': {'type': 'string', 'description': 'Clé recherchée (SIREN, num_finess, code INSEE, …).'}, 'found': {'type': 'boolean'}, 'message': {'type': 'string', 'description': 'Explication actionnable quand `found=false` (cause probable + remédiation).'}, 'lookupStatus': {'enum': ['found', 'not_found', 'ambiguous'], 'type': 'string'}}, 'description': 'LookupResult discriminé par `found`. true → payload métier à plat (siren, nomComplet, etc.). false → `lookupStatus`/`key`/`message` actionnables. `lookupStatus` est toujours présent runtime (validé par tests).'}
입력 스키마
{'type': 'object', 'required': ['nom'], 'properties': {'nom': {'type': 'string', 'description': "Nom de l'établissement tel qu'on le dit (3 caractères min). Accents, casse et ponctuation indifférents. Sans le nom de la commune (le mettre dans `nom_commune`)."}, 'limit': {'type': 'number', 'default': 50, 'maximum': 200, 'minimum': 1, 'description': 'Candidats bruts lus avant seuil et tri (1-200, défaut 50). Monter si le nom est très partagé (« Saint Antoine » : 42 fiches).'}, 'code_insee': {'type': 'string', 'description': 'Code INSEE de la commune (5 caractères). Paris/Lyon/Marseille : 75056 / 69123 / 13055 acceptés (ville entière) comme un arrondissement. XOR avec `nom_commune` et `departement`.'}, 'departement': {'type': 'string', 'description': "Code département (ex : '94', '2A', '971'). Seul = filtre département ; avec `nom_commune` = hint de désambiguïsation."}, 'nom_commune': {'type': 'string', 'description': 'Nom officiel de la commune où se trouve l\'établissement (résolu via geo.api.gouv.fr). Ex : "Villejuif", "Paris". Combinable avec `departement` comme hint de désambiguïsation. XOR avec `code_insee`.'}, 'include_freshness': {'type': 'boolean', 'default': False, 'description': "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."}}}
출력 스키마
{'type': 'object', 'required': ['statut', 'candidats', 'commune_prouvee', 'raison_commune', 'tronque'], 'properties': {'statut': {'enum': ['unique', 'ambigu', 'aucun'], 'type': 'string'}, 'tronque': {'type': 'boolean'}, 'candidats': {'type': 'array'}, 'raison_commune': {'enum': ['un_seul_candidat', 'candidats_meme_commune', 'communes_divergentes', 'tronque', 'aucun_candidat'], 'type': 'string'}, 'commune_prouvee': {'type': ['object', 'null'], 'description': '{ code_insee, ville } quand tous les candidats sont dans la même commune (commune-mère PLM), sinon null.'}, 'lignes_rejetees': {'type': 'number'}, 'query_normalisee': {'type': 'string'}, 'communes_candidates': {'type': 'array', 'items': {'type': 'string'}}, 'meilleure_similarite': {'type': ['number', 'null']}}, 'description': 'Résultat de recherche par nom : statut, candidats triés, preuve de commune.'}
입력 스키마
{'type': 'object', 'required': ['categorie'], 'properties': {'limit': {'type': 'number', 'default': 100, 'maximum': 500, 'minimum': 1, 'description': 'Nombre max de résultats (1-500, défaut 100).'}, 'categorie': {'enum': ['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'], 'type': 'string', 'description': 'Famille FINESS recherchée (24 valeurs disponibles, voir enum).'}, 'code_insee': {'type': 'string', 'description': 'Code INSEE de commune (5 caractères). Optionnel. XOR strict avec `departement` et `nom_commune`.'}, 'departement': {'type': 'string', 'description': "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`."}, 'nom_commune': {'type': 'string', '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.'}, 'include_freshness': {'type': 'boolean', 'default': False, 'description': "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."}}}
출력 스키마
{'type': 'object', 'required': ['count', 'results'], 'properties': {'count': {'type': 'number', 'description': "Nombre d'entrées retournées dans `results` (post-troncature)."}, 'total': {'type': 'number', 'description': 'Effectif 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`.'}, 'results': {'type': 'array', 'items': {'type': 'object'}, 'description': 'Entrées métier (shape spécifique au tool, cf. description du tool).'}, 'freshness': {'type': 'object', 'description': 'Fraîcheur des sources (présent si `include_freshness: true`).'}, 'perimetre': {'type': 'object', 'properties': {'lens': {'type': 'string'}, 'compte': {'type': 'string'}, 'exclut': {'type': 'string'}, 'source': {'type': 'string'}, 'completeness_note': {'type': 'string'}}, 'description': 'Lentille de la source : ce que le comptage inclut/exclut. Lire `completeness_note` et la restituer au lecteur final.'}, 'truncated': {'type': 'boolean', 'description': 'true 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_metadata': {'type': 'object', 'description': 'Metadata de la query (radius_km, departement, filtres appliqués, …).'}, 'activite_hebergee': {'type': 'object', 'properties': {'note': {'type': 'string'}, 'count': {'type': 'integer'}, 'activite': {'type': 'string'}, 'truncated': {'type': 'boolean'}, 'sites_apercu': {'type': 'array', 'items': {'type': 'object', 'properties': {'num_finess': {'type': 'string'}, 'categorie_code': {'type': 'string'}, 'raison_sociale': {'type': 'string'}, 'categorie_libelle': {'type': 'string'}}}}, 'densite_pour_100k_hab': {'type': 'number'}}, '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."}}, 'description': 'Résultat de query avec metadata. `results` est tronqué à `limit` côté serveur (cf. `truncated` quand applicable).'}
입력 스키마
{'type': 'object', 'required': ['lon', 'lat'], 'properties': {'lat': {'type': 'number', 'description': 'Latitude du centre (WGS84).'}, 'lon': {'type': 'number', 'description': 'Longitude du centre (WGS84).'}, 'limit': {'type': 'number', 'default': 100, 'maximum': 500, 'minimum': 1, 'description': 'Nombre max de résultats (1-500, défaut 100).'}, 'familles': {'type': 'array', 'items': {'enum': ['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'], 'type': 'string'}, 'description': 'Familles FINESS à inclure (24 valeurs disponibles, voir enum). Si omis, toutes catégories.'}, 'radius_km': {'type': 'number', 'default': 5, 'maximum': 50, 'minimum': 0.1, 'description': 'Rayon en km (0.1-50, défaut 5).'}, 'include_freshness': {'type': 'boolean', 'default': False, 'description': "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."}}}
출력 스키마
{'type': 'object', 'required': ['count', 'results'], 'properties': {'count': {'type': 'number', 'description': "Nombre d'entrées retournées dans `results` (post-troncature)."}, 'total': {'type': 'number', 'description': 'Effectif 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`.'}, 'results': {'type': 'array', 'items': {'type': 'object'}, 'description': 'Entrées métier (shape spécifique au tool, cf. description du tool).'}, 'freshness': {'type': 'object', 'description': 'Fraîcheur des sources (présent si `include_freshness: true`).'}, 'perimetre': {'type': 'object', 'properties': {'lens': {'type': 'string'}, 'compte': {'type': 'string'}, 'exclut': {'type': 'string'}, 'source': {'type': 'string'}, 'completeness_note': {'type': 'string'}}, 'description': 'Lentille de la source : ce que le comptage inclut/exclut. Lire `completeness_note` et la restituer au lecteur final.'}, 'truncated': {'type': 'boolean', 'description': 'true 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_metadata': {'type': 'object', 'description': 'Metadata de la query (radius_km, departement, filtres appliqués, …).'}, 'activite_hebergee': {'type': 'object', 'properties': {'note': {'type': 'string'}, 'count': {'type': 'integer'}, 'activite': {'type': 'string'}, 'truncated': {'type': 'boolean'}, 'sites_apercu': {'type': 'array', 'items': {'type': 'object', 'properties': {'num_finess': {'type': 'string'}, 'categorie_code': {'type': 'string'}, 'raison_sociale': {'type': 'string'}, 'categorie_libelle': {'type': 'string'}}}}, 'densite_pour_100k_hab': {'type': 'number'}}, '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."}}, 'description': 'Résultat de query avec metadata. `results` est tronqué à `limit` côté serveur (cf. `truncated` quand applicable).'}
입력 스키마
{'type': 'object', 'required': ['lon', 'lat', 'naf'], 'properties': {'lat': {'type': 'number', 'description': 'Latitude WGS84 du centre de la zone.'}, 'lon': {'type': 'number', 'description': 'Longitude WGS84 du centre de la zone.'}, 'naf': {'type': 'string', 'description': "Code NAF SIRENE à comparer (ex: '8690B' labos d'analyses médicales, '4773Z' pharmacies, '8621Z' médecine générale)."}, 'familles': {'type': 'array', 'items': {'enum': ['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'], 'type': 'string'}, 'description': 'Familles 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_km': {'type': 'number', 'default': 5, 'maximum': 50, 'minimum': 0.1, 'description': 'Rayon de la zone en km (0.1-50, défaut 5).'}, 'max_unites_legales': {'type': 'number', 'default': 10, 'maximum': 25, 'minimum': 1, 'description': "Nombre maximum d'unités légales DINUM à déplier (1-25, défaut 10). Au-delà : truncated_unites_legales=true."}}}
출력 스키마
{'type': 'object', 'required': ['finess_sites', 'sirene_sirets', 'coverage_ratio', 'methodology', 'familles_auto_derivees', 'coverage_status'], 'properties': {'caveats': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Limitations méthodologiques explicites (discipline zéro overclaim).'}, 'perimetre': {'type': 'object', 'properties': {'lens': {'type': 'string'}, 'compte': {'type': 'string'}, 'exclut': {'type': 'string'}, 'source': {'type': 'string'}, 'completeness_note': {'type': 'string'}}, 'description': 'Lentille de la source : ce que le comptage inclut/exclut. Lire `completeness_note` et la restituer au lecteur final.'}, 'methodology': {'type': 'string', 'description': "Description LLM-friendly de l'algorithme appliqué."}, 'finess_sites': {'type': 'number', 'description': 'Nombre de sites FINESS dans le rayon (référentiel DREES).'}, 'matched_count': {'type': 'number', 'description': 'Nombre de matchs greedy Dice ≥ 0.7.'}, 'sirene_sirets': {'type': 'number', 'description': 'Nombre de SIRET physiques actifs au NAF cible dans le rayon (DINUM/SIRENE).'}, 'coverage_ratio': {'type': ['number', 'null'], 'description': 'matched / finess_sites ∈ [0, 1]. null si `sirene_sirets === 0` (zone rurale + NAF rare → ratio non calculable).'}, 'coverage_status': {'enum': ['computed', 'scope_empty_unknown_naf', 'scope_empty_familles_incompatible'], 'type': 'string', 'description': 'Statut 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_samples': {'type': 'array', 'items': {'type': 'object'}}, 'finess_only_count': {'type': 'number'}, 'sirene_only_count': {'type': 'number'}, 'finess_only_samples': {'type': 'array', 'items': {'type': 'object'}}, 'sirene_only_samples': {'type': 'array', 'items': {'type': 'object'}}, 'familles_excluees_naf': {'type': 'array', 'items': {'type': 'string'}, 'description': "Familles 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_derivees': {'type': ['array', 'null'], 'items': {'type': 'string'}, 'description': "Familles 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_legales': {'type': 'boolean', 'description': 'true si le cap `maxUnitesLegales` a été atteint avant énumération complète.'}}, 'description': 'Audit de couverture FINESS vs SIRENE dans un rayon. coverage_ratio = matched / total_finess. Caveats explicites pour cadrer la méthode (FINESS = sites physiques agréés, SIRENE = SIRET actifs au NAF cible).'}
입력 스키마
{'type': 'object', 'required': ['adresse'], 'properties': {'adresse': {'type': 'string', 'description': 'Adresse complète à géocoder.'}, 'codePostal': {'type': 'string', 'description': 'Optionnel — limiter le résultat à un code postal pour désambiguïser.'}, 'codeCommune': {'type': 'string', 'description': 'Optionnel — limiter au code INSEE de commune.'}}}
입력 스키마
{'type': 'object', 'required': ['code'], 'properties': {'code': {'type': 'string', 'description': 'Code INSEE 5 caractères. Ex: "75056" Paris, "59009" Villeneuve-d\'Ascq, "2A004" Ajaccio.'}}}
출력 스키마
{'type': 'object', 'required': ['found', 'lookupStatus'], 'properties': {'key': {'type': 'string', 'description': 'Clé recherchée (SIREN, num_finess, code INSEE, …).'}, 'found': {'type': 'boolean'}, 'message': {'type': 'string', 'description': 'Explication actionnable quand `found=false` (cause probable + remédiation).'}, 'lookupStatus': {'enum': ['found', 'not_found', 'ambiguous'], 'type': 'string'}}, 'description': 'LookupResult discriminé par `found`. true → payload métier à plat (siren, nomComplet, etc.). false → `lookupStatus`/`key`/`message` actionnables. `lookupStatus` est toujours présent runtime (validé par tests).'}
입력 스키마
{'type': 'object', 'required': ['num_finess'], 'properties': {'num_finess': {'type': 'string', 'description': 'Numéro FINESS exact (9 chiffres).'}}}
출력 스키마
{'type': 'object', 'required': ['found', 'lookupStatus'], 'properties': {'key': {'type': 'string', 'description': 'Clé recherchée (SIREN, num_finess, code INSEE, …).'}, 'found': {'type': 'boolean'}, 'message': {'type': 'string', 'description': 'Explication actionnable quand `found=false` (cause probable + remédiation).'}, 'lookupStatus': {'enum': ['found', 'not_found', 'ambiguous'], 'type': 'string'}}, 'description': 'LookupResult discriminé par `found`. true → payload métier à plat (siren, nomComplet, etc.). false → `lookupStatus`/`key`/`message` actionnables. `lookupStatus` est toujours présent runtime (validé par tests).'}
입력 스키마
{'type': 'object', 'required': ['num_finess'], 'properties': {'num_finess': {'type': 'string', 'description': "Numéro FINESS exact 9 chiffres. Ex: '590048997'."}, 'rpps_limit': {'type': 'integer', 'description': "Nombre 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_detail': {'type': 'boolean', 'default': True, 'description': "Inclure 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`."}}}
출력 스키마
{'type': 'object', 'required': ['found', 'lookupStatus'], 'properties': {'key': {'type': 'string', 'description': 'Clé recherchée (SIREN, num_finess, code INSEE, …).'}, 'found': {'type': 'boolean'}, 'message': {'type': 'string', 'description': 'Explication actionnable quand `found=false` (cause probable + remédiation).'}, 'lookupStatus': {'enum': ['found', 'not_found', 'ambiguous'], 'type': 'string'}}, 'description': 'LookupResult discriminé par `found`. true → payload métier à plat (siren, nomComplet, etc.). false → `lookupStatus`/`key`/`message` actionnables. `lookupStatus` est toujours présent runtime (validé par tests).'}
입력 스키마
{'type': 'object', 'required': ['referentiel'], 'properties': {'limit': {'type': 'number', 'description': 'Nombre 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.'}, 'referentiel': {'enum': ['ameli_specialites', 'ameli_types_ps', 'rpps_savoir_faire'], 'type': 'string', 'description': 'Nomenclature à lister. `ameli_specialites` / `ameli_types_ps` = Ameli (libéraux conventionnés) ; `rpps_savoir_faire` = spécialités médicales ANS/RPPS (nomenclature DISTINCTE).'}, 'profession_code': {'type': 'string', 'description': "Ré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_freshness': {'type': 'boolean', 'default': False, 'description': "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."}, 'include_specialites': {'type': 'boolean', 'default': True, 'description': 'Ré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.'}}}
출력 스키마
{'type': 'object', 'required': ['count', 'results'], 'properties': {'count': {'type': 'number', 'description': "Nombre d'entrées retournées dans `results` (post-troncature)."}, 'total': {'type': 'number', 'description': 'Effectif 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`.'}, 'results': {'type': 'array', 'items': {'type': 'object'}, 'description': 'Entrées métier (shape spécifique au tool, cf. description du tool).'}, 'freshness': {'type': 'object', 'description': 'Fraîcheur des sources (présent si `include_freshness: true`).'}, 'perimetre': {'type': 'object', 'properties': {'lens': {'type': 'string'}, 'compte': {'type': 'string'}, 'exclut': {'type': 'string'}, 'source': {'type': 'string'}, 'completeness_note': {'type': 'string'}}, 'description': 'Lentille de la source : ce que le comptage inclut/exclut. Lire `completeness_note` et la restituer au lecteur final.'}, 'truncated': {'type': 'boolean', 'description': 'true 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_metadata': {'type': 'object', 'description': 'Metadata de la query (radius_km, departement, filtres appliqués, …).'}, 'activite_hebergee': {'type': 'object', 'properties': {'note': {'type': 'string'}, 'count': {'type': 'integer'}, 'activite': {'type': 'string'}, 'truncated': {'type': 'boolean'}, 'sites_apercu': {'type': 'array', 'items': {'type': 'object', 'properties': {'num_finess': {'type': 'string'}, 'categorie_code': {'type': 'string'}, 'raison_sociale': {'type': 'string'}, 'categorie_libelle': {'type': 'string'}}}}, 'densite_pour_100k_hab': {'type': 'number'}}, '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."}}, 'description': 'Résultat de query avec metadata. `results` est tronqué à `limit` côté serveur (cf. `truncated` quand applicable).'}
입력 스키마
{'type': 'object', 'properties': {'point': {'type': 'object', 'properties': {'lat': {'type': 'number'}, 'lon': {'type': 'number'}}, 'description': 'Coordonnées { lat, lon } si déjà connues (skip géocodage). Fournir `code_insee` avec.'}, 'adresse': {'type': 'string', 'description': 'Adresse cible, géocodée en interne via IGN. Ex: "12 rue Nationale, Lille". XOR avec `point`.'}, 'rayon_km': {'type': 'number', 'description': "Rayon du bassin de l'étude (km). Défaut 5."}, 'code_insee': {'type': 'string', 'description': 'Code INSEE commune (avec `point`, quand le géocodage est déjà fait).'}}}
입력 스키마
{'type': 'object', 'properties': {'code_insee': {'type': 'string', 'description': '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`.'}, 'departement': {'type': 'string', '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`).'}, 'nom_commune': {'type': 'string', '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.'}, 'finess_familles': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Familles 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).'}}}
입력 스키마
{'type': 'object', 'required': ['code'], 'properties': {'code': {'type': 'string', 'description': 'Code 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.'}}}
출력 스키마
{'type': 'object', 'required': ['found', 'lookupStatus'], 'properties': {'key': {'type': 'string', 'description': 'Clé recherchée (SIREN, num_finess, code INSEE, …).'}, 'found': {'type': 'boolean'}, 'message': {'type': 'string', 'description': 'Explication actionnable quand `found=false` (cause probable + remédiation).'}, 'lookupStatus': {'enum': ['found', 'not_found', 'ambiguous'], 'type': 'string'}}, 'description': 'LookupResult discriminé par `found`. true → payload métier à plat (siren, nomComplet, etc.). false → `lookupStatus`/`key`/`message` actionnables. `lookupStatus` est toujours présent runtime (validé par tests).'}
입력 스키마
{'type': 'object', 'required': ['rpps_id'], 'properties': {'rpps_id': {'type': 'string', 'pattern': '^\\s*\\d{11,12}\\s*$'}, 'include_freshness': {'type': 'boolean', 'default': False, 'description': "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."}}}
출력 스키마
{'type': 'object', 'required': ['found', 'lookupStatus'], 'properties': {'key': {'type': 'string', 'description': 'Clé recherchée (SIREN, num_finess, code INSEE, …).'}, 'found': {'type': 'boolean'}, 'message': {'type': 'string', 'description': 'Explication actionnable quand `found=false` (cause probable + remédiation).'}, 'lookupStatus': {'enum': ['found', 'not_found', 'ambiguous'], 'type': 'string'}}, 'description': 'LookupResult discriminé par `found`. true → payload métier à plat (siren, nomComplet, etc.). false → `lookupStatus`/`key`/`message` actionnables. `lookupStatus` est toujours présent runtime (validé par tests).'}
입력 스키마
{'type': 'object', 'required': ['lon', 'lat'], 'properties': {'lat': {'type': 'number', 'description': 'Latitude du centre (WGS84).'}, 'lon': {'type': 'number', 'description': 'Longitude du centre (WGS84).'}, 'limit': {'type': 'number', 'default': 100, 'maximum': 500, 'minimum': 1, 'description': 'Nombre max de résultats (1-500, défaut 100). Appliqué AVANT déduplication.'}, 'radius_km': {'type': 'number', 'default': 5, 'maximum': 50, 'minimum': 0.1, 'description': 'Rayon en km (0.1-50, défaut 5).'}, 'dedupe_by_ps': {'type': 'boolean', 'default': False, 'description': "Regrouper 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_only': {'type': 'boolean', '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_ps_codes': {'type': 'array', 'items': {'type': 'string'}, 'description': "Liste 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_codes': {'type': 'array', 'items': {'type': 'string'}, 'description': "Liste de codes spécialité Ameli (ex: ['01'] MG, ['03'] cardio). Si omis, toutes spécialités."}, 'include_freshness': {'type': 'boolean', 'default': False, 'description': "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."}}}
출력 스키마
{'type': 'object', 'required': ['count', 'results'], 'properties': {'count': {'type': 'number', 'description': "Nombre d'entrées retournées dans `results` (post-troncature)."}, 'total': {'type': 'number', 'description': 'Effectif 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`.'}, 'results': {'type': 'array', 'items': {'type': 'object'}, 'description': 'Entrées métier (shape spécifique au tool, cf. description du tool).'}, 'freshness': {'type': 'object', 'description': 'Fraîcheur des sources (présent si `include_freshness: true`).'}, 'perimetre': {'type': 'object', 'properties': {'lens': {'type': 'string'}, 'compte': {'type': 'string'}, 'exclut': {'type': 'string'}, 'source': {'type': 'string'}, 'completeness_note': {'type': 'string'}}, 'description': 'Lentille de la source : ce que le comptage inclut/exclut. Lire `completeness_note` et la restituer au lecteur final.'}, 'truncated': {'type': 'boolean', 'description': 'true 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_metadata': {'type': 'object', 'description': 'Metadata de la query (radius_km, departement, filtres appliqués, …).'}, 'activite_hebergee': {'type': 'object', 'properties': {'note': {'type': 'string'}, 'count': {'type': 'integer'}, 'activite': {'type': 'string'}, 'truncated': {'type': 'boolean'}, 'sites_apercu': {'type': 'array', 'items': {'type': 'object', 'properties': {'num_finess': {'type': 'string'}, 'categorie_code': {'type': 'string'}, 'raison_sociale': {'type': 'string'}, 'categorie_libelle': {'type': 'string'}}}}, 'densite_pour_100k_hab': {'type': 'number'}}, '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."}}, 'description': 'Résultat de query avec metadata. `results` est tronqué à `limit` côté serveur (cf. `truncated` quand applicable).'}
입력 스키마
{'type': 'object', 'required': ['departement'], 'properties': {'limit': {'type': 'number', 'default': 100, 'maximum': 500, 'minimum': 1, 'description': 'Nombre max de résultats (1-500, défaut 100). Appliqué AVANT déduplication.'}, 'offset': {'type': 'number', 'default': 0, 'minimum': 0, 'description': 'Décalage de pagination (≥ 0, défaut 0). Combiner avec `limit` pour énumérer un département à fort effectif. Re-paginer tant que `truncated=true`.'}, 'departement': {'type': 'string', 'description': "Code département INSEE : 2 caractères métropole/Corse ('01'-'95', '2A'/'2B'), 3 caractères DOM ('971'-'978')."}, 'dedupe_by_ps': {'type': 'boolean', 'default': False, 'description': "Regrouper les entrées par praticien (nom + prénom + code spécialité) et lister chaque adresse d'exercice dans `sites[]`. Défaut false."}, 'type_ps_code': {'type': 'string', 'description': "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')`."}, 'specialite_code': {'type': 'string', 'description': "Code spécialité Ameli (ex: '01' MG, '24' IDE, '26' kiné, '03' cardio). Optionnel. Liste complète via `lister_nomenclature(referentiel:'ameli_specialites')`."}, 'include_freshness': {'type': 'boolean', 'default': False, 'description': "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."}}}
출력 스키마
{'type': 'object', 'required': ['count', 'results'], 'properties': {'count': {'type': 'number', 'description': "Nombre d'entrées retournées dans `results` (post-troncature)."}, 'total': {'type': 'number', 'description': 'Effectif 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`.'}, 'results': {'type': 'array', 'items': {'type': 'object'}, 'description': 'Entrées métier (shape spécifique au tool, cf. description du tool).'}, 'freshness': {'type': 'object', 'description': 'Fraîcheur des sources (présent si `include_freshness: true`).'}, 'perimetre': {'type': 'object', 'properties': {'lens': {'type': 'string'}, 'compte': {'type': 'string'}, 'exclut': {'type': 'string'}, 'source': {'type': 'string'}, 'completeness_note': {'type': 'string'}}, 'description': 'Lentille de la source : ce que le comptage inclut/exclut. Lire `completeness_note` et la restituer au lecteur final.'}, 'truncated': {'type': 'boolean', 'description': 'true 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_metadata': {'type': 'object', 'description': 'Metadata de la query (radius_km, departement, filtres appliqués, …).'}, 'activite_hebergee': {'type': 'object', 'properties': {'note': {'type': 'string'}, 'count': {'type': 'integer'}, 'activite': {'type': 'string'}, 'truncated': {'type': 'boolean'}, 'sites_apercu': {'type': 'array', 'items': {'type': 'object', 'properties': {'num_finess': {'type': 'string'}, 'categorie_code': {'type': 'string'}, 'raison_sociale': {'type': 'string'}, 'categorie_libelle': {'type': 'string'}}}}, 'densite_pour_100k_hab': {'type': 'number'}}, '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."}}, 'description': 'Résultat de query avec metadata. `results` est tronqué à `limit` côté serveur (cf. `truncated` quand applicable).'}
입력 스키마
{'type': 'object', 'required': ['center', 'radius_km'], 'properties': {'limit': {'type': 'number', 'description': 'Nombre max de résultats retournés (défaut serveur 100).'}, 'center': {'type': 'object', 'required': ['lat', 'lon'], 'properties': {'lat': {'type': 'number', 'description': 'Latitude (WGS84).'}, 'lon': {'type': 'number', 'description': 'Longitude (WGS84).'}}, 'description': 'Centre du cercle de recherche (coordonnées WGS84).'}, 'radius_km': {'type': 'number', 'maximum': 50, 'minimum': 0.1, 'description': 'Rayon en km (0.1-50).'}, 'precise_only': {'type': 'boolean', 'default': False, 'description': "Si 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_codes': {'type': 'array', 'items': {'type': 'string'}, 'description': "Codes profession ANS (ex: ['10'] Médecin, ['60'] Infirmier). Si omis, toutes professions."}, 'include_etudiants': {'type': 'boolean'}, 'include_freshness': {'type': 'boolean', 'default': False, 'description': "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."}, 'savoir_faire_codes': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Codes savoir-faire ANS (spécialités fines DES/DESC). Si omis, tous savoir-faire.'}, 'mode_exercice_codes': {'type': 'array', 'items': {'type': 'string'}, 'description': "Codes mode d'exercice ANS (libéral / salarié / mixte). Si omis, tous modes."}, 'include_agents_publics': {'type': 'boolean'}}}
출력 스키마
{'type': 'object', 'required': ['count', 'results'], 'properties': {'count': {'type': 'number', 'description': "Nombre d'entrées retournées dans `results` (post-troncature)."}, 'total': {'type': 'number', 'description': 'Effectif 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`.'}, 'results': {'type': 'array', 'items': {'type': 'object'}, 'description': 'Entrées métier (shape spécifique au tool, cf. description du tool).'}, 'freshness': {'type': 'object', 'description': 'Fraîcheur des sources (présent si `include_freshness: true`).'}, 'perimetre': {'type': 'object', 'properties': {'lens': {'type': 'string'}, 'compte': {'type': 'string'}, 'exclut': {'type': 'string'}, 'source': {'type': 'string'}, 'completeness_note': {'type': 'string'}}, 'description': 'Lentille de la source : ce que le comptage inclut/exclut. Lire `completeness_note` et la restituer au lecteur final.'}, 'truncated': {'type': 'boolean', 'description': 'true 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_metadata': {'type': 'object', 'description': 'Metadata de la query (radius_km, departement, filtres appliqués, …).'}, 'activite_hebergee': {'type': 'object', 'properties': {'note': {'type': 'string'}, 'count': {'type': 'integer'}, 'activite': {'type': 'string'}, 'truncated': {'type': 'boolean'}, 'sites_apercu': {'type': 'array', 'items': {'type': 'object', 'properties': {'num_finess': {'type': 'string'}, 'categorie_code': {'type': 'string'}, 'raison_sociale': {'type': 'string'}, 'categorie_libelle': {'type': 'string'}}}}, 'densite_pour_100k_hab': {'type': 'number'}}, '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."}}, 'description': 'Résultat de query avec metadata. `results` est tronqué à `limit` côté serveur (cf. `truncated` quand applicable).'}
입력 스키마
{'type': 'object', 'required': ['departement'], 'properties': {'limit': {'type': 'number', 'description': 'Nombre max de résultats par page (défaut serveur 100).'}, 'offset': {'type': 'number', 'description': 'Offset pour pagination (défaut 0). Re-paginer tant que `truncated=true`.'}, 'departement': {'type': 'string', 'description': "Code département INSEE (ex: '75', '2A', '2B', '971'). Métropole 2 caractères (Corse '2A'/'2B', pas '20'), DOM/TOM 3 caractères."}, 'profession_code': {'type': 'string', 'description': "Code profession ANS (ex: '10' Médecin, '60' Infirmier). Optionnel."}, 'include_etudiants': {'type': 'boolean'}, 'include_freshness': {'type': 'boolean', 'default': False, 'description': "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."}, 'savoir_faire_code': {'type': 'string', 'description': 'Code savoir-faire ANS (spécialité fine DES/DESC). Optionnel.'}, 'mode_exercice_code': {'type': 'string', 'description': "Code mode d'exercice ANS (libéral / salarié / mixte). Optionnel."}, 'include_agents_publics': {'type': 'boolean'}}}
출력 스키마
{'type': 'object', 'required': ['count', 'results'], 'properties': {'count': {'type': 'number', 'description': "Nombre d'entrées retournées dans `results` (post-troncature)."}, 'total': {'type': 'number', 'description': 'Effectif 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`.'}, 'results': {'type': 'array', 'items': {'type': 'object'}, 'description': 'Entrées métier (shape spécifique au tool, cf. description du tool).'}, 'freshness': {'type': 'object', 'description': 'Fraîcheur des sources (présent si `include_freshness: true`).'}, 'perimetre': {'type': 'object', 'properties': {'lens': {'type': 'string'}, 'compte': {'type': 'string'}, 'exclut': {'type': 'string'}, 'source': {'type': 'string'}, 'completeness_note': {'type': 'string'}}, 'description': 'Lentille de la source : ce que le comptage inclut/exclut. Lire `completeness_note` et la restituer au lecteur final.'}, 'truncated': {'type': 'boolean', 'description': 'true 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_metadata': {'type': 'object', 'description': 'Metadata de la query (radius_km, departement, filtres appliqués, …).'}, 'activite_hebergee': {'type': 'object', 'properties': {'note': {'type': 'string'}, 'count': {'type': 'integer'}, 'activite': {'type': 'string'}, 'truncated': {'type': 'boolean'}, 'sites_apercu': {'type': 'array', 'items': {'type': 'object', 'properties': {'num_finess': {'type': 'string'}, 'categorie_code': {'type': 'string'}, 'raison_sociale': {'type': 'string'}, 'categorie_libelle': {'type': 'string'}}}}, 'densite_pour_100k_hab': {'type': 'number'}}, '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."}}, 'description': 'Résultat de query avec metadata. `results` est tronqué à `limit` côté serveur (cf. `truncated` quand applicable).'}
입력 스키마
{'type': 'object', 'properties': {'lat': {'type': 'number', 'description': 'Latitude du point (mode point).'}, 'lon': {'type': 'number', 'description': 'Longitude du point (mode point).'}, 'rayon_km': {'type': 'number', 'description': "Rayon du bassin en km (0 < r ≤ 10). Absent = profil de l'îlot seul."}, 'code_iris': {'type': 'string', 'description': 'Code IRIS 9 caractères (ex `751103701`) — alternatif au point.'}}}
출력 스키마
{'type': 'object', 'required': ['found', 'lookupStatus'], 'properties': {'key': {'type': 'string', 'description': 'Clé recherchée (SIREN, num_finess, code INSEE, …).'}, 'found': {'type': 'boolean'}, 'message': {'type': 'string', 'description': 'Explication actionnable quand `found=false` (cause probable + remédiation).'}, 'lookupStatus': {'enum': ['found', 'not_found', 'ambiguous'], 'type': 'string'}}, 'description': 'LookupResult discriminé par `found`. true → payload métier à plat (siren, nomComplet, etc.). false → `lookupStatus`/`key`/`message` actionnables. `lookupStatus` est toujours présent runtime (validé par tests).'}
입력 스키마
{'type': 'object', 'required': ['num_finess'], 'properties': {'num_finess': {'type': 'string', 'description': 'Numéro FINESS exact (9 chiffres).'}}}
출력 스키마
{'type': 'object', 'required': ['found', 'lookupStatus'], 'properties': {'key': {'type': 'string', 'description': 'Clé recherchée (SIREN, num_finess, code INSEE, …).'}, 'found': {'type': 'boolean'}, 'message': {'type': 'string', 'description': 'Explication actionnable quand `found=false` (cause probable + remédiation).'}, 'lookupStatus': {'enum': ['found', 'not_found', 'ambiguous'], 'type': 'string'}}, 'description': 'LookupResult discriminé par `found`. true → payload métier à plat (siren, nomComplet, etc.). false → `lookupStatus`/`key`/`message` actionnables. `lookupStatus` est toujours présent runtime (validé par tests).'}
입력 스키마
{'type': 'object', 'required': ['lon', 'lat'], 'properties': {'lat': {'type': 'number', 'description': 'Latitude (WGS84).'}, 'lon': {'type': 'number', 'description': 'Longitude (WGS84).'}}}
입력 스키마
{'type': 'object', 'required': ['num_finess'], 'properties': {'limit': {'type': 'number'}, 'num_finess': {'type': 'string', 'pattern': '^\\d{9}$'}, 'include_etudiants': {'type': 'boolean'}, 'include_freshness': {'type': 'boolean', 'default': False, 'description': "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."}, 'include_agents_publics': {'type': 'boolean'}}}
출력 스키마
{'type': 'object', 'required': ['count', 'results'], 'properties': {'count': {'type': 'number', 'description': "Nombre d'entrées retournées dans `results` (post-troncature)."}, 'total': {'type': 'number', 'description': 'Effectif 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`.'}, 'results': {'type': 'array', 'items': {'type': 'object'}, 'description': 'Entrées métier (shape spécifique au tool, cf. description du tool).'}, 'freshness': {'type': 'object', 'description': 'Fraîcheur des sources (présent si `include_freshness: true`).'}, 'perimetre': {'type': 'object', 'properties': {'lens': {'type': 'string'}, 'compte': {'type': 'string'}, 'exclut': {'type': 'string'}, 'source': {'type': 'string'}, 'completeness_note': {'type': 'string'}}, 'description': 'Lentille de la source : ce que le comptage inclut/exclut. Lire `completeness_note` et la restituer au lecteur final.'}, 'truncated': {'type': 'boolean', 'description': 'true 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_metadata': {'type': 'object', 'description': 'Metadata de la query (radius_km, departement, filtres appliqués, …).'}, 'activite_hebergee': {'type': 'object', 'properties': {'note': {'type': 'string'}, 'count': {'type': 'integer'}, 'activite': {'type': 'string'}, 'truncated': {'type': 'boolean'}, 'sites_apercu': {'type': 'array', 'items': {'type': 'object', 'properties': {'num_finess': {'type': 'string'}, 'categorie_code': {'type': 'string'}, 'raison_sociale': {'type': 'string'}, 'categorie_libelle': {'type': 'string'}}}}, 'densite_pour_100k_hab': {'type': 'number'}}, '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."}}, 'description': 'Résultat de query avec metadata. `results` est tronqué à `limit` côté serveur (cf. `truncated` quand applicable).'}
입력 스키마
{'type': 'object', 'required': ['nom'], 'properties': {'nom': {'type': 'string', 'description': 'Nom de famille (non vide).'}, 'limit': {'type': 'number', 'default': 100, 'maximum': 500, 'minimum': 1, 'description': 'Nombre max de résultats (1-500, défaut 100).'}, 'prenom': {'type': 'string', 'description': 'Prénom du PS.'}, 'departement': {'type': 'string', 'description': "Code département INSEE (ex: '75', '2A', '2B', '971'). Métropole 2 caractères (Corse '2A'/'2B', pas '20'), DOM/COM 3 caractères."}, 'include_etudiants': {'type': 'boolean'}, 'include_freshness': {'type': 'boolean', 'default': False, 'description': "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."}, 'include_agents_publics': {'type': 'boolean'}}}
출력 스키마
{'type': 'object', 'required': ['count', 'results'], 'properties': {'count': {'type': 'number', 'description': "Nombre d'entrées retournées dans `results` (post-troncature)."}, 'total': {'type': 'number', 'description': 'Effectif 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`.'}, 'results': {'type': 'array', 'items': {'type': 'object'}, 'description': 'Entrées métier (shape spécifique au tool, cf. description du tool).'}, 'freshness': {'type': 'object', 'description': 'Fraîcheur des sources (présent si `include_freshness: true`).'}, 'perimetre': {'type': 'object', 'properties': {'lens': {'type': 'string'}, 'compte': {'type': 'string'}, 'exclut': {'type': 'string'}, 'source': {'type': 'string'}, 'completeness_note': {'type': 'string'}}, 'description': 'Lentille de la source : ce que le comptage inclut/exclut. Lire `completeness_note` et la restituer au lecteur final.'}, 'truncated': {'type': 'boolean', 'description': 'true 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_metadata': {'type': 'object', 'description': 'Metadata de la query (radius_km, departement, filtres appliqués, …).'}, 'activite_hebergee': {'type': 'object', 'properties': {'note': {'type': 'string'}, 'count': {'type': 'integer'}, 'activite': {'type': 'string'}, 'truncated': {'type': 'boolean'}, 'sites_apercu': {'type': 'array', 'items': {'type': 'object', 'properties': {'num_finess': {'type': 'string'}, 'categorie_code': {'type': 'string'}, 'raison_sociale': {'type': 'string'}, 'categorie_libelle': {'type': 'string'}}}}, 'densite_pour_100k_hab': {'type': 'number'}}, '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."}}, 'description': 'Résultat de query avec metadata. `results` est tronqué à `limit` côté serveur (cf. `truncated` quand applicable).'}
입력 스키마
{'type': 'object', 'required': ['num_finess'], 'properties': {'num_finess': {'type': 'string', 'description': 'Numéro FINESS exact (9 chiffres).'}}}
출력 스키마
{'type': 'object', 'required': ['found', 'lookupStatus'], 'properties': {'key': {'type': 'string', 'description': 'Clé recherchée (SIREN, num_finess, code INSEE, …).'}, 'found': {'type': 'boolean'}, 'message': {'type': 'string', 'description': 'Explication actionnable quand `found=false` (cause probable + remédiation).'}, 'lookupStatus': {'enum': ['found', 'not_found', 'ambiguous'], 'type': 'string'}}, 'description': 'LookupResult discriminé par `found`. true → payload métier à plat (siren, nomComplet, etc.). false → `lookupStatus`/`key`/`message` actionnables. `lookupStatus` est toujours présent runtime (validé par tests).'}
최근 도구 변경
유사한 MCP 서버
SupplyGraph.AI Data
Provides China-focused location, surrounding-area, company, industry-chain, property, population, retail, and regional business i…
Microburbs Australian Property Data
Provides Australian property, suburb, valuation, sales, rental, zoning, school, risk, geospatial, and census statistics.
Clink Forge
Provides pay-per-call access to attested government datasets, primarily CDC and HHS health data plus EPA air-quality observations.
Medicare Coverage
Provides structured Medicare coverage documents, policy timelines, utilization, enrollment, supplier, and payment-related data fr…
Openfda
Provides access to FDA drug, labeling, approval, adverse-event, recall, shortage, warning-letter, and enforcement data for biomed…
Fda Drug Competition
Analyzes FDA Orange Book drug applications, patents, exclusivities, generic competition, and loss-of-exclusivity timelines.
Cms Open Payments
Searches and analyzes CMS Open Payments data on payments from pharmaceutical and device companies to physicians, hospitals, and o…
Fda Devices
Searches FDA medical-device regulatory datasets covering 510(k)s, PMAs, classifications, registrations, recalls, UDI records, and…