Skip to main content
Glama

Core 3/4: Quote with live price, stock and the mandate check

request_quote

Generate a signed, expiring quote with live prices and availability from Valio Aimo, including mandate checks and alternatives, without placing an order.

Instructions

Get a signed, expiring quote with live prices and availability from Valio Aimo. Places no order.

delivery_date: YYYY-MM-DD. items: one per need: {product_ids: [...], amount, unit: 'L' | 'KG' | 'SALES_UNIT', substitute_for?, use?} (use: what the product is for, e.g. 'coffee', 'dessert', 'ingredient-in-recipe:Tiramisu'; a substitute that doesn't suit it, like another brand of whipping cream for a dessert, waits for a person) (pack, packs mean SALES_UNIT = cartons/packs as sold; 'ST' (PCS, KPL) counts pieces when the product has them: 20 ST of a carton of 6 = 4 cartons, rounded up, and the line says so in unit_note). Give several candidate ids per need and an amount in L or KG: the gateway picks the cheapest orderable one per L/KG, splitting across products when stock is short. Mark substitutes with substitute_for. Always pass mandate_id: the quote then includes mandate_preview (silent | notify | ask | block, and why). Check quote.lines[].orderable, quote.uncovered and mandate_preview, then place_order with quote.id before quote.expires_at. If quote.options is present, an item can't be covered as asked (stock short, later date, cut-off passed, undeliverable). Each option is a complete alternative for that item (kind, lines, total, delivery_dates, tradeoff, substitute, mandate_preview), best first. Present them to the buyer, or pick per the mandate (an option whose mandate_preview is silent/notify needs no human). Never silently drop the uncovered amount. option_id: to take an option, call request_quote again with only agent_id, mandate_id and option_id (e.g. 'Q-1A2B3C4D.O2'): you get a fresh signed quote with that item's lines replaced; then place_order it. rationale: one sentence on the buyer's business need (e.g. "breakfast milk for 400 guests"); it is signed into the quote and shown to the humans who audit or approve. State the need, not your reasoning steps. declared_risks: optional, up to 5 short sentences (200 chars each) on what YOU are unsure about (e.g. "not sure 10 L covers Saturday"). Each one holds the order for a human (rule agent.declared_risk) with your words; it can never make an order go through more easily. Say it here rather than ordering on a guess. buyer_request: the buyer's own message to you, verbatim (at most 2,000 characters), not your summary. Signed into the quote; the gateway reads its quantities ("1 539 litraa" = 1,539 L) and, when the quote has none of them, asks a person (rule quantity.request_mismatch). mandate_preview.request_quantities shows what it read. offer_id: a Valio Aimo offer from list_offers (e.g. 'OF-1A2B3C4D'), only when the buyer wants it: name the offer's product_ids in items; they are priced at min(offer price, live price) and the quote carries offer. The mandate decides as always (rule offer.applied tells the buyer). agent_id: optional when your credential covers mandate_id (see my_mandates); required without a mandate. agent_token: only if you can't send the Authorization: Bearer header and the mandate requires agent auth. Returns {quote (schema /schemas/quote.json), jws (sous-quote+jws over quote)}.

Tool call template

This tool declares no required parameters. Add optional parameters from the input schema as needed.

{
  "id": 1,
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "arguments": {},
    "name": "request_quote"
  }
}

Input Schema

NameRequiredDescriptionDefault
itemsNo
agent_idNo
offer_idNo
option_idNo
rationaleNo
mandate_idNo
agent_tokenNo
buyer_requestNo
delivery_dateNo
declared_risksNo

Output Schema

NameRequiredDescriptionDefault
jwsYesCompact JWS over `quote`, verifiable with /.well-known/jwks.json
quoteYes

Schema Changelog

Changes observed during successful MCP inspections.

  1. First observedv0.2.0

TDQS

A4.6/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=false, destructiveHint=false, idempotentHint=false and openWorldHint=true, but the description adds substantial behavior the annotations cannot: the quote is signed (jws) and expiring, declared_risks "holds the order for a human" and "can never make an order go through more easily," and the gateway silently substitutes only per purpose/mandate rules. It does not state auth failure modes or rate limits, so it stops short of a 5.

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

Conciseness3/5

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

The core statement is correctly front-loaded in the first two sentences, but the body is a wall of stacked parentheticals and inconsistent indentation (a stray double space before "Give several candidate ids", mid-sentence rule names like "rule quantity.request_mismatch"). Nearly every sentence carries information, yet the formatting makes it hard to scan under time pressure.

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 10-parameter, mutation-adjacent orchestration tool this covers the full decision surface: the quote lifecycle, the option round-trip, the offer path, mandate preview tiers, and the human-hold escape hatch via declared_risks. Since the return value is documented by /schemas/quote.json, the description does not need to enumerate the response shape and correctly points to it instead.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Top-level schema coverage is 0%, so the description carries the load and does: it explains delivery_date format, items composition, why to give several candidate product_ids, the meaning of substitute_for, the signed-and-audited nature of rationale, the 5x200-char cap and human-hold effect of declared_risks, the 2,000-char verbatim rule for buyer_request, and the offer_id pricing rule min(offer price, live price). It also adds gateway behavior absent from the schema, e.g. cheapest-orderable selection with splitting across products when stock is short.

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?

Opens with a specific verb+resource and scope: "Get a signed, expiring quote with live prices and availability from Valio Aimo," immediately followed by "Places no order." That single clause distinguishes it from place_order, and the title's "Core 3/4" framing plus the mandate preview mention separates it from can_i_order and list_offers.

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?

Gives an explicit end-to-end sequence: check quote.lines[].orderable, quote.uncovered and mandate_preview, then call place_order with quote.id before quote.expires_at. It also scopes conditional parameters (offer_id "only when the buyer wants it") and describes the follow-up path for option_id, so an agent knows when to re-call versus when to order.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.