此 MCP 可以做什么
Provides SAP analytics intelligence through searchable firm, market, opportunity, news, concept, study, training, and knowledge-graph data.
工具
输入模式
{'type': 'object', 'required': ['by'], 'properties': {'by': {'enum': ['country', 'region', 'kind', 'module', 'sap_signal_band'], 'type': 'string', 'description': 'Which facet to count on. Required — there is no default worth guessing.'}, 'kind': {'type': 'string', 'description': 'Restrict to one organisation kind before counting, same vocabulary as search_firms. Combining it with `by:"kind"` is legal and returns that single bucket.'}, 'query': {'type': 'string', 'maxLength': 200, 'description': 'Free-text filter, case-insensitive. EVERY word must appear in the record (substring per word, any order), so a natural-language phrase narrows the answer instead of having to match verbatim.'}, 'module': {'type': 'string', 'description': 'Restrict to organisations with a DECLARED link to one SAP module code before counting, same vocabulary as search_firms\' `module`. Combining it with `by:"module"` is legal and returns that single bucket (plus the null bucket).'}, 'region': {'enum': ['EMEA', 'AMER', 'LATAM', 'APAC', 'AFRICA', 'GLOBAL'], 'type': 'string', 'description': "Region code of the HQ country — the platform's six-value geography: EMEA (Europe AND the Middle East), AMER (North America), LATAM, APAC, AFRICA (its own region, not folded into EMEA), GLOBAL (country unknown). Case-insensitive on input; anything else is refused."}, 'country': {'type': 'string', 'pattern': '^[A-Za-z]{2}$', 'description': 'ISO-3166-1 alpha-2 country code, e.g. DE, FR, CH.'}}, 'additionalProperties': False}
输出模式
{'type': 'object', 'required': ['tool', 'result_count', 'rows', '_attribution'], 'properties': {'rows': {'type': 'array', 'items': {'type': 'object', 'properties': {'n': {'type': ['integer', 'null']}, 'value': {'type': ['string', 'null']}, 'citation_url': {'type': 'string'}, 'citation_scope': {'enum': ['record', 'section_hub'], 'type': 'string'}}}}, 'tool': {'type': 'string'}, '_meta': {'type': 'object'}, '_attribution': {'type': 'string'}, 'result_count': {'type': 'integer'}}}
输入模式
{'type': 'object', 'properties': {'level': {'type': 'string', 'description': 'Restrict to one level, matched case-insensitively: Beginner · Intermediate · Advanced · Expert. Counts in `_meta.available_levels`.'}, 'limit': {'type': 'integer', 'default': 10, 'maximum': 50, 'minimum': 1, 'description': 'Max rows (hard cap 50).'}, 'query': {'type': 'string', 'maxLength': 200, 'description': 'Free-text filter, case-insensitive. EVERY word must appear in the record (substring per word, any order), so a natural-language phrase narrows the answer instead of having to match verbatim.'}, 'track': {'type': 'string', 'description': 'Restrict to one track, by SLUG (`databricks-data-eng`) or by English name (`Databricks & Data Eng.`), matched case-insensitively. The live vocabulary with per-track counts is `_meta.available_tracks` on every response. The numeric track_id is deliberately NOT accepted — it is an internal counter, and passing `6` would look like naming a subject.'}, 'cursor': {'type': 'string', 'maxLength': 512, 'description': "Opaque token from a previous response's `_meta.next_cursor`. Pass it back with the SAME filter arguments; `null` means the last page. Changing a filter refuses the cursor."}}, 'additionalProperties': False}
输出模式
{'type': 'object', 'required': ['tool', 'result_count', 'rows', '_attribution'], 'properties': {'rows': {'type': 'array', 'items': {'type': 'object', 'properties': {'id': {'type': ['string', 'null'], 'description': 'Module id, e.g. M001 — the value get_academy_module takes.'}, 'slug': {'type': ['string', 'null']}, 'tags': {'type': ['array', 'null'], 'items': {'type': 'string'}}, 'level': {'type': ['string', 'null']}, 'status': {'type': ['string', 'null'], 'description': "Editorial access marker: 'available' or 'legend-pass'. Served, not filtered on. READ 'legend-pass' AS 'sold at the CONSULTANT tier': it is a LEGACY label from when the paid tier was called Legend, it sits on the majority of rows, and the tier that actually opens the body here is Consultant (get_academy_module). The site stopped rendering this field for exactly that reason on 2026-07-26; this endpoint still serves the raw value, so the LABEL is the stale half and the tier floor is the true one."}, 'title_en': {'type': ['string', 'null']}, 'title_fr': {'type': ['string', 'null']}, 'is_preview': {'type': ['boolean', 'null'], 'description': 'The second free-access marker. Does NOT coincide with status — read both.'}, 'summary_en': {'type': ['string', 'null']}, 'summary_fr': {'type': ['string', 'null']}, 'track_slug': {'type': ['string', 'null']}, 'updated_at': {'type': ['string', 'null']}, 'citation_url': {'type': 'string'}, 'track_name_en': {'type': ['string', 'null']}, 'track_name_fr': {'type': ['string', 'null']}, 'citation_scope': {'enum': ['record', 'section_hub'], 'type': 'string'}, 'duration_minutes': {'type': ['number', 'null']}}}}, 'tool': {'type': 'string'}, '_meta': {'type': 'object'}, '_attribution': {'type': 'string'}, 'result_count': {'type': 'integer'}}}
输入模式
{'type': 'object', 'properties': {'lang': {'type': 'string', 'pattern': '^[A-Za-z]{2}$', 'description': "Reading language for the TITLE — 'EN' (default), 'FR' or 'DE'. This is a RENDERING choice, never a filter: it changes which string `title` carries, never which rows come back. Read `title_lang` on every row for the language actually served: it differs from what you asked for exactly when that translation does not exist (the live FR/DE coverage is counted on every response in `_meta.untranslated_leg`), and the verbatim is served instead, labelled with the language the harvest chain measured. `source_lang` always carries the language the ADVERTISER wrote in, translated or not. The promoted leg has no translated columns at all: its rows ignore this argument and say so with `title_lang: null` — see `_meta.untranslated_leg`."}, 'limit': {'type': 'integer', 'default': 10, 'maximum': 50, 'minimum': 1, 'description': 'Max rows (hard cap 50).'}, 'query': {'type': 'string', 'maxLength': 200, 'description': 'Free-text filter, case-insensitive. EVERY word must appear in the record (substring per word, any order), so a natural-language phrase narrows the answer instead of having to match verbatim.'}, 'cursor': {'type': 'string', 'maxLength': 512, 'description': "Opaque token from a previous response's `_meta.next_cursor`. Pass it back with the SAME filter arguments; `null` means the last page. Changing a filter refuses the cursor."}, 'country': {'type': 'string', 'pattern': '^[A-Za-z]{2}$', 'description': "ISO-3166-1 alpha-2 code, applied to both legs as a predicate on the row's own country_code. It NO LONGER selects the site-radar leg alone: the promoted feed carried country_code on almost none of its rows until 2026-08-28 and now carries it on most, so a country filter now returns both legs. A row still without one is dropped because it does not match, not because its leg was excluded by assumption. `_meta.match_count_by_leg` shows what each leg contributed on YOUR call — read the split there, never from a figure quoted in this text."}, 'location': {'type': 'string', 'description': "City or place, matched case-insensitively as a substring of the posting's location. The promoted leg is all-German (Hamburg, Frankfurt am Main, Bremen, Munich, Cologne, Dortmund, Hanover, Landshut, Mannheim, Stuttgart); the site-radar leg is worldwide."}, 'remote_mode': {'type': 'string', 'description': "Restrict to one work-location policy: `remote`, `hybrid` or `onsite`. READ THIS BEFORE ANSWERING A REMOTE QUESTION: a large share of the radar declares no policy at all (`_meta.remote_mode_undeclared` carries the live count — roughly half the radar when last measured, and a frozen pair written here drifted ~30% in two days), and an undeclared row is NOT an on-site row — it is a posting that does not say. Any value here therefore sets those rows aside rather than classifying them, exactly as the site's own filter does, and `_meta.remote_mode_undeclared` reports how many were set aside. The promoted leg carries its own `remote_mode` column and is filtered by the same predicate. Read `_meta.available_remote_modes` for the live spread before assuming a value exists."}, 'employment_type': {'enum': ['freelance', 'contract', 'permanent'], 'type': 'string', 'description': 'Restrict to one engagement type. THE RADAR IS MOSTLY PERMANENT, so a freelance or contract question answered off an unfiltered page is answered with salaried jobs. For the actual split, make the filtered call and read `_meta.tranche_total_row_count` — it is counted at query time. The promoted leg declared NO contract_type until 2026-08-28 and now declares one on most of its rows, so a value here no longer drops that leg wholesale — only the rows still silent. THOSE ROWS ARE NOT A FOURTH TYPE AND NOT PERMANENT ONES: `_meta.available_employment_types` counts only what declares, and `_meta.employment_type_undeclared` carries the rest, so the two together are the rows THIS call read (`_meta.employment_mix_rows_read` — a window, NOT the tranche: `_meta.tranche_total_row_count` is the population) and either alone is not even that. Read both before quoting a mix, and quote the window with it.'}}, 'additionalProperties': False}
输出模式
{'type': 'object', 'required': ['tool', 'result_count', 'rows', '_attribution'], 'properties': {'rows': {'type': 'array', 'items': {'type': 'object', 'properties': {'id': {'type': ['string', 'null'], 'description': "The posting's identity — stable across calls, key for dedup."}, 'leg': {'type': ['string', 'null'], 'description': '`promoted` or `site_radar` — which of the two merged public legs served this row.'}, 'title': {'type': ['string', 'null']}, 'skills': {'type': ['array', 'null'], 'description': 'Skills the posting names. Null when it names none.'}, 'source': {'type': ['string', 'null']}, 'category': {'type': ['string', 'null']}, 'currency': {'type': ['string', 'null']}, 'location': {'type': ['string', 'null']}, 'firm_name': {'type': ['string', 'null']}, 'posted_at': {'type': ['string', 'null']}, 'rate_band': {'type': ['object', 'null'], 'description': "Editorial benchmark for this posting's (seniority × product × region) cell — NOT a rate the employer offered. `basis` and `kind` are inside the object on purpose, so no extraction can lift the numbers away from what they mean. 2026-08-29: this band is a SUBSCRIBER surface and is no longer carried by the public radar file this lane reads — expect it to be null here. The posting's OWN published rate, when it has one, stays in currency / daily_rate_min / daily_rate_max."}, 'seniority': {'type': ['string', 'null']}, 'expires_at': {'type': ['string', 'null']}, 'salary_max': {'type': ['number', 'null']}, 'salary_min': {'type': ['number', 'null'], 'description': "The posting's own advertised salary, YEARLY (see `salary_period`). Null when none was published, and null when the published amount cannot be a yearly salary — `salary_withheld_reason` then says why."}, 'source_url': {'type': ['string', 'null']}, 'title_lang': {'type': ['string', 'null'], 'description': "ISO-639-1 language the SERVED `title` is written in. READ IT ON EVERY ROW: it is what you asked for in `lang` when that translation exists, and the advertiser's own language when it does not (the live FR/DE coverage is counted on every response in `_meta.untranslated_leg`). Null when the harvest chain could not decide — on some site-radar rows too, counted in `_meta.untranslated_radar_rows` — and on every promoted-leg row, which carries no translated column at all. ⚠️ THIS FIELD CHANGED REFERENT ON 2026-09-04: until then it named the language the ADVERTISER wrote in — that fact now lives in `source_lang`. The two coincided while no translation was served and diverge from the first one that is."}, 'description': {'type': ['string', 'null'], 'description': 'Posting text, HTML stripped, clamped. Null on the radar leg.'}, 'rate_period': {'type': ['string', 'null']}, 'remote_mode': {'type': ['string', 'null'], 'description': "The posting's declared work-location policy (`remote` / `hybrid` / `onsite`). NULL means the posting does not say — never read it as on-site."}, 'source_lang': {'type': ['string', 'null'], 'description': "ISO-639-1 language the ADVERTISER wrote the title in, measured by the harvest chain and never changed by `lang` — 'en' on 1,566 rows, 'de' on 337 (2026-08-23). Null when the chain could not decide, and on the promoted leg. Compare it with `title_lang` to know whether the title you are quoting is the advertiser's own words or this platform's rendering of them: a harvested posting is a third party's text, and saying which of the two you are citing is the only honest way to quote it."}, 'canonical_id': {'type': ['string', 'null'], 'description': 'Set when the site folded this posting into another one it judged identical: `citation_url` is then the page of THAT posting (`canonical_id`). When both are matched, only the canonical row is served and `_meta.duplicates_folded` counts the fold. Null otherwise.'}, 'citation_url': {'type': 'string'}, 'country_code': {'type': ['string', 'null'], 'description': "ISO-3166-1 alpha-2 of the posting's own country. Null on almost all of the promoted leg."}, 'salary_period': {'type': ['string', 'null'], 'description': '`year` when salary_min/salary_max are served. Null otherwise — never a guessed unit.'}, 'citation_scope': {'enum': ['record', 'section_hub'], 'type': 'string'}, 'daily_rate_max': {'type': ['number', 'null']}, 'daily_rate_min': {'type': ['number', 'null'], 'description': 'Only when the source declares a DAILY rate period — never converted from other periods.'}, 'duration_months': {'type': ['number', 'null']}, 'employment_type': {'type': ['string', 'null']}, 'application_link': {'type': ['string', 'null'], 'description': '`public` (source_url is served) or `members_only` (the link to the original listing is the paid Consultant-tier deliverable; the row and its facts stay public).'}, 'salary_withheld_reason': {'type': ['string', 'null'], 'description': "Why a published salary was NOT served: `below_annual_floor` (the low end is below any yearly salary in that currency — a monthly or daily figure filed as a salary) or `board_estimate` (the job board's own min = max estimate, not the employer's). The amount is withheld, never converted. Null when nothing was withheld."}}}}, 'tool': {'type': 'string'}, '_meta': {'type': 'object'}, '_attribution': {'type': 'string'}, 'result_count': {'type': 'integer'}}}
输入模式
{'type': 'object', 'properties': {'kind': {'enum': ['agency_placement', 'professional_services_esn', 'professional_services_big4', 'vendor_partner', 'vendor_sap', 'platform_marketplace', 'other'], 'type': 'string', 'description': 'Restrict to one provider kind (placement agencies, ESN/SI practices, Big-4, SAP partners, platforms). Communities, schools and public bodies are never in this population.'}, 'limit': {'type': 'integer', 'default': 10, 'maximum': 50, 'minimum': 1, 'description': 'Max rows (hard cap 50).'}, 'cursor': {'type': 'string', 'maxLength': 512, 'description': "Opaque token from a previous response's `_meta.next_cursor`. Pass it back with the SAME filter arguments; `null` means the last page. Changing a filter refuses the cursor."}, 'module': {'type': 'string', 'description': 'Restrict to firms with a DECLARED link to one SAP module code (UPPERCASE snake_case, e.g. DATASPHERE, BDC, SAC — call count_firms_by {by:"module"} for the live vocabulary). Absence means no declared link, never incapacity.'}, 'region': {'enum': ['EMEA', 'AMER', 'LATAM', 'APAC', 'AFRICA', 'GLOBAL'], 'type': 'string', 'description': "Region code of the HQ country — the platform's six-value geography: EMEA (Europe AND the Middle East), AMER (North America), LATAM, APAC, AFRICA (its own region, not folded into EMEA), GLOBAL (country unknown). Case-insensitive on input; anything else is refused."}, 'country': {'type': 'string', 'pattern': '^[A-Za-z]{2}$', 'description': 'ISO-3166-1 alpha-2 country code, e.g. DE, FR, CH.'}, 'local_only': {'type': 'boolean', 'default': True, 'description': 'true (default): only firms with no sister entity abroad. false: every provider of the market, groups included.'}}, 'additionalProperties': False}
输出模式
{'type': 'object', 'required': ['tool', 'result_count', 'rows', '_attribution'], 'properties': {'rows': {'type': 'array', 'items': {'type': 'object', 'properties': {'kind': {'type': ['string', 'null']}, 'name': {'type': ['string', 'null']}, 'slug': {'type': ['string', 'null']}, 'region': {'type': ['string', 'null']}, 'hq_city': {'type': ['string', 'null']}, 'website': {'type': ['string', 'null']}, 'hq_country': {'type': ['string', 'null']}, 'citation_url': {'type': 'string'}, 'size_bracket': {'type': ['string', 'null']}, 'citation_scope': {'enum': ['record', 'section_hub'], 'type': 'string'}, 'sap_signal_band': {'type': ['string', 'null']}, 'brand_family_key': {'type': ['string', 'null']}, 'declared_modules': {'type': ['array', 'null']}, 'sister_countries': {'type': ['array', 'null']}, 'partnerships_declared': {'type': ['integer', 'null']}}}}, 'tool': {'type': 'string'}, '_meta': {'type': 'object'}, '_attribution': {'type': 'string'}, 'result_count': {'type': 'integer'}}}
输入模式
{'type': 'object', 'properties': {'limit': {'type': 'integer', 'default': 10, 'maximum': 50, 'minimum': 1, 'description': 'Max rows (hard cap 50).'}, 'query': {'type': 'string', 'maxLength': 200, 'description': 'Free-text filter, case-insensitive. EVERY word must appear in the record (substring per word, any order), so a natural-language phrase narrows the answer instead of having to match verbatim.'}, 'cursor': {'type': 'string', 'maxLength': 512, 'description': "Opaque token from a previous response's `_meta.next_cursor`. Pass it back with the SAME filter arguments; `null` means the last page. Changing a filter refuses the cursor."}, 'country': {'type': 'string', 'pattern': '^[A-Za-z]{2}$', 'description': 'ISO-3166-1 alpha-2 country code, e.g. DE, FR, CH.'}, 'product': {'enum': ['datasphere', 'bdc', 'sac', 'bw', 'bw4hana', 's4hana', 'ecc', 'hana', 'joule', 'businessobjects', 'bpc', 'successfactors', 'ariba', 'concur'], 'type': 'string', 'description': 'Keep only end-customers where this SAP product was DETECTED in use. Absence from the result means undetected, not unused.'}, 'industry': {'type': 'string', 'maxLength': 200, 'description': 'Industry or sector filter, matched case-insensitively.'}}, 'additionalProperties': False}
输出模式
{'type': 'object', 'required': ['tool', 'result_count', 'rows', '_attribution'], 'properties': {'rows': {'type': 'array', 'items': {'type': 'object', 'properties': {'id': {'type': ['string', 'null']}, 'name': {'type': ['string', 'null']}, 'industry': {'type': ['string', 'null']}, 'citation_url': {'type': 'string'}, 'country_code': {'type': ['string', 'null']}, 'citation_scope': {'enum': ['record', 'section_hub'], 'type': 'string'}, 'sap_client_verification_status': {'type': ['string', 'null']}}}}, 'tool': {'type': 'string'}, '_meta': {'type': 'object'}, '_attribution': {'type': 'string'}, 'result_count': {'type': 'integer'}}}
输入模式
{'type': 'object', 'required': ['id'], 'properties': {'id': {'type': 'string', 'description': 'Module id (`M001`) or slug (`datasphere-foundations`), verbatim from find_academy_modules.rows[].id / .slug.'}}, 'additionalProperties': False}
输出模式
{'type': 'object', 'required': ['tool', 'result_count', 'rows', '_attribution'], 'properties': {'rows': {'type': 'array', 'items': {'type': 'object', 'properties': {'id': {'type': ['string', 'null']}, 'slug': {'type': ['string', 'null']}, 'body_en': {'type': ['string', 'null']}, 'title_en': {'type': ['string', 'null']}, 'citation_url': {'type': 'string'}, 'objectives_en': {'type': ['array', 'null'], 'items': {'type': 'string'}, 'description': 'Learning objectives, one per element — a text[] column, not a paragraph.'}, 'citation_scope': {'enum': ['record', 'section_hub'], 'type': 'string'}}}}, 'tool': {'type': 'string'}, '_meta': {'type': 'object'}, '_attribution': {'type': 'string'}, 'result_count': {'type': 'integer'}}}
输入模式
{'type': 'object', 'required': ['slug'], 'properties': {'slug': {'type': 'string', 'description': 'Concept slug from search_concepts.'}}, 'additionalProperties': False}
输出模式
{'type': 'object', 'required': ['tool', 'result_count', 'rows', '_attribution'], 'properties': {'rows': {'type': 'array', 'items': {'type': 'object', 'properties': {'slug': {'type': ['string', 'null']}, 'title': {'type': ['string', 'null']}, 'summary': {'type': ['string', 'null']}, 'citation_url': {'type': 'string'}, 'citation_scope': {'enum': ['record', 'section_hub'], 'type': 'string'}}}}, 'tool': {'type': 'string'}, '_meta': {'type': 'object'}, '_attribution': {'type': 'string'}, 'result_count': {'type': 'integer'}}}
输入模式
{'type': 'object', 'required': ['slug'], 'properties': {'slug': {'type': 'string', 'description': 'Concept slug, verbatim from search_concepts.rows[].slug.'}}, 'additionalProperties': False}
输出模式
{'type': 'object', 'required': ['tool', 'result_count', 'rows', '_attribution'], 'properties': {'rows': {'type': 'array', 'items': {'type': 'object', 'properties': {'slug': {'type': ['string', 'null']}, 'body_en': {'type': ['string', 'null']}, 'title_en': {'type': ['string', 'null']}, 'citation_url': {'type': 'string'}, 'citation_scope': {'enum': ['record', 'section_hub'], 'type': 'string'}}}}, 'tool': {'type': 'string'}, '_meta': {'type': 'object'}, '_attribution': {'type': 'string'}, 'result_count': {'type': 'integer'}}}
输入模式
{'type': 'object', 'properties': {'country': {'type': 'string', 'pattern': '^[A-Za-z]{2}$', 'description': 'ISO-3166-1 alpha-2 country code, e.g. DE, FR, CH.'}, 'seniority': {'type': 'string', 'description': 'e.g. senior, principal.'}, 'specialisation': {'type': 'string', 'description': "One of the codes the aggregate actually holds — analytics_all, bw, bw4hana, bw4hana_sac, sac, datasphere (2026-08-09; the live list comes back as `_meta.available_specialisations` on every call). They are NOT evenly spread across countries: DE holds analytics_all only, at three seniorities, and datasphere exists for FR alone, as a median with confidence 'low'. There is no bdc row and no joule row in THIS aggregate — but the platform does price BDC: `find_opportunities` carries a panel-inferred band on the live postings, €1,000–€1,400/day P25–P75 for Senior BDC on 52 German postings (2026-08-10). A code this aggregate does not hold returns 0 rows and the available codes; it never widens to a neighbouring band, and 0 here does not mean the platform is silent."}}, 'additionalProperties': False}
输出模式
{'type': 'object', 'required': ['tool', 'result_count', 'rows', '_attribution'], 'properties': {'rows': {'type': 'array', 'items': {'type': 'object', 'properties': {'note': {'type': ['string', 'null']}, 'basis': {'type': ['string', 'null'], 'description': 'external_published_median | external_published_range | panel — see /api/market-rates.json _meta.basis_values.'}, 'trend': {'type': ['string', 'null']}, 'source': {'type': ['string', 'null']}, 'country': {'type': ['string', 'null']}, 'accessed': {'type': ['string', 'null'], 'description': 'date the source was read (YYYY-MM-DD)'}, 'currency': {'type': ['string', 'null'], 'description': 'ISO-4217 unit of every daily_rate_* amount on THIS row (EUR, GBP, CHF) — never an envelope constant.'}, 'sap_scope': {'type': ['string', 'null'], 'description': 'what the source actually measures: sap_analytics | sap_general | erp_general | bi_non_sap'}, 'seniority': {'type': ['string', 'null']}, 'confidence': {'type': ['string', 'null']}, 'conversion': {'type': ['string', 'null'], 'description': 'how an hourly or monthly source figure was turned into a day rate'}, 'indicative': {'type': ['boolean', 'null'], 'description': 'true = orientation only: the source is a proxy (non-SAP BI band, generic ERP, agency monthly contract or marketing average). Never quote it as the SAP AI & analytics rate of its country.'}, 'source_url': {'type': ['string', 'null']}, 'sample_size': {'type': ['integer', 'null'], 'description': 'The sample the SOURCE states behind this row; null when it states none — never estimated.'}, 'source_date': {'type': ['string', 'null']}, 'source_type': {'type': ['string', 'null'], 'description': 'primary_agency_guide | primary_job_ads | primary_salary_survey | aggregator | marketing'}, 'citation_url': {'type': 'string'}, 'sample_basis': {'type': ['string', 'null'], 'description': 'What `sample_size` counts (profiles, vacancies…), when the source says.'}, 'client_market': {'type': ['string', 'null'], 'description': 'india_domestic (INR, Indian client) | eu_uk_remote (EUR, India-based contractor billed to an EU/UK client). Set on the India rows only.'}, 'source_period': {'type': ['string', 'null']}, 'citation_scope': {'enum': ['record', 'section_hub'], 'type': 'string'}, 'daily_rate_max': {'type': ['number', 'null'], 'description': 'Upper bound of the published band, in `currency`.'}, 'daily_rate_min': {'type': ['number', 'null'], 'description': 'Lower bound of the published band, in `currency`.'}, 'daily_rate_p10': {'type': ['number', 'null'], 'description': '10th percentile when the source publishes one, in `currency`.'}, 'daily_rate_p90': {'type': ['number', 'null'], 'description': '90th percentile when the source publishes one, in `currency`.'}, 'specialisation': {'type': ['string', 'null']}, 'yoy_change_pct': {'type': ['number', 'null']}, 'daily_rate_median': {'type': ['number', 'null'], 'description': 'Median when the source publishes one, in `currency`.'}, 'daily_rate_max_aud': {'type': ['number', 'null'], 'description': 'DEPRECATED — read daily_rate_max + currency.'}, 'daily_rate_max_chf': {'type': ['number', 'null'], 'description': 'DEPRECATED — read daily_rate_max + currency.'}, 'daily_rate_max_eur': {'type': ['number', 'null'], 'description': 'DEPRECATED — read daily_rate_max + currency.'}, 'daily_rate_max_gbp': {'type': ['number', 'null'], 'description': 'DEPRECATED — read daily_rate_max + currency.'}, 'daily_rate_max_hkd': {'type': ['number', 'null'], 'description': 'DEPRECATED — read daily_rate_max + currency.'}, 'daily_rate_max_inr': {'type': ['number', 'null'], 'description': 'DEPRECATED — read daily_rate_max + currency.'}, 'daily_rate_max_jpy': {'type': ['number', 'null'], 'description': 'DEPRECATED — read daily_rate_max + currency.'}, 'daily_rate_max_nzd': {'type': ['number', 'null'], 'description': 'DEPRECATED — read daily_rate_max + currency.'}, 'daily_rate_max_sgd': {'type': ['number', 'null'], 'description': 'DEPRECATED — read daily_rate_max + currency.'}, 'daily_rate_min_aud': {'type': ['number', 'null'], 'description': 'DEPRECATED — read daily_rate_min + currency.'}, 'daily_rate_min_chf': {'type': ['number', 'null'], 'description': 'DEPRECATED — read daily_rate_min + currency.'}, 'daily_rate_min_eur': {'type': ['number', 'null'], 'description': 'DEPRECATED — read daily_rate_min + currency.'}, 'daily_rate_min_gbp': {'type': ['number', 'null'], 'description': 'DEPRECATED — read daily_rate_min + currency.'}, 'daily_rate_min_hkd': {'type': ['number', 'null'], 'description': 'DEPRECATED — read daily_rate_min + currency.'}, 'daily_rate_min_inr': {'type': ['number', 'null'], 'description': 'DEPRECATED — read daily_rate_min + currency.'}, 'daily_rate_min_jpy': {'type': ['number', 'null'], 'description': 'DEPRECATED — read daily_rate_min + currency.'}, 'daily_rate_min_nzd': {'type': ['number', 'null'], 'description': 'DEPRECATED — read daily_rate_min + currency.'}, 'daily_rate_min_sgd': {'type': ['number', 'null'], 'description': 'DEPRECATED — read daily_rate_min + currency.'}, 'daily_rate_p10_gbp': {'type': ['number', 'null'], 'description': 'DEPRECATED — read daily_rate_p10 + currency.'}, 'daily_rate_p90_gbp': {'type': ['number', 'null'], 'description': 'DEPRECATED — read daily_rate_p90 + currency.'}, 'daily_rate_median_aud': {'type': ['number', 'null'], 'description': 'DEPRECATED — read daily_rate_median + currency.'}, 'daily_rate_median_eur': {'type': ['number', 'null'], 'description': 'DEPRECATED — read daily_rate_median + currency.'}, 'daily_rate_median_gbp': {'type': ['number', 'null'], 'description': 'DEPRECATED — read daily_rate_median + currency.'}, 'daily_rate_median_hkd': {'type': ['number', 'null'], 'description': 'DEPRECATED — read daily_rate_median + currency.'}, 'daily_rate_median_inr': {'type': ['number', 'null'], 'description': 'DEPRECATED — read daily_rate_median + currency.'}, 'daily_rate_median_jpy': {'type': ['number', 'null'], 'description': 'DEPRECATED — read daily_rate_median + currency.'}, 'daily_rate_median_nzd': {'type': ['number', 'null'], 'description': 'DEPRECATED — read daily_rate_median + currency.'}, 'daily_rate_median_sgd': {'type': ['number', 'null'], 'description': 'DEPRECATED — read daily_rate_median + currency.'}}}}, 'tool': {'type': 'string'}, '_meta': {'type': 'object'}, '_attribution': {'type': 'string'}, 'result_count': {'type': 'integer'}}}
输入模式
{'type': 'object', 'required': ['target_region'], 'properties': {'home_region': {'enum': ['EMEA', 'AMER', 'LATAM', 'APAC', 'AFRICA', 'GLOBAL'], 'type': 'string', 'description': 'Optional. The region you operate from today. When set, bridge groups are the families present in BOTH regions; when omitted, in the target region and any other.'}, 'target_region': {'enum': ['EMEA', 'AMER', 'LATAM', 'APAC', 'AFRICA', 'GLOBAL'], 'type': 'string', 'description': 'The region you want to enter. One of EMEA, AMER, LATAM, APAC, AFRICA (GLOBAL is refused: it is not a market).'}}, 'additionalProperties': False}
输出模式
{'type': 'object', 'required': ['tool', 'result_count', 'rows', '_attribution'], 'properties': {'rows': {'type': 'array', 'items': {'type': 'object', 'properties': {'rates': {'type': ['object', 'null']}, 'providers': {'type': ['object', 'null']}, 'home_region': {'type': ['string', 'null']}, 'citation_url': {'type': 'string'}, 'bridge_groups': {'type': ['array', 'null']}, 'end_customers': {'type': ['object', 'null']}, 'opportunities': {'type': ['object', 'null']}, 'professionals': {'type': ['object', 'null']}, 'target_region': {'type': ['string', 'null']}, 'citation_scope': {'enum': ['record', 'section_hub'], 'type': 'string'}}}}, 'tool': {'type': 'string'}, '_meta': {'type': 'object'}, '_attribution': {'type': 'string'}, 'result_count': {'type': 'integer'}}}
输入模式
{'type': 'object', 'required': ['slug'], 'properties': {'slug': {'type': 'string', 'description': 'The DATABASE slug, taken verbatim from search_firms.rows[].slug. It is not always the web slug in citation_url: a minority of published rows carry a numeric firm id instead (365 of them on 2026-08-09 — the population is read at query time and returned as `_meta.tranche_total_row_count`, never written down here). get_firm{slug:"00393"} is GULP, whose page is /companies/gulp/. Deriving a slug from the citation URL fails on those rows, and deriving it from the NAME is not safe either; carry rows[].slug across instead. A slug this tool refuses is not proof the firm is absent from the market or even from the database — the published tranche is an editorial subset, and a row the editor has not published is refused here exactly as a wrong slug is.'}}, 'additionalProperties': False}
输出模式
{'type': 'object', 'required': ['tool', 'result_count', 'rows', '_attribution'], 'properties': {'rows': {'type': 'array', 'items': {'type': 'object', 'properties': {'name': {'type': ['string', 'null']}, 'slug': {'type': ['string', 'null']}, 'citation_url': {'type': 'string'}, 'citation_scope': {'enum': ['record', 'section_hub'], 'type': 'string'}}}}, 'tool': {'type': 'string'}, '_meta': {'type': 'object'}, '_attribution': {'type': 'string'}, 'result_count': {'type': 'integer'}}}
输入模式
{'type': 'object', 'properties': {'mode': {'enum': ['freelance', 'permanent', 'subcontract'], 'type': 'string', 'description': 'Keep only firms whose profile declares this engagement mode (mode_freelance / mode_permanent / mode_subcontract). Same reading as `delivers`: declared-only.'}, 'name': {'type': 'string', 'maxLength': 200, 'description': 'Firm name, matched case-insensitively. Omit to browse the corpus by data completeness.'}, 'limit': {'type': 'integer', 'default': 3, 'maximum': 10, 'minimum': 1, 'description': 'Max rows (hard cap 10 — these rows are wide).'}, 'cursor': {'type': 'string', 'maxLength': 512, 'description': "Opaque token from a previous response's `_meta.next_cursor`. Pass it back with the SAME filter arguments; `null` means the last page. Changing a filter refuses the cursor."}, 'country': {'type': 'string', 'pattern': '^[A-Za-z]{2}$', 'description': 'ISO-3166-1 alpha-2 country code, e.g. DE, FR, CH.'}, 'delivers': {'enum': ['datasphere', 'bdc', 'sac', 'bw', 'bw4hana', 's4hana', 'ecc', 'hana', 'joule', 'businessobjects', 'bpc', 'successfactors', 'ariba', 'concur'], 'type': 'string', 'description': 'Keep only firms whose profile DECLARES delivery of this product (the `delivers_*` flags every row already carries). An undeclared flag drops the row: absence from the result means the profile does not declare it, not that the firm cannot deliver it.'}}, 'additionalProperties': False}
输出模式
{'type': 'object', 'required': ['tool', 'result_count', 'rows', '_attribution'], 'properties': {'rows': {'type': 'array', 'items': {'type': 'object', 'properties': {'name': {'type': ['string', 'null']}, 'citation_url': {'type': 'string'}, 'citation_scope': {'enum': ['record', 'section_hub'], 'type': 'string'}, 'firm_id_unique': {}, 'sap_partner_level': {'type': ['string', 'null']}, 'typical_day_rate_eur': {}}}}, 'tool': {'type': 'string'}, '_meta': {'type': 'object'}, '_attribution': {'type': 'string'}, 'result_count': {'type': 'integer'}}}
输入模式
{'type': 'object', 'required': ['id'], 'properties': {'id': {'type': 'string', 'maxLength': 160, 'description': 'Profile id, verbatim from find_sap_clients.rows[].id.'}}, 'additionalProperties': False}
输出模式
{'type': 'object', 'required': ['tool', 'result_count', 'rows', '_attribution'], 'properties': {'rows': {'type': 'array', 'items': {'type': 'object', 'properties': {'id': {'type': ['string', 'null']}, 'name': {'type': ['string', 'null']}, 'citation_url': {'type': 'string'}, 'citation_scope': {'enum': ['record', 'section_hub'], 'type': 'string'}, 'sap_products_used': {}}}}, 'tool': {'type': 'string'}, '_meta': {'type': 'object'}, '_attribution': {'type': 'string'}, 'result_count': {'type': 'integer'}}}
输入模式
{'type': 'object', 'required': ['slug'], 'properties': {'lang': {'type': 'string', 'default': 'en', 'pattern': '^[A-Za-z]{2}$', 'description': 'ISO-639-1 language of the edition, e.g. en or fr. Defaults to en.'}, 'slug': {'type': 'string', 'description': 'Study slug, verbatim from list_studies.rows[].slug.'}, 'section': {'type': 'string', 'maxLength': 200, 'description': "A section heading from a previous call's `sections` list. Omit to get the list."}}, 'additionalProperties': False}
输出模式
{'type': 'object', 'required': ['tool', 'result_count', 'rows', '_attribution'], 'properties': {'rows': {'type': 'array', 'items': {'type': 'object', 'properties': {'slug': {'type': ['string', 'null']}, 'title': {'type': ['string', 'null']}, 'citation_url': {'type': 'string'}, 'citation_scope': {'enum': ['record', 'section_hub'], 'type': 'string'}, 'section_heading': {'type': ['string', 'null']}}}}, 'tool': {'type': 'string'}, '_meta': {'type': 'object'}, '_attribution': {'type': 'string'}, 'result_count': {'type': 'integer'}}}
输入模式
{'type': 'object', 'properties': {}, 'additionalProperties': False}
输出模式
{'type': 'object', 'required': ['tool', 'result_count', 'rows', '_attribution'], 'properties': {'rows': {'type': 'array', 'items': {'type': 'object', 'properties': {'n': {'type': ['integer', 'null']}, 'kind': {'type': ['string', 'null']}, 'citation_url': {'type': 'string'}, 'citation_scope': {'enum': ['record', 'section_hub'], 'type': 'string'}}}}, 'tool': {'type': 'string'}, '_meta': {'type': 'object'}, '_attribution': {'type': 'string'}, 'result_count': {'type': 'integer'}}}
输入模式
{'type': 'object', 'properties': {'limit': {'type': 'integer', 'default': 10, 'maximum': 50, 'minimum': 1, 'description': 'Max rows (hard cap 50).'}, 'cursor': {'type': 'string', 'maxLength': 512, 'description': "Opaque token from a previous response's `_meta.next_cursor`. Pass it back with the SAME filter arguments; `null` means the last page. Changing a filter refuses the cursor."}, 'country': {'type': 'string', 'pattern': '^[A-Za-z]{2}$', 'description': 'ISO-3166-1 alpha-2 country code, e.g. DE, FR, CH.'}, 'platform_type': {'type': 'string', 'description': 'Restrict to one platform type, lowercase snake_case. The live vocabulary with counts is `_meta.available_platform_types` on every response — a well-formed unknown value returns no rows, it never widens the result.'}}, 'additionalProperties': False}
输出模式
{'type': 'object', 'required': ['tool', 'result_count', 'rows', '_attribution'], 'properties': {'rows': {'type': 'array', 'items': {'type': 'object', 'properties': {'name': {'type': ['string', 'null']}, 'slug': {'type': ['string', 'null']}, 'confidence': {'type': ['string', 'null'], 'description': 'Editorial confidence in the signup assessment.'}, 'hq_country': {'type': ['string', 'null']}, 'signup_url': {'type': ['string', 'null'], 'description': "The platform's own signup/profile-creation page, verified on assessed_at."}, 'assessed_at': {'type': ['string', 'null']}, 'citation_url': {'type': 'string'}, 'platform_type': {'type': ['string', 'null']}, 'citation_scope': {'enum': ['record', 'section_hub'], 'type': 'string'}}}}, 'tool': {'type': 'string'}, '_meta': {'type': 'object'}, '_attribution': {'type': 'string'}, 'result_count': {'type': 'integer'}}}
输入模式
{'type': 'object', 'properties': {'limit': {'type': 'integer', 'default': 10, 'maximum': 50, 'minimum': 1, 'description': 'Max rows (hard cap 50).'}, 'query': {'type': 'string', 'maxLength': 200, 'description': 'Free-text filter, case-insensitive. EVERY word must appear in the record (substring per word, any order), so a natural-language phrase narrows the answer instead of having to match verbatim.'}, 'cursor': {'type': 'string', 'maxLength': 512, 'description': "Opaque token from a previous response's `_meta.next_cursor`. Pass it back with the SAME filter arguments; `null` means the last page. Changing a filter refuses the cursor."}}, 'additionalProperties': False}
输出模式
{'type': 'object', 'required': ['tool', 'result_count', 'rows', '_attribution'], 'properties': {'rows': {'type': 'array', 'items': {'type': 'object', 'properties': {'code': {'type': ['string', 'null']}, 'category': {'type': ['string', 'null']}, 'label_en': {'type': ['string', 'null']}, 'citation_url': {'type': 'string'}, 'citation_scope': {'enum': ['record', 'section_hub'], 'type': 'string'}}}}, 'tool': {'type': 'string'}, '_meta': {'type': 'object'}, '_attribution': {'type': 'string'}, 'result_count': {'type': 'integer'}}}
输入模式
{'type': 'object', 'properties': {'lang': {'type': 'string', 'pattern': '^[A-Za-z]{2}$', 'description': 'ISO-639-1 language of the EDITION to list, e.g. en, fr or de — each study is published as one row per language. Omit it to see every edition of every study; the live list of languages actually present comes back as `_meta.available_languages` on every response. A well-formed code the corpus does not hold returns 0 rows.'}, 'limit': {'type': 'integer', 'default': 10, 'maximum': 50, 'minimum': 1, 'description': 'Max rows (hard cap 50).'}, 'query': {'type': 'string', 'maxLength': 200, 'description': 'Free-text filter, case-insensitive. EVERY word must appear in the record (substring per word, any order), so a natural-language phrase narrows the answer instead of having to match verbatim.'}, 'cursor': {'type': 'string', 'maxLength': 512, 'description': "Opaque token from a previous response's `_meta.next_cursor`. Pass it back with the SAME filter arguments; `null` means the last page. Changing a filter refuses the cursor."}}, 'additionalProperties': False}
输出模式
{'type': 'object', 'required': ['tool', 'result_count', 'rows', '_attribution'], 'properties': {'rows': {'type': 'array', 'items': {'type': 'object', 'properties': {'lang': {'type': ['string', 'null']}, 'slug': {'type': ['string', 'null']}, 'as_of': {'type': ['string', 'null']}, 'title': {'type': ['string', 'null']}, 'access': {'type': ['string', 'null']}, 'editions': {'type': ['array', 'null'], 'items': {'type': 'string'}}, 'word_count': {'type': ['integer', 'null']}, 'citation_url': {'type': 'string'}, 'citation_scope': {'enum': ['record', 'section_hub'], 'type': 'string'}}}}, 'tool': {'type': 'string'}, '_meta': {'type': 'object'}, '_attribution': {'type': 'string'}, 'result_count': {'type': 'integer'}}}
输入模式
{'type': 'object', 'properties': {'lang': {'type': 'string', 'pattern': '^[A-Za-z]{2}$', 'description': 'ISO-639-1 language for the LABELS — en, fr or de. Defaults to en. The fallback is declared and never silent: the language asked for, then English, then French, and `_meta.label_language_coverage` says on how many nodes each language is actually filled. Concept and module titles carry French; German arrives as the corpus is translated, and an untranslated node falls back rather than being hidden.'}, 'limit': {'type': 'integer', 'default': 10, 'maximum': 50, 'minimum': 1, 'description': 'Max rows (hard cap 50).'}, 'query': {'type': 'string', 'description': "Case-insensitive substring of a node's label. Applies to the NODE listing, not to a walk. Matched against the label SERVED, so it follows `lang`."}, 'cursor': {'type': 'string', 'maxLength': 512, 'description': "Opaque token from a previous response's `_meta.next_cursor`. Pass it back with the SAME filter arguments; `null` means the last page. Changing a filter refuses the cursor."}, 'node_id': {'type': 'string', 'description': "Fully-qualified node id, `<type>:<id>` — `module:M178`, `concept:C001`, `study:ai-impact-2026-EN`, `vendor:alteryx`. With it, rows are that node's EDGES (one row per neighbour). Without it, rows are NODES."}, 'direction': {'enum': ['from', 'to', 'both'], 'type': 'string', 'description': 'Which side of the edge `node_id` must sit on. Default `both`. Ignored without `node_id`, and the response says so rather than pretending it applied.'}, 'edge_type': {'type': 'string', 'description': 'Restrict a walk to one relation. The served projection carries FIVE — teaches · taught_by · covers · related · mentions — and this list is a HINT, not the authority: read `_meta.available_edge_types`, computed on every call. A four-name list stood here while the projection served five, so `mentions` was reachable and undocumented.'}, 'node_type': {'type': 'string', 'description': 'Restrict to one carried node type: concept · module · study · vendor. Read `_meta.available_node_types`.'}}, 'additionalProperties': False}
输出模式
{'type': 'object', 'required': ['tool', 'result_count', 'rows', '_attribution'], 'properties': {'rows': {'type': 'array', 'items': {'type': 'object', 'properties': {'label': {'type': ['string', 'null'], 'description': 'In the language asked for when the node carries it, else the declared fallback — see `label_lang`.'}, 'node_id': {'type': ['string', 'null']}, 'direction': {'type': ['string', 'null'], 'description': '`out` = node_id → neighbour, `in` = neighbour → node_id, `both` = the relation is stored in both directions (served once — see `_meta.symmetric_edges_folded`). Walk rows only.'}, 'edge_type': {'type': ['string', 'null'], 'description': 'Present only on a walk (when `node_id` was given).'}, 'node_type': {'type': ['string', 'null']}, 'label_lang': {'type': ['string', 'null'], 'description': 'The language the served `label` is actually written in. It differs from the requested `lang` exactly when that translation does not exist.'}, 'citation_url': {'type': 'string'}, 'citation_scope': {'enum': ['record', 'section_hub'], 'type': 'string'}}}}, 'tool': {'type': 'string'}, '_meta': {'type': 'object'}, '_attribution': {'type': 'string'}, 'result_count': {'type': 'integer'}}}
输入模式
{'type': 'object', 'properties': {'limit': {'type': 'integer', 'default': 10, 'maximum': 50, 'minimum': 1, 'description': 'Max rows (hard cap 50).'}, 'query': {'type': 'string', 'maxLength': 200, 'description': 'Free-text filter, case-insensitive. EVERY word must appear in the record (substring per word, any order), so a natural-language phrase narrows the answer instead of having to match verbatim.'}, 'cursor': {'type': 'string', 'maxLength': 512, 'description': "Opaque token from a previous response's `_meta.next_cursor`. Pass it back with the SAME filter arguments; `null` means the last page. Changing a filter refuses the cursor."}, 'category': {'type': 'string', 'description': 'Concept category, matched case-insensitively as an exact value OR a prefix — so category:"datasphere" reaches \'Datasphere Core\'. The values are long human labels, not codes. DO NOT GUESS THEM FROM THIS TEXT: the live vocabulary with a row count per label comes back as `_meta.available_categories` on EVERY call, including a call that matched nothing. A list written here would say 14 labels with 2026-07-30 counts; the corpus holds 15 today, and five of those counts have moved. Read the envelope, not the prose.'}}, 'additionalProperties': False}
输出模式
{'type': 'object', 'required': ['tool', 'result_count', 'rows', '_attribution'], 'properties': {'rows': {'type': 'array', 'items': {'type': 'object', 'properties': {'slug': {'type': ['string', 'null']}, 'title': {'type': ['string', 'null']}, 'citation_url': {'type': 'string'}, 'citation_scope': {'enum': ['record', 'section_hub'], 'type': 'string'}}}}, 'tool': {'type': 'string'}, '_meta': {'type': 'object'}, '_attribution': {'type': 'string'}, 'result_count': {'type': 'integer'}}}
输入模式
{'type': 'object', 'properties': {'kind': {'enum': ['agency_placement', 'professional_services_big4', 'professional_services_esn', 'vendor_sap', 'vendor_partner', 'platform_marketplace', 'community_group', 'training_institution', 'client_enterprise', 'other'], 'type': 'string', 'description': 'Restrict to one organisation kind. This list is the vocabulary the corpus holds today, not a frontier — call list_firm_kinds for the live one. A malformed code is refused; a well-formed code the corpus does not hold returns no rows. Neither case is silently ignored, and neither widens the result.'}, 'limit': {'type': 'integer', 'default': 10, 'maximum': 50, 'minimum': 1, 'description': 'Max rows (hard cap 50).'}, 'query': {'type': 'string', 'maxLength': 200, 'description': 'Free-text filter, case-insensitive. EVERY word must appear in the record (substring per word, any order), so a natural-language phrase narrows the answer instead of having to match verbatim.'}, 'cursor': {'type': 'string', 'maxLength': 512, 'description': "Opaque token from a previous response's `_meta.next_cursor`. Pass it back with the SAME filter arguments; `null` means the last page. Changing a filter refuses the cursor."}, 'module': {'type': 'string', 'description': 'Restrict to organisations with a DECLARED link to one SAP module/product code (UPPERCASE snake_case, e.g. DATASPHERE, BDC, SAC, BW4HANA, S4HANA, JOULE — case-insensitive on input). The declared links are structured data, far more selective than free text: `count_firms_by {by:"module"}` gives the live vocabulary with counts. A minority of the directory declares any module at all, so this filter finds the DECLARED specialists — absence from the result means no declared link, never that the firm does not work on the module.'}, 'region': {'enum': ['EMEA', 'AMER', 'LATAM', 'APAC', 'AFRICA', 'GLOBAL'], 'type': 'string', 'description': "Region code of the HQ country — the platform's six-value geography: EMEA (Europe AND the Middle East), AMER (North America), LATAM, APAC, AFRICA (its own region, not folded into EMEA), GLOBAL (country unknown). Case-insensitive on input; anything else is refused."}, 'country': {'type': 'string', 'pattern': '^[A-Za-z]{2}$', 'description': 'ISO-3166-1 alpha-2 country code, e.g. DE, FR, CH.'}}, 'additionalProperties': False}
输出模式
{'type': 'object', 'required': ['tool', 'result_count', 'rows', '_attribution'], 'properties': {'rows': {'type': 'array', 'items': {'type': 'object', 'properties': {'kind': {'type': ['string', 'null']}, 'name': {'type': ['string', 'null']}, 'slug': {'type': ['string', 'null']}, 'claim': {'type': ['string', 'null']}, 'region': {'type': ['string', 'null']}, 'hq_city': {'type': ['string', 'null']}, 'website': {'type': ['string', 'null']}, 'jobs_url': {'type': ['string', 'null']}, 'hq_country': {'type': ['string', 'null']}, 'citation_url': {'type': 'string'}, 'founded_year': {'type': ['integer', 'null']}, 'size_bracket': {'type': ['string', 'null']}, 'citation_scope': {'enum': ['record', 'section_hub'], 'type': 'string'}, 'sap_signal_band': {'type': ['string', 'null']}, 'last_verified_at': {'type': ['string', 'null']}}}}, 'tool': {'type': 'string'}, '_meta': {'type': 'object'}, '_attribution': {'type': 'string'}, 'result_count': {'type': 'integer'}}}
输入模式
{'type': 'object', 'properties': {'limit': {'type': 'integer', 'default': 10, 'maximum': 50, 'minimum': 1, 'description': 'Max rows (hard cap 50).'}, 'query': {'type': 'string', 'maxLength': 200, 'description': 'Free-text filter, case-insensitive. EVERY word must appear in the record (substring per word, any order), so a natural-language phrase narrows the answer instead of having to match verbatim.'}, 'cursor': {'type': 'string', 'maxLength': 512, 'description': "Opaque token from a previous response's `_meta.next_cursor`. Pass it back with the SAME filter arguments; `null` means the last page. Changing a filter refuses the cursor."}, 'category': {'type': 'string', 'description': "Category code, matched case-insensitively. The live vocabulary is NOT written here — read `_meta.available_categories` on any response: every category label this corpus holds right now, with its active-row count, counted at query time. A written list held 21 values while the corpus held 22. One bucket needs a warning. 'SAC' is the noisiest label in this corpus because the acronym collides with unrelated ones — Windows 'Smart App Control', and the surname 'Sacks'. A 2026-07-30 cleanup reclassified half that bucket to AI for carrying no SAP signal at all; the collision pressure is structural and the bucket has kept growing since. For genuine SAC product news, pair category:'SAC' with query:'analytics cloud'."}, 'published_since': {'type': 'string', 'description': 'Lower bound on `published_at`, inclusive, as YYYY-MM-DD. Without a bound a period question is only answerable by walking pages — and `_meta.match_count` then counts the QUERY, not the period, so any figure quoted for the window would be wrong.'}, 'published_until': {'type': 'string', 'description': 'Upper bound on `published_at`, INCLUSIVE of the day named, as YYYY-MM-DD. Combine with `published_since` for a window; `_meta.match_count` then describes that window, which is what makes it quotable.'}}, 'additionalProperties': False}
输出模式
{'type': 'object', 'required': ['tool', 'result_count', 'rows', '_attribution'], 'properties': {'rows': {'type': 'array', 'items': {'type': 'object', 'properties': {'title': {'type': ['string', 'null']}, 'source_url': {'type': ['string', 'null']}, 'source_name': {'type': ['string', 'null']}, 'citation_url': {'type': 'string'}, 'published_at': {'type': ['string', 'null']}, 'citation_scope': {'enum': ['record', 'section_hub'], 'type': 'string'}}}}, 'tool': {'type': 'string'}, '_meta': {'type': 'object'}, '_attribution': {'type': 'string'}, 'result_count': {'type': 'integer'}}}
近期工具变更
类似的 MCP 服务器
UNESCO UIS — Education, Science & Culture Statistics (provenance-first)
Searches UNESCO education, science, culture, and demographic indicators and retrieves provenance-backed statistical records.
LiveDataLink
Exposes public-data tools covering economics, labor, banking, transport, books, legal opinions, carriers, environmental data, and…
Stratalize Healthcare
Retired Stratalize server exposing benchmark, market intelligence, compliance, financial, healthcare, legal, real estate, and eco…
Stratalize Governance
Retired Stratalize server exposing benchmark, market intelligence, compliance, financial, healthcare, legal, real estate, and eco…
Stratalize Oracle
Retired Stratalize server exposing benchmark, market intelligence, compliance, financial, healthcare, legal, real estate, and eco…
Stratalize Real Estate
Retired Stratalize server exposing benchmark, market intelligence, compliance, financial, healthcare, legal, real estate, and eco…
Stratalize Crypto & DeFi
Retired Stratalize server exposing benchmark, market intelligence, compliance, financial, healthcare, legal, real estate, and eco…
Valuein — SEC EDGAR Fundamentals & Smart-Money Data
Provides point-in-time SEC EDGAR fundamentals, filings, ownership signals, financial analysis, valuation models, research reports…