Skip to main content
Glama

Analytics Legends — SAP AI & Analytics MCP Server

Search the Academy training catalogue

find_academy_modules
Read-onlyIdempotent

Search the Analytics Legends Academy — the written training modules on SAP Datasphere, Business Data Cloud, SAP Analytics Cloud, BW/4HANA and Databricks — by track, level and free text. _meta.tranche_total_row_count carries the live catalogue size on every call; it is the only count to quote. Returns the catalogue entry: id, slug, EN/FR title, track, level, duration in minutes, tags and the editor's summary. DO NOT CONFUSE IT WITH list_sap_modules, which serves a different population under the same word: that one is the 40-row PRODUCT taxonomy (codes such as SAC, DATASPHERE) used to normalise product wording. This one is the course catalogue. Without query, rows come back in the catalogue's own CURRICULUM order — the order a reader is meant to take them in — track by track. This catalogue is written training, NOT SAP certification tracks: this server publishes no certification data at any tier, so a certification question has no answer here rather than a partial one. CATALOGUE ONLY — the module BODY is subscriber content, served by get_academy_module on this same endpoint with a subscriber key (Consultant tier or above), which is the same door the €29.90 Consultant Pass opens on the site. On THIS endpoint the machine-access subscription is the MCP Pass (€39.90/month, analyticslegends.ai/pricing/), which opens the ENTIRE paid tranche from one key; the €29.90 Consultant Pass is its web-subscriber equivalent and opens the same tier floor here. status and is_preview are SERVED, never filtered on: they are the two flags the platform marks free access with, they do not coincide (measured 2026-08-16: 38 rows status='available', 56 rows is_preview), and you decide which one your answer needs. PAGINATED WITH A KEY (a free one is enough): pass _meta.next_cursor back as cursor with the same filters until it is null; without a key, first 10 rows only. Read _meta.available_tracks and _meta.available_levels — both counted on the served population at call time — before assuming a facet value exists.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
levelNoRestrict to one level, matched case-insensitively: Beginner · Intermediate · Advanced · Expert. Counts in `_meta.available_levels`.
limitNoMax rows (hard cap 50).
queryNoFree-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.
trackNoRestrict 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.
cursorNoOpaque 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.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
rowsYes
toolYes
_metaNo
_attributionYes
result_countYes

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changed
    • changedOutput schema / properties / rows / items / properties / status / description
      Previous value: -"Editorial access marker: 'available' or 'legend-pass'. Served, not filtered on."New value: +"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."
  2. Changed1 schema field changed
    • changedInput schema / properties / query / description
      Previous value: -"Free-text filter, matched case-insensitively."New value: +"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."
  3. Changed1 schema field changed
    • changedInput schema / properties / cursor / description
      Previous value: -"Opaque token from a previous response's `_meta.next_cursor`. Pass it back with the SAME filter arguments to read the next page; a null `next_cursor` means you have reached the end. It is bound to those filters and refused if they change — a cursor names a POSITION in one ordering, and applying it to another query would start the page in the wrong place."New value: +"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."
  4. Changed6 schema fields changed
    • addedOutput schema / properties / rows / items / properties / summary_fr
      Added value: +{
      +  "type": [
      +    "string",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / rows / items / properties / tags
      Added value: +{
      +  "items": {
      +    "type": "string"
      +  },
      +  "type": [
      +    "array",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / rows / items / properties / title_fr
      Added value: +{
      +  "type": [
      +    "string",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / rows / items / properties / track_name_en
      Added value: +{
      +  "type": [
      +    "string",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / rows / items / properties / track_name_fr
      Added value: +{
      +  "type": [
      +    "string",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / rows / items / properties / updated_at
      Added value: +{
      +  "type": [
      +    "string",
      +    "null"
      +  ]
      +}
  5. Added

TDQS

A4.7/5.0
Behavior5/5

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

Annotations already declare the safe read-only, idempotent, closed-world profile, and the description adds substantially more: pagination is key-gated (free key gives cursor paging, no key = first 10 rows only), `status`/`is_preview` are served but never filtered on and do not coincide, `_meta.tranche_total_row_count` is the only count to quote, and body access requires a Consultant-tier subscriber key. This is real operational context beyond the annotations.

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

Conciseness3/5

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

Front-loaded with the purpose, but the single block runs long and carries pricing detail (€29.90 Consultant Pass vs €39.90 MCP Pass) that is tangential to invoking the tool, plus repeated emphasis on the catalogue-vs-certification point. Information-dense rather than wasteful, but it does not earn every sentence.

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

Completeness5/5

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

For a 5-parameter, zero-required search tool with an output schema and rich annotations, nothing an agent needs is missing: filtering, ordering semantics, pagination protocol, auth tier, and the meaning of the served flags are all covered. The return-field list is even summarised despite an output schema existing.

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

Parameters4/5

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

Schema coverage is 100%, so the schema already carries the parameter mechanics; the description nonetheless adds value by pointing at the live `_meta.available_tracks`/`available_levels` vocabularies as the source of valid facet values and by explaining that `track_id` is deliberately rejected. It stops short of adding syntax the schema lacks, so it sits just above the 3 baseline.

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

Purpose5/5

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

States a specific verb (search) and resource (the Academy written-training catalogue) and immediately distinguishes itself from the two siblings that share overlapping vocabulary — `list_sap_modules` (the 40-row product taxonomy) and `get_academy_module` (the module body). An agent can route correctly without opening any schema.

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

Usage Guidelines5/5

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

Explicit when-to-use (search the course catalogue by track/level/free text), explicit when-not (certification questions have no answer here, not a partial one; module bodies belong to `get_academy_module`), and names the sibling to use instead for product normalisation. It even tells the agent to read `_meta.available_tracks`/`available_levels` before assuming a facet value exists.

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.