스키마 작성 가이드¶
이 가이드는 UCP JSON 스키마 작성 규칙을 설명합니다. 메타데이터 필드, 레지스트리 패턴, 스키마 변형(variants), 버전 관리를 다룹니다.
스키마 메타데이터 필드¶
UCP 스키마는 표준 JSON Schema 필드와 UCP 전용 메타데이터를 함께 사용합니다.
| Field | Standard | Purpose | Required For |
|---|---|---|---|
$schema |
JSON Schema | JSON Schema draft 버전 선언 (draft/2020-12 SHOULD 사용) |
모든 스키마 |
$id |
JSON Schema | $ref 해석을 위한 스키마의 정규 URI |
모든 스키마 |
title |
JSON Schema | 사람이 읽을 수 있는 표시 이름 | 모든 스키마 |
description |
JSON Schema | 스키마 목적 및 사용 방식 | 모든 스키마 |
name |
UCP | 역도메인 식별자(레지스트리 키로도 사용) | capabilities, services, handlers |
version |
UCP | 엔터티 버전(YYYY-MM-DD 형식) |
capabilities, services, payment handlers |
id |
UCP | 다중 구성 구분을 위한 인스턴스 식별자 | payment handlers 전용 |
왜 Self-Describing인가?¶
Capability 스키마는 self-describing이어야 합니다. 플랫폼이 스키마를 가져왔을 때, 다른 문서를 교차 참조하지 않고도 해당 스키마가 어떤 capability와 버전을 의미하는지 즉시 판단할 수 있어야 합니다. 이는 다음 이유에서 중요합니다.
-
독립 버전 관리: Capability는 독립적으로 버전이 올라갈 수 있습니다. 버전은 URL에서 추론하면 안 되며 스키마 자체가 명시적으로 선언해야 합니다.
-
검증: 검증기는 capability 선언의
schemaURL이 가리키는 스키마 내부의name/version이 선언과 일치하는지 교차 검증할 수 있습니다. 불일치는 작성 오류이며 빌드 시점에 잡아야 합니다. -
개발자 경험: 통합 개발자가 스키마 파일을 읽을 때,
$idURL을 역추적하지 않아도 해당 capability를 즉시 이해할 수 있습니다. -
간결한 네임스페이스:
name필드는 표준화된 역도메인 식별자(예:dev.ucp.shopping.checkout)를 제공하며, 전체$idURL보다 간결하고 의미적으로 명확합니다.
왜 $id와 name을 둘 다 쓰는가?¶
| Field | Role | Format |
|---|---|---|
$id |
$ref 해석과 툴링을 위한 JSON Schema 기본 식별자 |
URI (스펙상 필수) |
name |
레지스트리 키이자 안정적 식별자 | 역도메인 |
JSON Schema 스펙에 따라 $id는 유효한 URI여야 합니다.
name은 레지스트리(capabilities, services, payment_handlers)에서 사용하는 키이며,
capability 협상에서 wire protocol 식별자로 사용됩니다.
즉, 인프라 변화에 따라 schema URL이 바뀌더라도 식별 체계는 분리되어 유지됩니다.
역도메인 형식은 네임스페이스 거버넌스를 제공합니다.
도메인 소유자가 자신의 네임스페이스(dev.ucp.*, com.shopify.*)를 통제해
UCP 엔터티와 벤더 엔터티 간 충돌을 피할 수 있습니다.
이 안정적인 식별 계층 덕분에,
향후 검증 가능한 자격증명, content-addressed 스키마 등으로
신뢰·해석 메커니즘이 진화해도 capability 협상은 깨지지 않습니다.
왜 version에 날짜를 쓰는가?¶
version 필드는 날짜 기반 버전(YYYY-MM-DD)을 사용하여 다음을 가능하게 합니다.
- Capability 협상: 플랫폼이 지원하는 특정 버전을 요청
- 브레이킹 체인지 관리: 새 버전은 새 날짜를 사용하고, 기존 버전은 유효하고 해석 가능하게 유지
- 독립 릴리스 주기: Extension이 자체 일정으로 릴리스 가능
스키마 카테고리¶
UCP 스키마는 프로토콜 내 역할에 따라 6개 카테고리로 구분됩니다.
Capability 스키마¶
ucp.capabilities{} 레지스트리에 나타나는 협상 대상 capability를 정의합니다.
- Top-level fields:
$schema,$id,title,description,name,version - Variants:
platform_schema,business_schema,response_schema
예시: checkout.json, fulfillment.json, discount.json, order.json
Service 스키마¶
ucp.services{} 레지스트리에 나타나는 전송 바인딩을 정의합니다.
각 전송(REST, MCP, A2A, Embedded)은 별도 엔트리입니다.
- Top-level fields:
$schema,$id,title,description,name,version - Variants:
platform_schema,business_schema - 전송별 요구사항:
- REST/MCP:
endpoint,schema(OpenAPI/OpenRPC URL) - A2A:
endpoint(Agent Card URL) - Embedded:
schema(OpenRPC URL)
- REST/MCP:
Payment Handler 스키마¶
ucp.payment_handlers{} 레지스트리의 payment handler 구성을 정의합니다.
- Top-level fields:
$schema,$id,title,description,name,version - Variants:
platform_schema,business_schema,response_schema - 인스턴스
id: 동일 handler의 다중 구성을 구분하기 위해 필수
예시: com.google.pay, dev.shopify.shop_pay, dev.ucp.processor_tokenizer
→ Handler 구조, config/instrument/credential 스키마, 전체 명세 템플릿은 Payment Handler Guide를 참고하세요.
Component 스키마¶
Capability 내부에 포함되는 데이터 구조이며 독립 협상 대상이 아닙니다. 레지스트리에 나타나지 않습니다.
- Top-level fields:
$schema,$id,title,description - 생략:
name,version(독립 버전 대상 아님)
예시:
schemas/shopping/payment.json— Payment 구성(Checkout의 일부)
Type 스키마¶
다른 스키마가 재사용하는 정의입니다. 레지스트리에 나타나지 않습니다.
- Top-level fields:
$schema,$id,title,description - 생략:
name,version
예시: types/buyer.json, types/line_item.json, types/postal_address.json
Meta 스키마¶
엔터티 payload가 아니라 프로토콜 구조 자체를 정의합니다.
- Top-level fields:
$schema,$id,title,description - 생략:
name,version
예시: ucp.json (entity base), capability.json, service.json, payment_handler.json
레지스트리 패턴¶
UCP는 capability, service, handler를
name을 키로 가지는 객체 레지스트리로 구성합니다.
(name 필드가 포함된 객체 배열을 기본 구조로 쓰지 않음)
{
"capabilities": {
"dev.ucp.shopping.checkout": [{"version": "2026-01-11"}],
"dev.ucp.shopping.fulfillment": [{"version": "2026-01-11"}]
},
"services": {
"dev.ucp.shopping": [
{"version": "2026-01-11", "transport": "rest"},
{"version": "2026-01-11", "transport": "mcp"}
]
},
"payment_handlers": {
"com.google.pay": [{"id": "gpay_1234", "version": "2026-01-11"}]
}
}
레지스트리 컨텍스트¶
동일한 레지스트리 구조가 3개 컨텍스트에서 재사용되며, 각 컨텍스트별 필수 필드가 다릅니다.
| Context | Location | Required Fields |
|---|---|---|
| Platform Profile | 공지된 URI | version, spec, schema |
| Business Profile | /.well-known/ucp |
version; 필요 시 config 추가 |
| API Responses | Checkout/order payload | version (+ handlers의 경우 id) |
엔터티 패턴¶
모든 capability, service, handler는 공통 entity 베이스 스키마를 확장합니다.
| Field | Type | Description |
|---|---|---|
version |
string | 엔터티 버전(YYYY-MM-DD) — 항상 필수 |
spec |
URI | 사람이 읽을 수 있는 명세 문서 |
schema |
URI | JSON Schema URL |
id |
string | 인스턴스 식별자(handlers 전용) |
config |
object | 엔터티별 설정 |
스키마 변형(Variants)¶
각 엔터티 타입은 컨텍스트별로 3가지 변형을 정의합니다.
platform_schema — discovery용 전체 선언
{
"dev.ucp.shopping.fulfillment": [{
"version": "2026-01-11",
"spec": "https://ucp.dev/specification/fulfillment",
"schema": "https://ucp.dev/schemas/shopping/fulfillment.json",
"config": {
"supports_multi_group": true
}
}]
}
business_schema — 비즈니스별 오버라이드
{
"dev.ucp.shopping.fulfillment": [{
"version": "2026-01-11",
"config": {
"allows_multi_destination": {"shipping": true}
}
}]
}
response_schema — API 응답용 최소 참조
스키마의 $defs에 세 변형을 모두 정의하세요.
"$defs": {
"platform_schema": {
"allOf": [{"$ref": "../capability.json#/$defs/platform_schema"}]
},
"business_schema": {
"allOf": [{"$ref": "../capability.json#/$defs/business_schema"}]
},
"response_schema": {
"allOf": [{"$ref": "../capability.json#/$defs/response_schema"}]
}
}
버전 전략¶
UCP Capability (dev.ucp.*)¶
UCP가 작성한 capability는 기본적으로 프로토콜 릴리스와 함께 버전이 올라갑니다. 필요 시 개별 capability가 독립 버전으로 분리될 may 가능성도 있습니다.
Vendor Capability (com.{vendor}.*)¶
dev.ucp.* 외 capability는 완전히 독립적으로 버전 관리합니다.
{
"name": "com.shopify.loyalty",
"version": "2025-09-01",
"spec": "https://shopify.dev/ucp/loyalty",
"schema": "https://shopify.dev/ucp/schemas/loyalty.json"
}
Vendor 스키마도 동일한 self-describing 요구사항을 따라야 합니다.
완전한 예시: Capability 스키마¶
Capability 스키마는 payload 구조와 선언 변형을 함께 정의합니다.
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://ucp.dev/schemas/shopping/checkout.json",
"name": "dev.ucp.shopping.checkout",
"version": "2026-01-11",
"title": "Checkout",
"description": "Base checkout schema. Extensions compose via allOf.",
"$defs": {
"platform_schema": {
"allOf": [{"$ref": "../capability.json#/$defs/platform_schema"}]
},
"business_schema": {
"allOf": [{"$ref": "../capability.json#/$defs/business_schema"}]
},
"response_schema": {
"allOf": [{"$ref": "../capability.json#/$defs/response_schema"}]
}
},
"type": "object",
"required": ["ucp", "id", "line_items", "status", "currency", "totals", "links"],
"properties": {
"ucp": {"$ref": "../ucp.json#/$defs/response_checkout_schema"},
"id": {"type": "string", "description": "Checkout identifier"},
"line_items": {"type": "array", "items": {"$ref": "types/line_item.json"}},
"status": {"type": "string", "enum": ["open", "completed", "expired"]},
"currency": {"type": "string", "pattern": "^[A-Z]{3}$"},
"totals": {"$ref": "types/totals.json"},
"links": {"$ref": "types/links.json"}
}
}
핵심 요점:
- Top-level
name,version으로 스키마를 self-describing하게 유지 $defsvariants로 컨텍스트별 검증 지원- Payload properties로 실제 checkout 응답 구조 정의