Skip to main content
Glama

Create a contract

defrr_create_contract

Use when a new deal is signed and you need its revenue and billing schedule worked out from the terms, without saving it anywhere. Returns every month's billing, revenue and deferred balance, and the contract's totals. For a deal priced in a foreign currency, send currency and exchangeRate and the term prices in that currency. For a contract that started in months that are already closed (a back-dated contract), pass lockedThrough: the months from its start through that month are caught up as one lump of revenue in the first open month, the way defrr's app does, and the result says how much (foreign currency works; a single-term contract needs a quantity of 1, renewals are fine). Nothing is corrected, credited or saved: to record the contract in the user's defrr organization, use defrr_save_contract instead, if you have it. Costs 1 credit (refunded if it fails).

Input Schema

NameRequiredDescriptionDefault
currencyNoOnly when the deal is priced in a foreign currency: its three-letter code, such as EUR. Then every term's price is in that currency.
scheduleYesThe contract's terms. The first term needs a startDate; each later term (a renewal) starts the day after the previous one ends when endDateIncluded is true (the default), or on the day the previous one ends when it is false.
exchangeRateNoRequired with currency: how much of the organization's base currency ONE unit of that currency is worth (1 EUR = 1.8 NZD is 1.8). The schedule and totals come back in the base currency, with the foreign prices beside them.
lockedThroughNoOnly for a back-dated contract: the latest closed month, as YYYY-MM (it must be on or after the contract's start month and before its last month). Revenue for the months through it is recognised together in the next month.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changed
    • addedInput schema / properties / lockedThrough
      Added value: +{
      +  "description": "Only for a back-dated contract: the latest closed month, as YYYY-MM (it must be on or after the contract's start month and before its last month). Revenue for the months through it is recognised together in the next month.",
      +  "pattern": "^\\d{4}-(0[1-9]|1[0-2])$",
      +  "type": "string"
      +}
  2. Changed2 schema fields changed
    • changedInput schema / properties / schedule / properties / terms / items / properties / price / description
      Previous value: -"The term's total price."New value: +"The term's total price: for all its units, not per unit."
    • addedInput schema / properties / schedule / properties / terms / items / properties / quantity
      Added value: +{
      +  "description": "Optional: how many units (seats) the term's total price covers, 1 if you leave it out. It doesn't change the schedule, which follows the total; it is recorded with the contract so its unit price can be seen.",
      +  "minimum": 1,
      +  "type": "integer"
      +}
  3. Changed2 schema fields changed
    • changedInput schema / properties / schedule / description
      Previous value: -"The contract's terms. The first term needs a startDate; each later term (a renewal) starts the day after the previous one ends when endDateIncluded is true, or on the day the previous one ends when it is false."New value: +"The contract's terms. The first term needs a startDate; each later term (a renewal) starts the day after the previous one ends when endDateIncluded is true (the default), or on the day the previous one ends when it is false."
    • changedInput schema / properties / schedule / properties / endDateIncluded / description
      Previous value: -"True if a term's end date is its last day (a 1 Jan to 31 Dec term). False if the end date is the first day of the next term. Defaults to false, so for a new contract send true with the last day the customer is covered (a year from 1 Mar 2026 is endDate 2027-02-28)."New value: +"Always send it. True if a term's end date is its last day (a year from 1 Mar 2026 ends 2027-02-28): use true unless the user's own dates show otherwise. False if the end date is the first day of the next term, as when the user gives the same calendar day a whole number of months later (10 Feb 2027 to 10 Feb 2028, so the last covered day is 9 Feb 2028). Defaults to true if left out."
  4. Changed1 schema field changed
    • changedInput schema / properties / schedule / properties / endDateIncluded / description
      Previous value: -"True if a term's end date is its last day (a 1 Jan to 31 Dec term). False if the end date is the first day of the next term. Defaults to false."New value: +"True if a term's end date is its last day (a 1 Jan to 31 Dec term). False if the end date is the first day of the next term. Defaults to false, so for a new contract send true with the last day the customer is covered (a year from 1 Mar 2026 is endDate 2027-02-28)."
  5. Changed2 schema fields changed
    • addedInput schema / properties / currency
      Added value: +{
      +  "description": "Only when the deal is priced in a foreign currency: its three-letter code, such as EUR. Then every term's price is in that currency.",
      +  "pattern": "^[A-Za-z]{3}$",
      +  "type": "string"
      +}
    • addedInput schema / properties / exchangeRate
      Added value: +{
      +  "description": "Required with currency: how much of the organization's base currency ONE unit of that currency is worth (1 EUR = 1.8 NZD is 1.8). The schedule and totals come back in the base currency, with the foreign prices beside them.",
      +  "exclusiveMinimum": 0,
      +  "type": "number"
      +}
  6. First observed

TDQS

A4.8/5.0
Behavior5/5

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

Goes well beyond the annotations: states nothing is corrected, credited or saved, that the call costs 1 credit (refunded on failure), and describes the returned monthly billing/revenue/deferred balance and totals. The non-read-only annotation is explained indirectly by the credit charge, though the 'create' name versus 'nothing saved' framing creates mild framing tension rather than a true contradiction.

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 the triggering condition and the no-persistence scope before any edge cases, and virtually every sentence carries operational content. It is dense, however, and the parenthetical about foreign currency / single-term quantity of 1 / renewals packs three caveats into one hard-to-parse clause.

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 four-parameter tool with a nested terms array and no output schema, the description covers trigger, side effects, cost, currency handling, back-dated behaviour, and return values. An agent has enough to decide whether to call it and how, and to reason about the response shape without an output schema.

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 earns credit by adding relational meaning the schema cannot, notably that exchangeRate is required with currency and quoted as base-currency-per-one-unit, and by spelling out the lockedThrough catch-up effect on the schedule. It does not add much on the nested term fields themselves, which the schema already documents fully.

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 and resource ('work out revenue and billing schedule from the terms') plus a crucial scope qualifier ('without saving it anywhere'). It also names the sibling it is not (defrr_save_contract), so an agent can separate this from cancel/reprice/process_renewal tools 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 trigger ('Use when a new deal is signed...'), explicit exclusion of persistence, and a named alternative ('to record the contract in the user's defrr organization, use defrr_save_contract instead'). It additionally gives conditional guidance for foreign-currency deals and back-dated contracts, which is exactly the when-to-use detail an agent needs.

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.