Skip to main content
Glama

Analytics Legends — SAP AI & Analytics MCP Server

Public SAP AI & analytics day-rate aggregate

get_day_rate_benchmark
Read-onlyIdempotent

The PUBLIC day-rate aggregate for SAP AI & analytics freelance work: min/max daily rate by country, specialisation and seniority — daily_rate_min / daily_rate_max (plus daily_rate_median, daily_rate_p10, daily_rate_p90 when the source publishes them), every amount in the row's own currency — with source, source date, confidence and the sample the source states. This is the free aggregate published at analyticslegends.ai/api/market-rates.json, and it is SMALL — a few dozen rows at most, every one of them a secondary source (a published market study or a job-board scan), and sample_size is null on most of them. NO COUNT IS WRITTEN HERE ON PURPOSE: _meta.tranche_total_row_count and the rows themselves are the live measure. A frozen pair stood here until 2026-08-27 — '11 rows on 2026-08-09 … sample_size null on 8 of them' — and the second half was WRONG (7 of 11) while the first was still right, which is the whole argument against writing either. NOTHING IS HELD BACK BEHIND IT: there is no paid counterpart to this aggregate. The community-contribution path exists (public.rate_contributions) but publishes nothing yet — v_community_rate_aggregates and v_rate_index are still empty, because a contributed rate only surfaces once a cell holds enough submissions to be reported without identifying anyone. So whatever percentile a source row happens to carry is served here, free, to everyone. The GB row carries a median, p10 and p90, and its own note says its min/max ARE the 25th and 75th percentiles. What is missing from this answer is missing from THIS aggregate; it is not a paid tier. THIS IS NOT THE ONLY RATE THE PLATFORM PUBLISHES, AND ON THE QUESTIONS THIS MARKET ASKS MOST IT IS THE THINNER ONE. The website carries a rate_band per live radar posting for signed-in subscribers — a panel-inferred P25–P75 band per (seniority × product × region) cell, Eursap n=312 plus the Analytics Legends operator panel. This server does not serve it (find_opportunities.rate_band is null on every row, with or without a key). The grid covers EUROPEAN cells only — DACH, FR/Benelux, UK/IE, Southern EU, Eastern EU, Nordics — and there it prices exactly the cells this small aggregate cannot (Senior Datasphere DACH, Senior BDC DACH), where specialisation:"bdc" here returns nothing. When this tool comes back empty for a country × product: in one of those European regions, say the AGGREGATE holds no row and that subscribers read the platform's band on the posting pages; ANYWHERE ELSE (Americas, APAC, Africa, Middle East) say the platform publishes no rate for that cell at any tier — never that subscribers get one. The two are different instruments: this one is a published market study, that one is an editorial benchmark attached to a live posting. Read _meta.available_countries / available_specialisations / available_seniorities — they are computed from the aggregate on every call — before concluding that a rate is unpublished, and quote each row with its own currency, its confidence and its source date.

Input Schema

NameRequiredDescriptionDefault
countryNoISO-3166-1 alpha-2 country code, e.g. DE, FR, CH.
seniorityNoe.g. senior, principal.
specialisationNoA specialisation code, matched exactly. The live list is `_meta.available_specialisations` on every call — no list is kept here, because a written one went stale. Codes are NOT evenly spread across countries: read the rows a country filter returns. A code this aggregate does not hold (bdc, joule) returns 0 rows and the available codes; it never widens to a neighbouring band. 0 rows here is an absence in THIS aggregate only — see the tool description for what the website's subscriber band covers and where no rate exists at any tier.

Output Schema

NameRequiredDescriptionDefault
rowsYes
toolYes
_metaNo
_attributionYes
result_countYes

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed2 schema fields changed
    • addedOutput schema / properties / rows / items / properties / daily_rate_max_usd
      Added value: +{
      +  "description": "DEPRECATED — read daily_rate_max + currency.",
      +  "type": [
      +    "number",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / rows / items / properties / daily_rate_min_usd
      Added value: +{
      +  "description": "DEPRECATED — read daily_rate_min + currency.",
      +  "type": [
      +    "number",
      +    "null"
      +  ]
      +}
  2. Changed3 schema fields changed
    • addedOutput schema / properties / rows / items / properties / daily_rate_max_zar
      Added value: +{
      +  "description": "DEPRECATED — read daily_rate_max + currency.",
      +  "type": [
      +    "number",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / rows / items / properties / daily_rate_median_zar
      Added value: +{
      +  "description": "DEPRECATED — read daily_rate_median + currency.",
      +  "type": [
      +    "number",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / rows / items / properties / daily_rate_min_zar
      Added value: +{
      +  "description": "DEPRECATED — read daily_rate_min + currency.",
      +  "type": [
      +    "number",
      +    "null"
      +  ]
      +}
  3. Changed1 schema field changed
    • changedInput schema / properties / specialisation / description
      Previous value: -"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."New value: +"A specialisation code, matched exactly. The live list is `_meta.available_specialisations` on every call — no list is kept here, because a written one went stale. Codes are NOT evenly spread across countries: read the rows a country filter returns. A code this aggregate does not hold (bdc, joule) returns 0 rows and the available codes; it never widens to a neighbouring band. 0 rows here is an absence in THIS aggregate only — see the tool description for what the website's subscriber band covers and where no rate exists at any tier."
  4. Changed5 schema fields changed
    • addedOutput schema / properties / rows / items / properties / client_market
      Added value: +{
      +  "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.",
      +  "type": [
      +    "string",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / rows / items / properties / daily_rate_max_inr
      Added value: +{
      +  "description": "DEPRECATED — read daily_rate_max + currency.",
      +  "type": [
      +    "number",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / rows / items / properties / daily_rate_median_inr
      Added value: +{
      +  "description": "DEPRECATED — read daily_rate_median + currency.",
      +  "type": [
      +    "number",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / rows / items / properties / daily_rate_min_inr
      Added value: +{
      +  "description": "DEPRECATED — read daily_rate_min + currency.",
      +  "type": [
      +    "number",
      +    "null"
      +  ]
      +}
    • changedOutput schema / properties / rows / items / properties / source_type / description
      Previous value: -"primary_agency_guide | primary_job_ads | aggregator | marketing"New value: +"primary_agency_guide | primary_job_ads | primary_salary_survey | aggregator | marketing"
  5. Changed1 schema field changed
    • changedOutput schema / properties / rows / items / properties / indicative / description
      Previous value: -"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 analytics rate of its country."New value: +"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."
  6. Changed21 schema fields changed
    • addedOutput schema / properties / rows / items / properties / accessed
      Added value: +{
      +  "description": "date the source was read (YYYY-MM-DD)",
      +  "type": [
      +    "string",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / rows / items / properties / conversion
      Added value: +{
      +  "description": "how an hourly or monthly source figure was turned into a day rate",
      +  "type": [
      +    "string",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / rows / items / properties / daily_rate_max_aud
      Added value: +{
      +  "description": "DEPRECATED — read daily_rate_max + currency.",
      +  "type": [
      +    "number",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / rows / items / properties / daily_rate_max_hkd
      Added value: +{
      +  "description": "DEPRECATED — read daily_rate_max + currency.",
      +  "type": [
      +    "number",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / rows / items / properties / daily_rate_max_jpy
      Added value: +{
      +  "description": "DEPRECATED — read daily_rate_max + currency.",
      +  "type": [
      +    "number",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / rows / items / properties / daily_rate_max_nzd
      Added value: +{
      +  "description": "DEPRECATED — read daily_rate_max + currency.",
      +  "type": [
      +    "number",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / rows / items / properties / daily_rate_max_sgd
      Added value: +{
      +  "description": "DEPRECATED — read daily_rate_max + currency.",
      +  "type": [
      +    "number",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / rows / items / properties / daily_rate_median_aud
      Added value: +{
      +  "description": "DEPRECATED — read daily_rate_median + currency.",
      +  "type": [
      +    "number",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / rows / items / properties / daily_rate_median_hkd
      Added value: +{
      +  "description": "DEPRECATED — read daily_rate_median + currency.",
      +  "type": [
      +    "number",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / rows / items / properties / daily_rate_median_jpy
      Added value: +{
      +  "description": "DEPRECATED — read daily_rate_median + currency.",
      +  "type": [
      +    "number",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / rows / items / properties / daily_rate_median_nzd
      Added value: +{
      +  "description": "DEPRECATED — read daily_rate_median + currency.",
      +  "type": [
      +    "number",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / rows / items / properties / daily_rate_median_sgd
      Added value: +{
      +  "description": "DEPRECATED — read daily_rate_median + currency.",
      +  "type": [
      +    "number",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / rows / items / properties / daily_rate_min_aud
      Added value: +{
      +  "description": "DEPRECATED — read daily_rate_min + currency.",
      +  "type": [
      +    "number",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / rows / items / properties / daily_rate_min_hkd
      Added value: +{
      +  "description": "DEPRECATED — read daily_rate_min + currency.",
      +  "type": [
      +    "number",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / rows / items / properties / daily_rate_min_jpy
      Added value: +{
      +  "description": "DEPRECATED — read daily_rate_min + currency.",
      +  "type": [
      +    "number",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / rows / items / properties / daily_rate_min_nzd
      Added value: +{
      +  "description": "DEPRECATED — read daily_rate_min + currency.",
      +  "type": [
      +    "number",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / rows / items / properties / daily_rate_min_sgd
      Added value: +{
      +  "description": "DEPRECATED — read daily_rate_min + currency.",
      +  "type": [
      +    "number",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / rows / items / properties / indicative
      Added value: +{
      +  "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 analytics rate of its country.",
      +  "type": [
      +    "boolean",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / rows / items / properties / sap_scope
      Added value: +{
      +  "description": "what the source actually measures: sap_analytics | sap_general | erp_general | bi_non_sap",
      +  "type": [
      +    "string",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / rows / items / properties / source_period
      Added value: +{
      +  "type": [
      +    "string",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / rows / items / properties / source_type
      Added value: +{
      +  "description": "primary_agency_guide | primary_job_ads | aggregator | marketing",
      +  "type": [
      +    "string",
      +    "null"
      +  ]
      +}
  7. Changed26 schema fields changed
    • addedOutput schema / properties / rows / items / properties / basis
      Added value: +{
      +  "description": "external_published_median | external_published_range | panel — see /api/market-rates.json _meta.basis_values.",
      +  "type": [
      +    "string",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / rows / items / properties / confidence
      Added value: +{
      +  "type": [
      +    "string",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / rows / items / properties / currency / description
      Added value: +"ISO-4217 unit of every daily_rate_* amount on THIS row (EUR, GBP, CHF) — never an envelope constant."
    • addedOutput schema / properties / rows / items / properties / daily_rate_max
      Added value: +{
      +  "description": "Upper bound of the published band, in `currency`.",
      +  "type": [
      +    "number",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / rows / items / properties / daily_rate_max_chf
      Added value: +{
      +  "description": "DEPRECATED — read daily_rate_max + currency.",
      +  "type": [
      +    "number",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / rows / items / properties / daily_rate_max_eur
      Added value: +{
      +  "description": "DEPRECATED — read daily_rate_max + currency.",
      +  "type": [
      +    "number",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / rows / items / properties / daily_rate_max_gbp
      Added value: +{
      +  "description": "DEPRECATED — read daily_rate_max + currency.",
      +  "type": [
      +    "number",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / rows / items / properties / daily_rate_median
      Added value: +{
      +  "description": "Median when the source publishes one, in `currency`.",
      +  "type": [
      +    "number",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / rows / items / properties / daily_rate_median_eur
      Added value: +{
      +  "description": "DEPRECATED — read daily_rate_median + currency.",
      +  "type": [
      +    "number",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / rows / items / properties / daily_rate_median_gbp
      Added value: +{
      +  "description": "DEPRECATED — read daily_rate_median + currency.",
      +  "type": [
      +    "number",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / rows / items / properties / daily_rate_min
      Added value: +{
      +  "description": "Lower bound of the published band, in `currency`.",
      +  "type": [
      +    "number",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / rows / items / properties / daily_rate_min_chf
      Added value: +{
      +  "description": "DEPRECATED — read daily_rate_min + currency.",
      +  "type": [
      +    "number",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / rows / items / properties / daily_rate_min_eur
      Added value: +{
      +  "description": "DEPRECATED — read daily_rate_min + currency.",
      +  "type": [
      +    "number",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / rows / items / properties / daily_rate_min_gbp
      Added value: +{
      +  "description": "DEPRECATED — read daily_rate_min + currency.",
      +  "type": [
      +    "number",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / rows / items / properties / daily_rate_p10
      Added value: +{
      +  "description": "10th percentile when the source publishes one, in `currency`.",
      +  "type": [
      +    "number",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / rows / items / properties / daily_rate_p10_gbp
      Added value: +{
      +  "description": "DEPRECATED — read daily_rate_p10 + currency.",
      +  "type": [
      +    "number",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / rows / items / properties / daily_rate_p90
      Added value: +{
      +  "description": "90th percentile when the source publishes one, in `currency`.",
      +  "type": [
      +    "number",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / rows / items / properties / daily_rate_p90_gbp
      Added value: +{
      +  "description": "DEPRECATED — read daily_rate_p90 + currency.",
      +  "type": [
      +    "number",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / rows / items / properties / note
      Added value: +{
      +  "type": [
      +    "string",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / rows / items / properties / sample_basis
      Added value: +{
      +  "description": "What `sample_size` counts (profiles, vacancies…), when the source says.",
      +  "type": [
      +    "string",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / rows / items / properties / sample_size / description
      Added value: +"The sample the SOURCE states behind this row; null when it states none — never estimated."
    • addedOutput schema / properties / rows / items / properties / source
      Added value: +{
      +  "type": [
      +    "string",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / rows / items / properties / source_date
      Added value: +{
      +  "type": [
      +    "string",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / rows / items / properties / source_url
      Added value: +{
      +  "type": [
      +    "string",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / rows / items / properties / trend
      Added value: +{
      +  "type": [
      +    "string",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / rows / items / properties / yoy_change_pct
      Added value: +{
      +  "type": [
      +    "number",
      +    "null"
      +  ]
      +}
  8. Changed1 schema field changed
    • changedInput schema / properties / specialisation / description
      Previous value: -"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 anywhere in the aggregate — the two products this market asks about most are the two it cannot price. A code the aggregate does not hold returns 0 rows and the available codes; it never widens to a neighbouring band."New value: +"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."
  9. Changed1 schema field changed
    • changedInput schema / properties / specialisation / description
      Previous value: -"e.g. datasphere, bdc, sac, bw4hana, joule."New value: +"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 anywhere in the aggregate — the two products this market asks about most are the two it cannot price. A code the aggregate does not hold returns 0 rows and the available codes; it never widens to a neighbouring band."
  10. Changed6 schema fields changed
    • removedOutput schema / properties / rows / items / properties / citation_note
      Removed value: -{
      -  "type": "string"
      -}
    • changedOutput schema / properties / rows / items / properties / country / type
      Previous value: -"string"New value: +[
      +  "string",
      +  "null"
      +]
    • changedOutput schema / properties / rows / items / properties / currency / type
      Previous value: -"string"New value: +[
      +  "string",
      +  "null"
      +]
    • changedOutput schema / properties / rows / items / properties / sample_size / type
      Previous value: -"integer"New value: +[
      +  "integer",
      +  "null"
      +]
    • changedOutput schema / properties / rows / items / properties / seniority / type
      Previous value: -"string"New value: +[
      +  "string",
      +  "null"
      +]
    • changedOutput schema / properties / rows / items / properties / specialisation / type
      Previous value: -"string"New value: +[
      +  "string",
      +  "null"
      +]
  11. Changed3 schema fields changed
    • addedOutput schema / properties / rows / items / properties / citation_note
      Added value: +{
      +  "type": "string"
      +}
    • addedOutput schema / properties / rows / items / properties / citation_scope
      Added value: +{
      +  "enum": [
      +    "record",
      +    "section_hub"
      +  ],
      +  "type": "string"
      +}
    • addedOutput schema / properties / rows / items / properties / citation_url
      Added value: +{
      +  "type": "string"
      +}
  12. Changed1 schema field changed
    • addedOutput schema / properties / rows / items / properties / currency
      Added value: +{
      +  "type": "string"
      +}
  13. First observed

TDQS

A3.7/5.0
Behavior3/5

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

Annotations already declare readOnly, idempotent, openWorld and non-destructive, so safety is covered. The description genuinely adds beyond that: the dataset is small (a few dozen rows), every row is a secondary source, `sample_size` is often null, each amount is in the row's own `currency`, and `_meta.available_*` is recomputed per call. Offset against this, the paragraph about a 'frozen pair' that stood until 2026-08-27 is changelog noise that consumes attention without informing a call.

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

Conciseness2/5

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

Purpose is front-loaded, but the text runs to roughly 500 words for a three-parameter read tool and includes internal meta-commentary (the stale '11 rows on 2026-08-09 … sample_size null on 8 of them' correction, 'NO COUNT IS WRITTEN HERE ON PURPOSE') that does not help an agent invoke the tool. Several sentences repeat the same point about the aggregate not being a paid tier.

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

Completeness4/5

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

An output schema exists, so return-field explanations are unnecessary, and the description still covers what an agent needs to interpret results: per-row currency, confidence, source date, empty-result meaning, and the coverage boundary against the subscriber band. It is more than complete; the remaining deficiency is editorial discipline, not missing information.

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

Parameters3/5

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

Schema coverage is 100%, so the schema already documents all three optional parameters, making 3 the baseline. The description reinforces empty-result semantics and warns that codes are unevenly spread across countries, but that guidance is already largely present in the `specialisation` schema description, so it adds little net meaning.

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

Purpose5/5

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

The opening sentence gives a specific verb+resource: a public day-rate aggregate returning min/max daily rate by country, specialisation and seniority, with named fields. It also explicitly distinguishes itself from the sibling/instrument it is not (`find_opportunities.rate_band` on live postings), so an agent can route between them without opening either schema.

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

Usage Guidelines4/5

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

It names the alternatives and the conditions that select them: community aggregates (v_community_rate_aggregates, v_rate_index) publish nothing yet, and the subscriber rate_band exists only on European radar postings. It even prescribes behaviour when results are empty (say the aggregate holds no row in European regions; say no rate exists at any tier elsewhere). The one gap is that the 'use this tool when a user asks about day rates' framing is implied rather than stated.

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

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.