Resolving Versions

How version resolution works, reference formats, and the resolution algorithm.

Resolution is the process of mapping a package reference to a specific version with artifact URLs. It is the first step in the download flow and is deliberately separated from artifact transfer to enable pre-flight checks and policy evaluation before committing to a download.

Why Separate Resolution from Download?

Resolution returns metadata, not bytes. This design enables:

  • Pre-flight checks – Inspect the version, digest, and size before downloading
  • Caching decisions – Use the digest to determine if a cached copy is still valid
  • Policy evaluation – Check certification level, origin, or other metadata before allowing download
  • Lightweight queries – Resolution is fast and cheap compared to transferring artifact bytes

The Resolve Endpoint

GET /v1/org/{org}/mcps/{name}/resolve?ref={ref}
ParameterLocationRequiredDescription
orgPathYesOrganization slug
namePathYesPackage name
refQueryYesVersion reference to resolve

Required scope: mcp:resolve for published versions, mcp:resolve:prepublish for draft and ingested versions.

Reference Formats

The ref parameter accepts multiple formats, each resolving through a different matching strategy:

Semantic Version

The most common reference format. Resolves to an exact version match.

?ref=1.0.0
?ref=2.3.1

Git SHA

Resolves to the version whose git_sha field matches. Useful for tracing a specific commit to its published artifact.

?ref=abc123def456
?ref=a1b2c3d4e5f6789012345678901234567890abcd

Both short and full SHA formats are supported.

Manifest Digest

Resolves to the version whose manifest has the specified digest. Useful for content-addressed lookups when you already know the manifest hash.

?ref=sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855

Bundle Digest

Resolves to the version whose bundle has the specified digest. Useful when you have a cached bundle and need to find its associated metadata.

?ref=sha256:a1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef123456

Resolution Algorithm

The registry processes the ref parameter through the following matching sequence:

  1. Exact semver match – Look for a version record where the version field exactly equals the ref
  2. Git SHA match – Look for a version record where the git_sha field matches
  3. Manifest digest match – Look for a version record where the manifest_digest field matches
  4. Bundle digest match – Look for a version record where the bundle_digest field matches

The first match wins. If multiple versions match (e.g., multiple versions from the same commit), the most recently created one is returned.

Status Filtering

By default, resolution only returns versions with status published. To resolve versions in other states (draft, ingested), the token must include the mcp:resolve:prepublish scope.

ScopeResolvable Statuses
mcp:resolvepublished only
mcp:resolve:prepublishdraft, ingested, published

Quarantined and revoked versions are never resolvable through the resolve endpoint.

Resolution Response

A successful resolution returns the version metadata along with artifact URLs:

{
  "package": "acme/weather-service",
  "ref": "1.0.0",
  "resolved": {
    "version": "1.0.0",
    "status": "published",
    "git_sha": "abc123def456",
    "repo_url": "https://github.com/acme/weather-service",
    "manifest": {
      "digest": "sha256:e3b0c44298fc...",
      "url": "/v1/org/acme/artifacts/sha256:e3b0c44298fc.../manifest"
    },
    "bundle": {
      "digest": "sha256:a1b2c3d4e5f6...",
      "url": "/v1/org/acme/artifacts/sha256:a1b2c3d4e5f6.../bundle",
      "size_bytes": 1048576
    },
    "evidence": [
      {
        "kind": "sbom",
        "digest": "sha256:789abc...",
        "url": "/v1/org/acme/artifacts/sha256:789abc.../evidence/sbom"
      }
    ]
  }
}

Response Fields

FieldDescription
packageFull package identifier (org/name)
refThe reference that was resolved
resolved.versionResolved semantic version
resolved.statusVersion status (published, draft, ingested)
resolved.git_shaSource commit hash
resolved.repo_urlSource repository URL
resolved.manifest.digestSHA-256 digest of the manifest
resolved.manifest.urlRelative URL to download the manifest
resolved.bundle.digestSHA-256 digest of the bundle
resolved.bundle.urlRelative URL to download the bundle
resolved.bundle.size_bytesSize of the bundle in bytes
resolved.evidenceArray of evidence artifacts with kind, digest, and URL

Pre-Flight Checks

After resolution, clients can perform checks before downloading:

Digest-Based Caching

If the client has a local cache keyed by digest, it can skip the download entirely:

RESOLVED=$(curl -s -H "Authorization: Bearer $TOKEN" \
  "https://registry.example.com/v1/org/acme/mcps/weather-service/resolve?ref=1.0.0")

BUNDLE_DIGEST=$(echo "$RESOLVED" | jq -r '.resolved.bundle.digest')

# Check local cache
if [ -f "$CACHE_DIR/$BUNDLE_DIGEST" ]; then
  echo "Bundle found in cache, skipping download"
else
  echo "Downloading bundle..."
  # ... download flow
fi

Size Verification

Check the bundle size before committing to download:

BUNDLE_SIZE=$(echo "$RESOLVED" | jq -r '.resolved.bundle.size_bytes')

if [ "$BUNDLE_SIZE" -gt "$MAX_ALLOWED_SIZE" ]; then
  echo "Bundle too large: $BUNDLE_SIZE bytes (max: $MAX_ALLOWED_SIZE)"
  exit 1
fi

Policy Evaluation

Inspect metadata to make trust decisions:

STATUS=$(echo "$RESOLVED" | jq -r '.resolved.status')
REPO_URL=$(echo "$RESOLVED" | jq -r '.resolved.repo_url')

# Only trust published versions from known repositories
if [ "$STATUS" != "published" ]; then
  echo "Version not published, aborting"
  exit 1
fi

if [[ ! "$REPO_URL" =~ ^https://github.com/acme/ ]]; then
  echo "Unknown repository origin, aborting"
  exit 1
fi

Examples

Resolve by Version

curl -H "Authorization: Bearer $TOKEN" \
  "https://registry.example.com/v1/org/acme/mcps/weather-service/resolve?ref=1.0.0"

Resolve by Git SHA

curl -H "Authorization: Bearer $TOKEN" \
  "https://registry.example.com/v1/org/acme/mcps/weather-service/resolve?ref=abc123def456"

Resolve by Digest

curl -H "Authorization: Bearer $TOKEN" \
  "https://registry.example.com/v1/org/acme/mcps/weather-service/resolve?ref=sha256:e3b0c44298fc..."

Complete Resolve-and-Download Script

# 1. Authenticate
TOKEN=$(curl -s -X POST https://registry.example.com/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{"username":"user","password":"pass"}' | jq -r .access_token)

# 2. Resolve
RESOLVED=$(curl -s -H "Authorization: Bearer $TOKEN" \
  "https://registry.example.com/v1/org/acme/mcps/weather-service/resolve?ref=1.0.0")

# 3. Extract artifact information
MANIFEST_URL=$(echo "$RESOLVED" | jq -r '.resolved.manifest.url')
MANIFEST_DIGEST=$(echo "$RESOLVED" | jq -r '.resolved.manifest.digest')
BUNDLE_URL=$(echo "$RESOLVED" | jq -r '.resolved.bundle.url')
BUNDLE_DIGEST=$(echo "$RESOLVED" | jq -r '.resolved.bundle.digest')

echo "Resolved version: $(echo "$RESOLVED" | jq -r '.resolved.version')"
echo "Bundle size: $(echo "$RESOLVED" | jq -r '.resolved.bundle.size_bytes') bytes"
echo "Bundle digest: $BUNDLE_DIGEST"

# 4. Download artifacts (see Downloading Artifacts page)

Error Responses

StatusError CodeDescription
401unauthorizedMissing or invalid authentication token
403forbiddenToken lacks mcp:resolve scope or resource access
404not_foundPackage does not exist or no version matches the ref

No Matching Version

If no version matches the ref, the registry returns 404 Not Found:

{
  "error": {
    "code": "not_found",
    "message": "No version matching ref '2.0.0' found for package acme/weather-service"
  }
}

Resolving Unpublished Versions

If the ref matches an unpublished version (draft or ingested) and the token only has mcp:resolve scope (not mcp:resolve:prepublish), the version is treated as not found and a 404 is returned.