Skip to main content
Glama

Save Referral settings

save_referral
Destructive

PARTIAL SAVE: writes ONLY the 'Referral' field of TitlePublicConfigurationModel; all other v1/v2 fields stay untouched. Referral / invite system configuration — invite codes, attribution rules, milestones (e.g. invite N friends → reward), per-side rewards (inviter + invitee). Reward bundles reference Reward.

Input Schema

NameRequiredDescriptionDefault
valueYesTitle's referral system configuration. Stored in TitlePublicConfigurationModel.ReferralDefinitions.
title_idYesTitleID, для которого сохраняются данные.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed12 schema fields changed
    • addedInput schema / definitions / ClientPlatform
      Added value: +{
      +  "description": "",
      +  "enum": [
      +    "Unknown",
      +    "Web",
      +    "Android",
      +    "Ios"
      +  ],
      +  "type": "string",
      +  "x-enum-descriptions": [
      +    "Platform was not reported, or the reported one contradicts the request fingerprint.",
      +    "Browser: web build, WebGL, or a messenger mini-app.",
      +    "Android build (Google Play Billing).",
      +    "iOS / iPadOS build (App Store, StoreKit)."
      +  ],
      +  "x-enumNames": [
      +    "Unknown",
      +    "Web",
      +    "Android",
      +    "Ios"
      +  ]
      +}
    • addedInput schema / definitions / ExperimentVariantCondition
      Added value: +{
      +  "description": "Experiment-variant membership condition — embedded in SegmentGate.Experiment. The gate passes if the player is assigned to one of Variants of experiment ExperimentID (empty list = just enrolled). A/B variants thus reuse the whole SegmentGate stack: make two configs (offer A, offer B), each gated to its variant.",
      +  "properties": {
      +    "ExperimentID": {
      +      "description": "Experiment ID whose assignment is checked.",
      +      "type": [
      +        "null",
      +        "string"
      +      ]
      +    },
      +    "Variants": {
      +      "description": "Allowed variants (any-of). Empty = being assigned to any variant is enough (enrolled). A player with no assignment for this experiment does NOT pass.",
      +      "items": {
      +        "type": "string"
      +      },
      +      "type": [
      +        "array",
      +        "null"
      +      ]
      +    }
      +  },
      +  "type": "object"
      +}
    • addedInput schema / definitions / ReferralCondition
      Added value: +{
      +  "description": "One invite qualification condition. Which fields are used depends on Type.",
      +  "properties": {
      +    "Balance": {
      +      "description": "CryptoBalance: token balance requirement, same shape as a play-access token gate (CurrencyID, NetworkID, MinBalance, BalanceSource OnChain/Combined/InGame). OnChain/Combined need a signature-verified wallet and are checked on login, refresh and Referral/CheckQualification.",
      +      "oneOf": [
      +        {
      +          "type": "null"
      +        },
      +        {
      +          "$ref": "#/definitions/WalletPlayTokenGate"
      +        }
      +      ]
      +    },
      +    "CurrencyID": {
      +      "description": "CryptoDeposited: crypto currency id (cfg.Currency.CryptoCurrencies) deposited into the game.",
      +      "type": [
      +        "null",
      +        "string"
      +      ]
      +    },
      +    "MinAmount": {
      +      "description": "CryptoDeposited: minimum total deposited, in whole tokens, over the player's lifetime.",
      +      "format": "decimal",
      +      "type": "number"
      +    },
      +    "MinValue": {
      +      "description": "Threshold for AccountAgeHours, Sessions, ActiveDays and PlayTimeMinutes.",
      +      "format": "int64",
      +      "type": "integer"
      +    },
      +    "QuestID": {
      +      "description": "QuestCompleted: quest id that must be completed (or claimed).",
      +      "type": [
      +        "null",
      +        "string"
      +      ]
      +    },
      +    "Segment": {
      +      "description": "Segment: audience gate the player must pass (level, premium, country, tutorial, platform).",
      +      "oneOf": [
      +        {
      +          "type": "null"
      +        },
      +        {
      +          "$ref": "#/definitions/SegmentGate"
      +        }
      +      ]
      +    },
      +    "Type": {
      +      "description": "Condition kind: NotGuest, AccountAgeHours, Sessions, ActiveDays, PlayTimeMinutes, Segment, QuestCompleted, WalletLinked, CryptoDeposited, CryptoBalance.",
      +      "oneOf": [
      +        {
      +          "$ref": "#/definitions/ReferralConditionType"
      +        }
      +      ]
      +    }
      +  },
      +  "type": "object"
      +}
    • addedInput schema / definitions / ReferralConditionGroup
      Added value: +{
      +  "description": "One group of conditions: all of them must be met.",
      +  "properties": {
      +    "Conditions": {
      +      "description": "Conditions of the group (AND).",
      +      "items": {
      +        "$ref": "#/definitions/ReferralCondition"
      +      },
      +      "type": [
      +        "array",
      +        "null"
      +      ]
      +    },
      +    "GroupID": {
      +      "description": "Optional group id for the UI.",
      +      "type": [
      +        "null",
      +        "string"
      +      ]
      +    }
      +  },
      +  "type": "object"
      +}
    • addedInput schema / definitions / ReferralConditionType
      Added value: +{
      +  "description": "",
      +  "enum": [
      +    "NotGuest",
      +    "AccountAgeHours",
      +    "Sessions",
      +    "ActiveDays",
      +    "PlayTimeMinutes",
      +    "Segment",
      +    "QuestCompleted",
      +    "WalletLinked",
      +    "CryptoDeposited",
      +    "CryptoBalance"
      +  ],
      +  "type": "string",
      +  "x-enumNames": [
      +    "NotGuest",
      +    "AccountAgeHours",
      +    "Sessions",
      +    "ActiveDays",
      +    "PlayTimeMinutes",
      +    "Segment",
      +    "QuestCompleted",
      +    "WalletLinked",
      +    "CryptoDeposited",
      +    "CryptoBalance"
      +  ]
      +}
    • addedInput schema / definitions / ReferralQualificationDefinition
      Added value: +{
      +  "description": "Invite qualification: the invite counts when ANY group is met; a group is met when ALL its conditions are met.",
      +  "properties": {
      +    "Enabled": {
      +      "description": "Whether the conditions apply. False = invites count immediately.",
      +      "type": "boolean"
      +    },
      +    "Groups": {
      +      "description": "Alternative groups of conditions (OR between groups, AND inside a group).",
      +      "items": {
      +        "$ref": "#/definitions/ReferralConditionGroup"
      +      },
      +      "type": [
      +        "array",
      +        "null"
      +      ]
      +    }
      +  },
      +  "type": "object"
      +}
    • addedInput schema / definitions / SegmentGate
      Added value: +{
      +  "description": "Unified \"who it is available/applies to\" gate. Replaces BoostSegmentGate (TimedBoost), MailboxSegmentDefinition filters and StoreOfferRules premium fields. All conditions are AND-ed. An empty/unset field = no constraint on that axis; an empty/null gate = available to everyone. Resolved by SegmentGateEvaluator.Passes.",
      +  "properties": {
      +    "ActiveWithinDays": {
      +      "description": "Active within the last X days (matches Usage.LastActiveAt). 0 = no restriction.",
      +      "format": "int32",
      +      "type": "integer"
      +    },
      +    "Countries": {
      +      "description": "Country filter (ISO 3166-1 alpha-2; matches PublicData.Country, else RegistrationCountry). Empty = all countries.",
      +      "items": {
      +        "type": "string"
      +      },
      +      "type": [
      +        "array",
      +        "null"
      +      ]
      +    },
      +    "Experiment": {
      +      "description": "A/B experiment condition: the gate passes only if the player is assigned to the required variant (ExperimentVariantCondition). null = not applied. A/B variants thus reuse the whole SegmentGate stack: two configs, each gated to its variant. Assignment is read from UserDataDocument.Experiments (sticky, stable-hash — see ExperimentAssigner).",
      +      "oneOf": [
      +        {
      +          "type": "null"
      +        },
      +        {
      +          "$ref": "#/definitions/ExperimentVariantCondition"
      +        }
      +      ]
      +    },
      +    "MaxLevel": {
      +      "description": "Maximum Board Rank. 0 = no upper bound.",
      +      "format": "int64",
      +      "type": "integer"
      +    },
      +    "MinLevel": {
      +      "description": "Minimum Board Rank (matches PublicData.BoardRank). 0 = no lower bound.",
      +      "format": "int64",
      +      "type": "integer"
      +    },
      +    "MinPremiumTier": {
      +      "description": "Minimum active premium tier (matches Premium.MaxActiveTier). 0 = no requirement.",
      +      "format": "int32",
      +      "type": "integer"
      +    },
      +    "Platforms": {
      +      "description": "Platforms the entity is available on. Empty/null = all. Unlike the other axes this one comes from the request platform (IGSService.ClientPlatform), not from the player document, and is passed to SegmentGateEvaluator.Passes as a separate REQUIRED argument. The axis is skipped when the platform is Unknown — deliberately soft, because it governs what is shown, not what is charged: payments are guarded by PriceOptionSelector.IsAvailableOn, where Unknown does not pass a non-empty platform list. Not needed to hide entities that simply cannot be paid for on a platform: storefronts already drop whatever has no available price option.",
      +      "items": {
      +        "$ref": "#/definitions/ClientPlatform"
      +      },
      +      "type": [
      +        "array",
      +        "null"
      +      ]
      +    },
      +    "RegisteredWithinDays": {
      +      "description": "Registered no earlier than X days ago (new players; matches RegistrationDate). 0 = no restriction.",
      +      "format": "int32",
      +      "type": "integer"
      +    },
      +    "RequiredPremiumIDs": {
      +      "description": "Required active premium IDs (ANY of the list is enough, via PremiumHelpers.GetActivePremiumIDs). Empty = no requirement.",
      +      "items": {
      +        "type": "string"
      +      },
      +      "type": [
      +        "array",
      +        "null"
      +      ]
      +    },
      +    "Segments": {
      +      "description": "Allowed economy segments (matches PlayerEconomyTuningState.Segment: \"F2P\",\"Dolphin\",\"Whale\",\"VIP\"). Empty = any.",
      +      "items": {
      +        "type": "string"
      +      },
      +      "type": [
      +        "array",
      +        "null"
      +      ]
      +    },
      +    "Tutorial": {
      +      "description": "Tutorial condition: the gate passes only if the player is in the required progression state (TutorialGateCondition). null = not applied. By the same trick as Experiment, this gives \"after onboarding\" gating in every module already using SegmentGate, with no edits to them. To close a whole module there is a cheaper path — TutorialGlobalSettings.Blocking: one check in ClientRun instead of a condition on every entity.",
      +      "oneOf": [
      +        {
      +          "type": "null"
      +        },
      +        {
      +          "$ref": "#/definitions/TutorialGateCondition"
      +        }
      +      ]
      +    }
      +  },
      +  "type": "object"
      +}
    • addedInput schema / definitions / TutorialGateCondition
      Added value: +{
      +  "description": "\"The player finished the tutorial\" condition — embedded in SegmentGate.Tutorial exactly as ExperimentVariantCondition is embedded in SegmentGate.Experiment. Thanks to that, tutorial gating works for free in EVERY module already using SegmentGate (Store / DealOffer / Quest / Reward / Leaderboard / ...). This is the per-entity gating level; to close a whole module use TutorialBlockingPolicy, which is cheaper.",
      +  "properties": {
      +    "FlowIDs": {
      +      "description": "Flows whose state is checked. Empty = the condition is not applied (the gate passes). Multiple entries are AND-ed: \"after the intro AND after the raid tutorial\".",
      +      "items": {
      +        "type": "string"
      +      },
      +      "type": [
      +        "array",
      +        "null"
      +      ]
      +    },
      +    "Mode": {
      +      "description": "What exactly must hold for those flows. Default Completed.",
      +      "oneOf": [
      +        {
      +          "$ref": "#/definitions/TutorialGateMode"
      +        }
      +      ]
      +    },
      +    "Negate": {
      +      "description": "Invert the condition. Needed for the reverse case — \"show this starter offer ONLY to players still in the tutorial\". Default false.",
      +      "type": "boolean"
      +    },
      +    "SkippedCountsAsCompleted": {
      +      "description": "Whether a Skipped flow counts as finished under Mode = Completed. Default true: if the publisher allowed skipping, the skipper must get the same game as the completer.",
      +      "type": "boolean"
      +    },
      +    "StepID": {
      +      "description": "The step that must be reached. Read only when Mode = StepReached, and applied to every flow in FlowIDs.",
      +      "type": [
      +        "null",
      +        "string"
      +      ]
      +    }
      +  },
      +  "type": "object"
      +}
    • addedInput schema / definitions / TutorialGateMode
      Added value: +{
      +  "description": "",
      +  "enum": [
      +    "Completed",
      +    "Started",
      +    "StepReached"
      +  ],
      +  "type": "string",
      +  "x-enum-descriptions": [
      +    "The flow is finished. Default.",
      +    "The flow is started (in progress or already finished).",
      +    "A specific step has been reached (TutorialGateCondition.StepID)."
      +  ],
      +  "x-enumNames": [
      +    "Completed",
      +    "Started",
      +    "StepReached"
      +  ]
      +}
    • addedInput schema / definitions / WalletGateBalanceSource
      Added value: +{
      +  "description": "",
      +  "enum": [
      +    "OnChain",
      +    "Combined",
      +    "InGame"
      +  ],
      +  "type": "string",
      +  "x-enumNames": [
      +    "OnChain",
      +    "Combined",
      +    "InGame"
      +  ]
      +}
    • addedInput schema / definitions / WalletPlayTokenGate
      Added value: +{
      +  "description": "One wallet-balance requirement for play access. Token contract and on-chain decimals are resolved from CryptoCurrencyDefinition.Networks by (CurrencyID, NetworkID), not duplicated here.",
      +  "properties": {
      +    "BalanceSource": {
      +      "description": "Where to read the balance compared against MinBalance: OnChain (wallet balance via RPC only), Combined (on-chain + in-game available balance InventoryV2.CryptoCurrencies[CurrencyID].Amount, excluding Frozen), InGame (in-game available balance only; no wallet, no RPC, NetworkID ignored). Default OnChain.",
      +      "oneOf": [
      +        {
      +          "$ref": "#/definitions/WalletGateBalanceSource"
      +        }
      +      ]
      +    },
      +    "CurrencyID": {
      +      "description": "CurrencyID (cfg.Currency.CryptoCurrencies) whose balance is checked. Its binding for NetworkID provides ContractAddress (mint for Solana) and Decimals.",
      +      "type": [
      +        "null",
      +        "string"
      +      ]
      +    },
      +    "DenyMessage": {
      +      "description": "Optional custom denial message shown to the client (otherwise a default text is used).",
      +      "type": [
      +        "null",
      +        "string"
      +      ]
      +    },
      +    "Enabled": {
      +      "description": "Whether the requirement is active. False skips this gate (does not block).",
      +      "type": "boolean"
      +    },
      +    "MinBalance": {
      +      "description": "Minimum balance in whole units (e.g. 1000 = 1000 game tokens).",
      +      "format": "decimal",
      +      "type": "number"
      +    },
      +    "NetworkID": {
      +      "description": "Network this gate applies to (key from Blockchain.Networks).",
      +      "type": [
      +        "null",
      +        "string"
      +      ]
      +    }
      +  },
      +  "type": "object"
      +}
    • addedInput schema / properties / value / properties / Qualification
      Added value: +{
      +  "description": "Conditions an invited player must meet before the invite counts (anti-farming, and invite leaderboards that count only real players). Until met, everything waits: the referrer's +1 (invite milestones), ReferralInvite event tokens and leaderboard points, the spend kickback and the invitee's activation reward. No deadline. Null or disabled = the invite counts immediately on binding.",
      +  "oneOf": [
      +    {
      +      "type": "null"
      +    },
      +    {
      +      "$ref": "#/definitions/ReferralQualificationDefinition"
      +    }
      +  ]
      +}
  2. Changed3 schema fields changed
    • changedInput schema / definitions / ResourceEntryType / enum
      Previous value: -[
      -  "Item",
      -  "VirtualCurrency",
      -  "CryptoCurrency",
      -  "Purchase",
      -  "RewardedVideoCredit",
      -  "PlatformCoin"
      -]New value: +[
      +  "Item",
      +  "VirtualCurrency",
      +  "CryptoCurrency",
      +  "Purchase",
      +  "RewardedVideoCredit",
      +  "PlatformCredits"
      +]
    • changedInput schema / definitions / ResourceEntryType / x-enum-descriptions
      Previous value: -[
      -  "Catalog item. Requires CatalogID, ItemID and Amount.",
      -  "In-game (off-chain) virtual currency. Requires CurrencyID and Amount. Looked up in cfg.Currency.VirtualCurrencies.",
      -  "On-chain cryptocurrency. Requires CurrencyID and Amount. Looked up in cfg.Currency.CryptoCurrencies.",
      -  "Real-money payment in a store. Requires only ProductID (a product from cfg.Purchase.Products); the amount and currency are decided by the store from the SKU price tier. NOT a storable resource and never passes through ResourceService — the money is paid outside before the server learns about it, so the entry is consumed by the receipt check (ExternalPaymentGate) and stripped before the resource operation. Allowed only in Consume and only for Consumable products.",
      -  "Rewarded-video credit. One credit equals one verified ad view that can be spent in systems requiring rewarded video (lootbox open, reward double, re-roll, booster). Granted +1 per server-verified view, or as N from milestones/quests/premium perks; spent -1 per gated action.",
      -  "Payment in Coin, the PLATFORM currency on the player's iDos Games account. Requires only Amount — the price in whole Coin. Like Purchase it is NOT a player resource and never enters ResourceService: it is settled by PlatformCoinPayment in the same transaction as the grant (buyer charged, author credited). Accepted only by the store (Store.Purchase) for now; allowed only in Consume."
      -]New value: +[
      +  "Catalog item. Requires CatalogID, ItemID and Amount.",
      +  "In-game (off-chain) virtual currency. Requires CurrencyID and Amount. Looked up in cfg.Currency.VirtualCurrencies.",
      +  "On-chain cryptocurrency. Requires CurrencyID and Amount. Looked up in cfg.Currency.CryptoCurrencies.",
      +  "Real-money payment in a store. Requires only ProductID (a product from cfg.Purchase.Products); the amount and currency are decided by the store from the SKU price tier. NOT a storable resource and never passes through ResourceService — the money is paid outside before the server learns about it, so the entry is consumed by the receipt check (ExternalPaymentGate) and stripped before the resource operation. Allowed only in Consume and only for Consumable products.",
      +  "Rewarded-video credit. One credit equals one verified ad view that can be spent in systems requiring rewarded video (lootbox open, reward double, re-roll, booster). Granted +1 per server-verified view, or as N from milestones/quests/premium perks; spent -1 per gated action.",
      +  "Payment in Credits, the PLATFORM currency on the player's iDos Games account (players see it as \"Aspis\" — write Aspis in player-facing text). Requires only Amount — the price in whole Credits. Like Purchase it is NOT a player resource and never enters ResourceService: it is settled by PlatformCreditsPayment in the same transaction as the grant (buyer charged, author credited). Accepted only by the store (Store.Purchase) for now; allowed only in Consume."
      +]
    • changedInput schema / definitions / ResourceEntryType / x-enumNames
      Previous value: -[
      -  "Item",
      -  "VirtualCurrency",
      -  "CryptoCurrency",
      -  "Purchase",
      -  "RewardedVideoCredit",
      -  "PlatformCoin"
      -]New value: +[
      +  "Item",
      +  "VirtualCurrency",
      +  "CryptoCurrency",
      +  "Purchase",
      +  "RewardedVideoCredit",
      +  "PlatformCredits"
      +]
  3. Changed3 schema fields changed
    • changedInput schema / definitions / ResourceEntryType / enum
      Previous value: -[
      -  "Item",
      -  "VirtualCurrency",
      -  "CryptoCurrency",
      -  "Purchase",
      -  "RewardedVideoCredit"
      -]New value: +[
      +  "Item",
      +  "VirtualCurrency",
      +  "CryptoCurrency",
      +  "Purchase",
      +  "RewardedVideoCredit",
      +  "PlatformCoin"
      +]
    • changedInput schema / definitions / ResourceEntryType / x-enum-descriptions
      Previous value: -[
      -  "Catalog item. Requires CatalogID, ItemID and Amount.",
      -  "In-game (off-chain) virtual currency. Requires CurrencyID and Amount. Looked up in cfg.Currency.VirtualCurrencies.",
      -  "On-chain cryptocurrency. Requires CurrencyID and Amount. Looked up in cfg.Currency.CryptoCurrencies.",
      -  "Real-money payment in a store. Requires only ProductID (a product from cfg.Purchase.Products); the amount and currency are decided by the store from the SKU price tier. NOT a storable resource and never passes through ResourceService — the money is paid outside before the server learns about it, so the entry is consumed by the receipt check (ExternalPaymentGate) and stripped before the resource operation. Allowed only in Consume and only for Consumable products.",
      -  "Rewarded-video credit. One credit equals one verified ad view that can be spent in systems requiring rewarded video (lootbox open, reward double, re-roll, booster). Granted +1 per server-verified view, or as N from milestones/quests/premium perks; spent -1 per gated action."
      -]New value: +[
      +  "Catalog item. Requires CatalogID, ItemID and Amount.",
      +  "In-game (off-chain) virtual currency. Requires CurrencyID and Amount. Looked up in cfg.Currency.VirtualCurrencies.",
      +  "On-chain cryptocurrency. Requires CurrencyID and Amount. Looked up in cfg.Currency.CryptoCurrencies.",
      +  "Real-money payment in a store. Requires only ProductID (a product from cfg.Purchase.Products); the amount and currency are decided by the store from the SKU price tier. NOT a storable resource and never passes through ResourceService — the money is paid outside before the server learns about it, so the entry is consumed by the receipt check (ExternalPaymentGate) and stripped before the resource operation. Allowed only in Consume and only for Consumable products.",
      +  "Rewarded-video credit. One credit equals one verified ad view that can be spent in systems requiring rewarded video (lootbox open, reward double, re-roll, booster). Granted +1 per server-verified view, or as N from milestones/quests/premium perks; spent -1 per gated action.",
      +  "Payment in Coin, the PLATFORM currency on the player's iDos Games account. Requires only Amount — the price in whole Coin. Like Purchase it is NOT a player resource and never enters ResourceService: it is settled by PlatformCoinPayment in the same transaction as the grant (buyer charged, author credited). Accepted only by the store (Store.Purchase) for now; allowed only in Consume."
      +]
    • changedInput schema / definitions / ResourceEntryType / x-enumNames
      Previous value: -[
      -  "Item",
      -  "VirtualCurrency",
      -  "CryptoCurrency",
      -  "Purchase",
      -  "RewardedVideoCredit"
      -]New value: +[
      +  "Item",
      +  "VirtualCurrency",
      +  "CryptoCurrency",
      +  "Purchase",
      +  "RewardedVideoCredit",
      +  "PlatformCoin"
      +]
  4. First observed

TDQS

A4.2/5.0
Behavior4/5

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

Annotations already declare a destructive, non-read-only write; the description adds the crucial behavioral fact that only the Referral field is overwritten while other fields survive. It does not say whether the ReferralDefinitions block itself is fully replaced (dropping previously set sub-fields) or whether Reward-referenced bundles must exist first, so a bit of the mutation risk surface is left implicit.

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

Conciseness5/5

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

Two sentences, with the most decision-relevant fact (PARTIAL SAVE) front-loaded in capitals. No filler and no restatement of the title.

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?

Given the very rich nested schema and the destructive annotation, the description supplies the key missing context: write scope and what the referral subsystem covers. It stops short of explaining replace-vs-merge behavior for the Referral block and the cross-module precondition for Reward references, which matter for a destructive write.

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% and the nested ReferralDefinitions fields are exhaustively documented, so the schema does the heavy lifting. The description adds only one piece of parameter-level meaning — that reward bundles reference Reward — which is a useful cross-module dependency but is phrased vaguely.

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+resource (save the Referral field of TitlePublicConfigurationModel) and immediately scopes it as a partial save, which cleanly separates it from siblings like save_title_data. The second sentence enumerates what the Referral config contains, so an agent knows exactly what domain it is writing.

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?

The 'PARTIAL SAVE ... all other v1/v2 fields stay untouched' framing effectively tells the agent when to prefer this over a whole-configuration save. It does not explicitly name an alternative tool or mention paired read usage (get_referral), so the routing guidance is clear but not fully closed.

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.