Skip to main content
Glama

Customer Intelligence & Segmentation

Score Customer Book (A/B/C/D)

customer_tiering
Read-only

Scores a customer book of 500 transaction rows OR FEWER into A/B/C/D tiers. Send the rows directly; this server runs the survival model (BG/NBD), spend model (Gamma-Gamma), tier migration, money layer and decision cards, and returns the full result including a per-customer ledger with explanation traces. For books LARGER than 500 rows use customer_tiering_get_engine instead — sending thousands of rows as tool arguments is slow and risks truncated JSON. Optionally accepts rep_contacts, which lets the money layer learn contact uplift from data rather than assuming it. Customer identifiers are CLEANED HERE before scoring: capitalisation, spacing, punctuation, legal-suffix and word-order variants (ACME PVT LTD / Acme Pvt. Ltd. / Acme Private Limited) are merged into one account by rule, so send the values exactly as they appear in the source and do not pre-normalise them. Anything that needs context instead of rules — 'Acme & Co' vs 'Acme Pvt Ltd', a name under two codes — comes back in identity_cleaning.review_candidates, unmerged, for you to judge from the surrounding rows and re-send via identity_overrides. Pass customer_name alongside a coded customer_id to have accounts reported by name.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
as_ofNoAnalysis date YYYY-MM-DD. Defaults to latest transaction date.
currencyNoISO currency code for money display (e.g. INR, USD, EUR). No FX conversion.USD
rep_contactsNoOptional rep-activity log [{customer_id, date}, ...]. Builds touched vs untouched Markov matrices and learns contact uplift per tier (≥ 10 touched transitions). Observational, not causal.
transactionsYesPurchase rows. Each item needs customer_id, date, and amount (> 0, finite). Send customer_id exactly as the source has it: capitalisation, spacing, punctuation, legal-suffix and word-order variants are merged here by rule. Do not pre-normalise. Add customer_name when the source has a name as well as a code.
horizon_monthsNoCLV projection horizon in months.
currency_symbolNoOverride display symbol (e.g. ₹, $, R$).
identity_overridesNoYour judgement calls on the review_candidates a previous call reported: {raw or reported customer value -> the account it belongs to}. Spelling variants are merged automatically and need no entry here; use this only for groups the rules deliberately left separate, and only after reading the surrounding rows or asking the user.
risk_period_monthsNoWindow over which neglect churn risk is assessed.
include_diagnosticsNoIf true, include MLE params and multi-start fit diagnostics.
rep_queue_max_itemsNoMax length of the daily SAVE/GROW/VERIFY rep queue.
annual_discount_rateNoAnnual discount rate for CLV (e.g. 0.10 = 10%).
assumed_upgrade_probNoFallback P(upgrade | contacted). Used only when learned data from rep_contacts is insufficient for that tier.
contact_effectivenessNoFallback fraction of at-risk churn recovered by one contact. Used only when rep_contacts is missing or too sparse for that tier.
min_customers_for_modelNoBelow this count, BG/NBD refuses to fit.
rep_queue_min_save_revenueNoIgnore SAVE candidates with lifetime revenue below this.
min_repeat_buyers_for_modelNoBelow this repeat-buyer count, BG/NBD refuses to fit.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
alertsNoList from the upstream customer tiering API.
statusYes1 = success, 0 = error
messageNo
metadataNoUpstream customer tiering API payload.
customersYesList from the upstream customer tiering API.
decisionsYesRanked plain-language manager cards (CALL NOW / GROW / CHECK). Money, days, account names only — no P(alive) / CLV / RFM jargon.
rep_queueYes
book_summaryNoUpstream customer tiering API payload.
book_exposureNo
uplift_targetsNoList from the upstream customer tiering API.
migration_modelNo
identity_cleaningYesWhat the server did to the customer identifiers before scoring: which spelling variants it merged by rule, which groups it deliberately left separate for YOU to rule on (review_candidates — read the rows and decide, then re-run with identity_overrides), how names were chosen for display, and the counts before and after. Always relay the merges and the open questions; the tiers depend on them.
money_assumptionsNo
data_quality_reportNoUpstream customer tiering API payload.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed25 schema fields changed
    • addedInput schema / additionalProperties
      Added value: +false
    • changedInput schema / properties / as_of / description
      Previous value: -"Analysis date YYYY-MM-DD. Defaults to latest transaction date. Example: 2025-12-31."New value: +"Analysis date YYYY-MM-DD. Defaults to latest transaction date."
    • addedInput schema / properties / as_of / examples
      Added value: +[
      +  "2025-12-31"
      +]
    • addedInput schema / properties / currency / examples
      Added value: +[
      +  "INR",
      +  "USD",
      +  "EUR"
      +]
    • addedInput schema / properties / currency_symbol / examples
      Added value: +[
      +  "₹",
      +  "$"
      +]
    • addedInput schema / properties / identity_overrides / additionalProperties
      Added value: +{
      +  "type": "string"
      +}
    • removedInput schema / properties / identity_overrides / items
      Removed value: -{
      -  "properties": {
      -    "from_value": {
      -      "type": "string"
      -    },
      -    "to_account": {
      -      "type": "string"
      -    }
      -  },
      -  "required": [
      -    "from_value",
      -    "to_account"
      -  ],
      -  "type": "object"
      -}
    • changedInput schema / properties / identity_overrides / type
      Previous value: -"array"New value: +"object"
    • addedInput schema / properties / rep_contacts / items / additionalProperties
      Added value: +false
    • changedInput schema / properties / rep_contacts / items / properties / customer_id / description
      Previous value: -"Must match a customer in transactions. Numeric codes must be sent as strings."New value: +"Must match a customer in transactions."
    • changedInput schema / properties / rep_contacts / items / properties / customer_id / type
      Previous value: -"string"New value: +[
      +  "string",
      +  "number"
      +]
    • addedInput schema / properties / transactions / items / additionalProperties
      Added value: +false
    • addedInput schema / properties / transactions / items / properties / amount / exclusiveMinimum
      Added value: +0
    • removedInput schema / properties / transactions / items / properties / amount / minimum
      Removed value: -0
    • changedInput schema / properties / transactions / items / properties / customer_id / description
      Previous value: -"Customer identifier exactly as the source has it. Spelling, case, spacing and legal-suffix variants are merged server-side before scoring; do not normalise it yourself. Numeric codes must be sent as strings."New value: +"Customer identifier exactly as the source has it. Spelling, case, spacing and legal-suffix variants are merged server-side before scoring; do not normalise it yourself."
    • changedInput schema / properties / transactions / items / properties / customer_id / type
      Previous value: -"string"New value: +[
      +  "string",
      +  "number"
      +]
    • addedOutput schema / properties / book_exposure / anyOf
      Added value: +[
      +  {
      +    "additionalProperties": true,
      +    "type": "object"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • removedOutput schema / properties / book_exposure / type
      Removed value: -"object"
    • changedOutput schema / properties / message / type
      Previous value: -"string"New value: +[
      +  "string",
      +  "null"
      +]
    • addedOutput schema / properties / migration_model / anyOf
      Added value: +[
      +  {
      +    "additionalProperties": true,
      +    "type": "object"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • removedOutput schema / properties / migration_model / type
      Removed value: -"object"
    • addedOutput schema / properties / money_assumptions / anyOf
      Added value: +[
      +  {
      +    "additionalProperties": true,
      +    "type": "object"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • removedOutput schema / properties / money_assumptions / type
      Removed value: -"object"
    • addedOutput schema / properties / rep_queue / anyOf
      Added value: +[
      +  {
      +    "additionalProperties": true,
      +    "type": "object"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • removedOutput schema / properties / rep_queue / type
      Removed value: -"object"
  2. Changed25 schema fields changed
    • removedInput schema / additionalProperties
      Removed value: -false
    • changedInput schema / properties / as_of / description
      Previous value: -"Analysis date YYYY-MM-DD. Defaults to latest transaction date."New value: +"Analysis date YYYY-MM-DD. Defaults to latest transaction date. Example: 2025-12-31."
    • removedInput schema / properties / as_of / examples
      Removed value: -[
      -  "2025-12-31"
      -]
    • removedInput schema / properties / currency / examples
      Removed value: -[
      -  "INR",
      -  "USD",
      -  "EUR"
      -]
    • removedInput schema / properties / currency_symbol / examples
      Removed value: -[
      -  "₹",
      -  "$"
      -]
    • removedInput schema / properties / identity_overrides / additionalProperties
      Removed value: -{
      -  "type": "string"
      -}
    • addedInput schema / properties / identity_overrides / items
      Added value: +{
      +  "properties": {
      +    "from_value": {
      +      "type": "string"
      +    },
      +    "to_account": {
      +      "type": "string"
      +    }
      +  },
      +  "required": [
      +    "from_value",
      +    "to_account"
      +  ],
      +  "type": "object"
      +}
    • changedInput schema / properties / identity_overrides / type
      Previous value: -"object"New value: +"array"
    • removedInput schema / properties / rep_contacts / items / additionalProperties
      Removed value: -false
    • changedInput schema / properties / rep_contacts / items / properties / customer_id / description
      Previous value: -"Must match a customer in transactions."New value: +"Must match a customer in transactions. Numeric codes must be sent as strings."
    • changedInput schema / properties / rep_contacts / items / properties / customer_id / type
      Previous value: -[
      -  "string",
      -  "number"
      -]New value: +"string"
    • removedInput schema / properties / transactions / items / additionalProperties
      Removed value: -false
    • removedInput schema / properties / transactions / items / properties / amount / exclusiveMinimum
      Removed value: -0
    • addedInput schema / properties / transactions / items / properties / amount / minimum
      Added value: +0
    • changedInput schema / properties / transactions / items / properties / customer_id / description
      Previous value: -"Customer identifier exactly as the source has it. Spelling, case, spacing and legal-suffix variants are merged server-side before scoring; do not normalise it yourself."New value: +"Customer identifier exactly as the source has it. Spelling, case, spacing and legal-suffix variants are merged server-side before scoring; do not normalise it yourself. Numeric codes must be sent as strings."
    • changedInput schema / properties / transactions / items / properties / customer_id / type
      Previous value: -[
      -  "string",
      -  "number"
      -]New value: +"string"
    • removedOutput schema / properties / book_exposure / anyOf
      Removed value: -[
      -  {
      -    "additionalProperties": true,
      -    "type": "object"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedOutput schema / properties / book_exposure / type
      Added value: +"object"
    • changedOutput schema / properties / message / type
      Previous value: -[
      -  "string",
      -  "null"
      -]New value: +"string"
    • removedOutput schema / properties / migration_model / anyOf
      Removed value: -[
      -  {
      -    "additionalProperties": true,
      -    "type": "object"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedOutput schema / properties / migration_model / type
      Added value: +"object"
    • removedOutput schema / properties / money_assumptions / anyOf
      Removed value: -[
      -  {
      -    "additionalProperties": true,
      -    "type": "object"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedOutput schema / properties / money_assumptions / type
      Added value: +"object"
    • removedOutput schema / properties / rep_queue / anyOf
      Removed value: -[
      -  {
      -    "additionalProperties": true,
      -    "type": "object"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedOutput schema / properties / rep_queue / type
      Added value: +"object"
  3. Changed6 schema fields changed
    • addedInput schema / properties / identity_overrides
      Added value: +{
      +  "additionalProperties": {
      +    "type": "string"
      +  },
      +  "description": "Your judgement calls on the review_candidates a previous call reported: {raw or reported customer value -> the account it belongs to}. Spelling variants are merged automatically and need no entry here; use this only for groups the rules deliberately left separate, and only after reading the surrounding rows or asking the user.",
      +  "type": "object"
      +}
    • changedInput schema / properties / transactions / description
      Previous value: -"Raw purchase rows. Each item needs customer_id, date, and amount (> 0, finite)."New value: +"Purchase rows. Each item needs customer_id, date, and amount (> 0, finite). Send customer_id exactly as the source has it: capitalisation, spacing, punctuation, legal-suffix and word-order variants are merged here by rule. Do not pre-normalise. Add customer_name when the source has a name as well as a code."
    • changedInput schema / properties / transactions / items / properties / customer_id / description
      Previous value: -"Stable customer identifier."New value: +"Customer identifier exactly as the source has it. Spelling, case, spacing and legal-suffix variants are merged server-side before scoring; do not normalise it yourself."
    • addedInput schema / properties / transactions / items / properties / customer_name
      Added value: +{
      +  "description": "Optional readable name for this account, when customer_id is a code. Used only to label the account in the result — grouping still happens on customer_id. Send it whenever the source has both, so the answer names accounts the way the user does.",
      +  "type": "string"
      +}
    • addedOutput schema / properties / identity_cleaning
      Added value: +{
      +  "additionalProperties": true,
      +  "description": "What the server did to the customer identifiers before scoring: which spelling variants it merged by rule, which groups it deliberately left separate for YOU to rule on (review_candidates — read the rows and decide, then re-run with identity_overrides), how names were chosen for display, and the counts before and after. Always relay the merges and the open questions; the tiers depend on them.",
      +  "type": "object"
      +}
    • changedOutput schema / required
      Previous value: -[
      -  "status",
      -  "decisions",
      -  "customers",
      -  "rep_queue"
      -]New value: +[
      +  "status",
      +  "decisions",
      +  "customers",
      +  "rep_queue",
      +  "identity_cleaning"
      +]
  4. First observed

TDQS

A4.8/5.0
Behavior5/5

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

Annotations already declare readOnlyHint=true and destructiveHint=false, and the description adds substantial behavioral context beyond that: ID variants are merged server-side by rule, ambiguous identities are surfaced unmerged in review_candidates, rep_contacts learning is 'observational, not causal', and full result includes per-customer ledgers with explanation traces. No contradiction with annotations.

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?

The description is long but every paragraph earns its place: core action, size limit and sibling routing, optional rep_contacts, and the identity-cleaning workflow are all present. Some instructions repeat the schema (e.g., 'do not pre-normalise'), but the repetition is intentional emphasis rather than filler.

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 tool with 16 parameters, nested objects, and an output schema, the description is unusually complete. It covers the pipeline, the boundary condition for the sibling tool, the identity-cleaning model the agent must understand, and where ambiguous cases surface. The output schema covers return values, so further return-format detail is unnecessary.

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 baseline is 3. The description adds meaningful semantics for key parameters: rep_contacts learns uplift from data rather than assuming it, transaction customer_id must be sent exactly as sourced without pre-normalisation, customer_name is only for reporting labels, and identity_overrides is for judgement calls on review_candidates. This elevates it above 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?

The description opens with a specific verb and resource: 'Scores a customer book of 500 transaction rows OR FEWER into A/B/C/D tiers.' It names the exact models run and what is returned (per-customer ledger with explanation traces), and it clearly distinguishes itself from the sibling by the 500-row boundary.

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 guidance is present: 'For books LARGER than 500 rows use customer_tiering_get_engine instead — sending thousands of rows as tool arguments is slow and risks truncated JSON.' It also tells agents not to pre-normalise identifiers and to use identity_overrides only after judging review_candidates, which prevents misuse.

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.

Resources