dockerhub-api 0.5.0__tar.gz → 1.0.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- dockerhub_api-1.0.1/MANIFEST.in +4 -0
- dockerhub_api-1.0.1/PKG-INFO +467 -0
- dockerhub_api-1.0.1/README.md +437 -0
- {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/dockerhub_api/agent_server.py +1 -1
- {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/dockerhub_api/auth.py +25 -26
- dockerhub_api-1.0.1/dockerhub_api/main_agent.json +18 -0
- {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/dockerhub_api/mcp_server.py +25 -38
- dockerhub_api-1.0.1/dockerhub_api/prompts/__init__.py +0 -0
- dockerhub_api-1.0.1/dockerhub_api/prompts/main_agent.json +18 -0
- dockerhub_api-1.0.1/dockerhub_api/skills/__init__.py +0 -0
- dockerhub_api-1.0.1/dockerhub_api/skills/dockerhub-starter/SKILL.md +19 -0
- dockerhub_api-1.0.1/dockerhub_api.egg-info/PKG-INFO +467 -0
- {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/dockerhub_api.egg-info/SOURCES.txt +4 -0
- dockerhub_api-1.0.1/dockerhub_api.egg-info/entry_points.txt +9 -0
- dockerhub_api-1.0.1/dockerhub_api.egg-info/requires.txt +18 -0
- {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/pyproject.toml +12 -6
- {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/requirements.txt +1 -1
- {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/tests/test_dockerhub_a2a_validation.py +1 -1
- {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/tests/test_dockerhub_mcp_validation.py +3 -3
- dockerhub_api-0.5.0/MANIFEST.in +0 -4
- dockerhub_api-0.5.0/PKG-INFO +0 -282
- dockerhub_api-0.5.0/README.md +0 -252
- dockerhub_api-0.5.0/dockerhub_api/main_agent.json +0 -14
- dockerhub_api-0.5.0/dockerhub_api.egg-info/PKG-INFO +0 -282
- dockerhub_api-0.5.0/dockerhub_api.egg-info/entry_points.txt +0 -3
- dockerhub_api-0.5.0/dockerhub_api.egg-info/requires.txt +0 -18
- {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/LICENSE +0 -0
- {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/dockerhub_api/__init__.py +0 -0
- {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/dockerhub_api/__main__.py +0 -0
- {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/dockerhub_api/api/__init__.py +0 -0
- {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/dockerhub_api/api/api_client_access_tokens.py +0 -0
- {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/dockerhub_api/api/api_client_audit_logs.py +0 -0
- {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/dockerhub_api/api/api_client_auth.py +0 -0
- {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/dockerhub_api/api/api_client_base.py +0 -0
- {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/dockerhub_api/api/api_client_groups.py +0 -0
- {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/dockerhub_api/api/api_client_org_access_tokens.py +0 -0
- {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/dockerhub_api/api/api_client_orgs.py +0 -0
- {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/dockerhub_api/api/api_client_registry.py +0 -0
- {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/dockerhub_api/api/api_client_registry_base.py +0 -0
- {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/dockerhub_api/api/api_client_repositories.py +0 -0
- {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/dockerhub_api/api/api_client_scim.py +0 -0
- {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/dockerhub_api/api/api_client_scout.py +0 -0
- {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/dockerhub_api/api_client.py +0 -0
- {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/dockerhub_api/dockerhub_input_models.py +0 -0
- {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/dockerhub_api/dockerhub_response_models.py +0 -0
- {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/dockerhub_api/mcp/__init__.py +0 -0
- {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/dockerhub_api/mcp/mcp_admin.py +0 -0
- {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/dockerhub_api/mcp/mcp_audit.py +0 -0
- {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/dockerhub_api/mcp/mcp_auth.py +0 -0
- {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/dockerhub_api/mcp/mcp_org.py +0 -0
- {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/dockerhub_api/mcp/mcp_registry.py +0 -0
- {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/dockerhub_api/mcp/mcp_repos.py +0 -0
- {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/dockerhub_api/mcp/mcp_scim.py +0 -0
- {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/dockerhub_api/mcp/mcp_scout.py +0 -0
- {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/dockerhub_api/mcp/mcp_teams.py +0 -0
- {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/dockerhub_api/mcp_config.json +0 -0
- {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/dockerhub_api.egg-info/dependency_links.txt +0 -0
- {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/dockerhub_api.egg-info/top_level.txt +0 -0
- {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/setup.cfg +0 -0
- {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/tests/test_api_audit.py +0 -0
- {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/tests/test_api_org.py +0 -0
- {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/tests/test_api_registry.py +0 -0
- {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/tests/test_api_repositories.py +0 -0
- {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/tests/test_api_scim.py +0 -0
- {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/tests/test_api_scout.py +0 -0
- {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/tests/test_api_teams.py +0 -0
- {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/tests/test_api_tokens.py +0 -0
- {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/tests/test_api_wrapper.py +0 -0
- {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/tests/test_auth.py +0 -0
- {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/tests/test_concept_parity.py +0 -0
- {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/tests/test_init_dynamics.py +0 -0
- {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/tests/test_models.py +0 -0
- {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/tests/test_rate_limit.py +0 -0
- {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/tests/test_startup.py +0 -0
|
@@ -0,0 +1,467 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: dockerhub-api
|
|
3
|
+
Version: 1.0.1
|
|
4
|
+
Summary: Docker Hub API + MCP Server + A2A Server
|
|
5
|
+
Author-email: Audel Rouhi <knucklessg1@gmail.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
8
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
9
|
+
Classifier: Environment :: Console
|
|
10
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Requires-Python: <3.15,>=3.11
|
|
13
|
+
Description-Content-Type: text/markdown
|
|
14
|
+
License-File: LICENSE
|
|
15
|
+
Requires-Dist: agent-utilities>=1.0.0
|
|
16
|
+
Requires-Dist: httpx>=0.27.0
|
|
17
|
+
Requires-Dist: python-dotenv>=1.0.0
|
|
18
|
+
Provides-Extra: mcp
|
|
19
|
+
Requires-Dist: agent-utilities[mcp]>=1.0.0; extra == "mcp"
|
|
20
|
+
Provides-Extra: agent
|
|
21
|
+
Requires-Dist: agent-utilities[agent,logfire]>=1.0.0; extra == "agent"
|
|
22
|
+
Provides-Extra: all
|
|
23
|
+
Requires-Dist: dockerhub-api[agent,logfire,mcp]>=1.0.0; extra == "all"
|
|
24
|
+
Provides-Extra: test
|
|
25
|
+
Requires-Dist: pytest-xdist>=3.6.0; extra == "test"
|
|
26
|
+
Requires-Dist: pytest; extra == "test"
|
|
27
|
+
Requires-Dist: pytest-asyncio; extra == "test"
|
|
28
|
+
Requires-Dist: pytest-cov; extra == "test"
|
|
29
|
+
Dynamic: license-file
|
|
30
|
+
|
|
31
|
+
# Dockerhub Api
|
|
32
|
+
## CLI or API | MCP | Agent
|
|
33
|
+
|
|
34
|
+

|
|
35
|
+

|
|
36
|
+

|
|
37
|
+

|
|
38
|
+

|
|
39
|
+

|
|
40
|
+

|
|
41
|
+

|
|
42
|
+

|
|
43
|
+

|
|
44
|
+

|
|
45
|
+
|
|
46
|
+
*Version: 1.0.1*
|
|
47
|
+
|
|
48
|
+
> **Documentation** — Installation, deployment, usage across the API, CLI, and MCP
|
|
49
|
+
> interfaces, the integrated A2A agent server, and guidance on the backing
|
|
50
|
+
> Docker Hub platform are maintained in [docs/](docs/index.md).
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## Table of Contents
|
|
55
|
+
|
|
56
|
+
- [Overview](#overview)
|
|
57
|
+
- [Key Features](#key-features)
|
|
58
|
+
- [Installation](#installation)
|
|
59
|
+
- [Usage](#usage)
|
|
60
|
+
- [Python API / CLI](#python-api--cli)
|
|
61
|
+
- [MCP](#mcp)
|
|
62
|
+
- [Agent (A2A)](#agent-a2a)
|
|
63
|
+
- [Environment Variables](#environment-variables)
|
|
64
|
+
- [Deployment](#deployment)
|
|
65
|
+
- [Safety Model](#safety-model)
|
|
66
|
+
- [Concepts](#concepts)
|
|
67
|
+
- [License](#license)
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## Overview
|
|
72
|
+
|
|
73
|
+
**Dockerhub Api** is a production-grade Agent and Model Context Protocol (MCP) server
|
|
74
|
+
that wraps the official **Docker Hub API v2** (`https://hub.docker.com`): repositories
|
|
75
|
+
and tags, immutable tags, personal and organization access tokens, organization
|
|
76
|
+
members/settings/invites, teams, audit logs, and SCIM 2.0 provisioning — plus the
|
|
77
|
+
**Registry HTTP API v2** (`registry-1.docker.io`: manifests, blobs, digests,
|
|
78
|
+
multi-arch inspection, OCI referrers, and gated push/delete) and **Docker Scout**
|
|
79
|
+
(`api.scout.docker.com`: CVE/SBOM/policy intelligence).
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## Key Features
|
|
84
|
+
|
|
85
|
+
- **Consolidated Action-Routed MCP Tools:** Nine togglable tool modules
|
|
86
|
+
(`hub_auth`, `hub_repos`, `hub_org`, `hub_teams`, `hub_audit`, `hub_scim`,
|
|
87
|
+
`hub_admin`, `hub_registry`, `hub_scout`) minimize token overhead in LLM contexts.
|
|
88
|
+
- **Three API surfaces, one package:** the Hub *management* API, the *Registry v2*
|
|
89
|
+
image API (its own host + per-repository scoped-token auth), and *Docker Scout*
|
|
90
|
+
— each with the same uniform envelope, redaction, and gating.
|
|
91
|
+
- **JWT Auth Lifecycle:** Short-lived bearer minted from `POST /v2/auth/token`
|
|
92
|
+
(password, PAT `dckr_pat_*`, or org access token), cached and refreshed before
|
|
93
|
+
expiry, with one transparent re-mint on 401.
|
|
94
|
+
- **Rate-Limit Telemetry:** `X-RateLimit-*` headers surfaced in every result;
|
|
95
|
+
HTTP 429 retried with bounded `Retry-After` backoff.
|
|
96
|
+
- **Safety by Default:** Deletes and org-settings writes are gated behind
|
|
97
|
+
`DOCKERHUB_ALLOW_DESTRUCTIVE` (default `False`); secrets are redacted from tool
|
|
98
|
+
results (plaintext tokens appear exactly once — on creation). Repository creation
|
|
99
|
+
stays enabled: it is the primary release-provisioning use case.
|
|
100
|
+
- **Integrated Graph Agent:** Built-in Pydantic AI agent (`dockerhub-agent`) with
|
|
101
|
+
A2A and AG-UI web interfaces.
|
|
102
|
+
- **Native Telemetry & Tracing:** Out-of-the-box OpenTelemetry exports and Langfuse
|
|
103
|
+
tracing via agent-utilities.
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## Installation
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
pip install dockerhub-api # API client only
|
|
111
|
+
pip install "dockerhub-api[mcp]" # + MCP server
|
|
112
|
+
pip install "dockerhub-api[agent]" # + A2A agent server
|
|
113
|
+
pip install "dockerhub-api[all]" # everything
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
| Extra | Adds |
|
|
117
|
+
|---|---|
|
|
118
|
+
| `mcp` | FastMCP server (`dockerhub-mcp`) via `agent-utilities[mcp]` |
|
|
119
|
+
| `agent` | Pydantic-AI A2A agent (`dockerhub-agent`) + Logfire via `agent-utilities[agent,logfire]` |
|
|
120
|
+
| `all` | `mcp` + `agent` |
|
|
121
|
+
| `test` | pytest toolchain for development |
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
# MCP server only (recommended for tool hosting — slim deps)
|
|
125
|
+
uv pip install "dockerhub-api[mcp]"
|
|
126
|
+
|
|
127
|
+
# Full agent runtime (Pydantic AI + epistemic-graph engine)
|
|
128
|
+
uv pip install "dockerhub-api[agent]"
|
|
129
|
+
|
|
130
|
+
# Everything (development)
|
|
131
|
+
uv pip install "dockerhub-api[all]" # or: python -m pip install "dockerhub-api[all]"
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Container images (`:mcp` vs `:agent`)
|
|
135
|
+
|
|
136
|
+
One multi-stage `docker/Dockerfile` builds two right-sized images, selected by `--target`:
|
|
137
|
+
|
|
138
|
+
| Image tag | Build target | Contents | Entrypoint |
|
|
139
|
+
|-----------|--------------|----------|------------|
|
|
140
|
+
| `knucklessg1/dockerhub-api:mcp` | `--target mcp` | `dockerhub-api[mcp]` — **slim**, no engine/`pydantic-ai`/`dspy`/`llama-index`/`tree-sitter` | `dockerhub-mcp` |
|
|
141
|
+
| `knucklessg1/dockerhub-api:latest` | `--target agent` (default) | `dockerhub-api[agent]` — **full** agent runtime + epistemic-graph engine | `dockerhub-agent` |
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
docker build --target mcp -t knucklessg1/dockerhub-api:mcp docker/ # slim MCP server
|
|
145
|
+
docker build --target agent -t knucklessg1/dockerhub-api:latest docker/ # full agent
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
`docker/mcp.compose.yml` runs the slim `:mcp` server; `docker/agent.compose.yml` runs the
|
|
149
|
+
agent (`:latest`) with a co-located `:mcp` sidecar.
|
|
150
|
+
|
|
151
|
+
### Knowledge-graph database (`epistemic-graph`)
|
|
152
|
+
|
|
153
|
+
The **full agent** (`[agent]` / `:latest`) embeds the **epistemic-graph** engine (pulled in
|
|
154
|
+
transitively via `agent-utilities[agent]`). For production — or to share one knowledge graph
|
|
155
|
+
across multiple agents — run **epistemic-graph as its own database container** and point the
|
|
156
|
+
agent at it instead of embedding it. Deployment recipes (single-node + Raft HA), connection
|
|
157
|
+
config, and the full database architecture (with diagrams) are documented in the
|
|
158
|
+
[epistemic-graph deployment guide](https://knuckles-team.github.io/epistemic-graph/deployment/).
|
|
159
|
+
The slim `[mcp]` server does **not** require the database.
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## Usage
|
|
164
|
+
|
|
165
|
+
### Python API / CLI
|
|
166
|
+
|
|
167
|
+
```python
|
|
168
|
+
from dockerhub_api.auth import get_client
|
|
169
|
+
|
|
170
|
+
api = get_client() # reads DOCKERHUB_URL / DOCKER_HUB_USER / DOCKER_HUB_TOKEN
|
|
171
|
+
|
|
172
|
+
repos = api.get_repositories(namespace="acme", ordering="-last_updated")
|
|
173
|
+
api.create_repository(namespace="acme", name="release-images", is_private=True)
|
|
174
|
+
tags = api.get_repository_tags(namespace="acme", repository="release-images")
|
|
175
|
+
print(api.rate_limit) # latest X-RateLimit-* snapshot
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
Every client method returns a uniform envelope:
|
|
179
|
+
`{"status_code": int, "data": ..., "rate_limit": {"limit", "remaining", "reset"}}`.
|
|
180
|
+
|
|
181
|
+
### MCP
|
|
182
|
+
|
|
183
|
+
#### Available MCP Tools
|
|
184
|
+
|
|
185
|
+
_Auto-generated — do not edit (synced by the `mcp-readme-table` pre-commit hook)._
|
|
186
|
+
|
|
187
|
+
<!-- MCP-TOOLS-TABLE:START -->
|
|
188
|
+
|
|
189
|
+
#### Condensed action-routed tools (default — `MCP_TOOL_MODE=condensed`)
|
|
190
|
+
|
|
191
|
+
| MCP Tool | Toggle Env Var | Description |
|
|
192
|
+
|----------|----------------|-------------|
|
|
193
|
+
| `hub_admin` | `ADMINTOOL` | Client diagnostics: 'rate_limit' returns the latest |
|
|
194
|
+
| `hub_audit` | `AUDITTOOL` | Read a Docker Hub account's audit trail: 'logs' lists events |
|
|
195
|
+
| `hub_auth` | `AUTHTOOL` | Manage Docker Hub authentication, personal access tokens (PATs), |
|
|
196
|
+
| `hub_org` | `ORGTOOL` | Manage a Docker Hub organization: settings (restricted images), |
|
|
197
|
+
| `hub_registry` | `REGISTRYTOOL` | Docker Registry v2 image operations (``registry-1.docker.io``): |
|
|
198
|
+
| `hub_repos` | `REPOSTOOL` | Manage Docker Hub repositories: list/create/inspect repositories, |
|
|
199
|
+
| `hub_scim` | `SCIMTOOL` | Docker Hub SCIM 2.0: service discovery (ServiceProviderConfig, |
|
|
200
|
+
| `hub_scout` | `SCOUTTOOL` | Docker Scout image intelligence (``api.scout.docker.com``): |
|
|
201
|
+
| `hub_teams` | `TEAMSTOOL` | Manage Docker Hub organization groups (teams) and their members. |
|
|
202
|
+
|
|
203
|
+
#### Verbose 1:1 API-mapped tools (`MCP_TOOL_MODE=verbose` or `both`)
|
|
204
|
+
|
|
205
|
+
<details>
|
|
206
|
+
<summary>54 per-operation tools — one per public API method (click to expand)</summary>
|
|
207
|
+
|
|
208
|
+
| MCP Tool | Toggle Env Var | Description |
|
|
209
|
+
|----------|----------------|-------------|
|
|
210
|
+
| `dockerhub_add_group_member` | `GROUPSTOOL` | Add a username to a group. |
|
|
211
|
+
| `dockerhub_assign_repository_group` | `REPOSITORIESTOOL` | Grant a team (group) ``read``/``write``/``admin`` on a repository. |
|
|
212
|
+
| `dockerhub_bulk_invite` | `ORGSTOOL` | Invite many users/emails at once (``POST /v2/invites/bulk``). |
|
|
213
|
+
| `dockerhub_check_repository` | `REPOSITORIESTOOL` | HEAD existence check for a repository. |
|
|
214
|
+
| `dockerhub_check_repository_tag` | `REPOSITORIESTOOL` | HEAD existence check for one tag. |
|
|
215
|
+
| `dockerhub_check_repository_tags` | `REPOSITORIESTOOL` | HEAD check: does the repository have any tags? |
|
|
216
|
+
| `dockerhub_create_access_token` | `ACCESS_TOKENSTOOL` | Create a personal access token. |
|
|
217
|
+
| `dockerhub_create_auth_token` | `AUTHTOOL` | Mint a short-lived JWT bearer from an identifier + secret. |
|
|
218
|
+
| `dockerhub_create_group` | `GROUPSTOOL` | Create a group (team) in an organization. |
|
|
219
|
+
| `dockerhub_create_org_access_token` | `ORG_ACCESS_TOKENSTOOL` | Create an organization access token. |
|
|
220
|
+
| `dockerhub_create_repository` | `REPOSITORIESTOOL` | Create an image repository in a namespace. |
|
|
221
|
+
| `dockerhub_create_scim_user` | `SCIMTOOL` | Provision a SCIM user. |
|
|
222
|
+
| `dockerhub_delete_access_token` | `ACCESS_TOKENSTOOL` | Delete a personal access token. Destructive — gated. |
|
|
223
|
+
| `dockerhub_delete_group` | `GROUPSTOOL` | Delete a group. Destructive — gated. |
|
|
224
|
+
| `dockerhub_delete_invite` | `ORGSTOOL` | Cancel an invite. Destructive — gated. |
|
|
225
|
+
| `dockerhub_delete_org_access_token` | `ORG_ACCESS_TOKENSTOOL` | Delete an organization access token. Destructive — gated. |
|
|
226
|
+
| `dockerhub_export_org_members` | `ORGSTOOL` | Export the member list as CSV (``GET /members/export``). |
|
|
227
|
+
| `dockerhub_get_access_token` | `ACCESS_TOKENSTOOL` | Get one personal access token by UUID. |
|
|
228
|
+
| `dockerhub_get_access_tokens` | `ACCESS_TOKENSTOOL` | List the personal access tokens of the authenticated user. |
|
|
229
|
+
| `dockerhub_get_audit_log_actions` | `AUDIT_LOGSTOOL` | List the audit-log action names available for a namespace. |
|
|
230
|
+
| `dockerhub_get_audit_logs` | `AUDIT_LOGSTOOL` | List audit-log events for a namespace. |
|
|
231
|
+
| `dockerhub_get_group` | `GROUPSTOOL` | Get one group. |
|
|
232
|
+
| `dockerhub_get_group_members` | `GROUPSTOOL` | List a group's members. |
|
|
233
|
+
| `dockerhub_get_groups` | `GROUPSTOOL` | List an organization's groups (teams). |
|
|
234
|
+
| `dockerhub_get_org_access_token` | `ORG_ACCESS_TOKENSTOOL` | Get one organization access token by id. |
|
|
235
|
+
| `dockerhub_get_org_access_tokens` | `ORG_ACCESS_TOKENSTOOL` | List an organization's access tokens. |
|
|
236
|
+
| `dockerhub_get_org_invites` | `ORGSTOOL` | List an organization's pending invites. |
|
|
237
|
+
| `dockerhub_get_org_members` | `ORGSTOOL` | List organization members (filter by search/type/role; paginated). |
|
|
238
|
+
| `dockerhub_get_org_settings` | `ORGSTOOL` | Get an organization's settings (restricted images policy). |
|
|
239
|
+
| `dockerhub_get_repositories` | `REPOSITORIESTOOL` | List a namespace's repositories (name filter + ordering enum). |
|
|
240
|
+
| `dockerhub_get_repository` | `REPOSITORIESTOOL` | Get one repository. |
|
|
241
|
+
| `dockerhub_get_repository_tag` | `REPOSITORIESTOOL` | Get one tag. |
|
|
242
|
+
| `dockerhub_get_repository_tags` | `REPOSITORIESTOOL` | List a repository's tags (paginated). |
|
|
243
|
+
| `dockerhub_get_scim_resource_type` | `SCIMTOOL` | Get one SCIM ResourceType by name. |
|
|
244
|
+
| `dockerhub_get_scim_resource_types` | `SCIMTOOL` | List the SCIM ResourceTypes. |
|
|
245
|
+
| `dockerhub_get_scim_schema` | `SCIMTOOL` | Get one SCIM Schema by id (URN). |
|
|
246
|
+
| `dockerhub_get_scim_schemas` | `SCIMTOOL` | List the SCIM Schemas. |
|
|
247
|
+
| `dockerhub_get_scim_service_provider_config` | `SCIMTOOL` | Get the SCIM ServiceProviderConfig. |
|
|
248
|
+
| `dockerhub_get_scim_user` | `SCIMTOOL` | Get one SCIM user by id. |
|
|
249
|
+
| `dockerhub_get_scim_users` | `SCIMTOOL` | List SCIM users (``startIndex``/``count``/``filter``/``sortBy``/``sortOrder``). |
|
|
250
|
+
| `dockerhub_login` | `AUTHTOOL` | Authenticate via the legacy login endpoint. |
|
|
251
|
+
| `dockerhub_patch_group` | `GROUPSTOOL` | Partially update a group (``PATCH``). |
|
|
252
|
+
| `dockerhub_remove_group_member` | `GROUPSTOOL` | Remove a username from a group. Destructive — gated. |
|
|
253
|
+
| `dockerhub_remove_org_member` | `ORGSTOOL` | Remove a member from the organization. Destructive — gated. |
|
|
254
|
+
| `dockerhub_replace_scim_user` | `SCIMTOOL` | Replace a SCIM user resource (``PUT``). |
|
|
255
|
+
| `dockerhub_resend_invite` | `ORGSTOOL` | Resend an invite (``PATCH /v2/invites/{id}/resend``). |
|
|
256
|
+
| `dockerhub_two_factor_login` | `AUTHTOOL` | Complete a 2FA login with the TOTP code (``POST /v2/users/2fa-login``). |
|
|
257
|
+
| `dockerhub_update_access_token` | `ACCESS_TOKENSTOOL` | Patch a personal access token's label and/or active state. |
|
|
258
|
+
| `dockerhub_update_group` | `GROUPSTOOL` | Replace a group's details (``PUT``). |
|
|
259
|
+
| `dockerhub_update_immutable_tags` | `REPOSITORIESTOOL` | Patch a repository's immutable-tags settings. |
|
|
260
|
+
| `dockerhub_update_org_access_token` | `ORG_ACCESS_TOKENSTOOL` | Patch an organization access token. |
|
|
261
|
+
| `dockerhub_update_org_member` | `ORGSTOOL` | Set a member's org role (``owner``, ``editor``, or ``member``). |
|
|
262
|
+
| `dockerhub_update_org_settings` | `ORGSTOOL` | Replace an organization's settings. Destructive — gated. |
|
|
263
|
+
| `dockerhub_verify_immutable_tags` | `REPOSITORIESTOOL` | Verify immutable-tag rules without applying them. |
|
|
264
|
+
|
|
265
|
+
</details>
|
|
266
|
+
|
|
267
|
+
_9 action-routed tool(s) (default) · 54 verbose 1:1 tool(s). Each is enabled unless its `<DOMAIN>TOOL` toggle is set false; `MCP_TOOL_MODE` selects the surface (`condensed` default · `verbose` 1:1 · `both`). Auto-generated — do not edit._
|
|
268
|
+
<!-- MCP-TOOLS-TABLE:END -->
|
|
269
|
+
|
|
270
|
+
### MCP Configuration Examples
|
|
271
|
+
|
|
272
|
+
<!-- MCP-CONFIG-EXAMPLES:START -->
|
|
273
|
+
|
|
274
|
+
> **Install the slim `[mcp]` extra.** All examples install `dockerhub-api[mcp]` — the
|
|
275
|
+
> MCP-server extra that pulls only the FastMCP / FastAPI tooling (`agent-utilities[mcp]`).
|
|
276
|
+
> It deliberately **excludes** the heavy agent runtime (`pydantic-ai`, the epistemic-graph
|
|
277
|
+
> engine, `dspy`, `llama-index`), so `uvx` / container installs are far smaller. Use the
|
|
278
|
+
> full `[agent]` extra only when you need the integrated Pydantic AI agent.
|
|
279
|
+
|
|
280
|
+
#### stdio Transport (local IDEs — Cursor, Claude Desktop, VS Code)
|
|
281
|
+
|
|
282
|
+
```json
|
|
283
|
+
{
|
|
284
|
+
"mcpServers": {
|
|
285
|
+
"dockerhub-mcp": {
|
|
286
|
+
"command": "uvx",
|
|
287
|
+
"args": [
|
|
288
|
+
"--from",
|
|
289
|
+
"dockerhub-api[mcp]",
|
|
290
|
+
"dockerhub-mcp"
|
|
291
|
+
],
|
|
292
|
+
"env": {
|
|
293
|
+
"MCP_TOOL_MODE": "condensed",
|
|
294
|
+
"ADMINTOOL": "True",
|
|
295
|
+
"AUDITTOOL": "True",
|
|
296
|
+
"AUTHTOOL": "True",
|
|
297
|
+
"DOCKERHUB_ALLOW_DESTRUCTIVE": "False",
|
|
298
|
+
"DOCKERHUB_JWT": "",
|
|
299
|
+
"DOCKERHUB_TOKEN": "dckr_pat_your_personal_access_token",
|
|
300
|
+
"DOCKERHUB_URL": "https://hub.docker.com",
|
|
301
|
+
"DOCKERHUB_USERNAME": "your_dockerhub_username",
|
|
302
|
+
"DOCKER_HUB_TOKEN": "",
|
|
303
|
+
"DOCKER_HUB_USER": "",
|
|
304
|
+
"DOCKER_REGISTRY_AUTH_URL": "https://auth.docker.io/token",
|
|
305
|
+
"DOCKER_REGISTRY_URL": "https://registry-1.docker.io",
|
|
306
|
+
"DOCKER_SCOUT_URL": "https://api.scout.docker.com",
|
|
307
|
+
"ORGTOOL": "True",
|
|
308
|
+
"REGISTRYTOOL": "True",
|
|
309
|
+
"REPOSTOOL": "True",
|
|
310
|
+
"SCIMTOOL": "True",
|
|
311
|
+
"SCOUTTOOL": "True",
|
|
312
|
+
"TEAMSTOOL": "True"
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
#### Streamable-HTTP Transport (networked / production)
|
|
320
|
+
|
|
321
|
+
```json
|
|
322
|
+
{
|
|
323
|
+
"mcpServers": {
|
|
324
|
+
"dockerhub-mcp": {
|
|
325
|
+
"command": "uvx",
|
|
326
|
+
"args": [
|
|
327
|
+
"--from",
|
|
328
|
+
"dockerhub-api[mcp]",
|
|
329
|
+
"dockerhub-mcp",
|
|
330
|
+
"--transport",
|
|
331
|
+
"streamable-http",
|
|
332
|
+
"--port",
|
|
333
|
+
"8000"
|
|
334
|
+
],
|
|
335
|
+
"env": {
|
|
336
|
+
"TRANSPORT": "streamable-http",
|
|
337
|
+
"HOST": "0.0.0.0",
|
|
338
|
+
"PORT": "8000",
|
|
339
|
+
"MCP_TOOL_MODE": "condensed",
|
|
340
|
+
"ADMINTOOL": "True",
|
|
341
|
+
"AUDITTOOL": "True",
|
|
342
|
+
"AUTHTOOL": "True",
|
|
343
|
+
"DOCKERHUB_ALLOW_DESTRUCTIVE": "False",
|
|
344
|
+
"DOCKERHUB_JWT": "",
|
|
345
|
+
"DOCKERHUB_TOKEN": "dckr_pat_your_personal_access_token",
|
|
346
|
+
"DOCKERHUB_URL": "https://hub.docker.com",
|
|
347
|
+
"DOCKERHUB_USERNAME": "your_dockerhub_username",
|
|
348
|
+
"DOCKER_HUB_TOKEN": "",
|
|
349
|
+
"DOCKER_HUB_USER": "",
|
|
350
|
+
"DOCKER_REGISTRY_AUTH_URL": "https://auth.docker.io/token",
|
|
351
|
+
"DOCKER_REGISTRY_URL": "https://registry-1.docker.io",
|
|
352
|
+
"DOCKER_SCOUT_URL": "https://api.scout.docker.com",
|
|
353
|
+
"ORGTOOL": "True",
|
|
354
|
+
"REGISTRYTOOL": "True",
|
|
355
|
+
"REPOSTOOL": "True",
|
|
356
|
+
"SCIMTOOL": "True",
|
|
357
|
+
"SCOUTTOOL": "True",
|
|
358
|
+
"TEAMSTOOL": "True"
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
Alternatively, connect to a pre-deployed Streamable-HTTP instance by `url`:
|
|
366
|
+
|
|
367
|
+
```json
|
|
368
|
+
{
|
|
369
|
+
"mcpServers": {
|
|
370
|
+
"dockerhub-mcp": {
|
|
371
|
+
"url": "http://localhost:8000/dockerhub-mcp/mcp"
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
Deploying the Streamable-HTTP server via Docker:
|
|
378
|
+
|
|
379
|
+
```bash
|
|
380
|
+
docker run -d \
|
|
381
|
+
--name dockerhub-mcp-mcp \
|
|
382
|
+
-p 8000:8000 \
|
|
383
|
+
-e TRANSPORT=streamable-http \
|
|
384
|
+
-e HOST=0.0.0.0 \
|
|
385
|
+
-e PORT=8000 \
|
|
386
|
+
-e MCP_TOOL_MODE=condensed \
|
|
387
|
+
-e ADMINTOOL=True \
|
|
388
|
+
-e AUDITTOOL=True \
|
|
389
|
+
-e AUTHTOOL=True \
|
|
390
|
+
-e DOCKERHUB_ALLOW_DESTRUCTIVE=False \
|
|
391
|
+
-e DOCKERHUB_JWT="" \
|
|
392
|
+
-e DOCKERHUB_TOKEN=dckr_pat_your_personal_access_token \
|
|
393
|
+
-e DOCKERHUB_URL=https://hub.docker.com \
|
|
394
|
+
-e DOCKERHUB_USERNAME=your_dockerhub_username \
|
|
395
|
+
-e DOCKER_HUB_TOKEN="" \
|
|
396
|
+
-e DOCKER_HUB_USER="" \
|
|
397
|
+
-e DOCKER_REGISTRY_AUTH_URL=https://auth.docker.io/token \
|
|
398
|
+
-e DOCKER_REGISTRY_URL=https://registry-1.docker.io \
|
|
399
|
+
-e DOCKER_SCOUT_URL=https://api.scout.docker.com \
|
|
400
|
+
-e ORGTOOL=True \
|
|
401
|
+
-e REGISTRYTOOL=True \
|
|
402
|
+
-e REPOSTOOL=True \
|
|
403
|
+
-e SCIMTOOL=True \
|
|
404
|
+
-e SCOUTTOOL=True \
|
|
405
|
+
-e TEAMSTOOL=True \
|
|
406
|
+
knucklessg1/dockerhub-api:mcp
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
_Auto-generated from the code-read env surface (`MCP_TOOL_MODE` + package vars) — do not edit._
|
|
410
|
+
<!-- MCP-CONFIG-EXAMPLES:END -->
|
|
411
|
+
|
|
412
|
+
<!-- BEGIN GENERATED: additional-deployment-options -->
|
|
413
|
+
### Additional Deployment Options
|
|
414
|
+
|
|
415
|
+
`dockerhub-api` can also run as a **local container** (Docker / Podman / `uv`) or be
|
|
416
|
+
consumed from a **remote deployment**. The
|
|
417
|
+
[Deployment guide](https://knuckles-team.github.io/dockerhub-api/deployment/) has full, copy-paste
|
|
418
|
+
`mcp_config.json` for all four transports — **stdio**, **streamable-http**,
|
|
419
|
+
**local container / uv**, and **remote URL**:
|
|
420
|
+
|
|
421
|
+
- **Local container / uv** — launch the server from `mcp_config.json` via `uvx`,
|
|
422
|
+
`docker run`, or `podman run`, or point at a local streamable-http container by `url`.
|
|
423
|
+
- **Remote URL** — connect to a server deployed behind Caddy at
|
|
424
|
+
`http://dockerhub-mcp.arpa/mcp` using the `"url"` key.
|
|
425
|
+
<!-- END GENERATED: additional-deployment-options -->
|
|
426
|
+
|
|
427
|
+
## Safety Model
|
|
428
|
+
|
|
429
|
+
| Operation class | Default | Override |
|
|
430
|
+
|---|---|---|
|
|
431
|
+
| Reads (repos, tags, members, logs, SCIM) | allowed | — |
|
|
432
|
+
| Repository create / immutable-tag config / invites / role updates | allowed | — |
|
|
433
|
+
| Deletes (PATs, OATs, groups, members, invites) | **blocked** | `DOCKERHUB_ALLOW_DESTRUCTIVE=True` |
|
|
434
|
+
| Org-settings writes (`PUT /v2/orgs/{org}/settings`) | **blocked** | `DOCKERHUB_ALLOW_DESTRUCTIVE=True` |
|
|
435
|
+
|
|
436
|
+
---
|
|
437
|
+
|
|
438
|
+
## Concepts
|
|
439
|
+
|
|
440
|
+
The concept registry (`CONCEPT:HUB-1.x`) is documented in
|
|
441
|
+
[docs/concepts.md](docs/concepts.md).
|
|
442
|
+
|
|
443
|
+
## License
|
|
444
|
+
|
|
445
|
+
MIT — see [LICENSE](LICENSE).
|
|
446
|
+
|
|
447
|
+
|
|
448
|
+
<!-- BEGIN agent-os-genesis-deploy (generated; do not edit between markers) -->
|
|
449
|
+
|
|
450
|
+
## Deploy with `agent-os-genesis`
|
|
451
|
+
|
|
452
|
+
This package can be provisioned for you — skill-guided — by the **`agent-os-genesis`**
|
|
453
|
+
universal skill (its *single-package deploy mode*): it picks your install method, seeds
|
|
454
|
+
secrets to OpenBao/Vault (or `.env`), trusts your enterprise CA, registers the MCP
|
|
455
|
+
server, and verifies it — the same machinery that stands up the whole Agent OS, narrowed
|
|
456
|
+
to just this package. Ask your agent to **"deploy `dockerhub-api` with agent-os-genesis"**.
|
|
457
|
+
|
|
458
|
+
| Install mode | Command |
|
|
459
|
+
|------|---------|
|
|
460
|
+
| Bare-metal, prod (PyPI) | `uvx dockerhub-mcp` · or `uv tool install dockerhub-api` |
|
|
461
|
+
| Bare-metal, dev (editable) | `uv pip install -e ".[all]"` · or `pip install -e ".[all]"` |
|
|
462
|
+
| Container, prod | deploy `knucklessg1/dockerhub-api:latest` via docker-compose / swarm / podman / podman-compose / kubernetes |
|
|
463
|
+
| Container, dev (editable) | deploy `docker/compose.dev.yml` (source-mounted at `/src`; edits live on restart) |
|
|
464
|
+
|
|
465
|
+
Secrets are read-existing + seeded via `vault_sync` — you are only prompted for what's missing.
|
|
466
|
+
|
|
467
|
+
<!-- END agent-os-genesis-deploy -->
|