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.
Files changed (74) hide show
  1. dockerhub_api-1.0.1/MANIFEST.in +4 -0
  2. dockerhub_api-1.0.1/PKG-INFO +467 -0
  3. dockerhub_api-1.0.1/README.md +437 -0
  4. {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/dockerhub_api/agent_server.py +1 -1
  5. {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/dockerhub_api/auth.py +25 -26
  6. dockerhub_api-1.0.1/dockerhub_api/main_agent.json +18 -0
  7. {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/dockerhub_api/mcp_server.py +25 -38
  8. dockerhub_api-1.0.1/dockerhub_api/prompts/__init__.py +0 -0
  9. dockerhub_api-1.0.1/dockerhub_api/prompts/main_agent.json +18 -0
  10. dockerhub_api-1.0.1/dockerhub_api/skills/__init__.py +0 -0
  11. dockerhub_api-1.0.1/dockerhub_api/skills/dockerhub-starter/SKILL.md +19 -0
  12. dockerhub_api-1.0.1/dockerhub_api.egg-info/PKG-INFO +467 -0
  13. {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/dockerhub_api.egg-info/SOURCES.txt +4 -0
  14. dockerhub_api-1.0.1/dockerhub_api.egg-info/entry_points.txt +9 -0
  15. dockerhub_api-1.0.1/dockerhub_api.egg-info/requires.txt +18 -0
  16. {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/pyproject.toml +12 -6
  17. {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/requirements.txt +1 -1
  18. {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/tests/test_dockerhub_a2a_validation.py +1 -1
  19. {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/tests/test_dockerhub_mcp_validation.py +3 -3
  20. dockerhub_api-0.5.0/MANIFEST.in +0 -4
  21. dockerhub_api-0.5.0/PKG-INFO +0 -282
  22. dockerhub_api-0.5.0/README.md +0 -252
  23. dockerhub_api-0.5.0/dockerhub_api/main_agent.json +0 -14
  24. dockerhub_api-0.5.0/dockerhub_api.egg-info/PKG-INFO +0 -282
  25. dockerhub_api-0.5.0/dockerhub_api.egg-info/entry_points.txt +0 -3
  26. dockerhub_api-0.5.0/dockerhub_api.egg-info/requires.txt +0 -18
  27. {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/LICENSE +0 -0
  28. {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/dockerhub_api/__init__.py +0 -0
  29. {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/dockerhub_api/__main__.py +0 -0
  30. {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/dockerhub_api/api/__init__.py +0 -0
  31. {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/dockerhub_api/api/api_client_access_tokens.py +0 -0
  32. {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/dockerhub_api/api/api_client_audit_logs.py +0 -0
  33. {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/dockerhub_api/api/api_client_auth.py +0 -0
  34. {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/dockerhub_api/api/api_client_base.py +0 -0
  35. {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/dockerhub_api/api/api_client_groups.py +0 -0
  36. {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/dockerhub_api/api/api_client_org_access_tokens.py +0 -0
  37. {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/dockerhub_api/api/api_client_orgs.py +0 -0
  38. {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/dockerhub_api/api/api_client_registry.py +0 -0
  39. {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/dockerhub_api/api/api_client_registry_base.py +0 -0
  40. {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/dockerhub_api/api/api_client_repositories.py +0 -0
  41. {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/dockerhub_api/api/api_client_scim.py +0 -0
  42. {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/dockerhub_api/api/api_client_scout.py +0 -0
  43. {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/dockerhub_api/api_client.py +0 -0
  44. {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/dockerhub_api/dockerhub_input_models.py +0 -0
  45. {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/dockerhub_api/dockerhub_response_models.py +0 -0
  46. {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/dockerhub_api/mcp/__init__.py +0 -0
  47. {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/dockerhub_api/mcp/mcp_admin.py +0 -0
  48. {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/dockerhub_api/mcp/mcp_audit.py +0 -0
  49. {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/dockerhub_api/mcp/mcp_auth.py +0 -0
  50. {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/dockerhub_api/mcp/mcp_org.py +0 -0
  51. {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/dockerhub_api/mcp/mcp_registry.py +0 -0
  52. {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/dockerhub_api/mcp/mcp_repos.py +0 -0
  53. {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/dockerhub_api/mcp/mcp_scim.py +0 -0
  54. {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/dockerhub_api/mcp/mcp_scout.py +0 -0
  55. {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/dockerhub_api/mcp/mcp_teams.py +0 -0
  56. {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/dockerhub_api/mcp_config.json +0 -0
  57. {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/dockerhub_api.egg-info/dependency_links.txt +0 -0
  58. {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/dockerhub_api.egg-info/top_level.txt +0 -0
  59. {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/setup.cfg +0 -0
  60. {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/tests/test_api_audit.py +0 -0
  61. {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/tests/test_api_org.py +0 -0
  62. {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/tests/test_api_registry.py +0 -0
  63. {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/tests/test_api_repositories.py +0 -0
  64. {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/tests/test_api_scim.py +0 -0
  65. {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/tests/test_api_scout.py +0 -0
  66. {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/tests/test_api_teams.py +0 -0
  67. {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/tests/test_api_tokens.py +0 -0
  68. {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/tests/test_api_wrapper.py +0 -0
  69. {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/tests/test_auth.py +0 -0
  70. {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/tests/test_concept_parity.py +0 -0
  71. {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/tests/test_init_dynamics.py +0 -0
  72. {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/tests/test_models.py +0 -0
  73. {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/tests/test_rate_limit.py +0 -0
  74. {dockerhub_api-0.5.0 → dockerhub_api-1.0.1}/tests/test_startup.py +0 -0
@@ -0,0 +1,4 @@
1
+ include LICENSE
2
+ include README.md
3
+ include requirements.txt
4
+ recursive-include dockerhub_api *.py *.json *.md *.yaml *.yml
@@ -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
+ ![PyPI - Version](https://img.shields.io/pypi/v/dockerhub-api)
35
+ ![MCP Server](https://badge.mcpx.dev?type=server 'MCP Server')
36
+ ![PyPI - Downloads](https://img.shields.io/pypi/dd/dockerhub-api)
37
+ ![GitHub Repo stars](https://img.shields.io/github/stars/Knuckles-Team/dockerhub-api)
38
+ ![PyPI - License](https://img.shields.io/pypi/l/dockerhub-api)
39
+ ![GitHub last commit (by committer)](https://img.shields.io/github/last-commit/Knuckles-Team/dockerhub-api)
40
+ ![GitHub issues](https://img.shields.io/github/issues/Knuckles-Team/dockerhub-api)
41
+ ![GitHub top language](https://img.shields.io/github/languages/top/Knuckles-Team/dockerhub-api)
42
+ ![GitHub repo size](https://img.shields.io/github/repo-size/Knuckles-Team/dockerhub-api)
43
+ ![PyPI - Wheel](https://img.shields.io/pypi/wheel/dockerhub-api)
44
+ ![PyPI - Implementation](https://img.shields.io/pypi/implementation/dockerhub-api)
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 -->