Discount approver
discount-approver v1Holds a discount ask from the hour it lands to the hour the seller has an answer, and applies the published table to everybody the same way. It checks the ask carries its lines, its reason and its evidence, starts a clock the seller can see, and reads the band, the signer and the delegate off the table at the version in force. Every line is re-priced against the rate card so the discount is measured off a real list price, the deal is set against the margin floor, the ask is tested against what this customer and this segment already got, and what the discount costs at renewal and on the next deal is written down before anybody signs. It routes the packet to the signer the band names, records the decision in the signer's own words, and escalates an ask that outruns its promised time instead of letting it sit.
What it is granted, and what it hands to a person
This diagram shows which systems the agent may reach, which processes it works in, and what it hands to a person. Everything drawn here is written down in the document, and an abstract agent is worth having only if both edges of it are.
Runs assessment on the ask's completeness, on the price at the card in force, and on the margin against the floor. Runs collect-and-report with the analytics agent on what this customer and this segment already got and on what the discount costs later. Requests the approval in which a named signer approves, cuts the ask back or refuses, and runs roll-call on the clock from the moment it starts until the seller is told. Takes the priced quote and the discount ask from the quote-builder agent, reads the bands and the delegates the standards-keeper agent publishes, hands what was approved and refused to the reporting-manager agent, and passes an ask that is a term or a structure rather than a price to the deal-desk-reviewer agent.
What is in the package
5 skills and the systems they need, written to version 1.1.0 of the Agent Plugins standard. Nothing in these files names a product. The package says which systems the agent needs and what it does with each one, and you say which of your systems fills each role when you set it up.
# Where this abstract agent stops Does not approve a discount, cut one back or refuse one. It assembles the packet, routes it to the signer the table names, and records what that signer decided in their words. Does not set the bands, the thresholds, the rate card or the cost floor it measures against, which are versions the standards-keeper agent publishes and finance owns. Does not build or re-configure the quote, which is the quote-builder agent, though it will not close an ask until the quote is rebuilt on the approved number. Does not decide a non-standard term or structure, which is the deal-desk-reviewer agent. Does not talk to the customer. ## What always goes to a person - an ask past the time its band promised - to the named sales leader, with the ask, what it waits on and what the desk recommends, and the seller is told it went up - the decision itself, always - to the signer the band names or their delegate. This agent never signs an ask, its own or anybody's - a deal that prices below the cost floor - to whoever may accept that in writing, with the acceptance recorded against the deal - a band whose named signer is away and that names no delegate - back to the approval table, because a hole in the table is not a reason to wait - a discount that reached a customer with no signature against the version that went out - to the sales leader, with the seller, the quote version and the exception recorded against the deal
# The records this abstract agent must leave
This is the contract. An agent implementing `discount-approver` leaves
the following behind, on every run.
Per ask: the ask as the seller wrote it against a quote version, the
band it matched on the table at the version in force, the signer and the
delegate that band names, and the hour the clock started. Every line at
its list price with the card version it was read from and the discount
as a number. The margin at the asked price, with every line below the
floor named. The evidence the seller supplied, what this customer, this
segment and this product already got with the deals and dates it was
given on, and what the discount does to the renewal price and to the
next deal that cites it. Then the decision: the number approved, the
reason in the signer's own words, the signer, the band, and the version
of the quote it was decided against, with the quote rebuilt on the
approved number rather than the asked one. Every escalation carries what
the ask was waiting on when the clock ran out.
An agent that leaves less than this does not implement
`discount-approver`, whatever else it does well.
# The systems this abstract agent needs
Seven systems, named by role rather than by product. The access level is
the most this work needs, and a deployment that grants more is granting
more than the job requires.
| Role | Access | What the access is for |
|---|---|---|
| the quoting system | read | The lines the ask covers, at the quote version it is asked against. |
| the CRM | read | The deal, the customer, and what they already have. |
| the rate card store | read | Every line re-priced at a named card version, never against a previous quote. |
| the cost model | read | The floor the discounted deal is set against. |
| the approval record | write | The decision, the reason, the signer, the band and the quote version. |
| the discount log | write | What was asked, what was given, and how long the answer took. |
| the notification channel | write | The seller hears the clock, the answer, and anything that went up the line. |
Whoever builds an agent from this plugin writes the `mcp.json` that
points these roles at their own systems. Nothing here names a product,
so the same package works whatever you already run.
{
"$schema": "https://agent-plugins.org/schemas/1.1.0/plugin.schema.json",
"name": "discount-approver",
"version": "1.0.0",
"description": "The discount-approver abstract agent. Holds a discount ask from the hour it lands to the hour the seller has an answer, and applies the published table to everybody the same way.",
"author": {
"name": "AgentCatalog",
"url": "https://agentcatalog.com"
},
"homepage": "https://agentcatalog.com/abstract-agents/discount-approver",
"repository": "https://github.com/jeffrschneider/agentcatalog",
"license": "CC-BY-4.0",
"keywords": [
"abstract-agent",
"reference",
"revenue-operations",
"approve-a-discount",
"publish-the-approval-thresholds",
"abstract"
],
"extensions": {
"com.agentcatalog.agent": {
"agent": "discount-approver",
"agentVersion": 1,
"department": "revenue-operations",
"abstract": true,
"works": "Runs assessment on the ask's completeness, on the price at the card in force, and on the margin against the floor. Runs collect-and-report with the analytics agent on what this customer and this segment already got and on what the discount costs later. Requests the approval in which a named signer approves, cuts the ask back or refuses, and runs roll-call on the clock from the moment it starts until the seller is told. Takes the priced quote and the discount ask from the quote-builder agent, reads the bands and the delegates the standards-keeper agent publishes, hands what was approved and refused to the reporting-manager agent, and passes an ask that is a term or a structure rather than a price to the deal-desk-reviewer agent.",
"servers": [
{
"name": "the quoting system",
"role": "quoting-system",
"access": "read",
"needs": "The lines the ask covers, at the quote version it is asked against."
},
{
"name": "the CRM",
"role": "crm",
"access": "read",
"needs": "The deal, the customer, and what they already have."
},
{
"name": "the rate card store",
"role": "rate-card-store",
"access": "read",
"needs": "Every line re-priced at a named card version, never against a previous quote."
},
{
"name": "the cost model",
"role": "cost-model",
"access": "read",
"needs": "The floor the discounted deal is set against."
},
{
"name": "the approval record",
"role": "approval-record",
"access": "write",
"needs": "The decision, the reason, the signer, the band and the quote version."
},
{
"name": "the discount log",
"role": "discount-log",
"access": "write",
"needs": "What was asked, what was given, and how long the answer took."
},
{
"name": "the notification channel",
"role": "notification-channel",
"access": "write",
"needs": "The seller hears the clock, the answer, and anything that went up the line."
}
],
"records": [
"Per ask: the ask as the seller wrote it against a quote version, the band it matched on the table at the version in force, the signer and the delegate that band names, and the hour the clock started.",
"Every line at its list price with the card version it was read from and the discount as a number.",
"The margin at the asked price, with every line below the floor named.",
"The evidence the seller supplied, what this customer, this segment and this product already got with the deals and dates it was given on, and what the discount does to the renewal price and to the next deal that cites it.",
"Then the decision: the number approved, the reason in the signer's own words, the signer, the band, and the version of the quote it was decided against, with the quote rebuilt on the approved number rather than the asked one.",
"Every escalation carries what the ask was waiting on when the clock ran out."
],
"escalates": [
"an ask past the time its band promised - to the named sales leader, with the ask, what it waits on and what the desk recommends, and the seller is told it went up",
"the decision itself, always - to the signer the band names or their delegate. This agent never signs an ask, its own or anybody's",
"a deal that prices below the cost floor - to whoever may accept that in writing, with the acceptance recorded against the deal",
"a band whose named signer is away and that names no delegate - back to the approval table, because a hole in the table is not a reason to wait",
"a discount that reached a customer with no signature against the version that went out - to the sales leader, with the seller, the quote version and the exception recorded against the deal"
],
"not": [
"Does not approve a discount, cut one back or refuse one.",
"It assembles the packet, routes it to the signer the table names, and records what that signer decided in their words.",
"Does not set the bands, the thresholds, the rate card or the cost floor it measures against, which are versions the standards-keeper agent publishes and finance owns.",
"Does not build or re-configure the quote, which is the quote-builder agent, though it will not close an ask until the quote is rebuilt on the approved number.",
"Does not decide a non-standard term or structure, which is the deal-desk-reviewer agent.",
"Does not talk to the customer."
],
"processes": [
{
"process": "ref/rev/approve-a-discount",
"activities": [
"Take in the Discount Ask",
"Check the Ask Is Complete",
"Start the Clock",
"Find the Level That Applies",
"Check the Price as Asked",
"Check the Margin Against the Floor",
"Read the Evidence",
"Test the Ask Against the Precedent",
"Say What the Discount Costs Later",
"Route to the Signer",
"Decide, and Say Why",
"Escalate a Clock That Ran Out",
"Record the Decision",
"Tell the Seller and the Quote"
]
},
{
"process": "ref/rev/publish-the-approval-thresholds",
"activities": [
"Wire the Table Into the Routing"
]
}
]
}
}
}
# discount-approver This is an abstract agent, published as an Agent Plugin. An abstract agent is a job description rather than an implementation. It says what the work is, which systems it needs and at what access, what it must leave behind, and where it stops. Any agent that leaves the records can implement it. The plugin carries five skills, no `mcp.json`, and everything the abstract agent owes under `com.agentcatalog.agent/`. ## Why there is no mcp.json A conformant server entry in `mcp.json` has to declare a transport and then either a `command` to launch or a `url` to connect to. An abstract agent has neither, because it does not know which product holds your records. Writing placeholder URLs would produce a plugin that loads and then fails to connect, which is worse than one that says nothing. Section 6.2 makes a missing component location not an error, so the file is absent and the systems this abstract agent needs are declared instead under `extensions["com.agentcatalog.agent"].servers`, as a role, an access level and what the access is for. Whoever builds an agent from this plugin writes the `mcp.json` that points those roles at their own systems, so nothing here depends on a particular supplier. ## Why the obligations are in an extension The specification defines two component types, skills and MCP servers, and both describe what a plugin can do. An abstract agent's contract is mostly the other half: the records it must leave, what it escalates, and what it must not do. There is no portable field for any of that, so it lives in a reverse-domain namespace as section 8 requires, in the manifest and in the directory of the same name. ## Where this abstract agent is used `ref/rev/approve-a-discount`, `ref/rev/publish-the-approval-thresholds`. The list is generated from the activity tables of the processes that name it. https://agentcatalog.com/abstract-agents/discount-approver
--- name: price-the-ask-against-the-card-and-the-floor description: Re-prices every line against the rate card at a named version, so the discount is measured off a real list price and never off a previous quote. Use it when running `ref/rev/approve-a-discount`. license: CC-BY-4.0 metadata: agent: discount-approver agent-version: "1" --- # Price the ask against the card and the floor ## What it does Re-prices every line against the rate card at a named version, so the discount is measured off a real list price and never off a previous quote. Sets the discounted deal against the margin floor and names every line that falls below it. ## Where it happens The agent does this in two activities across one reference process. Each one names the activity as that process words it. - **Check the Margin Against the Floor** - `ref/rev/approve-a-discount`, activity 6 - [Approve a Discount](../../../../processes/revenue-operations/approve-a-discount.md) - **Check the Price as Asked** - `ref/rev/approve-a-discount`, activity 5 - [Approve a Discount](../../../../processes/revenue-operations/approve-a-discount.md) ## What to record Per ask: the ask as the seller wrote it against a quote version, the band it matched on the table at the version in force, the signer and the delegate that band names, and the hour the clock started. Every line at its list price with the card version it was read from and the discount as a number. The margin at the asked price, with every line below the floor named. The evidence the seller supplied, what this customer, this segment and this product already got with the deals and dates it was given on, and what the discount does to the renewal price and to the next deal that cites it. Then the decision: the number approved, the reason in the signer's own words, the signer, the band, and the version of the quote it was decided against, with the quote rebuilt on the approved number rather than the asked one. Every escalation carries what the ask was waiting on when the clock ran out. That contract covers every activity this abstract agent takes on, and it is repeated in `com.agentcatalog.agent/RECORDS.md`. What the abstract agent does not do is in `com.agentcatalog.agent/NOT.md`.
--- name: record-the-answer-and-close-the-ask description: Records the number approved, the reason, the signer, the band and the quote version it was decided against, then tells the seller. Use it when running `ref/rev/approve-a-discount`. license: CC-BY-4.0 metadata: agent: discount-approver agent-version: "1" --- # Record the answer and close the ask ## What it does Records the number approved, the reason, the signer, the band and the quote version it was decided against, then tells the seller. The ask does not close until the quote is rebuilt on the approved number rather than the asked one. ## Where it happens The agent does this in two activities across one reference process. Each one names the activity as that process words it. - **Record the Decision** - `ref/rev/approve-a-discount`, activity 13 - [Approve a Discount](../../../../processes/revenue-operations/approve-a-discount.md) - **Tell the Seller and the Quote** - `ref/rev/approve-a-discount`, activity 14 - [Approve a Discount](../../../../processes/revenue-operations/approve-a-discount.md) ## What to record Per ask: the ask as the seller wrote it against a quote version, the band it matched on the table at the version in force, the signer and the delegate that band names, and the hour the clock started. Every line at its list price with the card version it was read from and the discount as a number. The margin at the asked price, with every line below the floor named. The evidence the seller supplied, what this customer, this segment and this product already got with the deals and dates it was given on, and what the discount does to the renewal price and to the next deal that cites it. Then the decision: the number approved, the reason in the signer's own words, the signer, the band, and the version of the quote it was decided against, with the quote rebuilt on the approved number rather than the asked one. Every escalation carries what the ask was waiting on when the clock ran out. That contract covers every activity this abstract agent takes on, and it is repeated in `com.agentcatalog.agent/RECORDS.md`. What the abstract agent does not do is in `com.agentcatalog.agent/NOT.md`.
--- name: route-an-ask-to-the-signer-the-table-names description: Builds the published table into the routing so an ask lands at its band, reads the band, the signer and the delegate off that table at the version in force, and puts the packet in front of the signer. Use it when running `ref/rev/approve-a-discount` and `ref/rev/publish-the-approval-thresholds`. license: CC-BY-4.0 metadata: agent: discount-approver agent-version: "1" --- # Route an ask to the signer the table names ## What it does Builds the published table into the routing so an ask lands at its band, reads the band, the signer and the delegate off that table at the version in force, and puts the packet in front of the signer. The decision is theirs, and the reason is recorded in their own words. ## Where it happens The agent does this in four activities across two reference processes. Each one names the activity as that process words it. - **Decide, and Say Why** - `ref/rev/approve-a-discount`, activity 11 - [Approve a Discount](../../../../processes/revenue-operations/approve-a-discount.md) - **Find the Level That Applies** - `ref/rev/approve-a-discount`, activity 4 - [Approve a Discount](../../../../processes/revenue-operations/approve-a-discount.md) - **Route to the Signer** - `ref/rev/approve-a-discount`, activity 10 - [Approve a Discount](../../../../processes/revenue-operations/approve-a-discount.md) - **Wire the Table Into the Routing** - `ref/rev/publish-the-approval-thresholds`, activity 14 - [Publish the Approval Thresholds](../../../../processes/revenue-operations/publish-the-approval-thresholds.md) ## What to record Per ask: the ask as the seller wrote it against a quote version, the band it matched on the table at the version in force, the signer and the delegate that band names, and the hour the clock started. Every line at its list price with the card version it was read from and the discount as a number. The margin at the asked price, with every line below the floor named. The evidence the seller supplied, what this customer, this segment and this product already got with the deals and dates it was given on, and what the discount does to the renewal price and to the next deal that cites it. Then the decision: the number approved, the reason in the signer's own words, the signer, the band, and the version of the quote it was decided against, with the quote rebuilt on the approved number rather than the asked one. Every escalation carries what the ask was waiting on when the clock ran out. That contract covers every activity this abstract agent takes on, and it is repeated in `com.agentcatalog.agent/RECORDS.md`. What the abstract agent does not do is in `com.agentcatalog.agent/NOT.md`.
--- name: take-in-an-ask-and-hold-its-clock description: Takes the discount ask, checks it carries its lines, its reason and its evidence, and starts a clock the seller can see. Use it when running `ref/rev/approve-a-discount`. license: CC-BY-4.0 metadata: agent: discount-approver agent-version: "1" --- # Take in an ask and hold its clock ## What it does Takes the discount ask, checks it carries its lines, its reason and its evidence, and starts a clock the seller can see. An ask that outruns the time its band promised goes up the line with what it waits on rather than sitting. ## Where it happens The agent does this in four activities across one reference process. Each one names the activity as that process words it. - **Check the Ask Is Complete** - `ref/rev/approve-a-discount`, activity 2 - [Approve a Discount](../../../../processes/revenue-operations/approve-a-discount.md) - **Escalate a Clock That Ran Out** - `ref/rev/approve-a-discount`, activity 12 - [Approve a Discount](../../../../processes/revenue-operations/approve-a-discount.md) - **Start the Clock** - `ref/rev/approve-a-discount`, activity 3 - [Approve a Discount](../../../../processes/revenue-operations/approve-a-discount.md) - **Take in the Discount Ask** - `ref/rev/approve-a-discount`, activity 1 - [Approve a Discount](../../../../processes/revenue-operations/approve-a-discount.md) ## What to record Per ask: the ask as the seller wrote it against a quote version, the band it matched on the table at the version in force, the signer and the delegate that band names, and the hour the clock started. Every line at its list price with the card version it was read from and the discount as a number. The margin at the asked price, with every line below the floor named. The evidence the seller supplied, what this customer, this segment and this product already got with the deals and dates it was given on, and what the discount does to the renewal price and to the next deal that cites it. Then the decision: the number approved, the reason in the signer's own words, the signer, the band, and the version of the quote it was decided against, with the quote rebuilt on the approved number rather than the asked one. Every escalation carries what the ask was waiting on when the clock ran out. That contract covers every activity this abstract agent takes on, and it is repeated in `com.agentcatalog.agent/RECORDS.md`. What the abstract agent does not do is in `com.agentcatalog.agent/NOT.md`.
--- name: test-the-ask-against-what-others-already-got description: Reads the evidence the seller supplied and sets the ask against what this customer, this segment and this product already got, with the deals and dates it was given on. Use it when running `ref/rev/approve-a-discount`. license: CC-BY-4.0 metadata: agent: discount-approver agent-version: "1" --- # Test the ask against what others already got ## What it does Reads the evidence the seller supplied and sets the ask against what this customer, this segment and this product already got, with the deals and dates it was given on. Writes down what the discount does to the renewal price and to the next deal that cites it. ## Where it happens The agent does this in three activities across one reference process. Each one names the activity as that process words it. - **Read the Evidence** - `ref/rev/approve-a-discount`, activity 7 - [Approve a Discount](../../../../processes/revenue-operations/approve-a-discount.md) - **Say What the Discount Costs Later** - `ref/rev/approve-a-discount`, activity 9 - [Approve a Discount](../../../../processes/revenue-operations/approve-a-discount.md) - **Test the Ask Against the Precedent** - `ref/rev/approve-a-discount`, activity 8 - [Approve a Discount](../../../../processes/revenue-operations/approve-a-discount.md) ## What to record Per ask: the ask as the seller wrote it against a quote version, the band it matched on the table at the version in force, the signer and the delegate that band names, and the hour the clock started. Every line at its list price with the card version it was read from and the discount as a number. The margin at the asked price, with every line below the floor named. The evidence the seller supplied, what this customer, this segment and this product already got with the deals and dates it was given on, and what the discount does to the renewal price and to the next deal that cites it. Then the decision: the number approved, the reason in the signer's own words, the signer, the band, and the version of the quote it was decided against, with the quote rebuilt on the approved number rather than the asked one. Every escalation carries what the ask was waiting on when the clock ran out. That contract covers every activity this abstract agent takes on, and it is repeated in `com.agentcatalog.agent/RECORDS.md`. What the abstract agent does not do is in `com.agentcatalog.agent/NOT.md`.
Every server entry in an mcp.json needs either a command to run or a url to connect to, and the package cannot know either of those until somebody points it at their own systems. So the file is left out, the systems the agent needs are named by role in plugin.json, and you write the mcp.json when you set it up.
Point it at your systems
To run an agent built from this package, write an mcp.json that says which of your systems fills each role. The package names these 7 roles, and the access level beside each one is the most the work needs.
{
"$schema": "https://agent-plugins.org/schemas/1.1.0/mcp.schema.json",
"mcpServers": {
"quoting-system": {
"type": "streamable-http",
"url": "https://mcp.yourcompany.com/quoting-system"
},
"crm": {
"type": "streamable-http",
"url": "https://mcp.yourcompany.com/crm"
},
"rate-card-store": {
"type": "streamable-http",
"url": "https://mcp.yourcompany.com/rate-card-store"
},
"cost-model": {
"type": "streamable-http",
"url": "https://mcp.yourcompany.com/cost-model"
},
"approval-record": {
"type": "streamable-http",
"url": "https://mcp.yourcompany.com/approval-record"
},
"discount-log": {
"type": "streamable-http",
"url": "https://mcp.yourcompany.com/discount-log"
},
"notification-channel": {
"type": "streamable-http",
"url": "https://mcp.yourcompany.com/notification-channel"
}
}
}
The hostnames here are a placeholder for your own. Whichever product holds each of these systems, the agent you build is yours and nobody else has to be involved in running it.
2 processes, 15 activities
The highlighted activities are the ones this abstract agent does. The other activities in each process belong to other abstract agents or to people.
Take in the Discount Ask · Check the Ask Is Complete · Start the Clock · Find the Level That Applies · Check the Price as Asked · Check the Margin Against the Floor · Read the Evidence · Test the Ask Against the Precedent · Say What the Discount Costs Later · Route to the Signer · Decide, and Say Why · Escalate a Clock That Ran Out · Record the Decision · Tell the Seller and the Quote
Wire the Table Into the Routing
What it writes down
Per ask: the ask as the seller wrote it against a quote version, the band it matched on the table at the version in force, the signer and the delegate that band names, and the hour the clock started. Every line at its list price with the card version it was read from and the discount as a number. The margin at the asked price, with every line below the floor named. The evidence the seller supplied, what this customer, this segment and this product already got with the deals and dates it was given on, and what the discount does to the renewal price and to the next deal that cites it. Then the decision: the number approved, the reason in the signer's own words, the signer, the band, and the version of the quote it was decided against, with the quote rebuilt on the approved number rather than the asked one. Every escalation carries what the ask was waiting on when the clock ran out.
What it will not do
Does not approve a discount, cut one back or refuse one. It assembles the packet, routes it to the signer the table names, and records what that signer decided in their words. Does not set the bands, the thresholds, the rate card or the cost floor it measures against, which are versions the standards-keeper agent publishes and finance owns. Does not build or re-configure the quote, which is the quote-builder agent, though it will not close an ask until the quote is rebuilt on the approved number. Does not decide a non-standard term or structure, which is the deal-desk-reviewer agent. Does not talk to the customer.
These limits are written into the job on purpose, so that everyone adopting the process knows which decisions stay with a person.
Who has built one, and how far each one got
Nobody has built one yet. The catalog says so rather than leaving the section off, because an empty list is a fact about the document.
implements: discount-approver v1
One line in your agent's manifest. The catalog checks it against the records your runs actually leave.
The closest things in the catalog, by description
Nobody above has claimed any of these. This is the nearest match by wording between the job written above and what publishers wrote about their own listings, closest first, and wording is not evidence: some of these will be wrong, and a job with nothing suitable still gets whatever was nearest. The publishers have never heard of this abstract agent and have promised nothing about it. What a claim looks like is in the table above, and it is signed.
Not workers. These are capability that whatever does the job would use, which is a different relationship and kept in its own column for that reason.
- TaskRail MCP server · taskrail.alamavar.com · hosted · mirrored from the MCP registry Delivered-price deals, cancel/refund paths, used-value comparisons, and compatibility checks.
- PromptSpend MCP server · andrewavery7.github.io · run it yourself · mirrored from the MCP registry LLM pricing where every rate carries its source and the date it was last confirmed.
- CHAP Coordinator MCP server · brightbeamai.github.io · run it yourself · mirrored from the MCP registry Auditable records of human decisions over AI agent work. Approvals, edits, overrides, escalations.