Endpoints: 28,729MCP servers: 18,413Payout addresses: 2,070Paid calls: 1,526Letters: 13Defects: 1,322counted 3 min ago
teppi

Server definition

Hash
sha256:7eaef53b01fa108dd63a132a6f4882e8f9d079196e2ab2830e3e0ef097441508
What it is
What a remote MCP server returned when asked what it offers: 34 tools

The blob, as servednamed by its sha256

{ "instructions": "The Islam West Africa Collection (IWAC) archives francophone West African newspaper articles, Islamic publications, archival documents, audiovisual records, fieldwork photographs, and academic references on Islam and Muslim societies in Benin, Burkina Faso, Côte d'Ivoire, Niger, Nigeria, and Togo.\n\nWORKFLOW: start with `search` (a concept or name), then `fetch` an id from the results to read the full text. The unified `search` matches each word of a multi-word query independently — every word must appear somewhere in the item — so 'pèlerinage Mecque' narrows results rather than failing; prefer a single concept per call. The finer search_* tools' `keyword` filter instead does ONE literal substring match, so for those search one term at a time ('pèlerinage', then 'Mecque'). When many items match, weigh result counts and AI abstracts before fetching full texts. Beyond search/fetch, finer tools exist (search_articles, search_publications, search_references, search_index, search_documents, plus get_* and list_*) with country, newspaper, subject, and date filters — prefer the `subject` filter over keywords for curated themes. For trends over time, call get_temporal_distribution (counts per year or month under the same filters) instead of paging through search results. To characterise a whole set rather than read it, the aggregate tools answer in one call what paging never will: get_topic_distribution (how it spreads over 30 precomputed LDA topics), get_field_distribution (rank its subjects, places, authors or languages), get_cooccurrence (what is discussed alongside what), and get_lexical_metrics (readability, lexical richness, length). All matching is accent- and case-insensitive; country filters take exact names (Benin, Burkina Faso, Côte d'Ivoire, Niger, Nigeria, Togo).\n\nISLAMIC CALENDAR: coverage driven by observances is invisible on a Gregorian axis — the lunar year drifts ~11 days a year, so over 1961-2025 each observance smears across all twelve Gregorian months. For that question call get_temporal_distribution with granularity=lunar_month, which pools every year into the twelve lunar months (Ramadan, Dhu al-Hijja/hajj and Shawwal/Korité all run well above the even split). calendar=hijri with granularity=year|month gives a Hijri time series instead. To read the items behind a peak, search_articles / search_publications take hijri_month (1-12, or a name in either transliteration — Ramadan, Chaabane, Dhou al-hijja) and hijri_year. Lunar dates are precomputed with the Umm al-Qura tables and need a full YYYY-MM-DD, so items dated only to a year or month are reported in imprecise_date_count and are ABSENT from lunar counts, not zero. They do not exist for references (an academic imprint date has no meaningful lunar reading).\n\nFULL-TEXT COVERAGE: this is the public dataset, and OCR full text ships only for items whose content is public on islam.zmo.de — about 56% of articles (7,546/13,397) and 86% of publications (1,298/1,501). Titles and subjects are searchable for ALL items, and AI abstracts (French AND English) for all but the newest arrivals: ingestion runs ahead of enrichment, so the most recent ~1,050 articles carry metadata only — no OCR, abstract, sentiment or topic — and, since rows come back newest-first, they sit on page 1. Nothing is invisible to discovery, but the full-text half of a keyword match covers only those shares, and a triage pass on description_ai should bound its dates rather than assume every row carries one. Call get_collection_stats for the live `fulltext_coverage` figures, treat keyword totals as a floor rather than a corpus-wide census, and disclose this whenever a count carries an argument.\n\nCALL ECONOMY: hosts stop a turn after roughly 20 tool calls, and the cap counts turns of the tool loop rather than the calls within one, so issue independent calls together in a single message rather than one at a time. Pick the aggregate tool whose numbers answer the question instead of running the family over the same filter. The stats and distribution tools render their own chart where the host supports it, at no extra call: never rebuild those numbers as a separate chart or artifact, and quote the figures in prose so the answer stands where nothing renders.\n\nRESULTS & ERRORS: list/search tools return a pagination envelope — read `total_matches` to gauge scale without paging, and request a sane `limit` (an over-large one is capped visibly via `requested_limit` + `limit_warning`, never silently dropped). Enumerated filters (`country`, `polarity`, `centrality`, `index_type`) are validated: an invalid value returns {error, valid_values} to self-correct — an error to fix, not a finding — whereas a VALID value with 0 rows is a real absence (there is no Nigerian press, so country='Nigeria' on search_articles is genuinely empty). Free-text filters (newspaper, subject, author, reference_type, language) are NOT validated, so a typo there returns 0 silently — sanity-check them. On list_locations / list_persons, `country` means 'mentioned in records from that country' (not 'located there') and `frequency` is a collection-wide total; the response restates this in a `note`. If `search` cannot load a subset it still returns the rest and names the missing ones in `unavailable_categories` + `coverage_warning` — those categories are ABSENT from the results, not empty, so retry or use their own search_* tool before concluding a term is unattested there.\n\nREPORT LANGUAGE: write the final report, synthesis, and follow-up questions in the language of the user's question. If the question is mixed, use its dominant language.\n\nQUERY LANGUAGE: formulate keyword/substr search strings and concept keywords in FRENCH for press articles, publications, documents, and index searches, even when the user asks in another language (laïcité, confrérie, pèlerinage, enseignement islamique). Academic references are multilingual: search title/abstract keywords in French and English when relevant, while keeping metadata/filter values such as reference_type and language in French. Keep proper names and canonical filter values exact.\n\nTRANSLITERATION: Arabic-Islamic terms appear in FRENCH transliteration — search the French form and try variants: Tabaski or Aïd el-Kébir (not 'Eid al-Adha'); Korité or Aïd el-Fitr; Maouloud/Mouloud (not 'Mawlid'); charia (not 'sharia'); confrérie; Wahhabisme.\n\nRESEARCH WORKFLOW: this server also serves its own operating manual as a resource. If you do not already have the `iwac-mcp` skill loaded, read `skill://iwac-mcp/SKILL.md` before a substantial research task. It carries the five-phase method, French search strategy and reporting conventions these tools assume. Its reference files (`skill://iwac-mcp/references/…`, listed in `skill://iwac-mcp`) are meant to be read on demand, not upfront.\n\nCITATIONS: every result has a `url` field such as https://islam.zmo.de/s/afrique_ouest/item/28576 — always cite IWAC items using this full URL (rendered as a markdown link), never a short form like \"art. #28576\" or \"item 28576\".\n\nCAVEATS: coverage is uneven — Niger is thin (one newspaper, 2018 on) and Nigeria has NO press articles (audiovisual only), so disclose this in any cross-country claim. The press is ~96% francophone, reflecting Western-educated Muslim voices more than Arabic-trained (arabisant) leaders. Never present results as exhaustive — absence of evidence is not evidence of absence. Polarity/sentiment fields are AI-derived, not editorial ground truth; press coverage reflects what was published, not necessarily what happened.", "tools": [ { "description": "Retrieve the full text and metadata of one IWAC item by an id returned from `search` (format '<category>:<number>', e.g. 'articles:28576'). Returns {id, title, text, url, metadata}: `text` is the item's OCR / abstract / transcription / description, `url` is the canonical islam.zmo.de link to cite, and `metadata` holds the remaining fields (author, date, country, newspaper, AI sentiment, …). Categories: articles, publications, references, documents, index, audiovisual, images.", "inputSchema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "id": { "description": "Item id from search, e.g. 'articles:28576' or 'references:11045'", "type": "string" } }, "required": [ "id" ], "type": "object" }, "name": "fetch", "outputSchema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "additionalProperties": false, "properties": { "category": { "type": "string" }, "id": { "type": "string" }, "metadata": { "additionalProperties": {}, "properties": {}, "type": "object" }, "recommended_tool": { "type": "string" }, "recommended_usage": { "additionalProperties": {}, "properties": {}, "type": "object" }, "text": { "type": "string" }, "text_source": { "type": "string" }, "text_truncated": { "type": "boolean" }, "title": { "type": "string" }, "url": { "type": "string" } }, "required": [ "id", "text", "category", "metadata" ], "type": "object" } }, { "description": "Get one article (by id): full metadata, the AI abstract (description_ai), AI sentiment, and OCR text. Pass a `keyword` to get ~2000-char excerpts around each match instead of the full (capped) OCR.", "inputSchema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "article_id": { "maximum": 9007199254740991, "minimum": -9007199254740991, "type": "integer" }, "context_chars": { "description": "Default 2000, max 5000", "maximum": 9007199254740991, "minimum": -9007199254740991, "type": "integer" }, "keyword": { "description": "Return excerpts around matches instead of the full OCR (accent-insensitive)", "type": "string" }, "max_excerpts": { "description": "Default 10, max 25", "maximum": 9007199254740991, "minimum": -9007199254740991, "type": "integer" } }, "required": [ "article_id" ], "type": "object" }, "name": "get_article", "outputSchema": null }, { "description": "Get one audiovisual record by id: full description and transcription (where one exists), creator/publishing channel, duration, medium, subjects, places, language, rights, source, and three distinct links — `url` (the IWAC page, the one to cite), `external_url` (where a harvested video plays) and `media_url` (a deposited file). `source_type` says which to expect.", "inputSchema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "audiovisual_id": { "maximum": 9007199254740991, "minimum": -9007199254740991, "type": "integer" } }, "required": [ "audiovisual_id" ], "type": "object" }, "name": "get_audiovisual", "outputSchema": null }, { "description": "Overall statistics for every IWAC subset, including `fulltext_coverage` — how many items in each subset actually carry searchable full text in this public dataset. Read that before treating any keyword count as a full-text census.", "inputSchema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": {}, "type": "object" }, "name": "get_collection_stats", "outputSchema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "additionalProperties": false, "properties": { "articles_by_country": { "additionalProperties": { "type": "number" }, "propertyNames": { "type": "string" }, "type": "object" }, "collection_name": { "type": "string" }, "dataset_url": { "type": "string" }, "date_range": { "additionalProperties": {}, "properties": { "earliest": { "type": "string" }, "latest": { "type": "string" } }, "required": [ "earliest", "latest" ], "type": "object" }, "failed_subsets": { "items": { "type": "string" }, "type": "array" }, "fulltext_coverage": { "additionalProperties": { "additionalProperties": {}, "properties": {}, "type": "object" }, "propertyNames": { "type": "string" }, "type": "object" }, "fulltext_note": { "type": "string" }, "newspaper_count": { "type": "number" }, "subset_counts": { "additionalProperties": { "type": "number" }, "propertyNames": { "type": "string" }, "type": "object" }, "total_records": { "type": "number" }, "view": { "type": "string" } }, "required": [ "view", "collection_name", "dataset_url", "subset_counts", "total_records" ], "type": "object" } }, { "description": "How often the top values of a multi-valued field appear on the SAME item — a subject/place co-mention matrix. Answers 'what is X discussed alongside' without reading anything: the pair counts are the structure of the tagging. Returns the top values, the full symmetric matrix (diagonal = each value's own count) and the strongest pairs.", "inputSchema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "country": { "description": "Exact country name: Benin | Burkina Faso | Côte d'Ivoire | Niger | Nigeria | Togo (accents optional)", "type": "string" }, "date_from": { "description": "YYYY-MM-DD (or YYYY)", "type": "string" }, "date_to": { "description": "YYYY-MM-DD (or YYYY)", "type": "string" }, "field": { "description": "subject (default) | spatial | author | language", "type": "string" }, "keyword": { "description": "ONE French concept keyword; substring over the subset's text fields", "type": "string" }, "newspaper": { "description": "Newspaper (articles) or periodical/series title (publications)", "type": "string" }, "subject": { "description": "Exact subject tag (pipe-aware)", "type": "string" }, "subset": { "description": "articles (default) | publications | references", "type": "string" }, "top_n": { "description": "Values on each axis (default 15, max 30)", "maximum": 9007199254740991, "minimum": -9007199254740991, "type": "integer" } }, "type": "object" }, "name": "get_cooccurrence", "outputSchema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "additionalProperties": false, "properties": { "field": { "type": "string" }, "filters": { "additionalProperties": {}, "properties": {}, "type": "object" }, "matrix": { "items": { "items": { "type": "number" }, "type": "array" }, "type": "array" }, "note": { "type": "string" }, "subset": { "type": "string" }, "top_pairs": { "items": { "additionalProperties": {}, "properties": {}, "type": "object" }, "type": "array" }, "total_matches": { "type": "number" }, "values": { "items": { "additionalProperties": {}, "properties": {}, "type": "object" }, "type": "array" }, "view": { "type": "string" } }, "required": [ "view", "subset", "field", "filters", "total_matches", "values", "matrix", "top_pairs" ], "type": "object" } }, { "description": "Compare article counts, newspaper counts, date ranges, and gpt-5-6-luna polarity across countries.", "inputSchema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": {}, "type": "object" }, "name": "get_country_comparison", "outputSchema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "additionalProperties": false, "properties": { "countries": { "items": { "additionalProperties": {}, "properties": {}, "type": "object" }, "type": "array" }, "polarity_model": { "type": "string" }, "total_countries": { "type": "number" }, "view": { "type": "string" } }, "required": [ "view", "total_countries", "countries" ], "type": "object" } }, { "description": "Get one archival document (by id): full metadata, AI description, and OCR text. Pass a `keyword` to get ~2000-char excerpts around each match instead of the full (capped) OCR — useful for long documents.", "inputSchema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "context_chars": { "description": "Default 2000, max 5000", "maximum": 9007199254740991, "minimum": -9007199254740991, "type": "integer" }, "document_id": { "maximum": 9007199254740991, "minimum": -9007199254740991, "type": "integer" }, "keyword": { "description": "Return excerpts around matches instead of the full OCR (accent-insensitive)", "type": "string" }, "max_excerpts": { "description": "Default 10, max 25", "maximum": 9007199254740991, "minimum": -9007199254740991, "type": "integer" } }, "required": [ "document_id" ], "type": "object" }, "name": "get_document", "outputSchema": null }, { "description": "Rank the values of one multi-valued field across a filtered set — the direct way to answer 'which places does this coverage name most', 'who signs these articles', 'what subjects dominate'. Pipe-joined fields (subject, spatial, author, language, country) are split, so an article tagged 'Prière|Ramadan' counts once for each. Optional over_time adds the per-year share of items that carry ANY value for the field, which is how you see e.g. bylines appearing as the press professionalises.", "inputSchema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "country": { "description": "Exact country name: Benin | Burkina Faso | Côte d'Ivoire | Niger | Nigeria | Togo (accents optional)", "type": "string" }, "date_from": { "description": "YYYY-MM-DD (or YYYY)", "type": "string" }, "date_to": { "description": "YYYY-MM-DD (or YYYY)", "type": "string" }, "field": { "description": "subject | spatial | author | language | newspaper | country", "type": "string" }, "keyword": { "description": "ONE French concept keyword; substring over the subset's text fields", "type": "string" }, "newspaper": { "description": "Newspaper (articles) or periodical/series title (publications)", "type": "string" }, "over_time": { "description": "Also return the per-year share of items carrying a value", "type": "boolean" }, "subject": { "description": "Exact subject tag (pipe-aware)", "type": "string" }, "subset": { "description": "articles (default) | publications | references", "type": "string" }, "top_n": { "description": "Values returned (default 25, max 100)", "maximum": 9007199254740991, "minimum": -9007199254740991, "type": "integer" } }, "required": [ "field" ], "type": "object" }, "name": "get_field_distribution", "outputSchema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "additionalProperties": false, "properties": { "coverage_by_year": { "additionalProperties": { "additionalProperties": {}, "properties": {}, "type": "object" }, "propertyNames": { "type": "string" }, "type": "object" }, "distinct_values": { "type": "number" }, "field": { "type": "string" }, "filters": { "additionalProperties": {}, "properties": {}, "type": "object" }, "items_with_value": { "type": "number" }, "note": { "type": "string" }, "other_values": { "type": "number" }, "subset": { "type": "string" }, "total_matches": { "type": "number" }, "values": { "items": { "additionalProperties": {}, "properties": {}, "type": "object" }, "type": "array" }, "view": { "type": "string" } }, "required": [ "view", "subset", "field", "filters", "total_matches", "items_with_value", "distinct_values", "values" ], "type": "object" } }, { "description": "Get one photograph by id: title, photographer, capture date, place and coordinates, subjects, rights, the IIIF manifest, and the full-resolution `image_url`. The server returns URLs, not image bytes.", "inputSchema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "image_id": { "maximum": 9007199254740991, "minimum": -9007199254740991, "type": "integer" } }, "required": [ "image_id" ], "type": "object" }, "name": "get_image", "outputSchema": null }, { "description": "Get full details of an index entry by id (raw dataset columns, French names — Titre, Prénom, Coordonnées…).", "inputSchema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "entry_id": { "maximum": 9007199254740991, "minimum": -9007199254740991, "type": "integer" } }, "required": [ "entry_id" ], "type": "object" }, "name": "get_index_entry", "outputSchema": null }, { "description": "Readability, lexical richness and length of the press text, averaged by year, newspaper or country. `Lisibilite_OCR` is a French readability score (higher = easier); `Richesse_Lexicale_OCR` is MATTR, a moving-average type-token ratio that is ALREADY length-robust — do not normalise it by word count or bin it by length. Readability is computed against a French lexicon, so non-French items are excluded from that metric (and counted in readability_excluded) rather than reported as unreadable; MATTR and word count need no lexicon and cover everything. Only items whose full text ships in this public dataset carry these columns at all.", "inputSchema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "country": { "description": "Exact country name: Benin | Burkina Faso | Côte d'Ivoire | Niger | Nigeria | Togo (accents optional)", "type": "string" }, "date_from": { "description": "YYYY-MM-DD (or YYYY)", "type": "string" }, "date_to": { "description": "YYYY-MM-DD (or YYYY)", "type": "string" }, "group_by": { "description": "year (default) | newspaper | country", "type": "string" }, "keyword": { "description": "ONE French concept keyword; substring over the subset's text fields", "type": "string" }, "newspaper": { "description": "Newspaper (articles) or periodical/series title (publications)", "type": "string" }, "subject": { "description": "Exact subject tag (pipe-aware)", "type": "string" }, "top_n": { "description": "Groups returned when grouping by newspaper (default 20, max 60)", "maximum": 9007199254740991, "minimum": -9007199254740991, "type": "integer" } }, "type": "object" }, "name": "get_lexical_metrics", "outputSchema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "additionalProperties": false, "properties": { "filters": { "additionalProperties": {}, "properties": {}, "type": "object" }, "group_by": { "type": "string" }, "groups": { "items": { "additionalProperties": {}, "properties": {}, "type": "object" }, "type": "array" }, "metrics": { "additionalProperties": { "additionalProperties": {}, "properties": {}, "type": "object" }, "propertyNames": { "type": "string" }, "type": "object" }, "note": { "type": "string" }, "readability_excluded": { "type": "number" }, "total_matches": { "type": "number" }, "view": { "type": "string" } }, "required": [ "view", "group_by", "filters", "total_matches", "groups", "metrics" ], "type": "object" } }, { "description": "Per-newspaper article counts and date ranges.", "inputSchema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "country": { "description": "Exact country name: Benin | Burkina Faso | Côte d'Ivoire | Niger | Togo (accents optional)", "type": "string" } }, "type": "object" }, "name": "get_newspaper_stats", "outputSchema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "additionalProperties": false, "properties": { "country_filter": { "type": "string" }, "newspapers": { "items": { "additionalProperties": {}, "properties": {}, "type": "object" }, "type": "array" }, "total_articles": { "type": "number" }, "total_newspapers": { "type": "number" }, "view": { "type": "string" } }, "required": [ "view", "total_newspapers", "total_articles", "newspapers" ], "type": "object" } }, { "description": "Places named by a filtered set of items, joined to the index's authority records so each carries coordinates where the index has them. Use this rather than get_field_distribution when the question is geographic — where coverage clusters — and the plain ranking when it is not. Only `Lieux` index entries are geocoded (555 of 683); persons, organisations and events carry no coordinates and never will, and any named place with no index entry comes back under `ungeocoded` rather than being dropped.", "inputSchema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "country": { "description": "Exact country name: Benin | Burkina Faso | Côte d'Ivoire | Niger | Nigeria | Togo (accents optional)", "type": "string" }, "date_from": { "description": "YYYY-MM-DD (or YYYY)", "type": "string" }, "date_to": { "description": "YYYY-MM-DD (or YYYY)", "type": "string" }, "keyword": { "description": "ONE French concept keyword; substring over the subset's text fields", "type": "string" }, "newspaper": { "description": "Newspaper (articles) or periodical/series title (publications)", "type": "string" }, "subject": { "description": "Exact subject tag (pipe-aware)", "type": "string" }, "subset": { "description": "articles (default) | publications | references", "type": "string" }, "top_n": { "description": "Geocoded places returned (default 60, max 200)", "maximum": 9007199254740991, "minimum": -9007199254740991, "type": "integer" } }, "type": "object" }, "name": "get_place_distribution", "outputSchema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "additionalProperties": false, "properties": { "filters": { "additionalProperties": {}, "properties": {}, "type": "object" }, "items_by_country": { "additionalProperties": { "type": "number" }, "propertyNames": { "type": "string" }, "type": "object" }, "items_with_place": { "type": "number" }, "note": { "type": "string" }, "places": { "items": { "additionalProperties": {}, "properties": {}, "type": "object" }, "type": "array" }, "subset": { "type": "string" }, "total_matches": { "type": "number" }, "ungeocoded": { "items": { "additionalProperties": {}, "properties": {}, "type": "object" }, "type": "array" }, "ungeocoded_mentions": { "type": "number" }, "view": { "type": "string" } }, "required": [ "view", "subset", "filters", "total_matches", "items_with_place", "places" ], "type": "object" } }, { "description": "Full OCR text of a publication, optionally returning ~2000-char excerpts around keyword matches (accent-insensitive; capped — see match_count vs excerpts_returned).", "inputSchema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "context_chars": { "description": "Default 2000, max 5000", "maximum": 9007199254740991, "minimum": -9007199254740991, "type": "integer" }, "keyword": { "type": "string" }, "max_excerpts": { "description": "Default 10, max 25", "maximum": 9007199254740991, "minimum": -9007199254740991, "type": "integer" }, "publication_id": { "maximum": 9007199254740991, "minimum": -9007199254740991, "type": "integer" } }, "required": [ "publication_id" ], "type": "object" }, "name": "get_publication_fulltext", "outputSchema": null }, { "description": "Full bibliographic record for one academic reference (by id), including the complete abstract (present for ~51% of references), subjects, DOI/URL, and host-work details (book, volume, issue, pages).", "inputSchema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "reference_id": { "maximum": 9007199254740991, "minimum": -9007199254740991, "type": "integer" } }, "required": [ "reference_id" ], "type": "object" }, "name": "get_reference", "outputSchema": null }, { "description": "A 2-D scatter of a filtered set, projected from the stored 768-dimension embeddings by PCA. Shows which items sit near each other in meaning — where a set splits into distinct strands and where it is one cloud. Read `explained_variance` before drawing any conclusion: with 768 dimensions the first two components usually carry a modest share, and a scatter explaining 6% of the variance is a much weaker claim than one explaining 40%. This is PCA, not UMAP: it spreads the broadest axes of variation and flattens fine cluster structure, so it is not comparable to the semantic landscapes on islam.zmo.de. Needs no API key — the vectors are a column in the dataset — but only items whose full text ships are embedded at all. NOTE the payload scales with `limit`: a point cloud is a chart, not something a text-only client can read, so for those the useful part is the explained-variance summary rather than the coordinates. Keep `limit` low unless a chart is going to be drawn.", "inputSchema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "color_by": { "description": "country | newspaper | subject | lda_topic_label | polarity (gpt-5-6-luna's label)", "type": "string" }, "country": { "description": "Exact country name: Benin | Burkina Faso | Côte d'Ivoire | Niger | Nigeria | Togo (accents optional)", "type": "string" }, "date_from": { "description": "YYYY-MM-DD (or YYYY)", "type": "string" }, "date_to": { "description": "YYYY-MM-DD (or YYYY)", "type": "string" }, "keyword": { "description": "ONE French concept keyword; substring over the subset's text fields", "type": "string" }, "limit": { "description": "Items projected (default 300, max 2000)", "maximum": 9007199254740991, "minimum": -9007199254740991, "type": "integer" }, "newspaper": { "description": "Newspaper (articles) or periodical/series title (publications)", "type": "string" }, "subject": { "description": "Exact subject tag (pipe-aware)", "type": "string" }, "subset": { "description": "articles (default) | publications | references", "type": "string" } }, "type": "object" }, "name": "get_semantic_map", "outputSchema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "additionalProperties": false, "properties": { "color_by": { "type": "string" }, "explained_variance": { "items": { "type": "number" }, "type": "array" }, "filters": { "additionalProperties": {}, "properties": {}, "type": "object" }, "groups": { "additionalProperties": { "type": "number" }, "propertyNames": { "type": "string" }, "type": "object" }, "note": { "type": "string" }, "points": { "items": { "additionalProperties": {}, "properties": {}, "type": "object" }, "type": "array" }, "projected": { "type": "number" }, "subset": { "type": "string" }, "total_matches": { "type": "number" }, "view": { "type": "string" } }, "required": [ "view", "subset", "filters", "total_matches", "projected", "explained_variance", "note" ], "type": "object" } }, { "description": "Aggregate AI polarity, centrality and subjectivity across a filter set. 5 models scored the corpus independently — gpt-5-6-luna, mistral-small-2603, deepseek-v4-flash-0731, gemma-4-31b-it, qwen3-8-27b — so model:\"all\" returns each one's distribution plus how often they AGREE. Treat disagreement as a fact about the judgement rather than noise: corpus-wide the panel is unanimous on polarity for only ~32% of articles, so in a set where the models split no single one's number should be quoted alone. All three scales are ordinal French labels; subjectivity is much the weakest and ships a caveat to quote with it. Articles were scored whether or not their full text ships, so these shares are not subject to the OCR coverage limit. The models do NOT all cover the same articles, so read each one's `coverage` before comparing counts: ~51 non-francophone articles are unscored by design, and qwen3-8-27b is 200 further short on articles peripheral to Islam.", "inputSchema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "country": { "description": "Exact country name: Benin | Burkina Faso | Côte d'Ivoire | Niger | Togo (accents optional)", "type": "string" }, "model": { "description": "gpt-5-6-luna | mistral-small-2603 | deepseek-v4-flash-0731 | gemma-4-31b-it | qwen3-8-27b | all | consensus — default gpt-5-6-luna; \"all\" adds the cross-model agreement, \"consensus\" returns the panel's precomputed majority (no annotator produced it, so it is never attributed to a model). The vendor shorthands chatgpt/mistral/deepseek/gemma/qwen also resolve to the model that ran. The generation-1 models (gemini-3-flash-preview, gpt-5-mini, ministral-14b-2512) are no longer served and return an error rather than a substitute — and 'gemini' is refused rather than read as gemma-4-31b-it, which is a different model line.", "type": "string" }, "newspaper": { "type": "string" }, "subject": { "type": "string" } }, "type": "object" }, "name": "get_sentiment_distribution", "outputSchema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "additionalProperties": false, "properties": { "agreement": { "additionalProperties": {}, "properties": {}, "type": "object" }, "agreement_matrix": { "additionalProperties": {}, "properties": {}, "type": "object" }, "by_model": { "additionalProperties": { "additionalProperties": {}, "properties": {}, "type": "object" }, "propertyNames": { "type": "string" }, "type": "object" }, "centrality_distribution": { "additionalProperties": { "type": "number" }, "propertyNames": { "type": "string" }, "type": "object" }, "consensus": { "additionalProperties": {}, "properties": {}, "type": "object" }, "coverage": { "additionalProperties": { "type": "number" }, "propertyNames": { "type": "string" }, "type": "object" }, "disputed": { "additionalProperties": {}, "properties": {}, "type": "object" }, "filters": { "additionalProperties": {}, "properties": {}, "type": "object" }, "model": { "type": "string" }, "model_caveat": { "type": "string" }, "models": { "items": { "type": "string" }, "type": "array" }, "note": { "type": "string" }, "polarity_distribution": { "additionalProperties": { "type": "number" }, "propertyNames": { "type": "string" }, "type": "object" }, "subjectivity": { "additionalProperties": {}, "properties": {}, "type": "object" }, "subjectivity_median_rank": { "additionalProperties": {}, "properties": {}, "type": "object" }, "total_articles": { "type": "number" }, "view": { "type": "string" } }, "required": [ "view", "model", "total_articles", "filters" ], "type": "object" } }, { "description": "The items nearest to a given one in meaning, by cosine similarity over the stored embeddings. Answers 'what else is like this' without a keyword — it finds pieces on the same event or theme that share no vocabulary. A neighbour above ~0.85 is usually the same story reprinted or lightly rewritten, which is how to spot syndication in this corpus; 0.6-0.8 is 'same subject, different piece'. Needs no API key: the item's own vector is a column, so nothing has to be embedded at request time. This is per-item, NOT the corpus-wide near-duplicate sweep — that is an all-pairs job and belongs offline.", "inputSchema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "id": { "description": "Item id — either a bare o:id ('3064') or the namespaced form search returns ('articles:3064')", "type": "string" }, "limit": { "description": "Neighbours returned (default 12, max 50)", "maximum": 9007199254740991, "minimum": -9007199254740991, "type": "integer" }, "min_score": { "description": "Drop neighbours below this cosine similarity (0-1)", "type": "number" }, "subset": { "description": "articles (default) | publications | references", "type": "string" } }, "required": [ "id" ], "type": "object" }, "name": "get_similar_items", "outputSchema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "additionalProperties": false, "properties": { "neighbours": { "items": { "additionalProperties": {}, "properties": {}, "type": "object" }, "type": "array" }, "note": { "type": "string" }, "source": { "additionalProperties": {}, "properties": {}, "type": "object" }, "subset": { "type": "string" }, "view": { "type": "string" } }, "required": [ "view", "subset", "source", "neighbours", "note" ], "type": "object" } }, { "description": "Counts of matching items per year (or month) — the direct way to chart coverage trends over time instead of paging through search results. Defaults to articles; also works on publications, references, documents, audiovisual, and images. Accepts the same filters as the corresponding search_* tool (keyword = ONE substring over the subset's text fields, country, newspaper/series, subject, date range). Optional group_by=country|newspaper returns one distribution per group. Items dated only to a year keep a bare-year key even at month granularity; undated items are counted in undated_count, never dropped silently. Set calendar=hijri to bucket by the Islamic (Umm al-Qura) calendar instead — with granularity=lunar_month this collapses every year into the twelve lunar months, which is the ONLY way to see observance-driven coverage (Ramadan, Dhu al-Hijja/hajj, Shawwal/Korité): the lunar year drifts ~11 days against the Gregorian, so a Gregorian axis smears each observance across all twelve months. Hijri buckets need a full YYYY-MM-DD, so items dated only to a year or month are reported in imprecise_date_count.", "inputSchema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "calendar": { "description": "gregorian (default) | hijri — bucket by the Islamic (Umm al-Qura) calendar", "type": "string" }, "country": { "description": "Exact country name: Benin | Burkina Faso | Côte d'Ivoire | Niger | Nigeria | Togo (accents optional)", "type": "string" }, "date_from": { "description": "YYYY-MM-DD (or YYYY)", "type": "string" }, "date_to": { "description": "YYYY-MM-DD (or YYYY)", "type": "string" }, "granularity": { "description": "year (default) | month | lunar_month (all years collapsed into 12 lunar months; needs calendar=hijri)", "type": "string" }, "group_by": { "description": "country | newspaper — one distribution per group value", "type": "string" }, "keyword": { "description": "ONE French concept keyword (French/English for references); substring over the subset's text fields", "type": "string" }, "newspaper": { "description": "Newspaper (articles) or periodical/series title (publications)", "type": "string" }, "subject": { "description": "Exact subject tag (pipe-aware)", "type": "string" }, "subset": { "description": "articles (default) | publications | references | documents | audiovisual", "type": "string" } }, "type": "object" }, "name": "get_temporal_distribution", "outputSchema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "additionalProperties": false, "properties": { "calendar": { "type": "string" }, "dated_count": { "type": "number" }, "distribution": { "additionalProperties": { "type": "number" }, "propertyNames": { "type": "string" }, "type": "object" }, "distribution_by_group": { "additionalProperties": { "additionalProperties": { "type": "number" }, "propertyNames": { "type": "string" }, "type": "object" }, "propertyNames": { "type": "string" }, "type": "object" }, "filters": { "additionalProperties": {}, "properties": {}, "type": "object" }, "granularity": { "type": "string" }, "group_by": { "type": "string" }, "imprecise_date_count": { "type": "number" }, "month_labels": { "additionalProperties": { "type": "string" }, "propertyNames": { "type": "string" }, "type": "object" }, "note": { "type": "string" }, "subset": { "type": "string" }, "total_matches": { "type": "number" }, "undated_count": { "type": "number" }, "view": { "type": "string" } }, "required": [ "view", "subset", "granularity", "filters", "total_matches", "dated_count", "undated_count" ], "type": "object" } }, { "description": "How a filtered set distributes across the precomputed LDA topics, each labelled by its top terms (articles carry 30 topics and are ~99.5% classified; references have their own 33-topic model and only ~46% carry an assignment, so read its `classified` against `total_matches`). Topics are assigned offline over the full text, so they describe what a piece is ABOUT rather than which words it contains — use this instead of keyword counting to map a corpus. Optional over_time returns per-year counts for the leading topics. min_prob keeps only articles where the topic is at least that dominant (mean assignment probability is 0.34, so 0.5 is already a strong filter).", "inputSchema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "country": { "description": "Exact country name: Benin | Burkina Faso | Côte d'Ivoire | Niger | Nigeria | Togo (accents optional)", "type": "string" }, "date_from": { "description": "YYYY-MM-DD (or YYYY)", "type": "string" }, "date_to": { "description": "YYYY-MM-DD (or YYYY)", "type": "string" }, "keyword": { "description": "ONE French concept keyword; substring over the subset's text fields", "type": "string" }, "min_prob": { "description": "0-1; keep only assignments at or above this probability", "type": "number" }, "newspaper": { "description": "Newspaper (articles) or periodical/series title (publications)", "type": "string" }, "over_time": { "description": "Also return per-year counts for the leading topics", "type": "boolean" }, "subject": { "description": "Exact subject tag (pipe-aware)", "type": "string" }, "subset": { "description": "articles (default) | references", "type": "string" }, "top_n": { "description": "Topics given their own band in over_time (default 8, max 15)", "maximum": 9007199254740991, "minimum": -9007199254740991, "type": "integer" } }, "type": "object" }, "name": "get_topic_distribution", "outputSchema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "additionalProperties": false, "properties": { "classified": { "type": "number" }, "filters": { "additionalProperties": {}, "properties": {}, "type": "object" }, "note": { "type": "string" }, "periods": { "items": { "type": "string" }, "type": "array" }, "series_by_topic": { "additionalProperties": { "additionalProperties": { "type": "number" }, "propertyNames": { "type": "string" }, "type": "object" }, "propertyNames": { "type": "string" }, "type": "object" }, "span": { "items": { "type": "string" }, "type": "array" }, "subset": { "type": "string" }, "topics": { "items": { "additionalProperties": {}, "properties": {}, "type": "object" }, "type": "array" }, "total_matches": { "type": "number" }, "trend_by_topic": { "additionalProperties": { "additionalProperties": {}, "properties": {}, "type": "object" }, "propertyNames": { "type": "string" }, "type": "object" }, "view": { "type": "string" } }, "required": [ "view", "subset", "filters", "total_matches", "classified", "topics" ], "type": "object" } }, { "description": "List audiovisual materials, newest first (francophone web video from Burkina Faso, Togo and Benin; deposited Nigerian Hausa/Arabic recordings). Filter by country, publishing channel or `source_type`.", "inputSchema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "country": { "description": "Exact country name: Benin | Burkina Faso | Côte d'Ivoire | Niger | Nigeria | Togo (accents optional). Burkina Faso, Togo, Benin and Nigeria only — no Niger or Ivorian items", "type": "string" }, "limit": { "description": "Default 20, max 50", "maximum": 9007199254740991, "minimum": -9007199254740991, "type": "integer" }, "offset": { "maximum": 9007199254740991, "minimum": -9007199254740991, "type": "integer" }, "publisher": { "description": "Substring on the publishing channel/broadcaster, e.g. RTB | AEEM | CERFI", "type": "string" }, "source_type": { "description": "youtube (harvested web video, the large majority) | deposited (recordings with a file, 47)", "type": "string" } }, "type": "object" }, "name": "list_audiovisual", "outputSchema": null }, { "description": "List lieux from the IWAC index, sorted by frequency (most-referenced first). The optional 'country' filter selects entries that APPEAR IN records from that country (mentioned-in, not located-in), ranked by collection-wide 'frequency' — so foreign and cross-border entries can appear. Nigeria returns none here (index frequency is computed from articles + publications + references, which have no Nigerian items — Nigeria is audiovisual only).", "inputSchema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "country": { "description": "Exact country name: Benin | Burkina Faso | Côte d'Ivoire | Niger | Nigeria | Togo (accents optional). Selects lieux MENTIONED IN records from that country, not entities located there", "type": "string" }, "limit": { "description": "Default 50, max 200", "maximum": 9007199254740991, "minimum": -9007199254740991, "type": "integer" }, "offset": { "maximum": 9007199254740991, "minimum": -9007199254740991, "type": "integer" } }, "type": "object" }, "name": "list_locations", "outputSchema": null }, { "description": "List the Islamic periodical/series titles in the publications subset, with issue counts and year ranges. Use the returned newspaper value as the `newspaper` filter on search_publications.", "inputSchema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "country": { "description": "Exact country name: Benin | Burkina Faso | Côte d'Ivoire | Niger | Togo (accents optional)", "type": "string" } }, "type": "object" }, "name": "list_periodicals", "outputSchema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "additionalProperties": false, "properties": { "country_filter": { "type": "string" }, "periodicals": { "items": { "additionalProperties": {}, "properties": {}, "type": "object" }, "type": "array" }, "total_periodicals": { "type": "number" }, "view": { "type": "string" } }, "required": [ "view", "total_periodicals", "periodicals" ], "type": "object" } }, { "description": "List personnes from the IWAC index, sorted by frequency (most-referenced first). The optional 'country' filter selects entries that APPEAR IN records from that country (mentioned-in, not located-in), ranked by collection-wide 'frequency' — so foreign and cross-border entries can appear. Nigeria returns none here (index frequency is computed from articles + publications + references, which have no Nigerian items — Nigeria is audiovisual only).", "inputSchema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "country": { "description": "Exact country name: Benin | Burkina Faso | Côte d'Ivoire | Niger | Nigeria | Togo (accents optional). Selects personnes MENTIONED IN records from that country, not entities located there", "type": "string" }, "limit": { "description": "Default 50, max 200", "maximum": 9007199254740991, "minimum": -9007199254740991, "type": "integer" }, "offset": { "maximum": 9007199254740991, "minimum": -9007199254740991, "type": "integer" } }, "type": "object" }, "name": "list_persons", "outputSchema": null }, { "description": "List sujets from the IWAC index, sorted by frequency (most-referenced first).", "inputSchema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "limit": { "description": "Default 50, max 200", "maximum": 9007199254740991, "minimum": -9007199254740991, "type": "integer" }, "offset": { "maximum": 9007199254740991, "minimum": -9007199254740991, "type": "integer" } }, "type": "object" }, "name": "list_subjects", "outputSchema": null }, { "description": "Search the Islam West Africa Collection across newspaper articles, Islamic publications, archival documents, academic references, audiovisual recordings, photographs, and the authority index (persons/places/organisations/events/subjects). Pass ONE concept or name — e.g. 'Tijaniyya', 'laïcité', 'Sheikh Gumi', 'pèlerinage'. Matching is accent- and case-insensitive; a multi-word query requires every word to appear somewhere in the item, so prefer a single concept per call. Write query strings and concept keywords in French for press/publication/document/index discovery even when the user's report language is not French. Academic references are multilingual, so try French and English title/abstract terms when relevant; metadata/filter labels remain French. Use the French transliteration of Islamic terms (Tabaski not 'Eid al-Adha', charia not 'sharia', Maouloud not 'Mawlid'). Returns {results:[{id,title,url,category}], ranking}; each result's `category` names its subset and the `ranking` field documents the ordering. Pass an id to `fetch` to read the full text. For filtered queries (by country, date, or newspaper) use the search_* tools instead.", "inputSchema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "limit": { "description": "Max results across all categories. Default 20, max 50.", "maximum": 9007199254740991, "minimum": -9007199254740991, "type": "integer" }, "query": { "description": "One concept, name, or short phrase; use French concept terms for primary sources, and French/English terms for references", "minLength": 1, "type": "string" } }, "required": [ "query" ], "type": "object" }, "name": "search", "outputSchema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "additionalProperties": false, "properties": { "count": { "maximum": 9007199254740991, "minimum": -9007199254740991, "type": "integer" }, "coverage_warning": { "type": "string" }, "deep_scan": { "type": "boolean" }, "limit": { "maximum": 9007199254740991, "minimum": -9007199254740991, "type": "integer" }, "limit_warning": { "type": "string" }, "ranking": { "type": "string" }, "requested_limit": { "maximum": 9007199254740991, "minimum": -9007199254740991, "type": "integer" }, "results": { "items": { "additionalProperties": {}, "properties": { "category": { "type": "string" }, "id": { "type": "string" }, "title": { "type": "string" }, "url": { "type": "string" } }, "required": [ "id", "category" ], "type": "object" }, "type": "array" }, "unavailable_categories": { "items": { "type": "string" }, "type": "array" } }, "required": [ "results", "count", "limit", "ranking", "deep_scan" ], "type": "object" } }, { "description": "Search IWAC newspaper articles by keyword (title + OCR + AI abstracts, French and English), country, newspaper, subject, and date range. Use French concept keywords regardless of the user's report language. Matching is accent- and case-insensitive.", "inputSchema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "country": { "description": "Exact country name: Benin | Burkina Faso | Côte d'Ivoire | Niger | Togo (accents optional)", "type": "string" }, "date_from": { "description": "YYYY-MM-DD (or YYYY)", "type": "string" }, "date_to": { "description": "YYYY-MM-DD (or YYYY)", "type": "string" }, "hijri_month": { "description": "Islamic lunar month: 1-12, or a name (Ramadan, Chaabane, Chawwal, Dhu al-Hijja). Pulls the articles behind an observance peak — matches only items with a full YYYY-MM-DD date.", "type": "string" }, "hijri_year": { "description": "Islamic (Umm al-Qura) year, e.g. 1445", "maximum": 9007199254740991, "minimum": -9007199254740991, "type": "integer" }, "keyword": { "description": "Concept keyword; substring match on title, OCR text, and the French and English AI abstracts. Prefer French for the OCR; an English term still matches via the English abstract", "type": "string" }, "limit": { "description": "Default 20, max 100 (10 and 25 with with_description)", "maximum": 9007199254740991, "minimum": -9007199254740991, "type": "integer" }, "newspaper": { "type": "string" }, "offset": { "maximum": 9007199254740991, "minimum": -9007199254740991, "type": "integer" }, "subject": { "type": "string" }, "with_description": { "description": "Include each article's ~500-char AI abstract (description_ai) for triage without get_article. Adds ~125 tokens/row, so `limit` defaults to 10 and caps at 25 while this is on.", "type": "boolean" } }, "type": "object" }, "name": "search_articles", "outputSchema": null }, { "description": "Search audiovisual materials by keyword and metadata: francophone web video from Burkina Faso, Togo and Benin (TV reports, association and campus recordings), plus deposited Nigerian Hausa/Arabic recordings. Keyword matches title, creator, publisher, subject, spatial, language, source, the item's own description (the richest text most of these items have) and its transcription where one exists. Each row says which population it is from (`source_type`) and carries either `external_url` (a video to watch) or `media_url` (a file), never both.", "inputSchema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "country": { "description": "Exact country name: Benin | Burkina Faso | Côte d'Ivoire | Niger | Nigeria | Togo (accents optional). Burkina Faso, Togo, Benin and Nigeria only — no Niger or Ivorian items", "type": "string" }, "keyword": { "description": "Substring match across audiovisual title/metadata fields", "type": "string" }, "language": { "description": "Exact language value, e.g. Français | Haoussa | Arabe | Anglais | Mooré", "type": "string" }, "limit": { "description": "Default 20, max 50", "maximum": 9007199254740991, "minimum": -9007199254740991, "type": "integer" }, "medium": { "description": "Exact carrier medium: Vidéo sur le web | DVD | CD (validated, accents optional)", "type": "string" }, "offset": { "maximum": 9007199254740991, "minimum": -9007199254740991, "type": "integer" }, "publisher": { "description": "Substring on the publishing channel/broadcaster, e.g. RTB | AEEM | CERFI", "type": "string" }, "source_type": { "description": "youtube (harvested web video, the large majority) | deposited (recordings with a file, 47)", "type": "string" }, "subject": { "description": "Exact subject tag — only ~27 rows carry one, so prefer publisher/keyword", "type": "string" } }, "type": "object" }, "name": "search_audiovisual", "outputSchema": null }, { "description": "Filter articles by gpt-5-6-luna sentiment labels (accent/case-insensitive exact match). One model's reading, not a consensus — 4 other models scored the same articles and often disagree; get_sentiment_distribution with model:\"all\" shows by how much. `subjectivity` is much the weakest of the three scales, so treat a set selected on it as a lead to read rather than as a finding.", "inputSchema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "centrality": { "description": "Très central | Central | Secondaire | Marginal | Non abordé", "type": "string" }, "country": { "description": "Exact country name: Benin | Burkina Faso | Côte d'Ivoire | Niger | Togo (accents optional)", "type": "string" }, "disputed": { "description": "polarite | centralite | subjectivite — keep only articles the panel SPLIT on for that field (French field names, as stored). Selects contested readings, not a sentiment value.", "type": "string" }, "limit": { "description": "Default 20, max 100", "maximum": 9007199254740991, "minimum": -9007199254740991, "type": "integer" }, "offset": { "maximum": 9007199254740991, "minimum": -9007199254740991, "type": "integer" }, "polarity": { "description": "Très positif | Positif | Neutre | Négatif | Très négatif | Non applicable", "type": "string" }, "subject": { "type": "string" }, "subjectivity": { "description": "Très objectif | Plutôt objectif | Mixte | Plutôt subjectif | Très subjectif — least to most subjective. Unscored where the model answered Non abordé, so this filter also excludes those.", "type": "string" } }, "type": "object" }, "name": "search_by_sentiment", "outputSchema": null }, { "description": "Search the small archival-documents subset (~26 items: Islamic association reports, flyers, project documents — mostly Burkina Faso). Use French concept keywords regardless of the user's report language. Most have OCR text and an AI description. Call with no arguments to list all.", "inputSchema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "country": { "description": "Exact country name: Benin | Burkina Faso | Côte d'Ivoire | Niger | Nigeria | Togo (accents optional). Corpus is mostly Burkina Faso/Togo/Benin", "type": "string" }, "keyword": { "description": "Concept keyword; substring match on title, OCR, the French and English AI descriptions, and subject (accent-insensitive)", "type": "string" }, "limit": { "description": "Default 15, max 50", "maximum": 9007199254740991, "minimum": -9007199254740991, "type": "integer" }, "offset": { "maximum": 9007199254740991, "minimum": -9007199254740991, "type": "integer" } }, "type": "object" }, "name": "search_documents", "outputSchema": null }, { "description": "Search the IWAC photographs (30 items: mosques, radio stations, schools, signage and street scenes documented during fieldwork). Keyword matches title, creator, subject, place and the rare caption. Each result carries `image_url` (the full-resolution file), `coordinates` ('lat, lng' where known) and the canonical IWAC page. Call with no arguments to list all. Captions are almost never present, so prefer subject/place filters over keywords, or semantic_search_images when it is enabled.", "inputSchema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "country": { "description": "Exact country name: Benin | Burkina Faso | Côte d'Ivoire | Niger | Nigeria | Togo (accents optional)", "type": "string" }, "creator": { "description": "Photographer name (substring match)", "type": "string" }, "date_from": { "description": "YYYY-MM-DD (or YYYY)", "type": "string" }, "date_to": { "description": "YYYY-MM-DD (or YYYY)", "type": "string" }, "keyword": { "description": "French concept keyword; substring match on title, creator, subject, place and caption", "type": "string" }, "limit": { "description": "Default 20, max 50", "maximum": 9007199254740991, "minimum": -9007199254740991, "type": "integer" }, "offset": { "maximum": 9007199254740991, "minimum": -9007199254740991, "type": "integer" }, "spatial": { "description": "Exact place name, e.g. Ouagadougou (pipe-aware)", "type": "string" }, "subject": { "description": "Exact subject tag (pipe-aware)", "type": "string" } }, "type": "object" }, "name": "search_images", "outputSchema": null }, { "description": "Search the IWAC authority index (persons, places, organisations, events, subjects) by name. Accent/case-insensitive.", "inputSchema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "index_type": { "description": "Exact type (accents optional), validated against: Personnes | Lieux | Organisations | Événements | Sujets | Notices d'autorité. An unrecognised value returns an error listing the valid types.", "type": "string" }, "keyword": { "description": "Search term matched against the entry title", "type": "string" }, "limit": { "description": "Default 20, max 100", "maximum": 9007199254740991, "minimum": -9007199254740991, "type": "integer" }, "offset": { "maximum": 9007199254740991, "minimum": -9007199254740991, "type": "integer" } }, "required": [ "keyword" ], "type": "object" }, "name": "search_index", "outputSchema": null }, { "description": "Search Islamic publications (periodical issues, books). `keyword` matches title, subject, table of contents, and full OCR text (TOC hits come back as matching_toc_entries); use French concept keywords regardless of the user's report language. Filter by newspaper/series, subject, country and year. Use list_periodicals to discover series titles, and get_publication_fulltext for keyword excerpts from a single issue.", "inputSchema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "country": { "description": "Exact country name: Benin | Burkina Faso | Côte d'Ivoire | Niger | Togo (accents optional)", "type": "string" }, "date_from": { "description": "Earliest year, YYYY", "type": "string" }, "date_to": { "description": "Latest year, YYYY", "type": "string" }, "hijri_month": { "description": "Islamic lunar month: 1-12, or a name (Ramadan, Chaabane, Chawwal, Dhu al-Hijja). Matches only issues with a full YYYY-MM-DD date — ~83% of them.", "type": "string" }, "hijri_year": { "description": "Islamic (Umm al-Qura) year, e.g. 1445", "maximum": 9007199254740991, "minimum": -9007199254740991, "type": "integer" }, "keyword": { "description": "French concept keyword; substring match on title + subject + table of contents + OCR (accent-insensitive)", "type": "string" }, "limit": { "description": "Default 20, max 100", "maximum": 9007199254740991, "minimum": -9007199254740991, "type": "integer" }, "newspaper": { "description": "Periodical/series title (see list_periodicals)", "type": "string" }, "offset": { "maximum": 9007199254740991, "minimum": -9007199254740991, "type": "integer" }, "subject": { "description": "Subject tag (~87% of issues are tagged)", "type": "string" } }, "type": "object" }, "name": "search_publications", "outputSchema": null }, { "description": "Search academic references (journal articles, book chapters, theses, books, reports) by keyword and metadata. `keyword` is a single substring match over title + abstract, so search ONE term per call (combined terms like 'pèlerinage Mecque' miss results). References are multilingual: try French and English title/abstract keywords when relevant; metadata/filter values such as `reference_type` and `language` use French labels. Results include a short abstract snippet — use get_reference for the full abstract and bibliographic detail.", "inputSchema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "author": { "type": "string" }, "country": { "description": "Exact country name: Benin | Burkina Faso | Côte d'Ivoire | Niger | Nigeria | Togo (accents optional)", "type": "string" }, "date_from": { "description": "Earliest year, YYYY", "type": "string" }, "date_to": { "description": "Latest year, YYYY", "type": "string" }, "keyword": { "description": "One French or English concept keyword; substring match on title + abstract (one term per call, accent-insensitive)", "type": "string" }, "language": { "description": "e.g. Français | Anglais", "type": "string" }, "limit": { "description": "Default 20, max 100", "maximum": 9007199254740991, "minimum": -9007199254740991, "type": "integer" }, "offset": { "maximum": 9007199254740991, "minimum": -9007199254740991, "type": "integer" }, "reference_type": { "description": "Substring match. Values: Article de revue | Chapitre de livre | Livre | Mémoire de maitrise | Rapport | Thèse de doctorat | Communication scientifique | Compte rendu de livre | Article d'encyclopédie | Mémoire de licence | Article de blog | Working paper. Use the full label for precision — 'Livre' alone also matches 'Chapitre de livre' and 'Compte rendu de livre'.", "type": "string" }, "subject": { "description": "Subject tag (sparse: ~27% of references are tagged)", "type": "string" } }, "type": "object" }, "name": "search_references", "outputSchema": null } ] }
Verify it yourselfcurl -s https://api.teppi.xyz/v1/evidence/sha256:7eaef53b01fa108dd63a132a6f4882e8f9d079196e2ab2830e3e0ef097441508 | sha256sum