# UCP Capability Intersection Algorithm: How It Negotiates Compatible Features

> Learn how the UCP capability intersection algorithm computes compatible features by intersecting profiles and selecting optimal versions. Ensure seamless integration with UCP.

- Repository: [Universal Commerce Protocol (UCP)/ucp](https://github.com/Universal-Commerce-Protocol/ucp)
- Tags: deep-dive
- Published: 2026-04-26

---

**The UCP capability intersection algorithm deterministically calculates a compatible capability set by intersecting business and platform profiles, selecting the highest mutual version, and pruning orphaned extensions until a stable hierarchy is reached.**

The Universal Commerce Protocol (UCP) employs a server-select negotiation model where businesses determine active session capabilities by running this algorithm against declared profiles. Located in the `/.well-known/ucp` endpoint and transmitted via the `UCP-Agent` header, these profiles feed into a four-step process defined in the [`docs/specification/overview.md`](https://github.com/Universal-Commerce-Protocol/ucp/blob/main/docs/specification/overview.md) file that guarantees both parties support every activated feature at compatible versions.

## How the UCP Capability Intersection Algorithm Works

The algorithm processes two JSON capability arrays—one from the **business profile** and one from the **platform profile**—to produce a deterministic result set that respects hierarchical dependencies.

### Step 1: Compute Raw Intersection

The algorithm first filters capabilities by **name**, retaining only entries present in both input profiles. This creates the initial candidate set based on exact string matches of the `name` field defined in [`source/schemas/capability.json`](https://github.com/Universal-Commerce-Protocol/ucp/blob/main/source/schemas/capability.json).

### Step 2: Select Highest Mutual Version

For each intersected capability, the algorithm compares version strings from both profiles. It computes the set intersection of available versions and selects the **lexicographically latest** date string (highest version). If no common version exists between the business and platform declarations, that capability is dropped from the result set entirely.

### Step 3 and 4: Prune Orphaned Extensions

Capabilities marked as extensions declare parent dependencies via the `extends` field. An extension survives only if at least one of its specified parents remains in the active set after version selection. Because extensions can chain (an extension may itself be a parent of another), this pruning step iterates in a loop until no further capabilities are removed, ensuring the final hierarchy contains no orphaned nodes.

## Implementation Examples

These implementations mirror the logic found in the specification and can be integrated into UCP-aware services.

### Python Implementation

```python
def intersect_capabilities(business, platform):
    # 1️⃣  raw name intersection

    names = {c["name"] for c in business} & {c["name"] for c in platform}
    
    # 2️⃣  version selection

    result = {}
    for name in names:
        b_versions = {c["version"] for c in business if c["name"] == name}
        p_versions = {c["version"] for c in platform if c["name"] == name}
        common = b_versions & p_versions
        if common:
            result[name] = max(common)  # highest version wins

    
    # 3️⃣ & 4️⃣ prune extensions iteratively

    changed = True
    while changed:
        changed = False
        for name, cap in list(result.items()):
            extends = cap.get("extends")
            if not extends:
                continue
            parents = extends if isinstance(extends, list) else [extends]
            if not any(parent in result for parent in parents):
                del result[name]
                changed = True
    
    return result

```

### TypeScript Implementation

```typescript
interface Capability {
  name: string;
  version: string;
  extends?: string | string[];
}

function intersect(
  business: Capability[],
  platform: Capability[]
): Record<string, string> {
  // 1️⃣ name intersection
  const names = new Set(
    business.map(c => c.name).filter(n => platform.some(p => p.name === n))
  );

  // 2️⃣ version selection
  const intersected: Record<string, string> = {};
  for (const name of names) {
    const bVers = new Set(
      business.filter(c => c.name === name).map(c => c.version)
    );
    const pVers = new Set(
      platform.filter(c => c.name === name).map(c => c.version)
    );
    const common = [...bVers].filter(v => pVers.has(v));
    if (common.length) {
      intersected[name] = common.sort().pop()!; // highest version
    }
  }

  // 3️⃣ & 4️⃣ prune extensions
  let changed = true;
  while (changed) {
    changed = false;
    for (const [name, version] of Object.entries(intersected)) {
      const cap = business.concat(platform).find(c => c.name === name)!;
      const ext = cap.extends;
      if (!ext) continue;
      const parents = Array.isArray(ext) ? ext : [ext];
      if (!parents.some(p => intersected[p])) {
        delete intersected[name];
        changed = true;
      }
    }
  }

  return intersected;
}

```

## File Structure and Source References

The authoritative definitions and schemas reside in specific paths within the `Universal-Commerce-Protocol/ucp` repository:

- **[`docs/specification/overview.md`](https://github.com/Universal-Commerce-Protocol/ucp/blob/main/docs/specification/overview.md)** — Contains the formal **Negotiation Protocol** section describing the intersection algorithm and its four-step flow.
- **[`source/schemas/capability.json`](https://github.com/Universal-Commerce-Protocol/ucp/blob/main/source/schemas/capability.json)** — Defines the JSON Schema for capability objects, including the `name`, `version`, and optional `extends` properties.
- **[`source/discovery/profile_schema.json`](https://github.com/Universal-Commerce-Protocol/ucp/blob/main/source/discovery/profile_schema.json)** — Specifies the structure for business and platform profiles, including the embedded `capabilities` array used as algorithm input.
- **[`main.py`](https://github.com/Universal-Commerce-Protocol/ucp/blob/main/main.py)** — Serves as the reference integration point where the algorithm consumes platform profiles and emits the negotiated capability set for response headers.

## Summary

- The **UCP capability intersection algorithm** enables server-select negotiation by computing the exact overlap between business and platform capability declarations.
- It guarantees compatibility by selecting only the **highest mutually supported version** for each intersected capability name.
- **Hierarchical integrity** is enforced through iterative pruning of extensions whose parent capabilities were removed during version selection.
- All definitions are grounded in the JSON schemas located at [`source/schemas/capability.json`](https://github.com/Universal-Commerce-Protocol/ucp/blob/main/source/schemas/capability.json) and [`source/discovery/profile_schema.json`](https://github.com/Universal-Commerce-Protocol/ucp/blob/main/source/discovery/profile_schema.json), with the algorithm specification residing in [`docs/specification/overview.md`](https://github.com/Universal-Commerce-Protocol/ucp/blob/main/docs/specification/overview.md).

## Frequently Asked Questions

### What happens if the business and platform share no common capability versions?

If the version intersection for a specific capability name is empty, the algorithm drops that capability from the final set. According to the specification in [`docs/specification/overview.md`](https://github.com/Universal-Commerce-Protocol/ucp/blob/main/docs/specification/overview.md), a capability is activated only when both parties list at least one identical version string.

### How does the algorithm handle circular extension dependencies?

The iterative pruning loop naturally handles chains of extensions, including circular references, because it continues until no changes occur (`changed = false`). If an extension's parent is removed in one iteration, the child is removed in the next, propagating the pruning effect through the dependency graph until stability is reached.

### Where should the negotiated capability set be declared in the UCP response?

The final result of the intersection algorithm populates the `ucp.capabilities` field in the response object. As implemented in [`main.py`](https://github.com/Universal-Commerce-Protocol/ucp/blob/main/main.py), this set is derived from the business profile intersection with the platform profile and returned according to the *Response Capability Selection* protocol rules.

### Can a capability extend multiple parents simultaneously?

Yes. The `extends` field in [`source/schemas/capability.json`](https://github.com/Universal-Commerce-Protocol/ucp/blob/main/source/schemas/capability.json) accepts either a single string or an array of strings. During the pruning phase, an extension is retained if **at least one** of its declared parents exists in the active set, allowing for flexible capability composition while maintaining strict hierarchical validation.