Real, buyable product and service offers — live pricing and trackable links for any MCP agent.
Maintain this server? Claim it
Call this server's tools from your browser. Nothing to install.
Bearer <AON API key>. Use an issued live key from https://developer.aon.pro; no credential is embedded in this manifest.
Requests go through mcptry because browsers can't call most MCP servers directly. Header values are sent to the server for that request only and are never stored or logged.
Tool list from our last check. Connect live to refresh it.
Hosted AON MCP category-guidance extension. This server returns it from tools/list, but Protocol v1.0 does not require it. Get the decision factors buyers weigh inside one AON Taxonomy v1 category, so you can ask the right clarifying question before searching. Call it when intent is vague ("I need a card", "looking for software") — each factor comes with the concrete options to choose between. Pass 'all' to see which categories currently ship a decision schema. Categories without a schema return a plain note, not an error; searching still works without one.
AON Taxonomy v1 category id such as finance.credit_lending, computers_electronics.computers.software, arts_entertainment.adult_entertainment, arts_entertainment.igaming, or 'all' to list the categories that have a schema. Use aon_resolve_category to obtain an id from free text.
Optional ad placement id. This argument takes precedence over the X-AON-Placement-Id HTTP header; when omitted, the header supplies the placement. The placement must be active and identifies the application that receives attribution. If neither is provided (or the value is empty), the call runs in anonymous mode under AON's shared default placement: it works, but earns no attribution or revenue.
This tool isn't marked read-only, so it may change something on the server or in an account you connected.
Hosted AON MCP category-guidance extension. This server returns it from tools/list, but Protocol v1.0 does not require it. Get the decision factors buyers weigh inside one AON Taxonomy v1 category, so you can ask the right clarifying question before searching. Call it when intent is vague ("I need a card", "looking for software") — each factor comes with the concrete options to choose between. Pass 'all' to see which categories currently ship a decision schema. Categories without a schema return a plain note, not an error; searching still works without one.
| Argument | Type | Description |
|---|---|---|
| category_id* | string | AON Taxonomy v1 category id such as finance.credit_lending, computers_electronics.computers.software, arts_entertainment.adult_entertainment, arts_entertainment.igaming, or 'all' to list the categories that have a schema. Use aon_resolve_category to obtain an id from free text. |
| placement_id | string | Optional ad placement id. This argument takes precedence over the X-AON-Placement-Id HTTP header; when omitted, the header supplies the placement. The placement must be active and identifies the application that receives attribution. If neither is provided (or the value is empty), the call runs in anonymous mode under AON's shared default placement: it works, but earns no attribution or revenue. |
{
"type": "object",
"required": [
"category_id"
],
"properties": {
"category_id": {
"type": "string",
"description": "AON Taxonomy v1 category id such as finance.credit_lending, computers_electronics.computers.software, arts_entertainment.adult_entertainment, arts_entertainment.igaming, or 'all' to list the categories that have a schema. Use aon_resolve_category to obtain an id from free text."
},
"placement_id": {
"type": "string",
"description": "Optional ad placement id. This argument takes precedence over the X-AON-Placement-Id HTTP header; when omitted, the header supplies the placement. The placement must be active and identifies the application that receives attribution. If neither is provided (or the value is empty), the call runs in anonymous mode under AON's shared default placement: it works, but earns no attribution or revenue."
}
}
}Restore or cancel the default watch for an AON Offer or category. Call only when the user explicitly asks to resume or stop receiving changes; eligible search results establish the default watch automatically. This initial scaffold acknowledges the request with success but does not persist or change watch state yet; the internal workflow will be added later.
| Argument | Type | Description |
|---|---|---|
| target* | object | The Offer or category whose watch should be restored or cancelled. |
| operation* | string | watch restores or enables the target watch; unwatch cancels it. |
| idempotency_key | string | Optional caller-generated key reserved for idempotent processing when persistence is implemented. |
{
"type": "object",
"required": [
"operation",
"target"
],
"properties": {
"target": {
"type": "object",
"required": [
"kind",
"id"
],
"properties": {
"id": {
"type": "string",
"maxLength": 256,
"minLength": 1,
"description": "The target id returned by AON."
},
"kind": {
"enum": [
"offer",
"category"
],
"type": "string",
"description": "The protocol target kind."
}
},
"description": "The Offer or category whose watch should be restored or cancelled."
},
"operation": {
"enum": [
"watch",
"unwatch"
],
"type": "string",
"description": "watch restores or enables the target watch; unwatch cancels it."
},
"idempotency_key": {
"type": "string",
"maxLength": 256,
"minLength": 1,
"description": "Optional caller-generated key reserved for idempotent processing when persistence is implemented."
}
}
}Turn a free-text product or service description into AON Taxonomy v1 category ids you can safely pass to aon_search_offers. If this server lists the optional aon_get_category_schema extension, its input also accepts an id resolved here. Call this first whenever you would otherwise be guessing at a category id — the taxonomy is fixed, and invented ids come back as corrections instead of results. Returns `matches` (up to 3 candidates, each with `category_id`, `display_name` and a 0-1 `score`, best first) plus a `note` explaining the match. When nothing matches exactly, the closest candidates still come back with a "no exact match" note, so a misspelled or unusual phrase gets a usable suggestion rather than an error.
| Argument | Type | Description |
|---|---|---|
| query* | string | What the user is shopping for, in words: "hiking boots", "team chat software", "credit card". A category id or a legacy alias also resolves. |
| placement_id | string | Optional ad placement id. This argument takes precedence over the X-AON-Placement-Id HTTP header; when omitted, the header supplies the placement. The placement must be active and identifies the application that receives attribution. If neither is provided (or the value is empty), the call runs in anonymous mode under AON's shared default placement: it works, but earns no attribution or revenue. |
{
"type": "object",
"required": [
"query"
],
"properties": {
"query": {
"type": "string",
"description": "What the user is shopping for, in words: \"hiking boots\", \"team chat software\", \"credit card\". A category id or a legacy alias also resolves."
},
"placement_id": {
"type": "string",
"description": "Optional ad placement id. This argument takes precedence over the X-AON-Placement-Id HTTP header; when omitted, the header supplies the placement. The placement must be active and identifies the application that receives attribution. If neither is provided (or the value is empty), the call runs in anonymous mode under AON's shared default placement: it works, but earns no attribution or revenue."
}
}
}Web search finds articles about products; this returns real, buyable offers the user can act on — pricing plus a trackable checkout link for each one. Call this when the user shows purchase intent ("which laptop under $800", "cheapest CRM for a 3-person team", "credit card with lounge access"). The arguments use the AgentOffer Query v1.0 nested core plus explicitly marked AON MCP private extensions; they are not the closed REST request schema. Minimum: intent.content[0] = {"type":"input_text","text":"<one natural sentence>"}. Narrow by category with AON Taxonomy v1 ids in `constraints.category_ids` — copy those ids from aon_resolve_category, never invent them. The response is the full query result as JSON text: `data.offers[]` (each with pricing and a tracking link you should surface verbatim), `data.request_id`, `data.protocol_version`, `data.language`, an optional `data.engagement` block of follow-up suggestions, and `extra.hints[]` when an argument was corrected. To act on a suggestion, merge its `query_helper.request_patch` into your next call — the patch keys are protocol field paths, so they merge straight into this same request object — echo its `query_helper.origin` back in `intent.origin[]`, and pass the previous `data.request_id` as `context.session.previous_request_id` so already-shown offers are not repeated. Results are relevance-gated: an empty `offers` list is a real answer, not an error.
| Argument | Type | Description |
|---|---|---|
| sort | string | AON private extension (not part of the AgentOffer protocol). Only recommended is supported today; any other value is treated as unset and reported in extra.hints. |
| intent* | object | |
| context | object | |
| pagination | object | AON private extension (not part of the AgentOffer v1.0 request object). |
Submit an explicit user feedback action for an AON Offer. Call only after the user clearly dismisses it or says they are not interested; never infer this from silence or other behavior. This initial scaffold acknowledges the request with success but does not persist feedback or change delivery yet; the internal workflow will be added later.
| Argument | Type | Description |
|---|---|---|
| target* | object | The Offer that received the explicit feedback. |
| feedback* | string | dismissed hides this item temporarily; not_interested cancels the default watch for the target. |
| idempotency_key | string | Optional caller-generated key reserved for idempotent processing when persistence is implemented. |
{
"type": "object",
"required": [
"target",
"feedback"
],
"properties": {
"target": {
"type": "object",
"required": [
"kind",
"id"
],
"properties": {
"id": {
"type": "string",
"maxLength": 256,
"minLength": 1,
"description": "The Offer id returned by AON."
},
"kind": {
"type": "string",
"const": "offer",
"description": "The protocol target kind; feedback currently targets an Offer."
}
},
"description": "The Offer that received the explicit feedback."
},
"feedback": {
"enum": [
"dismissed",
"not_interested"
],
"type": "string",
"description": "dismissed hides this item temporarily; not_interested cancels the default watch for the target."
},
"idempotency_key": {
"type": "string",
"maxLength": 256,
"minLength": 1,
"description": "Optional caller-generated key reserved for idempotent processing when persistence is implemented."
}
}
}| request_id | string | Your idempotency key. Use an unguessable value (UUID). Reuse it to retry the SAME query; if you change what you are asking for, send a NEW id — otherwise you get the previous answer back with no error. Omit it and every call is treated as new. In anonymous mode (no placement_id) request_id is echoed but never replayed — every call is computed fresh. |
| constraints | object |
| force_offer | boolean | The search always stays relevance-gated and returns at least one offer when it is set to true. |
| placement_id | string | Optional ad placement id. This argument takes precedence over the X-AON-Placement-Id HTTP header; when omitted, the header supplies the placement. The placement must be active and identifies the application that receives attribution. If neither is provided (or the value is empty), the call runs in anonymous mode under AON's shared default placement: it works, but earns no attribution or revenue. |
| response_options | object |
{
"type": "object",
"required": [
"intent"
],
"properties": {
"sort": {
"enum": [
"recommended"
],
"type": "string",
"default": "recommended",
"description": "AON private extension (not part of the AgentOffer protocol). Only recommended is supported today; any other value is treated as unset and reported in extra.hints."
},
"intent": {
"type": "object",
"required": [
"content"
],
"properties": {
"origin": {
"type": "array",
"items": {
"type": "object",
"required": [
"kind",
"id"
],
"properties": {
"id": {
"type": "string"
},
"kind": {
"enum": [
"offer",
"category",
"topic",
"query_helper"
],
"type": "string"
}
}
},
"maxItems": 3,
"description": "Echo back the query_helper.origin entries of any suggestion the user accepted."
},
"content": {
"type": "array",
"items": {
"type": "object",
"required": [
"type",
"text"
],
"properties": {
"text": {
"type": "string"
},
"type": {
"enum": [
"input_text"
],
"type": "string"
}
}
},
"description": "The user's intent. One item, single line, under 200 characters — a sentence, not a keyword list."
},
"signals": {
"type": "object",
"properties": {
"budget": {
"type": "object",
"properties": {
"max": {
"type": "number",
"description": "Upper price bound the user accepts."
},
"currency": {
"type": "string",
"description": "ISO 4217 code, e.g. USD, EUR, JPY."
}
}
},
"timeframe": {
"enum": [
"now",
"this_week",
"this_month",
"later"
],
"type": "string",
"description": "When the user wants to act."
},
"purchase_stage": {
"enum": [
"exploring",
"comparing",
"ready_to_buy"
],
"type": "string",
"description": "How far along the user is."
}
},
"description": "Structured intent signals. They are forwarded upstream and enter the shared query pipeline, but this layer makes NO promise that they change the number or order of results."
},
"confidence": {
"type": "number",
"maximum": 1,
"description": "Only with inferred_context. Must be greater than 0.",
"exclusiveMinimum": 0
},
"provenance": {
"enum": [
"user_expressed",
"inferred_context"
],
"type": "string",
"description": "Who produced this intent. inferred_context requires confidence; user_expressed must NOT carry confidence."
}
}
},
"context": {
"type": "object",
"properties": {
"session": {
"type": "object",
"properties": {
"recent_topics": {
"type": "array",
"items": {
"type": "string"
},
"description": "Up to 10 distilled topic phrases (50 chars each) from the recent conversation."
},
"previous_request_id": {
"type": "string",
"description": "data.request_id of the previous round, so offers already shown are not repeated."
}
}
},
"session_id": {
"type": "string",
"description": "Stable, unguessable id for this conversation — use a fresh unique value such as a UUID and reuse it across rounds. With a user identity, cross-round de-duplication engages when both are present; in anonymous mode (no user identity) de-duplication and intent memory are keyed by this id alone, so a guessable value (e.g. 'session-1') would mix your history with other callers'."
},
"user_profile": {
"type": "object",
"properties": {
"country": {
"type": "string",
"description": "Viewer country, uppercase ISO 3166-1 alpha-2 (e.g. US). Used when location_ids is absent."
},
"location_ids": {
"type": "array",
"items": {
"type": "string"
},
"description": "1-10 numeric AON Location Registry ids for the viewer's current location, most specific first. Takes precedence over country. Never infer from the user's text."
},
"user_pseudo_id": {
"type": "string",
"description": "AON private extension (not part of the AgentOffer v1.0 context object). Fallback only — prefer the x-aon-user-pseudo-id HTTP header, which always wins over this field."
},
"verified_age_over": {
"type": "integer",
"maximum": 120,
"minimum": 13,
"description": "Integer the integrator has VERIFIED the viewer is at least (e.g. 18). Never guess or infer it. Offers whose min_age is above it are excluded; omit when unverified and age is not evaluated."
}
},
"description": "Optional viewer targeting context. location_ids, country and verified_age_over are AgentOffer v1.0 fields; user_pseudo_id is an AON private extension."
}
}
},
"pagination": {
"type": "object",
"properties": {
"limit": {
"type": "integer",
"maximum": 20,
"minimum": 1,
"description": "Maximum number of offers to return (default 3, hard cap 20). A spoken count such as \"show me 5\" may raise this up to 20."
},
"offset": {
"type": "integer",
"minimum": 0,
"description": "Number of offers to skip, for paging through a category with limit=20, offset=0/20/40."
}
},
"description": "AON private extension (not part of the AgentOffer v1.0 request object)."
},
"request_id": {
"type": "string",
"description": "Your idempotency key. Use an unguessable value (UUID). Reuse it to retry the SAME query; if you change what you are asking for, send a NEW id — otherwise you get the previous answer back with no error. Omit it and every call is treated as new. In anonymous mode (no placement_id) request_id is echoed but never replayed — every call is computed fresh."
},
"constraints": {
"type": "object",
"properties": {
"offer_types": {
"type": "array",
"items": {
"enum": [
"physical_product",
"digital_goods",
"content",
"online_service",
"offline_service"
],
"type": "string"
},
"description": "Hard filter on offer_info.offer_type. Values are OR; combined with category constraints using AND. Omission preserves inference; [] clears the type filter and suppresses type inference.",
"uniqueItems": true
},
"category_ids": {
"type": "array",
"items": {
"type": "string"
},
"description": "AON Taxonomy v1 category ids, e.g. finance.credit_lending. An unknown id comes back as a correction, not results."
},
"excluded_category_ids": {
"type": "array",
"items": {
"type": "string"
},
"description": "AON Taxonomy v1 category ids to leave out of results. Parent ids exclude descendant offer categories."
}
}
},
"force_offer": {
"type": "boolean",
"default": false,
"description": "The search always stays relevance-gated and returns at least one offer when it is set to true."
},
"placement_id": {
"type": "string",
"description": "Optional ad placement id. This argument takes precedence over the X-AON-Placement-Id HTTP header; when omitted, the header supplies the placement. The placement must be active and identifies the application that receives attribution. If neither is provided (or the value is empty), the call runs in anonymous mode under AON's shared default placement: it works, but earns no attribution or revenue."
},
"response_options": {
"type": "object",
"properties": {
"thinking_mode": {
"type": "boolean",
"default": true,
"description": "Set false to drop the per-offer match_reason explanation from the response."
}
}
}
}
}