# Interacting with Clinchr

Clinchr's agent-commerce demo: a synthetic catalogue proving the end-to-end agent surface on a domain we control.

Supplementary guidance (the Agent Card is authoritative). All product facts, prices, and availability come from this retailer's catalogue only.

## Transports
- Agent Card (A2A skills): https://commerce-surface-g5mfb3pigq-nw.a.run.app/t/clinchr/.well-known/agent-card.json
- MCP (Streamable HTTP): POST JSON-RPC to https://commerce-surface-g5mfb3pigq-nw.a.run.app/t/clinchr/mcp (tools: get_product, ask_question); call `tools/list` for live schemas, then `tools/call` with `arguments`.
- A2A (JSON-RPC): POST `message/send` to https://commerce-surface-g5mfb3pigq-nw.a.run.app/t/clinchr/a2a (call shape below).
- Plain HTTP (REST): POST https://commerce-surface-g5mfb3pigq-nw.a.run.app/t/clinchr/tools/{tool} (envelope below).

## Request envelope (REST)
Every REST call nests its arguments under `args`; arguments sent at the top level are rejected. Shape: `{"args": {...}, "agent_context": {...}}` (`agent_context` is optional and untrusted).

## Tools
### get_product
Ranked, in-stock catalogue search. Params: `query_text` (string, required), `k` (positive int, optional — how many to return), `session_id` (string, optional — attribution only; search is stateless).

```sh
curl -X POST https://commerce-surface-g5mfb3pigq-nw.a.run.app/t/clinchr/tools/get_product \
  -H 'Content-Type: application/json' \
  -d '{"args": {"query_text": "wireless headphones", "k": 3}}'
```

### ask_question
Grounded, multi-turn Q&A over the catalogue. Params: `session_id` (string, required — see Sessions below), `message` (string, required — the shopper's question).

```sh
curl -X POST https://commerce-surface-g5mfb3pigq-nw.a.run.app/t/clinchr/tools/ask_question \
  -H 'Content-Type: application/json' \
  -d '{"args": {"session_id": "<your-uuid>", "message": "Which headphones are noise-cancelling?"}}'
```

## A2A call shape
`message/send` selects a skill via `message.metadata.skill` (an Agent Card skill id, not the tool name) and reads the tool args from a `data` part. Example for the `find_product` skill:

```json
{"jsonrpc": "2.0", "id": 1, "method": "message/send", "params": {"message": {"metadata": {"skill": "find_product"}, "parts": [{"kind": "data", "data": {"query_text": "wireless headphones"}}]}}}
```

## Sessions
`session_id` is an opaque string YOU generate (e.g. a UUID) and reuse across the turns of one conversation. It is **required** for `ask_question`: answers are conversational, so the surface persists your last query per session to resolve follow-ups (e.g. "is that one waterproof?"). It is scoped per tenant and never shared — a blank or shared id would let one agent's turns bleed into another's, so each conversation must own a unique id. For `get_product` it is optional and used only for telemetry attribution (search is stateless).

## Checkout
Checkout is not enabled for this retailer: `place_order` returns a not-enabled response (or `tool_not_enabled` when the tool is disabled for the tenant). This is expected, not an error — complete purchases on the merchant's store.

## Rate limits
This surface is open to any agent — no API key — and applies per-IP rate limits and daily answer-generation budgets. Over-limit calls return HTTP 429 with a Retry-After header (REST) or a JSON-RPC error with `data.retry_after_seconds` (MCP/A2A); honour them and back off. Oversized queries are rejected with a `query_too_long` error. When the daily answer-generation budget is reached, grounded answers fall back to catalogue facts only (no generation). Contact gabe@clinchr.ai for limit increases or to appeal a restriction.
