Skip to content

Commit ade2b4c

Browse files
committed
feat(order): Get Order operation w/ platform-auth
Add synchronous GET endpoint for order retrieval, complementing the existing webhook push mechanism. Both return the same current-state snapshot shape - webhooks deliver proactively to avoid polling, GET provides on-demand access for reconciliation and conversational use. Authorization model: Who - MUST authenticate (non-negotiable, any UCP mechanism) What - MAY scope access (platform credentials -> own orders, buyer authorization -> buyer's orders, or custom policies) MAY omit or redact fields based on context or business policy When - MAY enforce data availability (retention, erasure)
1 parent d076fc9 commit ade2b4c

7 files changed

Lines changed: 732 additions & 7 deletions

File tree

docs/specification/order-mcp.md

Lines changed: 294 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,294 @@
1+
<!--
2+
Copyright 2026 UCP Authors
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
-->
16+
17+
# Order Capability - MCP Binding
18+
19+
This document specifies the Model Context Protocol (MCP) binding for the
20+
[Order Capability](order.md).
21+
22+
## Protocol Fundamentals
23+
24+
### Discovery
25+
26+
Businesses advertise MCP transport availability through their UCP profile at
27+
`/.well-known/ucp`.
28+
29+
```json
30+
{
31+
"ucp": {
32+
"version": "2026-01",
33+
"services": {
34+
"dev.ucp.shopping": {
35+
"version": "2026-01",
36+
"spec": "https://ucp.dev/specification/overview",
37+
"mcp": {
38+
"schema": "https://ucp.dev/services/shopping/mcp.openrpc.json",
39+
"endpoint": "https://business.example.com/ucp/mcp"
40+
}
41+
}
42+
},
43+
"capabilities": [
44+
{
45+
"name": "dev.ucp.shopping.order",
46+
"version": "2026-01",
47+
"spec": "https://ucp.dev/specification/order",
48+
"schema": "https://ucp.dev/schemas/shopping/order.json"
49+
}
50+
]
51+
}
52+
}
53+
```
54+
55+
### Request Metadata
56+
57+
MCP clients **MUST** include a `meta` object in every request containing
58+
protocol metadata:
59+
60+
```json
61+
{
62+
"jsonrpc": "2.0",
63+
"id": 1,
64+
"method": "tools/call",
65+
"params": {
66+
"name": "get_order",
67+
"arguments": {
68+
"meta": {
69+
"ucp-agent": {
70+
"profile": "https://platform.example/.well-known/ucp"
71+
}
72+
},
73+
"id": "order_abc123"
74+
}
75+
}
76+
}
77+
```
78+
79+
The `meta["ucp-agent"]` field is **required** on all requests to enable
80+
[capability negotiation](overview.md#negotiation-protocol). Platforms **MAY**
81+
include additional metadata fields.
82+
83+
## Tools
84+
85+
UCP Capabilities map 1:1 to MCP Tools.
86+
87+
| Tool | Operation | Description |
88+
| :---- | :---- | :---- |
89+
| `get_order` | [Get Order](order.md#get-order) | Get the current state of an order. |
90+
91+
### `get_order`
92+
93+
Maps to the [Get Order](order.md#get-order) operation. Returns the
94+
current-state snapshot of an order.
95+
96+
#### Input Schema
97+
98+
* `meta` (Object, required): Request metadata with `ucp-agent.profile`.
99+
* `id` (String, required): The ID of the order.
100+
101+
#### Output Schema
102+
103+
{{ schema_fields('order', 'order') }}
104+
105+
#### Example
106+
107+
=== "Request"
108+
109+
```json
110+
{
111+
"jsonrpc": "2.0",
112+
"id": 1,
113+
"method": "tools/call",
114+
"params": {
115+
"name": "get_order",
116+
"arguments": {
117+
"meta": {
118+
"ucp-agent": {
119+
"profile": "https://platform.example/.well-known/ucp"
120+
}
121+
},
122+
"id": "order_abc123"
123+
}
124+
}
125+
}
126+
```
127+
128+
=== "Response"
129+
130+
```json
131+
{
132+
"jsonrpc": "2.0",
133+
"id": 1,
134+
"result": {
135+
"structuredContent": {
136+
"order": {
137+
"ucp": {
138+
"version": "2026-01",
139+
"capabilities": {
140+
"dev.ucp.shopping.order": [{"version": "2026-01"}]
141+
}
142+
},
143+
"id": "order_abc123",
144+
"checkout_id": "checkout_xyz789",
145+
"permalink_url": "https://business.example.com/orders/abc123",
146+
"line_items": [
147+
{
148+
"id": "li_shoes",
149+
"item": { "id": "prod_shoes", "title": "Running Shoes", "price": 3000 },
150+
"quantity": { "total": 1, "fulfilled": 1 },
151+
"totals": [
152+
{"type": "subtotal", "amount": 3000},
153+
{"type": "total", "amount": 3000}
154+
],
155+
"status": "fulfilled"
156+
}
157+
],
158+
"fulfillment": {
159+
"expectations": [
160+
{
161+
"id": "exp_1",
162+
"line_items": [{ "id": "li_shoes", "quantity": 1 }],
163+
"method_type": "shipping",
164+
"destination": {
165+
"street_address": "123 Main St",
166+
"address_locality": "Austin",
167+
"address_region": "TX",
168+
"address_country": "US",
169+
"postal_code": "78701"
170+
},
171+
"description": "Delivered"
172+
}
173+
],
174+
"events": [
175+
{
176+
"id": "evt_1",
177+
"occurred_at": "2026-01-08T10:30:00Z",
178+
"type": "delivered",
179+
"line_items": [{ "id": "li_shoes", "quantity": 1 }],
180+
"tracking_number": "1Z999AA10123456784",
181+
"tracking_url": "https://ups.com/track/1Z999AA10123456784",
182+
"description": "Delivered to front door"
183+
}
184+
]
185+
},
186+
"adjustments": [],
187+
"totals": [
188+
{ "type": "subtotal", "amount": 3000 },
189+
{ "type": "fulfillment", "amount": 800 },
190+
{ "type": "tax", "amount": 304 },
191+
{ "type": "total", "amount": 4104 }
192+
]
193+
}
194+
},
195+
"content": [
196+
{
197+
"type": "text",
198+
"text": "{\"order\":{\"ucp\":{...},\"id\":\"order_abc123\",...}}"
199+
}
200+
]
201+
}
202+
}
203+
```
204+
205+
=== "Not Found"
206+
207+
```json
208+
{
209+
"jsonrpc": "2.0",
210+
"id": 1,
211+
"result": {
212+
"structuredContent": {
213+
"order": {
214+
"ucp": {
215+
"version": "2026-01",
216+
"capabilities": {
217+
"dev.ucp.shopping.order": [{"version": "2026-01"}]
218+
}
219+
},
220+
"messages": [
221+
{
222+
"type": "error",
223+
"code": "not_found",
224+
"content": "Order not found."
225+
}
226+
]
227+
}
228+
},
229+
"content": [
230+
{
231+
"type": "text",
232+
"text": "Order not found."
233+
}
234+
]
235+
}
236+
}
237+
```
238+
239+
=== "Not Authorized"
240+
241+
```json
242+
{
243+
"jsonrpc": "2.0",
244+
"id": 1,
245+
"result": {
246+
"structuredContent": {
247+
"order": {
248+
"ucp": {
249+
"version": "2026-01",
250+
"capabilities": {
251+
"dev.ucp.shopping.order": [{"version": "2026-01"}]
252+
}
253+
},
254+
"messages": [
255+
{
256+
"type": "error",
257+
"code": "unauthorized",
258+
"content": "Not authorized to access this order."
259+
}
260+
]
261+
}
262+
},
263+
"content": [
264+
{
265+
"type": "text",
266+
"text": "Not authorized to access this order."
267+
}
268+
]
269+
}
270+
}
271+
```
272+
273+
## Error Handling
274+
275+
When the business cannot return an order, the response includes a `messages`
276+
array describing the outcome. Platforms **MUST** check `messages` before
277+
accessing order fields.
278+
279+
## Conformance
280+
281+
Platforms implementing the MCP binding:
282+
283+
* **MUST** include `meta.ucp-agent.profile` on all requests
284+
* **MUST** check the `messages` array in responses before accessing order data
285+
* **SHOULD** delegate to the business via `permalink_url` for the authoritative
286+
order experience - the business site is the source of truth for order details
287+
and post-purchase operations
288+
* **SHOULD** rely on webhooks as the primary order update channel and use
289+
`get_order` for reconciliation or on-demand retrieval
290+
291+
Businesses implementing the MCP binding:
292+
293+
* **MUST** authenticate requests to order data before returning a response
294+
(see [Order Capability - Authorization](order.md#authorization))

0 commit comments

Comments
 (0)