Skip to main content
Glama

Analytics Legends — SAP Analytics Intelligence

Search the SAP AI & analytics firm directory

search_firms
Read-onlyIdempotent

Search the published Analytics Legends directory of SAP AI & analytics service providers — placement agencies, Big-4 and ESN practices, SAP vendors, platforms and community groups — by country, kind, declared SAP module and free text. Returns name, HQ country/city, website, careers URL and a one-line editorial claim. SAP END-CUSTOMER companies are NOT in this directory: they are a separate paid dataset, excluded here by the is_client FLAG — not by the client_enterprise kind code. The two are different columns, and where a row's flag and its kind label disagree in the SSOT it is the flag that decides what this tool serves, so read the flag's meaning into the answer and not the label's. PAGINATED: the whole matched set is reachable — pass _meta.next_cursor back as cursor with the same filters until it is null. When query is set, rows are ordered by how well the NAME matches it (exact, then prefix, then substring), and rows matching only the description come last; without query the order is the directory's own quality ranking.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
kindNoRestrict 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.
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.
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.
moduleNoRestrict 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.
countryNoISO-3166-1 alpha-2 country code, e.g. DE, FR, CH.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
rowsYes
toolYes
_metaNo
_attributionYes
result_countYes

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changed
    • changedInput schema / properties / kind / enum
      Previous value: -[
      -  "agency_placement",
      -  "professional_services_big4",
      -  "professional_services_esn",
      -  "vendor_sap",
      -  "vendor_partner",
      -  "platform_marketplace",
      -  "community_group",
      -  "client_enterprise",
      -  "other"
      -]New value: +[
      +  "agency_placement",
      +  "professional_services_big4",
      +  "professional_services_esn",
      +  "vendor_sap",
      +  "vendor_partner",
      +  "platform_marketplace",
      +  "community_group",
      +  "training_institution",
      +  "client_enterprise",
      +  "other"
      +]
  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. Changed8 schema fields changed
    • addedOutput schema / properties / rows / items / properties / claim
      Added value: +{
      +  "type": [
      +    "string",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / rows / items / properties / founded_year
      Added value: +{
      +  "type": [
      +    "integer",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / rows / items / properties / hq_city
      Added value: +{
      +  "type": [
      +    "string",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / rows / items / properties / jobs_url
      Added value: +{
      +  "type": [
      +    "string",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / rows / items / properties / last_verified_at
      Added value: +{
      +  "type": [
      +    "string",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / rows / items / properties / region
      Added value: +{
      +  "type": [
      +    "string",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / rows / items / properties / sap_signal_band
      Added value: +{
      +  "type": [
      +    "string",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / rows / items / properties / size_bracket
      Added value: +{
      +  "type": [
      +    "string",
      +    "null"
      +  ]
      +}
  5. Changed1 schema field changed
    • addedInput schema / properties / module
      Added value: +{
      +  "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.",
      +  "type": "string"
      +}
  6. Changed1 schema field changed
    • addedInput schema / properties / cursor
      Added value: +{
      +  "description": "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.",
      +  "maxLength": 512,
      +  "type": "string"
      +}
  7. Changed1 schema field changed
    • changedInput schema / properties / kind / description
      Previous value: -"Restrict to one organisation kind. Call list_firm_kinds for live counts. A value outside this list is refused, not silently ignored."New value: +"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."
  8. Changed1 schema field changed
    • changedInput schema / properties / kind / enum
      Previous value: -[
      -  "agency_placement",
      -  "professional_services_big4",
      -  "professional_services_esn",
      -  "vendor_sap",
      -  "vendor_partner",
      -  "platform_marketplace",
      -  "community_group",
      -  "other"
      -]New value: +[
      +  "agency_placement",
      +  "professional_services_big4",
      +  "professional_services_esn",
      +  "vendor_sap",
      +  "vendor_partner",
      +  "platform_marketplace",
      +  "community_group",
      +  "client_enterprise",
      +  "other"
      +]
  9. Changed1 schema field changed
    • changedInput schema / properties / kind / enum
      Previous value: -[
      -  "agency_placement",
      -  "professional_services_big4",
      -  "professional_services_esn",
      -  "vendor_sap",
      -  "vendor_partner",
      -  "platform_marketplace",
      -  "community_group"
      -]New value: +[
      +  "agency_placement",
      +  "professional_services_big4",
      +  "professional_services_esn",
      +  "vendor_sap",
      +  "vendor_partner",
      +  "platform_marketplace",
      +  "community_group",
      +  "other"
      +]
  10. Changed6 schema fields changed
    • removedOutput schema / properties / rows / items / properties / citation_note
      Removed value: -{
      -  "type": "string"
      -}
    • changedOutput schema / properties / rows / items / properties / hq_country / type
      Previous value: -"string"New value: +[
      +  "string",
      +  "null"
      +]
    • changedOutput schema / properties / rows / items / properties / kind / type
      Previous value: -"string"New value: +[
      +  "string",
      +  "null"
      +]
    • changedOutput schema / properties / rows / items / properties / name / type
      Previous value: -"string"New value: +[
      +  "string",
      +  "null"
      +]
    • changedOutput schema / properties / rows / items / properties / slug / type
      Previous value: -"string"New value: +[
      +  "string",
      +  "null"
      +]
    • changedOutput schema / properties / rows / items / properties / website / type
      Previous value: -"string"New value: +[
      +  "string",
      +  "null"
      +]
  11. Changed2 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"
      +}
  12. Changed1 schema field changed
    • changedInput schema / properties / kind / description
      Previous value: -"Restrict to one organisation kind. Call list_firm_kinds for live counts."New value: +"Restrict to one organisation kind. Call list_firm_kinds for live counts. A value outside this list is refused, not silently ignored."
  13. First observed

TDQS

A4.4/5.0
Behavior5/5

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

Annotations already cover the safety profile (readOnly/idempotent/non-destructive), yet the description adds substantial operationally relevant behavior beyond them: full pagination via _meta.next_cursor, cursor refusal when filters change, name-match ordering tiers when `query` is set, and quality ranking otherwise. The flag-vs-kind-code precedence rule for `is_client` is an unusual and genuinely important disclosure.

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

Conciseness4/5

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

Front-loaded with purpose and scope, then pagination and ordering; every sentence carries information. The flag-versus-kind digression is the longest stretch and slightly repetitive ('the two are different columns', 'read the flag's meaning... not the label's'), which keeps it just short of fully tight.

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?

An output schema exists, so return fields need not be spelled out, and the description still covers the essentials an agent needs: inclusion/exclusion boundary, pagination loop, ordering rules, and filter vocabulary sources. Nothing material is missing for a 6-param, optional-only search tool.

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 description coverage is 100%, so every parameter is already documented in the schema, including the cursor, module, kind and query semantics. The description largely restates those (module absence, cursor reuse) and only the query ordering tiers add meaning beyond the schema. Baseline 3 is appropriate when the schema does the heavy lifting.

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 and resource ('Search the published Analytics Legends directory of SAP AI & analytics service providers') and enumerates the entity kinds it covers. It also carves out the boundary against the end-customer dataset, so an agent can distinguish it from find_sap_clients/get_sap_client_profile without opening another 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?

Gives clear usage context: what is included, what is excluded (SAP end-customers live in a separate paid dataset), and routes the agent to count_firms_by for live module vocabulary and list_firm_kinds for kinds. It stops short of naming the sibling tool that serves the excluded end-customers, leaving that inference to the agent.

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.