AON — Agent Offer Network
VerifiedFeaturedRemoteAbout AON — Agent Offer Network
AON MCP connects MCP-capable agents to searchable offers for real products and services, with live prices and tracked links. Builders can attribute clicks and conversions to an application placement; some feedback and watch tools are acknowledged but not yet persisted.
Key features
- 01Search offers using natural-language intent
- 02Resolve text to taxonomy category IDs
- 03Return live pricing and tracked links
- 04Suggest validated follow-up queries
- 05Optional category decision guidance
- 06Feedback and watch tools in early scaffold
Use cases
- 01Find products matching a user's request
- 02Narrow a search by resolving a category
- 03Present offers with tracked destination links
- 04Ask category-specific questions before searching
MCP support
AON provides tools over stateless Streamable HTTP at `https://api.aon.pro/v1/mcp`. MCP clients can search offers, resolve categories, and access optional category guidance; feedback and watch calls are currently acknowledged but not persisted.
Configuration
Remote servers need no local install. Pick your client, then copy the config or install in one click.
https://api.aon.pro/v1/mcpclaude mcp add --transport http aon-agent-offer-network https://api.aon.pro/v1/mcp{"mcpServers":{"aon-agent-offer-network":{"type":"http","url":"https://api.aon.pro/v1/mcp"}}}Open in Cursor{"servers":{"aon-agent-offer-network":{"type":"http","url":"https://api.aon.pro/v1/mcp"}}}Open in VS Code{"mcpServers":{"aon-agent-offer-network":{"type":"http","url":"https://api.aon.pro/v1/mcp"}}}{"mcpServers":{"aon-agent-offer-network":{"serverUrl":"https://api.aon.pro/v1/mcp"}}}Run commands in a terminal; paste JSON into the client’s MCP config and restart. Servers that need sign-in will prompt on first connect.
https://api.aon.pro/v1/mcpAuth requiredTools
5| Parameter | Type | Required | Description |
|---|---|---|---|
| sort | enum | No | 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.recommended |
| intent | object | Yes | |
| intent.origin | array | No | Echo back the query_helper.origin entries of any suggestion the user accepted. |
| intent.content | array | Yes | The user's intent. One item, single line, under 200 characters — a sentence, not a keyword list. |
| intent.signals | object | No | 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. |
| intent.signals.budget | object | No | |
| intent.signals.budget.max | number | No | Upper price bound the user accepts. |
| intent.signals.budget.currency | string | No | ISO 4217 code, e.g. USD, EUR, JPY. |
| intent.signals.timeframe | enum | No | When the user wants to act.now | this_week | this_month | later |
| intent.signals.purchase_stage | enum | No | How far along the user is.exploring | comparing | ready_to_buy |
| intent.confidence | number | No | Only with inferred_context. Must be greater than 0. |
| intent.provenance | enum | No | Who produced this intent. inferred_context requires confidence; user_expressed must NOT carry confidence.user_expressed | inferred_context |
| context | object | No | |
| context.session | object | No | |
| context.session.recent_topics | array | No | Up to 10 distilled topic phrases (50 chars each) from the recent conversation. |
| context.session.previous_request_id | string | No | data.request_id of the previous round, so offers already shown are not repeated. |
| context.session_id | string | No | 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'. |
| context.user_profile | object | No | Optional viewer targeting context. location_ids, country and verified_age_over are AgentOffer v1.0 fields; user_pseudo_id is an AON private extension. |
| context.user_profile.country | string | No | Viewer country, uppercase ISO 3166-1 alpha-2 (e.g. US). Used when location_ids is absent. |
| context.user_profile.location_ids | array | No | 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. |
| context.user_profile.user_pseudo_id | string | No | 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. |
| context.user_profile.verified_age_over | integer | No | 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. |
| pagination | object | No | AON private extension (not part of the AgentOffer v1.0 request object). |
| pagination.limit | integer | No | 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. |
| pagination.offset | integer | No | Number of offers to skip, for paging through a category with limit=20, offset=0/20/40. |
| request_id | string | No | 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 | No | |
| constraints.category_ids | array | No | AON Taxonomy v1 category ids, e.g. finance.credit_lending. An unknown id comes back as a correction, not results. |
| constraints.excluded_category_ids | array | No | AON Taxonomy v1 category ids to leave out of results. Parent ids exclude descendant offer categories. |
| force_offer | boolean | No | The search always stays relevance-gated and returns at least one offer when it is set to true. |
| placement_id | string | No | 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 | No | |
| response_options.thinking_mode | boolean | No | Set false to drop the per-offer match_reason explanation from the response. |
Details
From the project READMEAON MCP Server
Give any MCP-capable agent the ability to recommend real, buyable products and services — live pricing and a trackable link on every offer, drawn from the Agent Offer Network.
- Endpoint:
POST https://api.aon.pro/v1/mcp - Transport: Streamable HTTP (stateless JSON-RPC 2.0 — no SSE, no session handshake)
- Placement (recommended): send your placement ID in the
X-AON-Placement-Idheader — create one in the Developer Portal. Without it, search still works in anonymous mode, but earnings cannot be attributed to your application - Quick Start: run the curl or client examples with your placement ID
- Docs: docs.aon.pro/mcp
Tools
The Hosted AON endpoint currently lists five tools. Protocol v1.0 names the
four base tools below; aon_get_category_schema is an optional Hosted
category-guidance extension, not a portable Protocol v1.0 guarantee. Discover
it through tools/list before calling it.
aon_search_offers— Search offers by natural-language intent; every result carries live pricing, a tracking link, and pre-validated follow-up suggestions.aon_resolve_category— Turn free text into AON Taxonomy v1 category ids.aon_get_category_schema— Optional Hosted extension: decision factors for a resolved category id, to ask the right clarifying question before searching.aon_submit_feedback— Record an explicit "dismissed" / "not interested" on an offer (early scaffold: acknowledged, not persisted yet).aon_manage_watch— Restore or cancel the default watch on an offer or category on explicit request (early scaffold: acknowledged, not persisted yet).
| Tool | What it does |
|---|---|
aon_search_offers | Search offers by natural-language intent. Arguments are an AgentOffer Query request object — the same shape as the REST API. Returns offers with pricing, a tracking link each, and an engagement block of pre-validated follow-up suggestions the agent can act on. |
aon_resolve_category | Turn free text ("hiking boots", "team chat software") into AON Taxonomy v1 category ids — the model never has to memorize or invent them. |
aon_get_category_schema | Optional Hosted extension: return decision factors for an already resolved category id, to ask the right clarifying question before searching. Its standalone result does not add decision_factors to the Query request or response. |
aon_submit_feedback | Record an explicit "dismissed" / "not interested" from the user on an offer — never inferred from silence. Early scaffold: the call is acknowledged with success, but feedback is not persisted yet; the workflow behind it is rolling out. |
aon_manage_watch | Restore (watch) or cancel (unwatch) the default watch on an offer or category when the user explicitly asks. Early scaffold: acknowledged with success, watch state not persisted yet. |
Design notes agents benefit from:
- Forgiving by design — invalid values never fail a search; they are
treated as "not sent" and corrected in
extra.hints[]. Only a malformed, unknown or inactive placement, invalid JSON, a missingintent.content, or an oversized body hard-fail. A missing placement is not an error: the call runs in anonymous mode. - Relevance-gated — an empty result list is a real answer, never filler.
- Guidance loop — follow-up suggestions carry an RFC 7386
request_patchthat merges straight into the next call, plus anoriginto echo back for adoption attribution.
Quick start
curl -s -X POST https://api.aon.pro/v1/mcp \
-H "Content-Type: application/json" \
-H "X-AON-Placement-Id: $AON_PLACEMENT_ID" \
-d '{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "aon_search_offers",
"arguments": {
"intent": {
"content": [
{ "type": "input_text", "text": "credit card with cashback" }
]
}
}
},
"id": 1
}'
No placement yet? Create an application and a placement in the
Developer Portal, and store the placement ID
(plc_…) in $AON_PLACEMENT_ID. It identifies your placement and is safe to
use in client configuration.
To just try the endpoint, drop the X-AON-Placement-Id header: the call runs in
anonymous mode through AON's shared default placement, the response carries
extra.identity.mode="anonymous", and it earns nothing — clicks and
conversions from anonymous calls cannot be attributed to your application,
including retroactively. Configure your placement ID before real traffic.
Client setup
Ready-to-paste configs live in examples/:
| Client | Config |
|---|---|
| Claude Code | examples/claude-code |
| Claude Desktop | examples/claude-desktop (via mcp-remote) |
| Cursor | examples/cursor |
| VS Code | examples/vscode |
| Plain curl | examples/curl |
Rate limits
/v1/mcp allows 60 tools/call requests per minute per application; handshake
calls (initialize, tools/list, notifications/*) are never counted. An
over-limit tools/call returns HTTP 429 with a Retry-After header and JSON-RPC error -32000 so the
model can read the retry advice. Details:
Rate Limits & FAQ.
Monetization & attribution
Every offer carries a tracked destination link (action.payload.url).
Surface it verbatim — clicks and conversions attribute to your placement's
application, which is the basis for developer revenue share. Reporting lives
in the Developer Portal.
Registry manifest
server.json is the MCP registry manifest for this server
(schema 2025-12-11, namespace pro.aon — DNS-verified against the aon.pro domain).
Related repositories
protocol— AgentOffer Protocol specs (normative)schema— JSON Schemas, TypeScript types, taxonomyexamples— HTTP / SDK / agent integration examplesrfcs— protocol evolution proposals
License
Comments
New to MCP?
From what the protocol is to installing your first server, these answers cover most first questions.
An open protocol that defines how AI applications connect to external tools and data in a uniform way. Clients talk to the model; MCP servers provide tools, resources and prompt templates. They exchange standard messages, so one server can be reused by many clients.