Skip to content

Use /protocol/{version}.tgz for schema sync instead of per-file downloads #180

Description

@bokelley

The AdCP spec repo now publishes a single gzipped bundle per version at /protocol/{version}.tgz (and /protocol/latest.tgz for the dev snapshot). The bundle contains schemas + compliance storyboards + openapi, wrapped under a single adcp-{version}/ directory for safe extraction. This SDK can replace the current per-file sync with one HTTP request.

Current state

schemas/cache/ contains a per-file mirror of the spec schemas, with .hashes.json used to skip re-fetching unchanged files. That's clever but requires many HTTP round trips per sync and maintenance of the hash map.

Proposed change

One fetch + verify + extract:

import hashlib, tarfile, urllib.request
from pathlib import Path

VERSION = \"latest\"  # or pin to a released semver
BASE = f\"https://adcontextprotocol.org/protocol\"

tgz = Path(f\"{VERSION}.tgz\")
sha = Path(f\"{VERSION}.tgz.sha256\")
urllib.request.urlretrieve(f\"{BASE}/{VERSION}.tgz\", tgz)
urllib.request.urlretrieve(f\"{BASE}/{VERSION}.tgz.sha256\", sha)

expected = sha.read_text().split()[0]
got = hashlib.sha256(tgz.read_bytes()).hexdigest()
if got != expected:
    raise RuntimeError(f\"checksum mismatch: {got} != {expected}\")

with tarfile.open(tgz) as t:
    t.extractall(\"schemas/cache\", filter=\"data\")
# Resulting layout: schemas/cache/adcp-{VERSION}/{schemas,compliance,openapi}/

Why

  • One request instead of ~250. The bundle is ~1.4 MB gzipped for the full schema tree.
  • Integrity built in. SHA-256 sidecar at /protocol/{version}.tgz.sha256 guarantees the bytes haven't changed.
  • Immutable caching on pinned versions. /protocol/3.1.0.tgz is served with Cache-Control: immutable, max-age=31536000 — pin once, trust forever.
  • Storyboards come for free. The same bundle contains compliance/ with the full storyboard tree — if this SDK ever wants to run storyboards locally, the fixtures are already extracted.
  • Retires .hashes.json. Checksum is the file itself, not a map you have to keep in sync.

Discovery endpoint

/protocol/ returns a JSON manifest listing available versions + the latest dev bundle. Useful for "pin when available, fall back to latest" logic.

Related

Layout inside adcp-{version}/ is a stable contract within a given major version.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions