Status: Draft
Version: 0.1.0-draft
Companion Context Protocol (CCP) defines a vendor-neutral contract for permissioned companion-animal context exchange.
CCP lets authorized systems request only the pet context needed for a task, with consent, provenance, and safety boundaries.
This document is a draft protocol proposal. It is not a consensus standard, certification program, or adopted industry baseline. Implementers should treat it as design-partner review material until independent systems have reviewed the model, attempted implementations, and resolved compatibility feedback in public artifacts.
The protocol defines:
CCP is transport-neutral. JSON Schema is the canonical contract. MCP, OpenAPI/HTTP, SDKs, and other transports can implement CCP-compatible flows.
CCP is not:
CCP separates the domain contract from integration transports.
The same CCP request should be expressible through multiple surfaces:
A transport is CCP-compatible when it preserves the same authorization, minimization, provenance, visibility, and omission semantics.
MCP is one adapter for CCP. It is not the protocol itself.
Actor: A person, organization, system, agent, or service requesting or acting on context.
Actor type: A discrete trust posture for an actor in policy evaluation. The draft defines seven values:
owner — primary consent authority for a pet.caregiver — a person granted ongoing care responsibility by an owner (e.g., a partner, family member, or paid caregiver).facility — an organization providing in-person services (boarding, daycare, grooming) acting under a service agreement.merchant — a commerce-side actor requesting commerce-safe context for product recommendation or filtering.agent_client — software acting on behalf of an authenticated end-user (e.g., an LLM assistant carrying out a user task). The user is in the loop.service_integration — a system-to-system non-interactive client running under its own credentials (e.g., a vendor backend syncing on a schedule). No human is in the loop at request time.vet — reserved for veterinary-side actors. No vet profile, scope, or flow exists in this draft. The normative server requirement to reject requester_actor_type: "vet" until a vet-export profile is defined appears in Conformance Requirements.The boundary between agent_client and service_integration is interactive consent capability. An agent_client represents a session in which the user can be re-prompted for consent during the request lifecycle; a service_integration cannot. Asynchronous workflows triggered by a prior user action but processed without an interactive session are service_integration. Implementers should err toward service_integration when consent freshness cannot be re-established at request time.
CareNetworkActorType (the relationship enum used by pickup_actor_type, PickupActor.actor_type, and CareNetworkActorRef.actor_type) shares some value names with ActorType (e.g., owner, caregiver) but is a distinct namespace. A care-network relationship value MUST NOT be used to infer a global ActorType trust posture; it describes a candidate’s relationship to a pet, not the requester’s policy class.
Requests, grants, and authorization decisions all carry actor types so that scope evaluation, omission rules, and audit records can distinguish, for example, an agent acting on behalf of an owner from a merchant requesting context directly. Actor type is policy metadata — it does not by itself grant access. The server-side binding requirement appears in Conformance Requirements. Future drafts may extend this enum as new profiles (e.g., vet export) land.
Pet: The companion animal that context describes.
Owner: An actor with primary consent authority for a pet, subject to future multi-owner rules.
Caregiver: An actor delegated by an owner or facility to perform specific care-related tasks.
Requester: The actor or client asking for context.
Grant: A permission record authorizing a requester to access specific context for a specific pet, purpose, and time window. Grants carry the actor type of both the grantor and the grantee. Grant issuance, storage, presentation, signature format, revocation propagation, and proof-of-possession are not standardized in this draft.
Purpose: The task or reason for the request, such as product_recommendation.
Visibility class: A safety label that constrains where a context item may be exposed.
Provenance: Metadata describing where a fact came from, when it was recorded, and how trustworthy or fresh it is.
Omission: A machine-readable explanation that context exists or was requested but was not returned.
The draft ships four narrow schema-backed slices: Care Facility Context (boarding_preparation), Care Facility Pickup Verification (pickup_verification), Care Network Lookup (care_network_lookup), and Commerce Context.
Profile order in this section is not a claim about market priority or ecosystem consensus. The Care Facility and Care Network slices are listed first because they sit closest to a clear custodian (the facility’s practice-management or facility-management system) and a concrete operational pain point — intake-form re-keying, pickup-desk verification, and ambiguous caregiver contact and authority. Commerce Context is listed after because, while its schemas are equally complete, merchants already capture pet profiles at signup and the consent path runs through the merchant rather than a third-party protocol — so Commerce should not be treated as the canonical worked example.
The boarding-preparation slice lets an authorized care facility request boarding-preparation context for one pet, facility, and service window. The pickup-verification slice lets an authorized care facility verify whether one pickup actor may pick up one pet for one facility and service window. The Care Network lookup slice lets an authorized requester retrieve a minimized actor, relationship, contact-channel, action-authorization, or revocation subset for one pet and one subject actor.
The boarding-preparation care-facility slice can include:
The boarding-preparation care-facility slice excludes by default:
The Commerce Context Profile lets authorized clients request commerce-safe pet context for product recommendations and filtering while excluding unrelated sensitive context. It remains a valid profile, but it is not the lead adoption wedge — implementers reviewing CCP for the first time should generally start with the Care Facility flows above.
The Commerce profile should support:
The Commerce profile should exclude by default:
Facility Truth is a design candidate, not a schema-backed profile in this version. It would cover public or operational facility facts such as hours, services, service areas, eligibility constraints, certifications, contact methods, booking links, accepted pet types, freshness, and provenance. It should be developed separately from pet-specific context because public facility facts have different consent, authorization, and provenance requirements — the design proposes that a public-facts subset could be served without a PermissionGrant, which would remove the grant-transport prerequisites that gate the pet-specific profiles. Facility Truth is the strongest design candidate ahead of expanding Commerce, and its promotion to a schema-backed profile is tracked separately.
PetProfileBasic pet identity and physical context needed for safe compatibility filtering.
Identifiers such as pet_id remain plain strings. Returned context fields are field envelopes containing:
valuevisibilityprovenanceProvenance is mandatory audit metadata for returned facts and summaries. It is not a separately grantable context scope in the Commerce Context Profile.
The Commerce Context Profile minimizes canonical PetProfile and DietProfile shapes through CommercePetProfile and CommerceDietProfile. These profile-specific objects allow partial context but require commerce_safe visibility on every returned field and object metadata.
Expected fields include:
pet_iddisplay_namespeciesbreedbreed_mixsexage_yearslife_stageweightsize_classmetadataDietProfileDiet, allergy, sensitivity, feeding, and product-exclusion context.
Expected fields include:
diet_profile_idpet_idfood_brandsproteinsfeeding_scheduleallergiessensitivitiestreats_allowedproduct_exclusionsowner_notes_summarymetadataCommerceContextA minimized commerce-safe bundle derived from one or more pet context objects.
CommerceContext supports partial responses. A server may return only the granted portions of the context and must explain omitted fields in the response envelope. Nested profile objects may also be partial, but every returned field must still include visibility and provenance.
Expected fields include:
pet_idpurposepet_profilediet_profilepreferencespurchase_history_summarymetadataPermissionGrantA scoped authorization record.
PermissionGrant defines the interoperable authorization record shape, not the full grant transport system. Possession of a grant_id is not sufficient authority. A compatible server must verify current grant state against trusted authorization data and fail closed when issuer authority, requester identity, subject pet, purpose, scopes, facility boundary, service window, expiration, or revocation state cannot be verified.
Expected fields include:
grant_idsubject_pet_idgrantor_actor_idgrantor_actor_typegrantee_actor_idgrantee_actor_typescopespurposesexpires_atstatuscreated_atrevoked_atgrantor_actor_type and grantee_actor_type are required. They use the ActorType enum and let policy distinguish, for example, an owner-to-merchant grant from an owner-to-agent-client grant when evaluating scopes or audit-logging access.
ContextProvenanceSource and trust metadata attached to facts, observations, or generated summaries.
Expected fields include:
source_typesource_actor_idsource_systemrecorded_atverified_atconfidencestale_aftersource_record_refderived_fromIf source_type is generated, the provenance object must include source_system and derived_from.
Scopes are necessary but not sufficient.
A CCP server should evaluate access using:
For example, pet.commerce_context.read with purpose: product_recommendation should not expose staff-only behavior notes, raw wellness timelines, diagnosis history, or billing records.
Responses should include an authorization_decision object recording:
allowed, partial, or denied.The response status, authorization_decision.decision, and commerce_context value must be consistent:
ok responses use decision allowed, include non-null context, and have no omissions.partial responses use decision partial, include non-null context, and include at least one omission.denied responses use decision denied, return commerce_context: null, and include at least one omission.Every returned context item should have one or more visibility classes.
Returned context fields should use the field envelope shape:
{
"value": "large",
"visibility": ["owner_visible", "commerce_safe"],
"provenance": {
"source_type": "generated",
"source_system": "example-ccp-server",
"recorded_at": "2026-05-04T16:30:00Z",
"derived_from": ["example://pets/pet_luna_001/profile/weight"]
}
}
Initial visibility classes:
owner_visiblecaregiver_visiblestaff_onlyvet_shareablefacility_shareablecommerce_safecare_network_visiblecontact_shareableaction_authorization_visibleagent_summary_onlyrestricted_sensitiveVisibility classes are not simple additive permissions.
Deny-oriented classes take precedence over allow-oriented classes.
Initial precedence rules:
restricted_sensitive must not be returned unless the request has an explicit matching grant and purpose.staff_only must not be returned to commerce contexts.agent_summary_only may be summarized but raw source observations should be omitted.commerce_safe may be returned for commerce purposes only when the requested scope and grant also allow it.owner_visible, caregiver_visible, and vet_shareable do not imply commerce access.commerce_safe must not be combined with staff_only, restricted_sensitive, facility_shareable, care_network_visible, contact_shareable, or action_authorization_visible on the same returned field. Profile-bound classes are mutually exclusive on a given field; cross-profile reuse requires a separate authorized response in the other profile.facility_shareable may be returned for care-facility purposes only when the requested scope, purpose, grant, facility, and service window also allow it.facility_shareable must not be combined with staff_only, restricted_sensitive, commerce_safe, care_network_visible, contact_shareable, or action_authorization_visible on the same returned field.care_network_visible, contact_shareable, and action_authorization_visible may be returned for Care Network lookup only when the requested actor, scope, purpose, grant, and freshness checks allow that field.care_network_visible, contact_shareable, and action_authorization_visible must not be combined with staff_only, restricted_sensitive, commerce_safe, or facility_shareable on the same returned field.contact_shareable does not imply action authority, and action_authorization_visible does not imply access to contact channels.Initial commerce-safe scopes:
pet.profile.readpet.diet.readpet.commerce_context.readpet.permission_grants.readpet.product_exclusions.readpet.preferences.readpet.purchase_history.summary.readpet.permission_grants.read is used by optional grant lookup adapter operations such as GET /permission-grants/{grant_id} and ccp_permission_grant_get.
Initial care-facility scopes:
pet.facility_booking_context.readpet.care_instructions.readpet.feeding_instructions.readpet.vaccinations.status.readpet.pickup_authorization.readpet.emergency_contacts.readInitial care-network lookup scopes:
pet.care_network.actor_refs.readpet.care_network.relationships.readpet.care_network.contact_channels.readpet.care_network.action_authorizations.readpet.care_network.revocation_status.readDeferred medication scope recognized for omissions and denied-scope reporting:
pet.medications.administration.readFuture profiles may define additional scopes for wellness, vet export, medication administration, facility writeback, and payment authority.
Initial commerce purposes:
product_recommendationproduct_filteringInitial care-facility purposes:
boarding_preparationpickup_verificationInitial care-network purposes:
care_network_lookupCCP responses should omit restricted data by default and explain omissions with machine-readable reasons.
Initial omission reason codes:
not_requestedscope_missingpurpose_not_allowedvisibility_restrictedgrant_expiredgrant_revokedfacility_mismatchservice_window_inactivesource_stalenot_availablesummary_onlyAn omission should include:
fieldreasonvisibility_classrequired_scopedetailOmissions belong in the response envelope. Nested context objects should not carry their own omissions array unless a future profile explicitly defines object-local omissions and non-overlap rules.
Example flow:
purpose: boarding_preparation.authorization_decision.CareFacilityContext.facility_shareable visibility and provenance.See examples/permission-grant-care-facility-boarding-preparation.json, examples/care-facility-boarding-preparation-request.json, examples/care-facility-boarding-preparation-response.json, examples/care-facility-facility-mismatch-denied-response.json, and examples/care-facility-expired-service-window-denied-response.json.
The illustrative HTTP adapter for this flow is openapi/care-facility-context.openapi.json.
The illustrative MCP adapter for this flow is mcp/care-facility-context.tools.json.
Implementation guidance for this flow is docs/implementers/care-facility-context-server.md.
Example flow:
pet.pickup_authorization.read to a facility for one pet and service window.purpose: pickup_verification.authorization_decision.PickupVerificationContext only when pickup verification context may be returned.ok responses require authorization_status: authorized and release_allowed: true.pickup_verification_context: null.A pickup-verification request MUST carry a required pickup_actor_id and pickup_actor_type describing the candidate pickup actor. pickup_actor_type uses a care-network relationship enum (owner, caregiver, family_contact, friend_contact, pickup_contact, emergency_contact, facility_staff, organization, integration_client) — distinct from the global ActorType because it describes the candidate’s relationship to the pet, not the requester’s trust posture. The same enum constrains PickupActor.actor_type on the response. The candidate’s pickup_actor_type does not by itself grant release authority; release decisions are made against the pet’s pickup authorization records regardless of relationship type.
The pickup-verification slice must not return feeding instructions, medication details, billing data, payment authority, household context, identity document copies or numbers, full Care Network data, wellness timelines, diagnosis history, treatment history, staff-only notes, or unrelated contacts.
See examples/permission-grant-care-facility-pickup-verification.json, examples/care-facility-pickup-verification-request.json, examples/care-facility-pickup-verification-response.json, examples/care-facility-pickup-verification-owner-confirmation-response.json, examples/care-facility-pickup-verification-facility-mismatch-denied-response.json, and examples/care-facility-pickup-verification-inactive-service-window-denied-response.json.
The illustrative HTTP adapter for this flow is openapi/care-facility-pickup-verification.openapi.json.
The illustrative MCP adapter for this flow is mcp/care-facility-pickup-verification.tools.json.
Implementation guidance for this flow is docs/implementers/care-facility-pickup-verification-server.md.
Example flow:
purpose: care_network_lookup with one subject_actor_id.authorization_decision.CareNetworkContext only for that subject actor.care_network_context: null.The Care Network lookup slice must not return full household records, unrelated people, unrelated pets, billing data, payment authority, identity document copies or numbers, medical or wellness history, diagnosis history, treatment history, staff-only notes, sensitive relationship narratives, or free-text dispute details. A relationship may be visible without contact access, and a contact channel may be visible without action authority.
See examples/permission-grant-care-network-lookup.json, examples/care-network-lookup-request.json, examples/care-network-lookup-response.json, examples/care-network-lookup-contact-withheld-response.json, and examples/care-network-lookup-denied-response.json.
The illustrative HTTP adapter for this flow is openapi/care-network-lookup.openapi.json.
The illustrative MCP adapter for this flow is mcp/care-network-lookup.tools.json.
Implementation guidance for this flow is docs/implementers/care-network-lookup-server.md.
Example flow:
pet.commerce_context.read for purpose: product_recommendation.authorization_decision.CommerceContext.See examples/permission-grant-commerce-context.json, examples/commerce-context-request.json, examples/commerce-context-response.json, and examples/commerce-context-denied-response.json.
The illustrative HTTP adapter for this flow is openapi/commerce-context.openapi.json.
The illustrative MCP adapter for this flow is mcp/commerce-context.tools.json.
Implementation guidance for this flow is docs/implementers/commerce-context-server.md.
Every profile implementation MUST also:
requester_actor_type on every request and echo it on the response’s authorization_decision. The echo MUST equal the request value; servers MUST NOT silently coerce or substitute. Servers MUST verify the asserted requester_actor_type against the trust posture of the authenticated transport principal and reject mismatches as authorization failures rather than silently honoring a client-asserted privilege class. If the transport provides no authenticated principal, servers MUST reject the request as an authorization failure; there is no defined unauthenticated fallback.grantor_actor_type and grantee_actor_type on every grant. Servers MUST verify grantor_actor_type against the authenticated identity of the grant issuer at issuance time; a grant MUST NOT carry a grantor_actor_type the issuer is not entitled to claim. The grantee_actor_type MUST match the requester_actor_type of any request that references the grant.requester_actor_type: "vet" as an authorization failure until a vet-export profile is defined; the value remains in the enum as a reserved placeholder for that future profile.The transport-layer requirements above (principal binding, no-principal rejection, grantor-binding-at-issuance, vet rejection) cannot be exercised by the canonical conformance runner because CCP is transport-neutral. docs/implementers/conformance-checklist.md separates the machine-checked surface from the requirements that implementers MUST self-attest in their own integration tests or runtime authorization layer.
A CCP Commerce Context Profile implementation should:
A CCP Care Facility Context Profile implementation should:
A CCP Care Facility Pickup Verification implementation should:
pickup_verification).facility_shareable and reject staff_only or restricted_sensitive on returned context fields.pet.pickup_authorization.read scope.ok responses, require authorization_status: authorized and release_allowed: true.partial responses, omit release_allowed or report it as false, and do not claim authorization_status: authorized.denied responses, return pickup_verification_context: null with at least one omission.A CCP Care Network Lookup implementation should: