portage-ucp 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +15 -0
  3. data/LICENSE +21 -0
  4. data/README.md +97 -0
  5. data/exe/portage-ucp-check +25 -0
  6. data/lib/portage/ucp/adapter.rb +58 -0
  7. data/lib/portage/ucp/authenticator.rb +26 -0
  8. data/lib/portage/ucp/capabilities/cart.rb +16 -0
  9. data/lib/portage/ucp/capabilities/catalog.rb +11 -0
  10. data/lib/portage/ucp/capabilities/checkout.rb +17 -0
  11. data/lib/portage/ucp/capabilities/identity_linking.rb +13 -0
  12. data/lib/portage/ucp/capabilities/order.rb +11 -0
  13. data/lib/portage/ucp/capability.rb +27 -0
  14. data/lib/portage/ucp/capability_negotiator.rb +40 -0
  15. data/lib/portage/ucp/capability_registry.rb +21 -0
  16. data/lib/portage/ucp/check.rb +96 -0
  17. data/lib/portage/ucp/configuration.rb +35 -0
  18. data/lib/portage/ucp/dispatcher.rb +39 -0
  19. data/lib/portage/ucp/errors.rb +12 -0
  20. data/lib/portage/ucp/manifest.rb +58 -0
  21. data/lib/portage/ucp/mcp/server.rb +83 -0
  22. data/lib/portage/ucp/observability.rb +31 -0
  23. data/lib/portage/ucp/payment_token_guard.rb +41 -0
  24. data/lib/portage/ucp/rack/manifest_endpoint.rb +49 -0
  25. data/lib/portage/ucp/rack/webhook_endpoint.rb +54 -0
  26. data/lib/portage/ucp/rate_limiter.rb +27 -0
  27. data/lib/portage/ucp/resolver.rb +133 -0
  28. data/lib/portage/ucp/schema_validator.rb +53 -0
  29. data/lib/portage/ucp/support/amounts.rb +43 -0
  30. data/lib/portage/ucp/support/api_error.rb +39 -0
  31. data/lib/portage/ucp/support/checkout_state.rb +42 -0
  32. data/lib/portage/ucp/support/http_client.rb +54 -0
  33. data/lib/portage/ucp/support/idempotency.rb +26 -0
  34. data/lib/portage/ucp/support/line_item_status.rb +44 -0
  35. data/lib/portage/ucp/support/not_found.rb +25 -0
  36. data/lib/portage/ucp/support/token_exchange.rb +43 -0
  37. data/lib/portage/ucp/support/totals.rb +31 -0
  38. data/lib/portage/ucp/value_objects.rb +186 -0
  39. data/lib/portage/ucp/version.rb +5 -0
  40. data/lib/portage/ucp/wire_envelope.rb +25 -0
  41. data/lib/portage/ucp.rb +44 -0
  42. data/schemas/2026-04-08/schemas/capability.json +70 -0
  43. data/schemas/2026-04-08/schemas/payment_handler.json +67 -0
  44. data/schemas/2026-04-08/schemas/service.json +190 -0
  45. data/schemas/2026-04-08/schemas/shopping/cart.json +134 -0
  46. data/schemas/2026-04-08/schemas/shopping/catalog_lookup.json +207 -0
  47. data/schemas/2026-04-08/schemas/shopping/catalog_search.json +64 -0
  48. data/schemas/2026-04-08/schemas/shopping/checkout.json +131 -0
  49. data/schemas/2026-04-08/schemas/shopping/discount.json +148 -0
  50. data/schemas/2026-04-08/schemas/shopping/fulfillment.json +154 -0
  51. data/schemas/2026-04-08/schemas/shopping/order.json +113 -0
  52. data/schemas/2026-04-08/schemas/shopping/payment.json +16 -0
  53. data/schemas/2026-04-08/schemas/shopping/types/adjustment.json +69 -0
  54. data/schemas/2026-04-08/schemas/shopping/types/amount.json +8 -0
  55. data/schemas/2026-04-08/schemas/shopping/types/attribution.json +11 -0
  56. data/schemas/2026-04-08/schemas/shopping/types/available_payment_instrument.json +22 -0
  57. data/schemas/2026-04-08/schemas/shopping/types/business_fulfillment_config.json +38 -0
  58. data/schemas/2026-04-08/schemas/shopping/types/buyer.json +25 -0
  59. data/schemas/2026-04-08/schemas/shopping/types/category.json +20 -0
  60. data/schemas/2026-04-08/schemas/shopping/types/context.json +42 -0
  61. data/schemas/2026-04-08/schemas/shopping/types/description.json +22 -0
  62. data/schemas/2026-04-08/schemas/shopping/types/detail_option_value.json +22 -0
  63. data/schemas/2026-04-08/schemas/shopping/types/error_code.json +17 -0
  64. data/schemas/2026-04-08/schemas/shopping/types/error_response.json +31 -0
  65. data/schemas/2026-04-08/schemas/shopping/types/expectation.json +62 -0
  66. data/schemas/2026-04-08/schemas/shopping/types/fulfillment.json +25 -0
  67. data/schemas/2026-04-08/schemas/shopping/types/fulfillment_available_method.json +45 -0
  68. data/schemas/2026-04-08/schemas/shopping/types/fulfillment_destination.json +16 -0
  69. data/schemas/2026-04-08/schemas/shopping/types/fulfillment_event.json +67 -0
  70. data/schemas/2026-04-08/schemas/shopping/types/fulfillment_group.json +45 -0
  71. data/schemas/2026-04-08/schemas/shopping/types/fulfillment_method.json +67 -0
  72. data/schemas/2026-04-08/schemas/shopping/types/fulfillment_option.json +56 -0
  73. data/schemas/2026-04-08/schemas/shopping/types/info_code.json +13 -0
  74. data/schemas/2026-04-08/schemas/shopping/types/input_correlation.json +24 -0
  75. data/schemas/2026-04-08/schemas/shopping/types/item.json +33 -0
  76. data/schemas/2026-04-08/schemas/shopping/types/line_item.json +46 -0
  77. data/schemas/2026-04-08/schemas/shopping/types/link.json +25 -0
  78. data/schemas/2026-04-08/schemas/shopping/types/media.json +36 -0
  79. data/schemas/2026-04-08/schemas/shopping/types/message.json +18 -0
  80. data/schemas/2026-04-08/schemas/shopping/types/message_error.json +49 -0
  81. data/schemas/2026-04-08/schemas/shopping/types/message_info.json +37 -0
  82. data/schemas/2026-04-08/schemas/shopping/types/message_warning.json +53 -0
  83. data/schemas/2026-04-08/schemas/shopping/types/option_value.json +20 -0
  84. data/schemas/2026-04-08/schemas/shopping/types/order_confirmation.json +26 -0
  85. data/schemas/2026-04-08/schemas/shopping/types/order_line_item.json +69 -0
  86. data/schemas/2026-04-08/schemas/shopping/types/pagination.json +62 -0
  87. data/schemas/2026-04-08/schemas/shopping/types/payment_credential.json +17 -0
  88. data/schemas/2026-04-08/schemas/shopping/types/payment_instrument.json +58 -0
  89. data/schemas/2026-04-08/schemas/shopping/types/platform_fulfillment_config.json +14 -0
  90. data/schemas/2026-04-08/schemas/shopping/types/postal_address.json +44 -0
  91. data/schemas/2026-04-08/schemas/shopping/types/price.json +22 -0
  92. data/schemas/2026-04-08/schemas/shopping/types/price_filter.json +17 -0
  93. data/schemas/2026-04-08/schemas/shopping/types/price_range.json +21 -0
  94. data/schemas/2026-04-08/schemas/shopping/types/product.json +89 -0
  95. data/schemas/2026-04-08/schemas/shopping/types/product_option.json +25 -0
  96. data/schemas/2026-04-08/schemas/shopping/types/rating.json +34 -0
  97. data/schemas/2026-04-08/schemas/shopping/types/retail_location.json +28 -0
  98. data/schemas/2026-04-08/schemas/shopping/types/reverse_domain_name.json +8 -0
  99. data/schemas/2026-04-08/schemas/shopping/types/search_filters.json +20 -0
  100. data/schemas/2026-04-08/schemas/shopping/types/selected_option.json +25 -0
  101. data/schemas/2026-04-08/schemas/shopping/types/shipping_destination.json +26 -0
  102. data/schemas/2026-04-08/schemas/shopping/types/signals.json +22 -0
  103. data/schemas/2026-04-08/schemas/shopping/types/signed_amount.json +7 -0
  104. data/schemas/2026-04-08/schemas/shopping/types/total.json +75 -0
  105. data/schemas/2026-04-08/schemas/shopping/types/totals.json +98 -0
  106. data/schemas/2026-04-08/schemas/shopping/types/variant.json +193 -0
  107. data/schemas/2026-04-08/schemas/shopping/types/warning_code.json +13 -0
  108. data/schemas/2026-04-08/schemas/transports/embedded_config.json +27 -0
  109. data/schemas/2026-04-08/schemas/ucp.json +364 -0
  110. data/schemas/2026-04-08/services/shopping/embedded.openrpc.json +634 -0
  111. data/schemas/2026-04-08/services/shopping/mcp.openrpc.json +492 -0
  112. metadata +283 -0
@@ -0,0 +1,492 @@
1
+ {
2
+ "openrpc": "1.3.2",
3
+ "info": {
4
+ "title": "UCP Shopping Service",
5
+ "description": "Canonical MCP/JSON-RPC interface for UCP Shopping service. Schema references are logical pointers - actual payload shape is determined by negotiated capabilities.\n\n**Endpoint Resolution:** This spec defines methods only. The endpoint URL MUST be obtained from the merchant's discovery profile at `/.well-known/ucp` under `services[\"dev.ucp.shopping\"][transport=mcp].endpoint`. The server entry below is a placeholder for tooling compatibility.",
6
+ "version": "2026-04-08"
7
+ },
8
+ "servers": [
9
+ {
10
+ "name": "merchant",
11
+ "url": "{endpoint}",
12
+ "description": "Merchant-provided endpoint from UCP discovery profile",
13
+ "variables": {
14
+ "endpoint": {
15
+ "default": "https://merchant.example.com/ucp/mcp",
16
+ "description": "Obtain from /.well-known/ucp → services[\"dev.ucp.shopping\"][transport=mcp].endpoint"
17
+ }
18
+ }
19
+ }
20
+ ],
21
+ "components": {
22
+ "schemas": {
23
+ "checkout_result": {
24
+ "oneOf": [
25
+ {
26
+ "$ref": "https://ucp.dev/2026-04-08/schemas/shopping/checkout.json"
27
+ },
28
+ {
29
+ "$ref": "https://ucp.dev/2026-04-08/schemas/shopping/types/error_response.json"
30
+ }
31
+ ]
32
+ },
33
+ "cart_result": {
34
+ "oneOf": [
35
+ {
36
+ "$ref": "https://ucp.dev/2026-04-08/schemas/shopping/cart.json"
37
+ },
38
+ {
39
+ "$ref": "https://ucp.dev/2026-04-08/schemas/shopping/types/error_response.json"
40
+ }
41
+ ]
42
+ },
43
+ "order_result": {
44
+ "oneOf": [
45
+ {
46
+ "$ref": "https://ucp.dev/2026-04-08/schemas/shopping/order.json"
47
+ },
48
+ {
49
+ "$ref": "https://ucp.dev/2026-04-08/schemas/shopping/types/error_response.json"
50
+ }
51
+ ]
52
+ },
53
+ "catalog_get_product_result": {
54
+ "oneOf": [
55
+ {
56
+ "$ref": "https://ucp.dev/2026-04-08/schemas/shopping/catalog_lookup.json#/$defs/get_product_response"
57
+ },
58
+ {
59
+ "$ref": "https://ucp.dev/2026-04-08/schemas/shopping/types/error_response.json"
60
+ }
61
+ ]
62
+ },
63
+ "meta": {
64
+ "type": "object",
65
+ "description": "Request metadata.",
66
+ "required": [
67
+ "ucp-agent"
68
+ ],
69
+ "additionalProperties": true,
70
+ "properties": {
71
+ "ucp-agent": {
72
+ "type": "object",
73
+ "description": "Platform agent identification. Maps to HTTP UCP-Agent header.",
74
+ "required": [
75
+ "profile"
76
+ ],
77
+ "properties": {
78
+ "profile": {
79
+ "type": "string",
80
+ "format": "uri",
81
+ "description": "URL to the platform's UCP profile document."
82
+ }
83
+ }
84
+ },
85
+ "idempotency-key": {
86
+ "type": "string",
87
+ "format": "uuid",
88
+ "description": "Unique key for retry safety. Maps to HTTP Idempotency-Key header."
89
+ }
90
+ }
91
+ }
92
+ }
93
+ },
94
+ "methods": [
95
+ {
96
+ "name": "create_checkout",
97
+ "summary": "Create a checkout",
98
+ "description": "Create a new checkout session.",
99
+ "params": [
100
+ {
101
+ "name": "meta",
102
+ "required": true,
103
+ "schema": {
104
+ "$ref": "#/components/schemas/meta"
105
+ }
106
+ },
107
+ {
108
+ "name": "checkout",
109
+ "required": true,
110
+ "schema": {
111
+ "$ref": "https://ucp.dev/2026-04-08/schemas/shopping/checkout.json"
112
+ }
113
+ }
114
+ ],
115
+ "result": {
116
+ "name": "checkout",
117
+ "schema": {
118
+ "$ref": "#/components/schemas/checkout_result"
119
+ }
120
+ }
121
+ },
122
+ {
123
+ "name": "get_checkout",
124
+ "summary": "Get checkout",
125
+ "params": [
126
+ {
127
+ "name": "meta",
128
+ "required": true,
129
+ "schema": {
130
+ "$ref": "#/components/schemas/meta"
131
+ }
132
+ },
133
+ {
134
+ "name": "id",
135
+ "required": true,
136
+ "schema": {
137
+ "type": "string"
138
+ }
139
+ }
140
+ ],
141
+ "result": {
142
+ "name": "checkout",
143
+ "schema": {
144
+ "$ref": "#/components/schemas/checkout_result"
145
+ }
146
+ }
147
+ },
148
+ {
149
+ "name": "update_checkout",
150
+ "summary": "Update checkout",
151
+ "params": [
152
+ {
153
+ "name": "meta",
154
+ "required": true,
155
+ "schema": {
156
+ "$ref": "#/components/schemas/meta"
157
+ }
158
+ },
159
+ {
160
+ "name": "id",
161
+ "required": true,
162
+ "schema": {
163
+ "type": "string"
164
+ }
165
+ },
166
+ {
167
+ "name": "checkout",
168
+ "required": true,
169
+ "schema": {
170
+ "$ref": "https://ucp.dev/2026-04-08/schemas/shopping/checkout.json"
171
+ }
172
+ }
173
+ ],
174
+ "result": {
175
+ "name": "checkout",
176
+ "schema": {
177
+ "$ref": "#/components/schemas/checkout_result"
178
+ }
179
+ }
180
+ },
181
+ {
182
+ "name": "complete_checkout",
183
+ "summary": "Complete checkout and place order",
184
+ "params": [
185
+ {
186
+ "name": "meta",
187
+ "required": true,
188
+ "schema": {
189
+ "allOf": [
190
+ {
191
+ "$ref": "#/components/schemas/meta"
192
+ },
193
+ {
194
+ "required": [
195
+ "ucp-agent",
196
+ "idempotency-key"
197
+ ]
198
+ }
199
+ ]
200
+ }
201
+ },
202
+ {
203
+ "name": "id",
204
+ "required": true,
205
+ "schema": {
206
+ "type": "string"
207
+ }
208
+ },
209
+ {
210
+ "name": "checkout",
211
+ "required": true,
212
+ "schema": {
213
+ "$ref": "https://ucp.dev/2026-04-08/schemas/shopping/checkout.json"
214
+ }
215
+ }
216
+ ],
217
+ "result": {
218
+ "name": "checkout",
219
+ "schema": {
220
+ "$ref": "#/components/schemas/checkout_result"
221
+ }
222
+ }
223
+ },
224
+ {
225
+ "name": "cancel_checkout",
226
+ "summary": "Cancel checkout",
227
+ "params": [
228
+ {
229
+ "name": "meta",
230
+ "required": true,
231
+ "schema": {
232
+ "allOf": [
233
+ {
234
+ "$ref": "#/components/schemas/meta"
235
+ },
236
+ {
237
+ "required": [
238
+ "ucp-agent",
239
+ "idempotency-key"
240
+ ]
241
+ }
242
+ ]
243
+ }
244
+ },
245
+ {
246
+ "name": "id",
247
+ "required": true,
248
+ "schema": {
249
+ "type": "string"
250
+ }
251
+ }
252
+ ],
253
+ "result": {
254
+ "name": "checkout",
255
+ "schema": {
256
+ "$ref": "#/components/schemas/checkout_result"
257
+ }
258
+ }
259
+ },
260
+ {
261
+ "name": "create_cart",
262
+ "summary": "Create a cart",
263
+ "description": "Create a new cart session.",
264
+ "params": [
265
+ {
266
+ "name": "meta",
267
+ "required": true,
268
+ "schema": {
269
+ "$ref": "#/components/schemas/meta"
270
+ }
271
+ },
272
+ {
273
+ "name": "cart",
274
+ "required": true,
275
+ "schema": {
276
+ "$ref": "https://ucp.dev/2026-04-08/schemas/shopping/cart.json"
277
+ }
278
+ }
279
+ ],
280
+ "result": {
281
+ "name": "cart",
282
+ "schema": {
283
+ "$ref": "#/components/schemas/cart_result"
284
+ }
285
+ }
286
+ },
287
+ {
288
+ "name": "get_cart",
289
+ "summary": "Get cart",
290
+ "params": [
291
+ {
292
+ "name": "meta",
293
+ "required": true,
294
+ "schema": {
295
+ "$ref": "#/components/schemas/meta"
296
+ }
297
+ },
298
+ {
299
+ "name": "id",
300
+ "required": true,
301
+ "schema": {
302
+ "type": "string"
303
+ }
304
+ }
305
+ ],
306
+ "result": {
307
+ "name": "cart",
308
+ "schema": {
309
+ "$ref": "#/components/schemas/cart_result"
310
+ }
311
+ }
312
+ },
313
+ {
314
+ "name": "update_cart",
315
+ "summary": "Update cart",
316
+ "params": [
317
+ {
318
+ "name": "meta",
319
+ "required": true,
320
+ "schema": {
321
+ "$ref": "#/components/schemas/meta"
322
+ }
323
+ },
324
+ {
325
+ "name": "id",
326
+ "required": true,
327
+ "schema": {
328
+ "type": "string"
329
+ }
330
+ },
331
+ {
332
+ "name": "cart",
333
+ "required": true,
334
+ "schema": {
335
+ "$ref": "https://ucp.dev/2026-04-08/schemas/shopping/cart.json"
336
+ }
337
+ }
338
+ ],
339
+ "result": {
340
+ "name": "cart",
341
+ "schema": {
342
+ "$ref": "#/components/schemas/cart_result"
343
+ }
344
+ }
345
+ },
346
+ {
347
+ "name": "cancel_cart",
348
+ "summary": "Cancel cart",
349
+ "params": [
350
+ {
351
+ "name": "meta",
352
+ "required": true,
353
+ "schema": {
354
+ "allOf": [
355
+ {
356
+ "$ref": "#/components/schemas/meta"
357
+ },
358
+ {
359
+ "required": [
360
+ "ucp-agent",
361
+ "idempotency-key"
362
+ ]
363
+ }
364
+ ]
365
+ }
366
+ },
367
+ {
368
+ "name": "id",
369
+ "required": true,
370
+ "schema": {
371
+ "type": "string"
372
+ }
373
+ }
374
+ ],
375
+ "result": {
376
+ "name": "cart",
377
+ "schema": {
378
+ "$ref": "#/components/schemas/cart_result"
379
+ }
380
+ }
381
+ },
382
+ {
383
+ "name": "search_catalog",
384
+ "summary": "Search for products in the catalog",
385
+ "description": "Search for products using query text, filters, and pagination.",
386
+ "params": [
387
+ {
388
+ "name": "meta",
389
+ "required": true,
390
+ "schema": {
391
+ "$ref": "#/components/schemas/meta"
392
+ }
393
+ },
394
+ {
395
+ "name": "catalog",
396
+ "required": true,
397
+ "schema": {
398
+ "$ref": "https://ucp.dev/2026-04-08/schemas/shopping/catalog_search.json#/$defs/search_request"
399
+ }
400
+ }
401
+ ],
402
+ "result": {
403
+ "name": "response",
404
+ "schema": {
405
+ "$ref": "https://ucp.dev/2026-04-08/schemas/shopping/catalog_search.json#/$defs/search_response"
406
+ }
407
+ }
408
+ },
409
+ {
410
+ "name": "lookup_catalog",
411
+ "summary": "Batch lookup products or variants by identifier",
412
+ "description": "Batch lookup of products or variants by identifier. See Catalog Lookup capability for supported identifier types and resolution behavior.",
413
+ "params": [
414
+ {
415
+ "name": "meta",
416
+ "required": true,
417
+ "schema": {
418
+ "$ref": "#/components/schemas/meta"
419
+ }
420
+ },
421
+ {
422
+ "name": "catalog",
423
+ "required": true,
424
+ "schema": {
425
+ "$ref": "https://ucp.dev/2026-04-08/schemas/shopping/catalog_lookup.json#/$defs/lookup_request"
426
+ }
427
+ }
428
+ ],
429
+ "result": {
430
+ "name": "response",
431
+ "schema": {
432
+ "$ref": "https://ucp.dev/2026-04-08/schemas/shopping/catalog_lookup.json#/$defs/lookup_response"
433
+ }
434
+ }
435
+ },
436
+ {
437
+ "name": "get_order",
438
+ "summary": "Get order",
439
+ "description": "Get the current state of an order. Returns the full order entity as a current-state snapshot.",
440
+ "params": [
441
+ {
442
+ "name": "meta",
443
+ "required": true,
444
+ "schema": {
445
+ "$ref": "#/components/schemas/meta"
446
+ }
447
+ },
448
+ {
449
+ "name": "id",
450
+ "required": true,
451
+ "schema": {
452
+ "type": "string",
453
+ "description": "The unique identifier of the order."
454
+ }
455
+ }
456
+ ],
457
+ "result": {
458
+ "name": "order",
459
+ "schema": {
460
+ "$ref": "#/components/schemas/order_result"
461
+ }
462
+ }
463
+ },
464
+ {
465
+ "name": "get_product",
466
+ "summary": "Get product details",
467
+ "description": "Retrieve complete product detail by identifier with optional interactive option selection.",
468
+ "params": [
469
+ {
470
+ "name": "meta",
471
+ "required": true,
472
+ "schema": {
473
+ "$ref": "#/components/schemas/meta"
474
+ }
475
+ },
476
+ {
477
+ "name": "catalog",
478
+ "required": true,
479
+ "schema": {
480
+ "$ref": "https://ucp.dev/2026-04-08/schemas/shopping/catalog_lookup.json#/$defs/get_product_request"
481
+ }
482
+ }
483
+ ],
484
+ "result": {
485
+ "name": "response",
486
+ "schema": {
487
+ "$ref": "#/components/schemas/catalog_get_product_result"
488
+ }
489
+ }
490
+ }
491
+ ]
492
+ }