Docker Hub API + MCP Server + A2A Server
Project description
Dockerhub Api
CLI or API | MCP | Agent
Version: 0.2.0
Documentation — Installation, deployment, usage across the API, CLI, and MCP interfaces, the integrated A2A agent server, and guidance on the backing Docker Hub platform are maintained in docs/.
Table of Contents
- Overview
- Key Features
- Installation
- Usage
- Environment Variables
- Deployment
- Safety Model
- Concepts
- License
Overview
Dockerhub Api is a production-grade Agent and Model Context Protocol (MCP) server
that wraps the official Docker Hub API v2 (https://hub.docker.com): repositories
and tags, immutable tags, personal and organization access tokens, organization
members/settings/invites, teams, audit logs, and SCIM 2.0 provisioning — plus the
Registry HTTP API v2 (registry-1.docker.io: manifests, blobs, digests,
multi-arch inspection, OCI referrers, and gated push/delete) and Docker Scout
(api.scout.docker.com: CVE/SBOM/policy intelligence).
Key Features
- Consolidated Action-Routed MCP Tools: Nine togglable tool modules
(
hub_auth,hub_repos,hub_org,hub_teams,hub_audit,hub_scim,hub_admin,hub_registry,hub_scout) minimize token overhead in LLM contexts. - Three API surfaces, one package: the Hub management API, the Registry v2 image API (its own host + per-repository scoped-token auth), and Docker Scout — each with the same uniform envelope, redaction, and gating.
- JWT Auth Lifecycle: Short-lived bearer minted from
POST /v2/auth/token(password, PATdckr_pat_*, or org access token), cached and refreshed before expiry, with one transparent re-mint on 401. - Rate-Limit Telemetry:
X-RateLimit-*headers surfaced in every result; HTTP 429 retried with boundedRetry-Afterbackoff. - Safety by Default: Deletes and org-settings writes are gated behind
DOCKERHUB_ALLOW_DESTRUCTIVE(defaultFalse); secrets are redacted from tool results (plaintext tokens appear exactly once — on creation). Repository creation stays enabled: it is the primary release-provisioning use case. - Integrated Graph Agent: Built-in Pydantic AI agent (
dockerhub-agent) with A2A and AG-UI web interfaces. - Native Telemetry & Tracing: Out-of-the-box OpenTelemetry exports and Langfuse tracing via agent-utilities.
Installation
pip install dockerhub-api # API client only
pip install "dockerhub-api[mcp]" # + MCP server
pip install "dockerhub-api[agent]" # + A2A agent server
pip install "dockerhub-api[all]" # everything
| Extra | Adds |
|---|---|
mcp |
FastMCP server (dockerhub-mcp) via agent-utilities[mcp] |
agent |
Pydantic-AI A2A agent (dockerhub-agent) + Logfire via agent-utilities[agent,logfire] |
all |
mcp + agent |
test |
pytest toolchain for development |
Or pull the published image:
docker pull knucklessg1/dockerhub-api:latest
Usage
Python API / CLI
from dockerhub_api.auth import get_client
api = get_client() # reads DOCKERHUB_URL / DOCKER_HUB_USER / DOCKER_HUB_TOKEN
repos = api.get_repositories(namespace="acme", ordering="-last_updated")
api.create_repository(namespace="acme", name="release-images", is_private=True)
tags = api.get_repository_tags(namespace="acme", repository="release-images")
print(api.rate_limit) # latest X-RateLimit-* snapshot
Every client method returns a uniform envelope:
{"status_code": int, "data": ..., "rate_limit": {"limit", "remaining", "reset"}}.
MCP
Available MCP Tools
| Tool Module | Toggle Env Var | Enabled by Default | Description & Nested Actions |
|---|---|---|---|
hub_auth |
AUTHTOOL |
True | Token lifecycle: create_token, login (deprecated), two_factor_login, list_pats, create_pat, get_pat, update_pat, delete_pat, list_oats, create_oat, get_oat, update_oat, delete_oat |
hub_repos |
REPOSTOOL |
True | Repositories & tags: list, create, get, check, list_tags, check_tags, get_tag, check_tag, set_immutable_tags, verify_immutable_tags, assign_group |
hub_org |
ORGTOOL |
True | Org admin: get_settings, update_settings, list_members, export_members, update_member, remove_member, list_invites, delete_invite, resend_invite, bulk_invite |
hub_teams |
TEAMSTOOL |
True | Teams: list, create, get, update, patch, delete, list_members, add_member, remove_member |
hub_audit |
AUDITTOOL |
True | Audit trail: logs, actions |
hub_scim |
SCIMTOOL |
True | SCIM 2.0: service_provider_config, resource_types, resource_type, schemas, schema, list_users, get_user, create_user, update_user |
hub_admin |
ADMINTOOL |
True | Diagnostics: rate_limit, whoami (local JWT introspection) |
hub_registry |
REGISTRYTOOL |
True | Registry v2 (registry-1.docker.io): api_version, list_tags, get_manifest, check_manifest, resolve_digest, list_platforms, get_config, inspect, get_blob, check_blob, list_referrers, delete_manifest†, delete_blob†, start_upload†, upload_chunk†, complete_upload†, mount_blob†, put_manifest† |
hub_scout |
SCOUTTOOL |
True | Docker Scout (api.scout.docker.com): summary, cves, vulnerabilities, sbom, compare, policies, policy_evaluation |
† Gated by DOCKERHUB_ALLOW_DESTRUCTIVE (push and delete are destructive).
Registry v2 vs. the Hub management API
hub_registry targets a different host and auth model than the other tools.
The Hub management API (hub.docker.com) uses one JWT from /v2/auth/token; the
Registry v2 API (registry-1.docker.io) authorizes each call with a
per-repository, per-action bearer obtained from a token service via a
401 WWW-Authenticate challenge. Both reuse the same DOCKER_HUB_USER /
DOCKER_HUB_TOKEN credentials (anonymous works for public pulls). Single-segment
repository names (e.g. nginx) are normalized to their official library/ path.
_catalog (registry-wide repository listing) is intentionally not implemented:
Docker Hub does not issue the registry-scoped token it requires. The chunked push
buffers each chunk in memory — it is intended for manifests, config, and
attestation blobs, not as a replacement for docker push of large layers.
from dockerhub_api.auth import get_registry_client, get_scout_client
reg = get_registry_client()
print(reg.inspect("nginx", "latest")["data"]["platforms"]) # multi-arch list
digest = reg.resolve_digest("nginx", "latest")["data"]["digest"]
print(reg.list_referrers("nginx", digest)["data"]) # SBOM/attestations
scout = get_scout_client()
print(scout.get_cves("myorg/app", reference="v1")["data"]) # CVE listing
Run the server:
export DOCKER_HUB_USER=youruser
export DOCKER_HUB_TOKEN=dckr_pat_xxx
dockerhub-mcp --transport streamable-http --host 0.0.0.0 --port 8000
Agent (A2A)
dockerhub-agent --mcp-url http://localhost:8000/mcp --web
Environment Variables
| Variable | Default | Purpose |
|---|---|---|
DOCKERHUB_URL |
https://hub.docker.com |
Docker Hub API base URL |
DOCKER_HUB_USER |
— | Account identifier (official hub-tool name, primary) |
DOCKER_HUB_TOKEN |
— | Password, PAT dckr_pat_*, or org access token (primary) |
DOCKERHUB_USERNAME / DOCKERHUB_TOKEN |
— | Legacy fallback aliases for the two above |
DOCKERHUB_JWT |
— | Optional pre-minted bearer (overrides credential exchange) |
DOCKERHUB_SSL_VERIFY |
True |
TLS certificate verification |
DOCKERHUB_ALLOW_DESTRUCTIVE |
False |
Enable deletes and org-settings writes |
AUTHTOOL … ADMINTOOL |
True |
Per-module MCP tool toggles (see table above) |
HOST / PORT / TRANSPORT |
0.0.0.0 / 8000 / stdio |
MCP server bind & transport (stdio, streamable-http, sse) |
AUTH_TYPE |
none |
MCP server auth mode (Docker image) |
MCP_URL |
— | MCP endpoint the A2A agent connects to |
ENABLE_OTEL |
True |
OpenTelemetry / Langfuse export via agent-utilities |
EUNOMIA_TYPE / EUNOMIA_POLICY_FILE / EUNOMIA_REMOTE_URL |
none / mcp_policies.json / — |
Eunomia access-governance middleware |
FASTMCP_LOG_LEVEL / NO_COLOR |
— | FastMCP logging controls |
A complete annotated template lives in .env.example.
Deployment
Docker Compose definitions ship in docker/:
cp .env.example .env # fill in DOCKER_HUB_USER / DOCKER_HUB_TOKEN
docker compose -f docker/mcp.compose.yml up -d # MCP server only
docker compose -f docker/agent.compose.yml up -d # MCP server + A2A agent (port 9018)
Both services expose /health endpoints; see
docs/deployment.md for transports, Caddy ingress, and
Technitium DNS guidance.
Additional Deployment Options
dockerhub-api can also run as a local container (Docker / Podman / uv) or be
consumed from a remote deployment. The
Deployment guide has full, copy-paste
mcp_config.json for all four transports — stdio, streamable-http,
local container / uv, and remote URL:
- Local container / uv — launch the server from
mcp_config.jsonviauvx,docker run, orpodman run, or point at a local streamable-http container byurl. - Remote URL — connect to a server deployed behind Caddy at
http://dockerhub-mcp.arpa/mcpusing the"url"key.
Safety Model
| Operation class | Default | Override |
|---|---|---|
| Reads (repos, tags, members, logs, SCIM) | allowed | — |
| Repository create / immutable-tag config / invites / role updates | allowed | — |
| Deletes (PATs, OATs, groups, members, invites) | blocked | DOCKERHUB_ALLOW_DESTRUCTIVE=True |
Org-settings writes (PUT /v2/orgs/{org}/settings) |
blocked | DOCKERHUB_ALLOW_DESTRUCTIVE=True |
Concepts
The concept registry (CONCEPT:HUB-1.x) is documented in
docs/concepts.md.
License
MIT — see LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file dockerhub_api-0.2.0.tar.gz.
File metadata
- Download URL: dockerhub_api-0.2.0.tar.gz
- Upload date:
- Size: 61.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
efd1c58ff241f07f96d4374dd623ee71d5041e7b9900e3b08b684620111cdcfa
|
|
| MD5 |
2deea5ca0efdd29f3708e6cbd85d29d0
|
|
| BLAKE2b-256 |
8dce6011719f17850fcf7bcfdec207de79ea6e22a8d8fde82383ae346454ae57
|
File details
Details for the file dockerhub_api-0.2.0-py3-none-any.whl.
File metadata
- Download URL: dockerhub_api-0.2.0-py3-none-any.whl
- Upload date:
- Size: 59.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8333b11bb9ae675ca99c359f55d7e5ce1eeaf4d329e3696cd506b988a7d6e1ef
|
|
| MD5 |
aeb01cfd6b57429461368b63c11f6cfb
|
|
| BLAKE2b-256 |
418b3f4aec1136afce6f2b8fe235e766f1e4b2fbdc0edbec24c4d75a31fa2421
|