dockerhub-api 0.1.0__py3-none-any.whl

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.
@@ -0,0 +1,58 @@
1
+ """MCP tool for Docker Hub repositories and tags.
2
+
3
+ CONCEPT:HUB-1.4 — action-routed MCP surface.
4
+ """
5
+
6
+ from typing import Any
7
+
8
+ from fastmcp import Context, FastMCP
9
+ from fastmcp.dependencies import Depends
10
+ from pydantic import Field
11
+
12
+ from dockerhub_api.mcp import get_hub_client, parse_params, redact_secrets, run_action
13
+
14
+
15
+ def register_repos_tools(mcp: FastMCP):
16
+ @mcp.tool(tags={"repositories"})
17
+ async def hub_repos(
18
+ action: str = Field(
19
+ description=(
20
+ "Action to perform. Must be one of: 'list', 'create', 'get', "
21
+ "'check', 'list_tags', 'check_tags', 'get_tag', 'check_tag', "
22
+ "'set_immutable_tags', 'verify_immutable_tags', 'assign_group'"
23
+ )
24
+ ),
25
+ params_json: str = Field(
26
+ default="{}", description="JSON string of parameters to pass to the action."
27
+ ),
28
+ client=Depends(get_hub_client),
29
+ ctx: Context | None = Field(
30
+ default=None, description="MCP context for progress reporting"
31
+ ),
32
+ ) -> Any:
33
+ """Manage Docker Hub repositories: list/create/inspect repositories,
34
+ browse tags, configure and verify immutable tags, and grant teams
35
+ repository permissions. Repository creation is the primary release
36
+ provisioning path and is allowed by default.
37
+ """
38
+ if ctx:
39
+ await ctx.info("Executing tool...")
40
+ try:
41
+ kwargs = parse_params(params_json)
42
+ except Exception as e:
43
+ return {"error": f"Invalid params_json: {e}"}
44
+
45
+ handlers = {
46
+ "list": client.get_repositories,
47
+ "create": client.create_repository,
48
+ "get": client.get_repository,
49
+ "check": client.check_repository,
50
+ "list_tags": client.get_repository_tags,
51
+ "check_tags": client.check_repository_tags,
52
+ "get_tag": client.get_repository_tag,
53
+ "check_tag": client.check_repository_tag,
54
+ "set_immutable_tags": client.update_immutable_tags,
55
+ "verify_immutable_tags": client.verify_immutable_tags,
56
+ "assign_group": client.assign_repository_group,
57
+ }
58
+ return redact_secrets(run_action(handlers, action, kwargs))
@@ -0,0 +1,56 @@
1
+ """MCP tool for Docker Hub SCIM 2.0 provisioning.
2
+
3
+ CONCEPT:HUB-1.4 — action-routed MCP surface.
4
+ CONCEPT:HUB-1.5 — SCIM provisioning.
5
+ """
6
+
7
+ from typing import Any
8
+
9
+ from fastmcp import Context, FastMCP
10
+ from fastmcp.dependencies import Depends
11
+ from pydantic import Field
12
+
13
+ from dockerhub_api.mcp import get_hub_client, parse_params, redact_secrets, run_action
14
+
15
+
16
+ def register_scim_tools(mcp: FastMCP):
17
+ @mcp.tool(tags={"scim"})
18
+ async def hub_scim(
19
+ action: str = Field(
20
+ description=(
21
+ "Action to perform. Must be one of: 'service_provider_config', "
22
+ "'resource_types', 'resource_type', 'schemas', 'schema', "
23
+ "'list_users', 'get_user', 'create_user', 'update_user'"
24
+ )
25
+ ),
26
+ params_json: str = Field(
27
+ default="{}", description="JSON string of parameters to pass to the action."
28
+ ),
29
+ client=Depends(get_hub_client),
30
+ ctx: Context | None = Field(
31
+ default=None, description="MCP context for progress reporting"
32
+ ),
33
+ ) -> Any:
34
+ """Docker Hub SCIM 2.0: service discovery (ServiceProviderConfig,
35
+ ResourceTypes, Schemas) and user provisioning (list with
36
+ startIndex/count/filter/sortBy/sortOrder, get, create, replace).
37
+ """
38
+ if ctx:
39
+ await ctx.info("Executing tool...")
40
+ try:
41
+ kwargs = parse_params(params_json)
42
+ except Exception as e:
43
+ return {"error": f"Invalid params_json: {e}"}
44
+
45
+ handlers = {
46
+ "service_provider_config": client.get_scim_service_provider_config,
47
+ "resource_types": client.get_scim_resource_types,
48
+ "resource_type": client.get_scim_resource_type,
49
+ "schemas": client.get_scim_schemas,
50
+ "schema": client.get_scim_schema,
51
+ "list_users": client.get_scim_users,
52
+ "get_user": client.get_scim_user,
53
+ "create_user": client.create_scim_user,
54
+ "update_user": client.replace_scim_user,
55
+ }
56
+ return redact_secrets(run_action(handlers, action, kwargs))
@@ -0,0 +1,55 @@
1
+ """MCP tool for Docker Hub groups (teams) and their membership.
2
+
3
+ CONCEPT:HUB-1.4 — action-routed MCP surface.
4
+ """
5
+
6
+ from typing import Any
7
+
8
+ from fastmcp import Context, FastMCP
9
+ from fastmcp.dependencies import Depends
10
+ from pydantic import Field
11
+
12
+ from dockerhub_api.mcp import get_hub_client, parse_params, redact_secrets, run_action
13
+
14
+
15
+ def register_teams_tools(mcp: FastMCP):
16
+ @mcp.tool(tags={"teams"})
17
+ async def hub_teams(
18
+ action: str = Field(
19
+ description=(
20
+ "Action to perform. Must be one of: 'list', 'create', 'get', "
21
+ "'update', 'patch', 'delete', 'list_members', 'add_member', "
22
+ "'remove_member'"
23
+ )
24
+ ),
25
+ params_json: str = Field(
26
+ default="{}", description="JSON string of parameters to pass to the action."
27
+ ),
28
+ client=Depends(get_hub_client),
29
+ ctx: Context | None = Field(
30
+ default=None, description="MCP context for progress reporting"
31
+ ),
32
+ ) -> Any:
33
+ """Manage Docker Hub organization groups (teams) and their members.
34
+ Group deletion and member removal require
35
+ DOCKERHUB_ALLOW_DESTRUCTIVE=True.
36
+ """
37
+ if ctx:
38
+ await ctx.info("Executing tool...")
39
+ try:
40
+ kwargs = parse_params(params_json)
41
+ except Exception as e:
42
+ return {"error": f"Invalid params_json: {e}"}
43
+
44
+ handlers = {
45
+ "list": client.get_groups,
46
+ "create": client.create_group,
47
+ "get": client.get_group,
48
+ "update": client.update_group,
49
+ "patch": client.patch_group,
50
+ "delete": client.delete_group,
51
+ "list_members": client.get_group_members,
52
+ "add_member": client.add_group_member,
53
+ "remove_member": client.remove_group_member,
54
+ }
55
+ return redact_secrets(run_action(handlers, action, kwargs))
@@ -0,0 +1,3 @@
1
+ {
2
+ "mcpServers": {}
3
+ }
@@ -0,0 +1,109 @@
1
+ #!/usr/bin/python
2
+ """Docker Hub MCP server entry point.
3
+
4
+ CONCEPT:HUB-1.4 — action-routed MCP surface. Registers the consolidated,
5
+ togglable tool modules (hub_auth, hub_repos, hub_org, hub_teams, hub_audit,
6
+ hub_scim, hub_admin) on an agent-utilities FastMCP server.
7
+ """
8
+
9
+ import warnings
10
+
11
+ with warnings.catch_warnings():
12
+ warnings.simplefilter("ignore")
13
+
14
+ warnings.filterwarnings("ignore", message=".*urllib3.*or chardet.*")
15
+ warnings.filterwarnings("ignore", message=".*urllib3.*or charset_normalizer.*")
16
+
17
+ import logging
18
+ import os
19
+ import sys
20
+ from typing import Any
21
+
22
+ from agent_utilities.base_utilities import to_boolean
23
+ from agent_utilities.mcp_utilities import create_mcp_server
24
+ from dotenv import find_dotenv, load_dotenv
25
+ from fastmcp.utilities.logging import get_logger
26
+
27
+ from dockerhub_api.mcp import (
28
+ register_admin_tools,
29
+ register_audit_tools,
30
+ register_auth_tools,
31
+ register_org_tools,
32
+ register_repos_tools,
33
+ register_scim_tools,
34
+ register_teams_tools,
35
+ )
36
+
37
+ __version__ = "0.1.0"
38
+ print(f"Docker Hub MCP v{__version__}", file=sys.stderr)
39
+
40
+ logger = get_logger(name="mcp_server")
41
+ logger.setLevel(logging.DEBUG)
42
+
43
+ DEFAULT_DOCKERHUB_SSL_VERIFY = to_boolean(
44
+ string=os.getenv("DOCKERHUB_SSL_VERIFY", "True")
45
+ )
46
+ DEFAULT_DOCKERHUB_URL = os.getenv("DOCKERHUB_URL", "https://hub.docker.com")
47
+ DEFAULT_DOCKERHUB_TOKEN = os.getenv("DOCKERHUB_TOKEN", None)
48
+
49
+ #: (env toggle, register function) — every consolidated tool module.
50
+ TOOL_REGISTRY = (
51
+ ("AUTHTOOL", register_auth_tools),
52
+ ("REPOSTOOL", register_repos_tools),
53
+ ("ORGTOOL", register_org_tools),
54
+ ("TEAMSTOOL", register_teams_tools),
55
+ ("AUDITTOOL", register_audit_tools),
56
+ ("SCIMTOOL", register_scim_tools),
57
+ ("ADMINTOOL", register_admin_tools),
58
+ )
59
+
60
+
61
+ def get_mcp_instance() -> tuple[Any, Any, Any, Any]:
62
+ """Initialize and return the Docker Hub MCP instance, args, and middlewares."""
63
+ load_dotenv(find_dotenv())
64
+ os.environ["FASTMCP_LOG_LEVEL"] = "ERROR"
65
+ os.environ["TERM"] = "dumb"
66
+ os.environ["NO_COLOR"] = "1"
67
+
68
+ args, mcp, middlewares = create_mcp_server(
69
+ name="DockerHub",
70
+ version=__version__,
71
+ instructions=(
72
+ "Docker Hub API MCP Server - Manage repositories, tags, access "
73
+ "tokens, organizations, teams, audit logs, and SCIM provisioning."
74
+ ),
75
+ )
76
+
77
+ registered_tags: list[str] = []
78
+ for toggle, register in TOOL_REGISTRY:
79
+ if to_boolean(string=os.getenv(toggle, "True")):
80
+ register(mcp)
81
+ registered_tags.append(toggle)
82
+
83
+ for mw in middlewares:
84
+ mcp.add_middleware(mw)
85
+
86
+ return mcp, args, middlewares, registered_tags
87
+
88
+
89
+ def mcp_server() -> None:
90
+ mcp, args, middlewares, registered_tags = get_mcp_instance()
91
+ print(f"{'dockerhub-api'} MCP v{__version__}", file=sys.stderr)
92
+ print("\nStarting MCP Server", file=sys.stderr)
93
+ print(f" Transport: {args.transport.upper()}", file=sys.stderr)
94
+ print(f" Auth: {args.auth_type}", file=sys.stderr)
95
+ print(f" Dynamic Tags Loaded: {len(set(registered_tags))}", file=sys.stderr)
96
+
97
+ if args.transport == "stdio":
98
+ mcp.run(transport="stdio")
99
+ elif args.transport == "streamable-http":
100
+ mcp.run(transport="streamable-http", host=args.host, port=args.port)
101
+ elif args.transport == "sse":
102
+ mcp.run(transport="sse", host=args.host, port=args.port)
103
+ else:
104
+ logger.error("Invalid transport", extra={"transport": args.transport})
105
+ sys.exit(1)
106
+
107
+
108
+ if __name__ == "__main__":
109
+ mcp_server()
@@ -0,0 +1,230 @@
1
+ Metadata-Version: 2.4
2
+ Name: dockerhub-api
3
+ Version: 0.1.0
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>=0.47.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]>=0.47.0; extra == "mcp"
20
+ Provides-Extra: agent
21
+ Requires-Dist: agent-utilities[agent,logfire]>=0.47.0; extra == "agent"
22
+ Provides-Extra: all
23
+ Requires-Dist: dockerhub-api[agent,logfire,mcp]>=0.1.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: 0.1.0*
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.
77
+
78
+ ---
79
+
80
+ ## Key Features
81
+
82
+ - **Consolidated Action-Routed MCP Tools:** Seven togglable tool modules
83
+ (`hub_auth`, `hub_repos`, `hub_org`, `hub_teams`, `hub_audit`, `hub_scim`,
84
+ `hub_admin`) minimize token overhead in LLM contexts.
85
+ - **JWT Auth Lifecycle:** Short-lived bearer minted from `POST /v2/auth/token`
86
+ (password, PAT `dckr_pat_*`, or org access token), cached and refreshed before
87
+ expiry, with one transparent re-mint on 401.
88
+ - **Rate-Limit Telemetry:** `X-RateLimit-*` headers surfaced in every result;
89
+ HTTP 429 retried with bounded `Retry-After` backoff.
90
+ - **Safety by Default:** Deletes and org-settings writes are gated behind
91
+ `DOCKERHUB_ALLOW_DESTRUCTIVE` (default `False`); secrets are redacted from tool
92
+ results (plaintext tokens appear exactly once — on creation). Repository creation
93
+ stays enabled: it is the primary release-provisioning use case.
94
+ - **Integrated Graph Agent:** Built-in Pydantic AI agent (`dockerhub-agent`) with
95
+ A2A and AG-UI web interfaces.
96
+ - **Native Telemetry & Tracing:** Out-of-the-box OpenTelemetry exports and Langfuse
97
+ tracing via agent-utilities.
98
+
99
+ ---
100
+
101
+ ## Installation
102
+
103
+ ```bash
104
+ pip install dockerhub-api # API client only
105
+ pip install "dockerhub-api[mcp]" # + MCP server
106
+ pip install "dockerhub-api[agent]" # + A2A agent server
107
+ pip install "dockerhub-api[all]" # everything
108
+ ```
109
+
110
+ | Extra | Adds |
111
+ |---|---|
112
+ | `mcp` | FastMCP server (`dockerhub-mcp`) via `agent-utilities[mcp]` |
113
+ | `agent` | Pydantic-AI A2A agent (`dockerhub-agent`) + Logfire via `agent-utilities[agent,logfire]` |
114
+ | `all` | `mcp` + `agent` |
115
+ | `test` | pytest toolchain for development |
116
+
117
+ Or pull the published image:
118
+
119
+ ```bash
120
+ docker pull knucklessg1/dockerhub-api:latest
121
+ ```
122
+
123
+ ---
124
+
125
+ ## Usage
126
+
127
+ ### Python API / CLI
128
+
129
+ ```python
130
+ from dockerhub_api.auth import get_client
131
+
132
+ api = get_client() # reads DOCKERHUB_URL / DOCKER_HUB_USER / DOCKER_HUB_TOKEN
133
+
134
+ repos = api.get_repositories(namespace="acme", ordering="-last_updated")
135
+ api.create_repository(namespace="acme", name="release-images", is_private=True)
136
+ tags = api.get_repository_tags(namespace="acme", repository="release-images")
137
+ print(api.rate_limit) # latest X-RateLimit-* snapshot
138
+ ```
139
+
140
+ Every client method returns a uniform envelope:
141
+ `{"status_code": int, "data": ..., "rate_limit": {"limit", "remaining", "reset"}}`.
142
+
143
+ ### MCP
144
+
145
+ #### Available MCP Tools
146
+
147
+ | Tool Module | Toggle Env Var | Enabled by Default | Description & Nested Actions |
148
+ |---|---|---|---|
149
+ | `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` |
150
+ | `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` |
151
+ | `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` |
152
+ | `hub_teams` | `TEAMSTOOL` | True | Teams: `list`, `create`, `get`, `update`, `patch`, `delete`, `list_members`, `add_member`, `remove_member` |
153
+ | `hub_audit` | `AUDITTOOL` | True | Audit trail: `logs`, `actions` |
154
+ | `hub_scim` | `SCIMTOOL` | True | SCIM 2.0: `service_provider_config`, `resource_types`, `resource_type`, `schemas`, `schema`, `list_users`, `get_user`, `create_user`, `update_user` |
155
+ | `hub_admin` | `ADMINTOOL` | True | Diagnostics: `rate_limit`, `whoami` (local JWT introspection) |
156
+
157
+ Run the server:
158
+
159
+ ```bash
160
+ export DOCKER_HUB_USER=youruser
161
+ export DOCKER_HUB_TOKEN=dckr_pat_xxx
162
+ dockerhub-mcp --transport streamable-http --host 0.0.0.0 --port 8000
163
+ ```
164
+
165
+ ### Agent (A2A)
166
+
167
+ ```bash
168
+ dockerhub-agent --mcp-url http://localhost:8000/mcp --web
169
+ ```
170
+
171
+ ---
172
+
173
+ ## Environment Variables
174
+
175
+ | Variable | Default | Purpose |
176
+ |---|---|---|
177
+ | `DOCKERHUB_URL` | `https://hub.docker.com` | Docker Hub API base URL |
178
+ | `DOCKER_HUB_USER` | — | Account identifier (official hub-tool name, primary) |
179
+ | `DOCKER_HUB_TOKEN` | — | Password, PAT `dckr_pat_*`, or org access token (primary) |
180
+ | `DOCKERHUB_USERNAME` / `DOCKERHUB_TOKEN` | — | Legacy fallback aliases for the two above |
181
+ | `DOCKERHUB_JWT` | — | Optional pre-minted bearer (overrides credential exchange) |
182
+ | `DOCKERHUB_SSL_VERIFY` | `True` | TLS certificate verification |
183
+ | `DOCKERHUB_ALLOW_DESTRUCTIVE` | `False` | Enable deletes and org-settings writes |
184
+ | `AUTHTOOL` … `ADMINTOOL` | `True` | Per-module MCP tool toggles (see table above) |
185
+ | `HOST` / `PORT` / `TRANSPORT` | `0.0.0.0` / `8000` / `stdio` | MCP server bind & transport (`stdio`, `streamable-http`, `sse`) |
186
+ | `AUTH_TYPE` | `none` | MCP server auth mode (Docker image) |
187
+ | `MCP_URL` | — | MCP endpoint the A2A agent connects to |
188
+ | `ENABLE_OTEL` | `True` | OpenTelemetry / Langfuse export via agent-utilities |
189
+ | `EUNOMIA_TYPE` / `EUNOMIA_POLICY_FILE` / `EUNOMIA_REMOTE_URL` | `none` / `mcp_policies.json` / — | Eunomia access-governance middleware |
190
+ | `FASTMCP_LOG_LEVEL` / `NO_COLOR` | — | FastMCP logging controls |
191
+
192
+ A complete annotated template lives in [.env.example](.env.example).
193
+
194
+ ---
195
+
196
+ ## Deployment
197
+
198
+ Docker Compose definitions ship in [docker/](docker/):
199
+
200
+ ```bash
201
+ cp .env.example .env # fill in DOCKER_HUB_USER / DOCKER_HUB_TOKEN
202
+ docker compose -f docker/mcp.compose.yml up -d # MCP server only
203
+ docker compose -f docker/agent.compose.yml up -d # MCP server + A2A agent (port 9018)
204
+ ```
205
+
206
+ Both services expose `/health` endpoints; see
207
+ [docs/deployment.md](docs/deployment.md) for transports, Caddy ingress, and
208
+ Technitium DNS guidance.
209
+
210
+ ---
211
+
212
+ ## Safety Model
213
+
214
+ | Operation class | Default | Override |
215
+ |---|---|---|
216
+ | Reads (repos, tags, members, logs, SCIM) | allowed | — |
217
+ | Repository create / immutable-tag config / invites / role updates | allowed | — |
218
+ | Deletes (PATs, OATs, groups, members, invites) | **blocked** | `DOCKERHUB_ALLOW_DESTRUCTIVE=True` |
219
+ | Org-settings writes (`PUT /v2/orgs/{org}/settings`) | **blocked** | `DOCKERHUB_ALLOW_DESTRUCTIVE=True` |
220
+
221
+ ---
222
+
223
+ ## Concepts
224
+
225
+ The concept registry (`CONCEPT:HUB-1.x`) is documented in
226
+ [docs/concepts.md](docs/concepts.md).
227
+
228
+ ## License
229
+
230
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1,34 @@
1
+ dockerhub_api/__init__.py,sha256=k1wiT9akFBY7B-yLh83mkS1NLgtnGjRiFEyisivWJgc,2507
2
+ dockerhub_api/__main__.py,sha256=U3vMyjze1PLsQP_7Ykt4ut64-J3zSRepGHR_hVDgv4M,99
3
+ dockerhub_api/agent_server.py,sha256=pc4lde4kFMFYNoYVUEiT7XQYjv1V1mG-HShDeJlFox0,2665
4
+ dockerhub_api/api_client.py,sha256=r2dnhw2iMA4FTrMibQOuus__gkQemsZ9P6gbZoOYHh0,1247
5
+ dockerhub_api/auth.py,sha256=OJeYPbtD6HReobaZE3wHnkE7oE8XZAKyKsxzUjaeCMI,8710
6
+ dockerhub_api/dockerhub_input_models.py,sha256=661VY4sWohGDc_QVnndbgRqI5mLVhOjED7fG9YS5ZPA,26142
7
+ dockerhub_api/dockerhub_response_models.py,sha256=3jA-3aPcaHSgZXF3gaLD-VFDqzCQ59nKzuFZrOeeevI,9280
8
+ dockerhub_api/main_agent.json,sha256=k9FA3f4eAiaeCbgCHj-ug5Vj38By7NhCbd9MMPdfhHw,983
9
+ dockerhub_api/mcp_config.json,sha256=2OOXrwO1sDLyHQqpZwhvDHizPIe3by6YmK4KFE333gI,23
10
+ dockerhub_api/mcp_server.py,sha256=XRxcRfE6Ph4-fh4T9TlA4bp_TZ8QAhiHv12zMXs1kzY,3512
11
+ dockerhub_api/api/__init__.py,sha256=Ofb5z_yDBJ2JgbZxwQys6YBX327RFc0kKeOCOp1p3QY,47
12
+ dockerhub_api/api/api_client_access_tokens.py,sha256=MsAgkA8QQOE3p5bLYL6mvjkqpg_ENasPILNfuR42zSE,2859
13
+ dockerhub_api/api/api_client_audit_logs.py,sha256=uGqiKE8gOzkT4o6bDmz1TrhEAUDSudHNSsSMZRETEYg,1810
14
+ dockerhub_api/api/api_client_auth.py,sha256=pqo2Rasdr-1lUXZRXK-q23SP2hGh-L2mafvMzuopzuc,3251
15
+ dockerhub_api/api/api_client_base.py,sha256=WTMyCIDRXgSQPpSR32S2cKBAZa1BZtsYOCzpYVW1rK0,12236
16
+ dockerhub_api/api/api_client_groups.py,sha256=FqGaAu9SznW2uCpZJyJEj1s07Wf7bVQhE1IBbxMUmX8,5336
17
+ dockerhub_api/api/api_client_org_access_tokens.py,sha256=j3yqMoeZ3UTuXpDbcnmbfzMqfmEq-Gf5jFPfpWF-khk,3709
18
+ dockerhub_api/api/api_client_orgs.py,sha256=l1siP_O_0GVzBrNrJTEHRchuL8lw-X0A7OJkjMQRSms,5644
19
+ dockerhub_api/api/api_client_repositories.py,sha256=wwT3oe9lCcGtSGN1uXGqahCbYcm4pBSbrY7JmnHBk5k,7512
20
+ dockerhub_api/api/api_client_scim.py,sha256=HLkUSzb1RHP0vOFpzANgMYKjTG4tPbgXfFKuD93FvoI,5287
21
+ dockerhub_api/mcp/__init__.py,sha256=IEb_LmnQCWTk_Y__wS-2qWs_5EFbDUTmNkfQGFdldBE,3694
22
+ dockerhub_api/mcp/mcp_admin.py,sha256=v-L8uCTWe7he-BAGoMl9dBapdHganA7RNgtRRGyPy48,1543
23
+ dockerhub_api/mcp/mcp_audit.py,sha256=HNGnBxrHnuND31zontePiD56Zp2ObRoKc7MlnhXk-mQ,1458
24
+ dockerhub_api/mcp/mcp_auth.py,sha256=bTi6teDamh5huppPGspwLKZqQ3-0d6eYtkDF-hJ-ntY,2652
25
+ dockerhub_api/mcp/mcp_org.py,sha256=GBwQ2_WW-Zb0MmdAtg4uRNTYa4tve4dxMDjEoPgOacM,2238
26
+ dockerhub_api/mcp/mcp_repos.py,sha256=CE3hcCYD1nzKidRDF-dRuyp2ANNN2uM2kiqpOodEE7s,2242
27
+ dockerhub_api/mcp/mcp_scim.py,sha256=ZoBP9UvYlcEKs8-NN-wX3WGujt-8vaLbOvo2Hrnsimo,2106
28
+ dockerhub_api/mcp/mcp_teams.py,sha256=upA2ojftlmNYlfZmoRNqkQAM0-oiyUqYQiBOOhtp7NE,1914
29
+ dockerhub_api-0.1.0.dist-info/licenses/LICENSE,sha256=lAmFjsQO9B015kHJ11AulWIYtfW4DjC-_eP_yamF5Yg,1068
30
+ dockerhub_api-0.1.0.dist-info/METADATA,sha256=6IDML66_rsD7497wU67qTlV4wUwhfe-gp8qolkV_Qfw,9268
31
+ dockerhub_api-0.1.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
32
+ dockerhub_api-0.1.0.dist-info/entry_points.txt,sha256=fDrOoLNTQvXQkguffAuFgiMXYi2KwnmE8N1a88esoMo,128
33
+ dockerhub_api-0.1.0.dist-info/top_level.txt,sha256=2WKbefEedQJEA-Vfhw7K1aRwo7riYKLL1BomvcXNMio,14
34
+ dockerhub_api-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (82.0.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,3 @@
1
+ [console_scripts]
2
+ dockerhub-agent = dockerhub_api.agent_server:agent_server
3
+ dockerhub-mcp = dockerhub_api.mcp_server:mcp_server
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Audel Rouhi
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1 @@
1
+ dockerhub_api