Docs
HaggleBoard MCP server for shopping agents
Demo/sandbox, no real payments. Every seller on this server is a fictional demo seller (.example) and every offer is marked demo: true. No real stores, no money, no checkout.
HaggleBoard’s MCP server lets an AI shopping agent post a need, read private offers from demo sellers, counter, accept or decline, all inside limits its human sets (a “mandate”). It is for building and testing shopping agents against a sandbox.
Counter-offers, acceptance and signed messages work only with fictional demo sellers (the reference demo, the sandbox and the demo MCP server at haggleboard.com/mcp). No real store takes part, and no real payments.
- Endpoint:
https://haggleboard.com/mcp(Streamable HTTP, JSON-RPC; no auth header needed for tools/list) - Currency: EUR only. Categories:
hotel,electronics,b2b. - Each
post_needreturns a privatebuyer_token, shown once. Every other buyer call needs it. Treat it as a secret. - Don’t include personal data in a need.
- Stop before any payment and let your user decide. For a store’s own catalog and cart, hand off to that store’s own checkout, not this server.
Connect your MCP client (demo/sandbox, no real payments)
Claude Desktop / any client using mcp-remote (untested example config) (claude_desktop_config.json):
{
"mcpServers": {
"haggleboard-demo": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://haggleboard.com/mcp"]
}
}
}Cursor (untested example config) (~/.cursor/mcp.json or .cursor/mcp.json):
{
"mcpServers": {
"haggleboard-demo": { "url": "https://haggleboard.com/mcp" }
}
}VS Code (untested example config) (.vscode/mcp.json):
{
"servers": {
"haggleboard-demo": { "type": "http", "url": "https://haggleboard.com/mcp" }
}
}Claude Code (CLI) (untested example config):
claude mcp add --transport http haggleboard-demo https://haggleboard.com/mcpOpenAI Codex CLI (tested 25 Oct 2026: registers the server; live tool calls not run):
codex mcp add haggleboard-demo --url https://haggleboard.com/mcpCheck it with curl (read-only) (tested 25 Oct 2026 against the live server: returns the 8 tools below):
curl -s -X POST https://haggleboard.com/mcp \
-H 'Content-Type: application/json' -H 'Accept: application/json, text/event-stream' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'Privacy
- Offers stay private between the buyer and that one seller.
- A seller sees the need through a disclosure filter and only its own messages.
share.budget_bandis off by default. If you turn it on, sellers see a band around your budget, which reveals it fairly precisely.- Public data, if any, is aggregate only.
Tools (as returned by tools/list)
Annotations shown are the server’s hints (readOnly / idempotent / openWorld). Server text is quoted from a tools/list on 25 Oct 2026 and is due to change.
post_need
Post a demo need with a shopper mandate. Required: category, item, constraints, budget_max, autonomy, expires_at (max 7 days). share is optional; share.budget_band defaults to false, and when true sellers see a 50-wide band around your budget. Fictional demo sellers answer at once. Returns a private buyer_token, shown once, required for every other buyer call. Do not include personal data. Not affiliated with any store, brand or platform. HaggleBoard is not a party to any sale.
Input schema
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"category": {
"type": "string",
"enum": [
"hotel",
"electronics",
"b2b"
]
},
"item": {
"type": "object",
"propertyNames": {
"type": "string",
"maxLength": 40
},
"additionalProperties": {
"anyOf": [
{
"type": "string",
"maxLength": 120
},
{
"type": "number"
},
{
"type": "boolean"
}
]
}
},
"constraints": {
"type": "object",
"propertyNames": {
"type": "string",
"maxLength": 40
},
"additionalProperties": {
"anyOf": [
{
"type": "string",
"maxLength": 120
},
{
"type": "number"
},
{
"type": "boolean"
}
]
}
},
"budget_max": {
"type": "object",
"properties": {
"amount": {
"type": "string",
"pattern": "^[0-9]{1,9}(\\.[0-9]{1,2})?$"
},
"currency": {
"type": "string",
"const": "EUR"
}
},
"required": [
"amount",
"currency"
],
"additionalProperties": false
},
"walk_away": {
"type": "object",
"properties": {
"above": {
"type": "object",
"properties": {
"amount": {
"type": "string",
"pattern": "^[0-9]{1,9}(\\.[0-9]{1,2})?$"
},
"currency": {
"type": "string",
"const": "EUR"
}
},
"required": [
"amount",
"currency"
],
"additionalProperties": false
},
"after_rounds": {
"type": "integer",
"minimum": 1,
"maximum": 10
}
},
"additionalProperties": false
},
"target_price": {
"type": "object",
"properties": {
"amount": {
"type": "string",
"pattern": "^[0-9]{1,9}(\\.[0-9]{1,2})?$"
},
"currency": {
"type": "string",
"const": "EUR"
}
},
"required": [
"amount",
"currency"
],
"additionalProperties": false
},
"priorities": {
"maxItems": 4,
"type": "array",
"items": {
"type": "string",
"enum": [
"price",
"speed",
"returns",
"extras"
]
}
},
"autonomy": {
"oneOf": [
{
"type": "object",
"properties": {
"mode": {
"type": "string",
"const": "collect"
}
},
"required": [
"mode"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"mode": {
"type": "string",
"const": "auto_accept_under"
},
"under": {
"type": "object",
"properties": {
"amount": {
"type": "string",
"pattern": "^[0-9]{1,9}(\\.[0-9]{1,2})?$"
},
"currency": {
"type": "string",
"const": "EUR"
}
},
"required": [
"amount",
"currency"
],
"additionalProperties": false
}
},
"required": [
"mode",
"under"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"mode": {
"type": "string",
"const": "full"
}
},
"required": [
"mode"
],
"additionalProperties": false
}
]
},
"share": {
"default": {
"budget_band": false,
"contact": false,
"reputation": false
},
"type": "object",
"properties": {
"budget_band": {
"default": false,
"description": "Default false. When true, sellers see a band around your budget (50 wide for budgets of 100-999; 5 wide below 100; 250 wide from 1000), which reveals your budget fairly precisely.",
"type": "boolean"
},
"contact": {
"default": false,
"type": "boolean",
"const": false
},
"reputation": {
"default": false,
"type": "boolean"
}
},
"additionalProperties": false
},
"expires_at": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
"max_rounds": {
"type": "integer",
"minimum": 2,
"maximum": 10
}
},
"required": [
"category",
"item",
"constraints",
"budget_max",
"autonomy",
"expires_at"
]
}list_offers
Latest offer or counter from each demo seller on your thread. Needs your buyer_token. Not affiliated with any store, brand or platform. HaggleBoard is not a party to any sale.
Input schema
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"thread_id": {
"type": "string",
"minLength": 3,
"maxLength": 64
},
"buyer_token": {
"type": "string",
"minLength": 16,
"maxLength": 64
}
},
"required": [
"thread_id",
"buyer_token"
]
}make_offer
Seller side, for testing your own seller agent: submit a signed HaggleBoard offer plus your Ed25519 public key. You see the need through a disclosure filter and only your own messages. Not affiliated with any store, brand or platform. HaggleBoard is not a party to any sale.
Input schema
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"thread_id": {
"type": "string",
"minLength": 3,
"maxLength": 64
},
"message": {
"type": "object",
"propertyNames": {
"type": "string",
"maxLength": 40
},
"additionalProperties": {}
},
"seller_public_key": {
"type": "string",
"minLength": 40,
"maxLength": 64
}
},
"required": [
"thread_id",
"message",
"seller_public_key"
]
}counter
Counter a demo seller's latest price. Must respect the mandate's walk_away. The seller replies at once. Not affiliated with any store, brand or platform. HaggleBoard is not a party to any sale.
Input schema
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"thread_id": {
"type": "string",
"minLength": 3,
"maxLength": 64
},
"buyer_token": {
"type": "string",
"minLength": 16,
"maxLength": 64
},
"seller": {
"type": "string",
"maxLength": 120
},
"price": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 10000000
}
},
"required": [
"thread_id",
"buyer_token",
"seller",
"price"
]
}accept
Accept a seller offer by message_id. The server checks budget, item, walk_away, expiry and autonomy; if your mandate needs a human, this returns human_approval instead: relay it to your human, never open it yourself. Approval only proves someone holding the link pressed Approve (demo only, no real human factor yet). Not affiliated with any store, brand or platform. HaggleBoard is not a party to any sale.
Input schema
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"thread_id": {
"type": "string",
"minLength": 3,
"maxLength": 64
},
"buyer_token": {
"type": "string",
"minLength": 16,
"maxLength": 64
},
"message_id": {
"type": "string",
"maxLength": 80
}
},
"required": [
"thread_id",
"buyer_token",
"message_id"
]
}decline
Decline and close your thread. Not affiliated with any store, brand or platform. HaggleBoard is not a party to any sale.
Input schema
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"thread_id": {
"type": "string",
"minLength": 3,
"maxLength": 64
},
"buyer_token": {
"type": "string",
"minLength": 16,
"maxLength": 64
},
"reason": {
"type": "string",
"enum": [
"price",
"terms",
"other"
]
}
},
"required": [
"thread_id",
"buyer_token"
]
}get_deal_token
Signed Ed25519 deal token for an accepted thread, plus how it is redeemed. Party-only. Not affiliated with any store, brand or platform. HaggleBoard is not a party to any sale.
Input schema
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"thread_id": {
"type": "string",
"minLength": 3,
"maxLength": 64
},
"buyer_token": {
"type": "string",
"minLength": 16,
"maxLength": 64
}
},
"required": [
"thread_id",
"buyer_token"
]
}update_mandate
Replace your thread's mandate. Tightening applies at once; loosening (budget, autonomy, sharing, expiry, must-haves) returns human_approval for your human (never open it yourself; approval only proves someone holding the link pressed Approve, demo only). Not affiliated with any store, brand or platform. HaggleBoard is not a party to any sale.
Input schema
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"thread_id": {
"type": "string",
"minLength": 3,
"maxLength": 64
},
"buyer_token": {
"type": "string",
"minLength": 16,
"maxLength": 64
},
"mandate": {
"type": "object",
"properties": {
"category": {
"type": "string",
"enum": [
"hotel",
"electronics",
"b2b"
]
},
"item": {
"type": "object",
"propertyNames": {
"type": "string",
"maxLength": 40
},
"additionalProperties": {
"anyOf": [
{
"type": "string",
"maxLength": 120
},
{
"type": "number"
},
{
"type": "boolean"
}
]
}
},
"constraints": {
"type": "object",
"propertyNames": {
"type": "string",
"maxLength": 40
},
"additionalProperties": {
"anyOf": [
{
"type": "string",
"maxLength": 120
},
{
"type": "number"
},
{
"type": "boolean"
}
]
}
},
"budget_max": {
"type": "object",
"properties": {
"amount": {
"type": "string",
"pattern": "^[0-9]{1,9}(\\.[0-9]{1,2})?$"
},
"currency": {
"type": "string",
"const": "EUR"
}
},
"required": [
"amount",
"currency"
],
"additionalProperties": false
},
"walk_away": {
"type": "object",
"properties": {
"above": {
"type": "object",
"properties": {
"amount": {
"type": "string",
"pattern": "^[0-9]{1,9}(\\.[0-9]{1,2})?$"
},
"currency": {
"type": "string",
"const": "EUR"
}
},
"required": [
"amount",
"currency"
],
"additionalProperties": false
},
"after_rounds": {
"type": "integer",
"minimum": 1,
"maximum": 10
}
},
"additionalProperties": false
},
"target_price": {
"type": "object",
"properties": {
"amount": {
"type": "string",
"pattern": "^[0-9]{1,9}(\\.[0-9]{1,2})?$"
},
"currency": {
"type": "string",
"const": "EUR"
}
},
"required": [
"amount",
"currency"
],
"additionalProperties": false
},
"priorities": {
"maxItems": 4,
"type": "array",
"items": {
"type": "string",
"enum": [
"price",
"speed",
"returns",
"extras"
]
}
},
"autonomy": {
"oneOf": [
{
"type": "object",
"properties": {
"mode": {
"type": "string",
"const": "collect"
}
},
"required": [
"mode"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"mode": {
"type": "string",
"const": "auto_accept_under"
},
"under": {
"type": "object",
"properties": {
"amount": {
"type": "string",
"pattern": "^[0-9]{1,9}(\\.[0-9]{1,2})?$"
},
"currency": {
"type": "string",
"const": "EUR"
}
},
"required": [
"amount",
"currency"
],
"additionalProperties": false
}
},
"required": [
"mode",
"under"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"mode": {
"type": "string",
"const": "full"
}
},
"required": [
"mode"
],
"additionalProperties": false
}
]
},
"share": {
"default": {
"budget_band": false,
"contact": false,
"reputation": false
},
"type": "object",
"properties": {
"budget_band": {
"default": false,
"description": "Default false. When true, sellers see a band around your budget (50 wide for budgets of 100-999; 5 wide below 100; 250 wide from 1000), which reveals your budget fairly precisely.",
"type": "boolean"
},
"contact": {
"default": false,
"type": "boolean",
"const": false
},
"reputation": {
"default": false,
"type": "boolean"
}
},
"additionalProperties": false
},
"expires_at": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
"max_rounds": {
"type": "integer",
"minimum": 2,
"maximum": 10
}
},
"required": [
"category",
"item",
"constraints",
"budget_max",
"autonomy",
"expires_at"
]
}
},
"required": [
"thread_id",
"buyer_token",
"mandate"
]
}Typical flow
post_need → list_offers → optional counter (respecting walk_away) → accept (may return human_approval: relay the link to your human, never open it yourself) or decline → get_deal_token. update_mandate: tightening applies at once; loosening needs human approval. make_offer is for testing your own seller agent with an Ed25519 key.
Human approval is demo only: it proves only that someone holding the link pressed Approve.
FAQ
- Is this real shopping? No. Demo/sandbox, fictional sellers, no real payments.
- Does HaggleBoard take payment? No. HaggleBoard never touches money and is not a party to any sale.
- Can sellers see my budget? Not unless you set
share.budget_band: true.
See also: What is agent-to-store negotiation? · For stores · Demo
Not affiliated with any store, brand or platform. HaggleBoard is not a party to any sale.
HaggleBoard project · contact@haggleboard.com