The Agentic Returns Integration enables AI agents and chatbots to guide shoppers through the Happy Returns return flow using the Model Context Protocol (MCP). This allows third-party integration partners to build conversational return experiences where an AI assistant can look up orders, present return options, and submit returns on behalf of shoppers.
The integration exposes a set of MCP tools that follow a sequential, guided flow. Each tool returns structured data and navigation metadata that tells the agent which step to perform next.
Agentic Returns currently supports retailers on the Shopify platform. Retailers on other platforms will receive a redirect to the merchant’s return portal or customer support.
| Component | Description |
|---|---|
| MCP Server | Stateless HTTP service exposing MCP tools at POST /returns/mcp via the MCP specification (version 2025-11-25). |
| Session Store | Redis-backed session management with configurable TTL (default 15 minutes). Sessions track return flow state across tool calls. |
| Transport | Streamable HTTP transport (stateless mode). Session continuity is managed by the application-level session_id, not the MCP transport session. |
This integration uses machine-to-machine (M2M) OAuth2 client_credentials flow. Dynamic Client Registration (DCR), Client-Initiated Metadata Discovery (CIMD), and OpenID Connect (OIDC) are not supported.
Contact Happy Returns to receive a client_id and client_secret for your integration.
Exchange your credentials for an access token:
POST https://mcp.happyreturns.com/oauth2/token
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials&client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET&scope=returns/mcp
Sample response:
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6...",
"expires_in": 3600,
"token_type": "Bearer"
}
Include the bearer token in the Authorization header on every request to the MCP endpoint:
POST https://mcp.happyreturns.com/returns/mcp
Authorization: Bearer YOUR_ACCESS_TOKEN
Content-Type: application/json
You are responsible for caching the access token and refreshing it before expiry. The expires_in field in the token response indicates the token’s TTL in seconds. Generate a new token before the current one expires to avoid service interruptions.
Tokens are bound to your client identity. All tool calls within a return session must use the same client credentials. Using a different client’s token mid-session will result in a
CLIENT_MISMATCH error.
Requests are rate-limited per client. When rate-limited, the server returns HTTP 429. Implement exponential backoff in your retry logic.
The return flow consists of six sequential steps. Each tool response includes a flow object that guides the agent to the next step.
getPurchaseDetails
Look up the order by retailer ID, order number, and zip code. Creates a session and returns returnable items.
selectItems
Select one or more items for return. Returns available return reasons for each item.
selectReturnReasons
Submit return reasons (and sub-reasons if applicable) for each item. Returns available refund methods.
selectRefundMethods
Submit refund method selections. Returns available drop-off methods (Return Bar and/or mail).
selectDropoffMethod
Select a drop-off method. Returns a refund preview with itemized details and totals.
startReturn
Submit the return. Returns confirmation details including the express code, QR code or shipping label, and return status page URL.
resetFlow can be called at any point to discard the session and restart from step 1.
getPurchaseDetails succeeds. A unique session_id is returned.startReturn succeeds. The session is marked as completed and only resetFlow is available.SESSION_NOT_FOUND.A Redis-based tool lock ensures that only one tool call executes against a session at a time. If a concurrent call is attempted, the server returns SESSION_PROCESSING_BUSY — the agent should wait briefly and retry.
startReturn is idempotent: if the return was already submitted, calling it again with the same session returns the cached confirmation response rather than creating a duplicate return.
Every tool response includes a flow object with navigation metadata:
| Field | Type | Description |
|---|---|---|
current_step | integer | Current position in the flow (1–6). |
max_steps | integer | Always 6. |
next_tool | string | Suggested next tool to call. Empty after completion. |
allowed_tools | string[] | Tools that may be called in the current state. Calling a tool not in this list returns TOOL_NOT_ALLOWED. |
previous_tool | object | The most recent tool call (name and parameters). Useful for context when resuming a flow or debugging. Not present in the getPurchaseDetails response. |
Your agent should always check allowed_tools before making a tool call. The flow engine dynamically computes which tools are available based on session state.
Every tool response includes two guidance fields in the structured content:
| Field | Description |
|---|---|
agent_instructions | Human-readable text the agent should relay to the shopper. Mirrors the content[].text in the MCP response. |
agent_requirements | Mandatory constraints the agent must follow. Present only when product or legal requirements apply (e.g. displaying the privacy policy, presenting Return Bar before mail). |
Your agent implementation must honor
agent_requirements when present. These include legal requirements such as displaying the Happy Returns privacy policy, and product requirements such as presenting Return Bar drop-off options before mail options.
When a tool call fails, the response includes:
isError: true in the MCP result envelopeerror_code field in the structured content identifying the failure typeagent_instructions message suitable for display to the shopper| Error Code | Description | Recovery |
|---|---|---|
INVALID_INPUT | Missing or malformed parameters | Correct the input and retry |
SESSION_NOT_FOUND | Session expired or not found | Call getPurchaseDetails to start a new session |
SESSION_COMPLETED | Return already submitted | Call getPurchaseDetails for a new return |
CLIENT_MISMATCH | Session belongs to a different client | Ensure all tool calls within a session use the same client credentials |
TOOL_NOT_ALLOWED | Tool not available in current state | Check flow.allowed_tools and call an allowed tool |
SERVICE_ERROR | Internal service failure | Retry with exponential backoff |
SESSION_PROCESSING_BUSY | Another request in progress | Wait briefly and retry |
ORDER_NOT_FOUND | Order not found | Verify retailer ID, order number, and zip code |
RETAILER_NOT_FOUND | Retailer ID not recognized | Verify the retailer ID |
RETAILER_NOT_SUPPORTED | Non-Shopify platform | Direct shopper to the merchant's return portal |
NO_RETURNABLE_ITEMS | No items eligible for return | Inform the shopper; check item details for reasons |
ITEM_NOT_FOUND | Item ID not in the order | Use item IDs from getPurchaseDetails |
ITEM_NOT_ELIGIBLE | Item not returnable | Select a different item |
INVALID_REFUND_METHOD | Invalid refund method ID | Use IDs from selectReturnReasons response |
INVALID_DROPOFF | Invalid drop-off method ID | Use IDs from selectRefundMethods response |
NO_DROPOFF_METHODS | No supported drop-off methods | Direct shopper to the merchant's return portal |
See the API Reference for the complete list of error codes per tool.
This integration uses the Streamable HTTP transport type as defined in MCP specification version 2025-11-25.
All MCP tool calls are sent to a single endpoint:
POST https://mcp.happyreturns.com/returns/mcp
Authorization: Bearer YOUR_ACCESS_TOKEN
Content-Type: application/json
MCP clients (agent frameworks, SDKs) handle the protocol-level details of request framing and response parsing. Your integration should use an MCP-compatible client library to invoke tools by name with the appropriate arguments.
Every tool response includes:
content — Human-readable text the agent can relay to the shopper.structuredContent — Machine-readable data containing the tool’s output fields, agent_instructions, agent_requirements (when applicable), and the flow navigation object.isError — Set to true on failure, with an error_code in structuredContent.MCP clients can discover available tools via the standard tools/list method, which returns tool names, descriptions, and input schemas. Refer to the MCP specification for protocol details.
Always use the flow.next_tool hint and check flow.allowed_tools before making a tool call. The server enforces tool ordering based on session state.
When returning multiple items, selectRefundMethods may return pending_item_ids if some items still need reason or refund method selections. Loop through the remaining items before proceeding to drop-off selection.
When both Return Bar and mail drop-off options are available, always present the Return Bar option first per the agent_requirements guidance. Only offer mail if the shopper declines or no Return Bar locations are available.
On successful getPurchaseDetails, the agent_requirements field includes mandatory privacy policy copy. Your agent must display this to the shopper before presenting item details.
In some regions (EU/UK), the mail drop-off method includes carrier_options with multiple service levels. The service_level parameter is required when calling selectDropoffMethod with mail in these cases.
For SERVICE_ERROR and SESSION_PROCESSING_BUSY responses, implement exponential backoff with a maximum of 3 retries. For SESSION_NOT_FOUND, start a fresh session with getPurchaseDetails.
| Tool | Step | Purpose | Key Inputs |
|---|---|---|---|
getPurchaseDetails | 1 | Look up order, create session | retailer_id, order_number, zip_code |
selectItems | 2 | Select items, get return reasons | session_id, item_ids |
selectReturnReasons | 3 | Submit reasons, get refund methods | session_id, items[].reason |
selectRefundMethods | 4 | Submit refund choices, get drop-off methods | session_id, items[].refund_method |
selectDropoffMethod | 5 | Select drop-off, preview refund | session_id, dropoff_method_id |
startReturn | 6 | Submit return, get confirmation | session_id |
resetFlow | — | Discard session and start over | session_id |
For detailed schemas, sample payloads, and the full error code reference, see the API Reference.