dockerhub-api 1.3.3__tar.gz → 1.3.6__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 (92) hide show
  1. {dockerhub_api-1.3.3/dockerhub_api.egg-info → dockerhub_api-1.3.6}/PKG-INFO +3 -9
  2. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/README.md +0 -2
  3. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/dockerhub_api/__init__.py +33 -0
  4. dockerhub_api-1.3.6/dockerhub_api/__main__.py +4 -0
  5. dockerhub_api-1.3.6/dockerhub_api/connector_sources.py +116 -0
  6. dockerhub_api-1.3.6/dockerhub_api/mcp_server.py +44 -0
  7. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/dockerhub_api/ontology/certification.json +6 -9
  8. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/dockerhub_api/ontology/dockerhub.ttl +13 -15
  9. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/dockerhub_api/ontology/mappings/source.yaml +1 -1
  10. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6/dockerhub_api.egg-info}/PKG-INFO +3 -9
  11. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/dockerhub_api.egg-info/SOURCES.txt +1 -8
  12. dockerhub_api-1.3.6/dockerhub_api.egg-info/entry_points.txt +5 -0
  13. dockerhub_api-1.3.6/dockerhub_api.egg-info/requires.txt +9 -0
  14. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/pyproject.toml +14 -17
  15. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/tests/test_dockerhub_mcp_validation.py +2 -2
  16. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/tests/test_fleet_name.py +3 -14
  17. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/tests/test_kg_ingest.py +1 -1
  18. dockerhub_api-1.3.3/MANIFEST.in +0 -4
  19. dockerhub_api-1.3.3/dockerhub_api/__main__.py +0 -4
  20. dockerhub_api-1.3.3/dockerhub_api/connectors/__init__.py +0 -0
  21. dockerhub_api-1.3.3/dockerhub_api/connectors/mcp_source_presets.json +0 -18
  22. dockerhub_api-1.3.3/dockerhub_api/connectors/tool_schema_fingerprints.json +0 -8
  23. dockerhub_api-1.3.3/dockerhub_api/mcp_server.py +0 -121
  24. dockerhub_api-1.3.3/dockerhub_api/prompts/__init__.py +0 -0
  25. dockerhub_api-1.3.3/dockerhub_api/skills/__init__.py +0 -0
  26. dockerhub_api-1.3.3/dockerhub_api.egg-info/entry_points.txt +0 -14
  27. dockerhub_api-1.3.3/dockerhub_api.egg-info/requires.txt +0 -15
  28. dockerhub_api-1.3.3/requirements.txt +0 -3
  29. dockerhub_api-1.3.3/tests/test_default_content_surfaces.py +0 -43
  30. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/LICENSE +0 -0
  31. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/dockerhub_api/api/__init__.py +0 -0
  32. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/dockerhub_api/api/api_client_access_tokens.py +0 -0
  33. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/dockerhub_api/api/api_client_audit_logs.py +0 -0
  34. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/dockerhub_api/api/api_client_auth.py +0 -0
  35. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/dockerhub_api/api/api_client_base.py +0 -0
  36. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/dockerhub_api/api/api_client_groups.py +0 -0
  37. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/dockerhub_api/api/api_client_org_access_tokens.py +0 -0
  38. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/dockerhub_api/api/api_client_orgs.py +0 -0
  39. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/dockerhub_api/api/api_client_registry.py +0 -0
  40. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/dockerhub_api/api/api_client_registry_base.py +0 -0
  41. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/dockerhub_api/api/api_client_repositories.py +0 -0
  42. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/dockerhub_api/api/api_client_scim.py +0 -0
  43. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/dockerhub_api/api/api_client_scout.py +0 -0
  44. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/dockerhub_api/api_client.py +0 -0
  45. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/dockerhub_api/auth.py +0 -0
  46. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/dockerhub_api/dockerhub_input_models.py +0 -0
  47. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/dockerhub_api/dockerhub_response_models.py +0 -0
  48. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/dockerhub_api/kg_ingest.py +0 -0
  49. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/dockerhub_api/mcp/__init__.py +0 -0
  50. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/dockerhub_api/mcp/mcp_admin.py +0 -0
  51. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/dockerhub_api/mcp/mcp_audit.py +0 -0
  52. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/dockerhub_api/mcp/mcp_auth.py +0 -0
  53. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/dockerhub_api/mcp/mcp_kg.py +0 -0
  54. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/dockerhub_api/mcp/mcp_org.py +0 -0
  55. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/dockerhub_api/mcp/mcp_registry.py +0 -0
  56. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/dockerhub_api/mcp/mcp_repos.py +0 -0
  57. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/dockerhub_api/mcp/mcp_scim.py +0 -0
  58. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/dockerhub_api/mcp/mcp_scout.py +0 -0
  59. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/dockerhub_api/mcp/mcp_teams.py +0 -0
  60. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/dockerhub_api/mcp_config.json +0 -0
  61. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/dockerhub_api/ontology/__init__.py +0 -0
  62. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/dockerhub_api/ontology/fixtures/records.json +0 -0
  63. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/dockerhub_api/ontology/migrations/manifest.json +0 -0
  64. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/dockerhub_api/ontology/shapes/connector.shacl.ttl +0 -0
  65. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/dockerhub_api/skills/dockerhub-api-operations/SKILL.md +0 -0
  66. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/dockerhub_api/skills/dockerhub-api-operations/agents/openai.yaml +0 -0
  67. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/dockerhub_api/skills/dockerhub-api-operations/references/catalog.md +0 -0
  68. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/dockerhub_api/skills/dockerhub-image-registry-scout/SKILL.md +0 -0
  69. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/dockerhub_api/skills/dockerhub-image-registry-scout/WORKFLOW.md +0 -0
  70. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/dockerhub_api/skills/dockerhub-org-administration/SKILL.md +0 -0
  71. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/dockerhub_api/skills/dockerhub-org-administration/WORKFLOW.md +0 -0
  72. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/dockerhub_api/skills/dockerhub-repository-management/SKILL.md +0 -0
  73. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/dockerhub_api/skills/dockerhub-repository-management/WORKFLOW.md +0 -0
  74. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/dockerhub_api.egg-info/dependency_links.txt +0 -0
  75. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/dockerhub_api.egg-info/top_level.txt +0 -0
  76. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/setup.cfg +0 -0
  77. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/tests/test_api_audit.py +0 -0
  78. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/tests/test_api_org.py +0 -0
  79. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/tests/test_api_registry.py +0 -0
  80. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/tests/test_api_repositories.py +0 -0
  81. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/tests/test_api_scim.py +0 -0
  82. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/tests/test_api_scout.py +0 -0
  83. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/tests/test_api_teams.py +0 -0
  84. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/tests/test_api_tokens.py +0 -0
  85. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/tests/test_api_wrapper.py +0 -0
  86. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/tests/test_auth.py +0 -0
  87. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/tests/test_dockerhub_a2a_validation.py +0 -0
  88. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/tests/test_identity_namespace_scoping.py +0 -0
  89. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/tests/test_init_dynamics.py +0 -0
  90. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/tests/test_models.py +0 -0
  91. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/tests/test_rate_limit.py +0 -0
  92. {dockerhub_api-1.3.3 → dockerhub_api-1.3.6}/tests/test_startup.py +0 -0
@@ -1,8 +1,8 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dockerhub-api
3
- Version: 1.3.3
3
+ Version: 1.3.6
4
4
  Summary: Docker Hub API + MCP Server
5
- Author-email: Project Maintainers <maintainers@users.noreply.github.com>
5
+ Author-email: Repository Maintainers <maintainers@knuckles.team>
6
6
  License: MIT
7
7
  Classifier: Development Status :: 5 - Production/Stable
8
8
  Classifier: License :: OSI Approved :: MIT License
@@ -12,13 +12,9 @@ Classifier: Programming Language :: Python :: 3
12
12
  Requires-Python: <3.15,>=3.12
13
13
  Description-Content-Type: text/markdown
14
14
  License-File: LICENSE
15
- Requires-Dist: agent-connector-sdk[mcp]<1.0.0,>=0.3.18
15
+ Requires-Dist: agent-connector-sdk[mcp]<0.6.0,>=0.5.4
16
16
  Requires-Dist: httpx>=0.28.1
17
17
  Requires-Dist: python-dotenv>=1.2.4
18
- Provides-Extra: mcp
19
- Requires-Dist: agent-connector-sdk[mcp]<1.0.0,>=0.3.18; extra == "mcp"
20
- Provides-Extra: all
21
- Requires-Dist: dockerhub-api[mcp]>=1.0.1; extra == "all"
22
18
  Provides-Extra: test
23
19
  Requires-Dist: pytest-xdist>=3.8.0; extra == "test"
24
20
  Requires-Dist: pytest>=9.1.1; extra == "test"
@@ -41,8 +37,6 @@ Dynamic: license-file
41
37
  ![PyPI - Wheel](https://img.shields.io/pypi/wheel/dockerhub-api)
42
38
  ![PyPI - Implementation](https://img.shields.io/pypi/implementation/dockerhub-api)
43
39
 
44
- *Version: 1.3.3*
45
-
46
40
  > **Documentation** — Installation, deployment, usage across the API, CLI, and MCP
47
41
  > Docker Hub platform are maintained in [docs/](docs/index.md).
48
42
 
@@ -13,8 +13,6 @@
13
13
  ![PyPI - Wheel](https://img.shields.io/pypi/wheel/dockerhub-api)
14
14
  ![PyPI - Implementation](https://img.shields.io/pypi/implementation/dockerhub-api)
15
15
 
16
- *Version: 1.3.3*
17
-
18
16
  > **Documentation** — Installation, deployment, usage across the API, CLI, and MCP
19
17
  > Docker Hub platform are maintained in [docs/](docs/index.md).
20
18
 
@@ -98,3 +98,36 @@ def __getattr__(name: str) -> Any:
98
98
 
99
99
  def __dir__() -> list[str]:
100
100
  return sorted(list(globals().keys()) + __all__)
101
+
102
+
103
+ from agent_connector_sdk.connector import Connector
104
+
105
+ from dockerhub_api.api.api_client_registry import RegistryApi
106
+ from dockerhub_api.api.api_client_scout import ScoutApi
107
+ from dockerhub_api.api_client import Api
108
+ from dockerhub_api.mcp import (
109
+ get_hub_client,
110
+ get_registry_client,
111
+ get_scout_client,
112
+ redact_secrets,
113
+ )
114
+
115
+ connector = Connector(
116
+ api=Api,
117
+ get_client=get_hub_client,
118
+ tools="dockerhub_api.mcp_server",
119
+ instructions="Docker Hub API MCP Server - Manage repositories, tags, access tokens, organizations, teams, audit logs, and SCIM provisioning; plus Registry v2 image operations (manifests, blobs, digests, multi-arch inspect, OCI referrers, gated push/delete) and Docker Scout CVE/SBOM/policy intelligence.",
120
+ verbose_targets=(
121
+ {
122
+ "client_cls": RegistryApi,
123
+ "get_client": get_registry_client,
124
+ "prefix": "dockerhub_registry",
125
+ },
126
+ {
127
+ "client_cls": ScoutApi,
128
+ "get_client": get_scout_client,
129
+ "prefix": "dockerhub_scout",
130
+ },
131
+ ),
132
+ result_coercer=redact_secrets,
133
+ )
@@ -0,0 +1,4 @@
1
+ from agent_connector_sdk import run
2
+
3
+ if __name__ == "__main__":
4
+ run()
@@ -0,0 +1,116 @@
1
+ """Data sources of this connector, declared by tool name (generated by connector-ontology-map migrate).
2
+
3
+ Served live as ``connector://resources``. Regenerate by editing the declarations, not the tools.
4
+ """
5
+
6
+ # ruff: noqa: E501
7
+ from __future__ import annotations
8
+
9
+ from agent_connector_sdk.ingest.live_declaration import source_meta
10
+
11
+ SOURCES = (
12
+ source_meta(
13
+ tool="dockerhub_get_repositories",
14
+ source_id="dockerhub-repositories",
15
+ record_type="Repository",
16
+ id_field="name",
17
+ cursor_field="last_updated",
18
+ page_param="page",
19
+ page_size_param="page_size",
20
+ pagination="page",
21
+ preset={
22
+ "doc_type": "repository",
23
+ "page_kind": "number",
24
+ "params_style": "args",
25
+ },
26
+ records_path="data.results",
27
+ server="dockerhub-mcp",
28
+ text_field="description",
29
+ title_field="name",
30
+ ),
31
+ )
32
+
33
+ SCHEMA_VERSION = 2
34
+
35
+ FIELD_SETS = {
36
+ "fields_1": {
37
+ "architecture": "xsd:string",
38
+ "digest": "xsd:string",
39
+ "imageSize": "xsd:integer",
40
+ "isPrivate": "xsd:boolean",
41
+ "lastPushed": "xsd:string",
42
+ "permission": "xsd:string",
43
+ "pullCount": "xsd:integer",
44
+ "scopes": "xsd:string",
45
+ "starCount": "xsd:integer",
46
+ },
47
+ }
48
+
49
+ SCHEMA_MAPPINGS = {
50
+ "AccessToken": {
51
+ "field_sets": ["fields_1"],
52
+ "ontology_class": None,
53
+ },
54
+ "ContainerImage": {
55
+ "field_sets": ["fields_1"],
56
+ "ontology_class": None,
57
+ },
58
+ "Namespace": {
59
+ "field_sets": ["fields_1"],
60
+ "ontology_class": None,
61
+ },
62
+ "Organization": {
63
+ "field_sets": ["fields_1"],
64
+ "ontology_class": "Namespace",
65
+ },
66
+ "Repository": {
67
+ "field_sets": ["fields_1"],
68
+ "ontology_class": "SoftwareProject",
69
+ },
70
+ "Team": {
71
+ "field_sets": ["fields_1"],
72
+ "ontology_class": "Team",
73
+ },
74
+ "Vulnerability": {
75
+ "field_sets": ["fields_1"],
76
+ "ontology_class": None,
77
+ },
78
+ }
79
+
80
+ RESOURCES = (
81
+ {
82
+ "id_prefix": "accesstoken",
83
+ "label": "Access Token",
84
+ "name": "AccessToken",
85
+ },
86
+ {
87
+ "id_prefix": "containerimage",
88
+ "label": "Container Image",
89
+ "name": "ContainerImage",
90
+ },
91
+ {
92
+ "id_prefix": "namespace",
93
+ "label": "Docker Hub Namespace",
94
+ "name": "Namespace",
95
+ },
96
+ {
97
+ "id_prefix": "organization",
98
+ "label": "Docker Hub Organization",
99
+ "name": "Organization",
100
+ },
101
+ {
102
+ "id_prefix": "repository",
103
+ "label": "Container Repository",
104
+ "name": "Repository",
105
+ },
106
+ {
107
+ "id_prefix": "team",
108
+ "label": "Team",
109
+ "name": "Team",
110
+ },
111
+ {
112
+ "id_prefix": "vulnerability",
113
+ "label": "Vulnerability",
114
+ "name": "Vulnerability",
115
+ },
116
+ )
@@ -0,0 +1,44 @@
1
+ #!/usr/bin/python
2
+ """Docker Hub MCP server entry point.
3
+
4
+ CONCEPT:DH-OS.audit.action-routed-mcp-surface — 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, hub_registry, hub_scout) on an agent-connector-sdk FastMCP
7
+ server.
8
+ """
9
+
10
+ import warnings
11
+
12
+ with warnings.catch_warnings():
13
+ warnings.simplefilter("ignore")
14
+
15
+ warnings.filterwarnings("ignore", message=".*urllib3.*or chardet.*")
16
+ warnings.filterwarnings("ignore", message=".*urllib3.*or charset_normalizer.*")
17
+
18
+
19
+ from dockerhub_api.mcp import (
20
+ register_admin_tools,
21
+ register_audit_tools,
22
+ register_auth_tools,
23
+ register_kg_tools,
24
+ register_org_tools,
25
+ register_registry_tools,
26
+ register_repos_tools,
27
+ register_scim_tools,
28
+ register_scout_tools,
29
+ register_teams_tools,
30
+ )
31
+
32
+ # SDK discovery registers the register_<tag>_tools functions bound in this module.
33
+ __all__ = [
34
+ "register_admin_tools",
35
+ "register_audit_tools",
36
+ "register_auth_tools",
37
+ "register_kg_tools",
38
+ "register_org_tools",
39
+ "register_registry_tools",
40
+ "register_repos_tools",
41
+ "register_scim_tools",
42
+ "register_scout_tools",
43
+ "register_teams_tools",
44
+ ]
@@ -1,12 +1,9 @@
1
1
  {
2
- "api_version": "arbora.io/v1",
2
+ "api_version": "graphos.io/v1",
3
3
  "artifacts": {
4
- "connector_manifest.yml": "1d2826d511f1b9ad3c921d7cca5d094285890c92bdd61cf4d27fc33853301e7d",
5
- "dockerhub_api/connectors/mcp_source_presets.json": "96b893636a49ece1a5f32decb9aea8e3740178cb5e4a19753748b4d18e7ca678",
6
- "dockerhub_api/connectors/tool_schema_fingerprints.json": "60f37329f11dc900fa385099069f005c7fc8f4b8afcb0ac05d48794b1c62324a",
7
- "dockerhub_api/ontology/dockerhub.ttl": "bd3f4498e3e9463ee4395a5da1d6afcbfc081a1437e1be52437ab4d52e18d55a",
4
+ "dockerhub_api/ontology/dockerhub.ttl": "263d36a1d975b161eb0e479310dc8fe5ac7c6f8977a053479d8e70707af0d858",
8
5
  "dockerhub_api/ontology/fixtures/records.json": "cdf24bdcd53b75daef789c05f93d55ced4ce4a138360a2ff9f1e34c55f8f6da8",
9
- "dockerhub_api/ontology/mappings/source.yaml": "72d333a63cb808bbc9a2f031834fa4c75919b11a8171ad5b347fad61247fa016",
6
+ "dockerhub_api/ontology/mappings/source.yaml": "84985121b0fe97a045b04a5c40183d434d3d7ca1bca29202080cb390955545a6",
10
7
  "dockerhub_api/ontology/migrations/manifest.json": "81a24f182615e83dc844c6e7f3a211d47705d2bfce4ee45b5c4b24134e64909f",
11
8
  "dockerhub_api/ontology/shapes/connector.shacl.ttl": "d42f68bb302d9a9e48fb3687b106416583661c5ac07c8aa7f35ed1622dcdae76"
12
9
  },
@@ -18,11 +15,11 @@
18
15
  "synthetic_fixture_contract": "passed"
19
16
  },
20
17
  "compatibility": {
21
- "agent_connector_sdk": ">=2.5.0,<3",
18
+ "agent_utilities": ">=2.5.0,<3",
22
19
  "bundle_schema": "2",
23
20
  "epistemic_graph": ">=2.27.0,<3"
24
21
  },
25
- "connector": "dockerhub-mcp",
22
+ "connector": "dockerhub-api",
26
23
  "kind": "ConnectorSourceAttestation",
27
24
  "live_certified": false,
28
25
  "mode": "offline-source",
@@ -32,5 +29,5 @@
32
29
  "signer": "UNSIGNED-PREVIEW",
33
30
  "signing_public_key": "",
34
31
  "status": "source-validated",
35
- "validated_at": "2026-08-26T13:42:55Z"
32
+ "validated_at": "2026-10-24T09:37:17Z"
36
33
  }
@@ -16,30 +16,25 @@
16
16
  rdfs:label "Docker Hub Namespace" ;
17
17
  rdfs:comment "A Docker Hub account/organization namespace that owns image repositories (the {namespace} in namespaces/{ns}/repositories)." .
18
18
 
19
- :Organization a owl:Class ;
20
- rdfs:subClassOf :Namespace ;
21
- rdfs:label "Docker Hub Organization" ;
22
- rdfs:comment "An organization namespace with members, teams, settings, and invites (hub_org)." .
19
+ :Organization a owl:Class .
20
+
21
+
22
+ :Repository a owl:Class .
23
23
 
24
- :Repository a owl:Class ;
25
- rdfs:label "Container Repository" ;
26
- rdfs:comment "A Docker Hub image repository holding tags and container images (hub_repos list/get)." .
27
24
 
28
25
  :ContainerImage a owl:Class ;
29
26
  rdfs:label "Container Image" ;
30
27
  rdfs:comment "A concrete, content-addressable OCI/Docker image (a repository tag resolving to a digest, size, and platform) — hub_repos list_tags / get_tag and hub_registry manifests." .
31
28
 
32
- :Team a owl:Class ;
33
- rdfs:label "Team" ;
34
- rdfs:comment "An organization group (team) granted repository permissions (hub_teams / hub_repos assign_group)." .
29
+ :Team a owl:Class .
30
+
35
31
 
36
32
  :AccessToken a owl:Class ;
37
33
  rdfs:label "Access Token" ;
38
34
  rdfs:comment "A personal or organization access token (PAT / OAT) scoped for registry and API access (hub_auth / hub_org tokens). Secret material is never ingested." .
39
35
 
40
- :Vulnerability a owl:Class ;
41
- rdfs:label "Vulnerability" ;
42
- rdfs:comment "A CVE / security finding reported against a container image by Docker Scout (hub_scout)." .
36
+ :Vulnerability a owl:Class .
37
+
43
38
 
44
39
  # --- links (owl:ObjectProperty) ---
45
40
 
@@ -138,5 +133,8 @@
138
133
  rdfs:comment """Docker Hub container-registry model — namespaces and organizations,
139
134
  image repositories, tags and the concrete container images they resolve to (digest,
140
135
  architecture, size), teams and their repository permissions, access tokens, and Docker
141
- Scout vulnerabilities — federated into the agent-connector-sdk knowledge-graph hub.""" ;
142
- owl:imports <http://knuckles.team/kg> .
136
+ Scout vulnerabilities — federated into the agent-connector-sdk knowledge-graph hub.""" .
137
+
138
+ # ontology-codemod R3
139
+ <http://knuckles.team/kg#ContainerImage> rdfs:subClassOf <http://knuckles.team/kg/infrastructure#ContainerImage> .
140
+ <http://knuckles.team/kg#Namespace> rdfs:subClassOf <http://knuckles.team/kg/infrastructure#Namespace> .
@@ -1,5 +1,5 @@
1
1
  schema_version: '1'
2
- connector: dockerhub-api
2
+ connector: dockerhub-mcp
3
3
  ontology_source: dockerhub
4
4
  sync:
5
5
  - preset: dockerhub-repositories
@@ -1,8 +1,8 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dockerhub-api
3
- Version: 1.3.3
3
+ Version: 1.3.6
4
4
  Summary: Docker Hub API + MCP Server
5
- Author-email: Project Maintainers <maintainers@users.noreply.github.com>
5
+ Author-email: Repository Maintainers <maintainers@knuckles.team>
6
6
  License: MIT
7
7
  Classifier: Development Status :: 5 - Production/Stable
8
8
  Classifier: License :: OSI Approved :: MIT License
@@ -12,13 +12,9 @@ Classifier: Programming Language :: Python :: 3
12
12
  Requires-Python: <3.15,>=3.12
13
13
  Description-Content-Type: text/markdown
14
14
  License-File: LICENSE
15
- Requires-Dist: agent-connector-sdk[mcp]<1.0.0,>=0.3.18
15
+ Requires-Dist: agent-connector-sdk[mcp]<0.6.0,>=0.5.4
16
16
  Requires-Dist: httpx>=0.28.1
17
17
  Requires-Dist: python-dotenv>=1.2.4
18
- Provides-Extra: mcp
19
- Requires-Dist: agent-connector-sdk[mcp]<1.0.0,>=0.3.18; extra == "mcp"
20
- Provides-Extra: all
21
- Requires-Dist: dockerhub-api[mcp]>=1.0.1; extra == "all"
22
18
  Provides-Extra: test
23
19
  Requires-Dist: pytest-xdist>=3.8.0; extra == "test"
24
20
  Requires-Dist: pytest>=9.1.1; extra == "test"
@@ -41,8 +37,6 @@ Dynamic: license-file
41
37
  ![PyPI - Wheel](https://img.shields.io/pypi/wheel/dockerhub-api)
42
38
  ![PyPI - Implementation](https://img.shields.io/pypi/implementation/dockerhub-api)
43
39
 
44
- *Version: 1.3.3*
45
-
46
40
  > **Documentation** — Installation, deployment, usage across the API, CLI, and MCP
47
41
  > Docker Hub platform are maintained in [docs/](docs/index.md).
48
42
 
@@ -1,12 +1,11 @@
1
1
  LICENSE
2
- MANIFEST.in
3
2
  README.md
4
3
  pyproject.toml
5
- requirements.txt
6
4
  dockerhub_api/__init__.py
7
5
  dockerhub_api/__main__.py
8
6
  dockerhub_api/api_client.py
9
7
  dockerhub_api/auth.py
8
+ dockerhub_api/connector_sources.py
10
9
  dockerhub_api/dockerhub_input_models.py
11
10
  dockerhub_api/dockerhub_response_models.py
12
11
  dockerhub_api/kg_ingest.py
@@ -31,9 +30,6 @@ dockerhub_api/api/api_client_registry_base.py
31
30
  dockerhub_api/api/api_client_repositories.py
32
31
  dockerhub_api/api/api_client_scim.py
33
32
  dockerhub_api/api/api_client_scout.py
34
- dockerhub_api/connectors/__init__.py
35
- dockerhub_api/connectors/mcp_source_presets.json
36
- dockerhub_api/connectors/tool_schema_fingerprints.json
37
33
  dockerhub_api/mcp/__init__.py
38
34
  dockerhub_api/mcp/mcp_admin.py
39
35
  dockerhub_api/mcp/mcp_audit.py
@@ -52,8 +48,6 @@ dockerhub_api/ontology/fixtures/records.json
52
48
  dockerhub_api/ontology/mappings/source.yaml
53
49
  dockerhub_api/ontology/migrations/manifest.json
54
50
  dockerhub_api/ontology/shapes/connector.shacl.ttl
55
- dockerhub_api/prompts/__init__.py
56
- dockerhub_api/skills/__init__.py
57
51
  dockerhub_api/skills/dockerhub-api-operations/SKILL.md
58
52
  dockerhub_api/skills/dockerhub-api-operations/agents/openai.yaml
59
53
  dockerhub_api/skills/dockerhub-api-operations/references/catalog.md
@@ -73,7 +67,6 @@ tests/test_api_teams.py
73
67
  tests/test_api_tokens.py
74
68
  tests/test_api_wrapper.py
75
69
  tests/test_auth.py
76
- tests/test_default_content_surfaces.py
77
70
  tests/test_dockerhub_a2a_validation.py
78
71
  tests/test_dockerhub_mcp_validation.py
79
72
  tests/test_fleet_name.py
@@ -0,0 +1,5 @@
1
+ [agent_connector_sdk.connector]
2
+ dockerhub-mcp = dockerhub_api:connector
3
+
4
+ [console_scripts]
5
+ dockerhub-mcp = agent_connector_sdk.cli:serve
@@ -0,0 +1,9 @@
1
+ agent-connector-sdk[mcp]<0.6.0,>=0.5.4
2
+ httpx>=0.28.1
3
+ python-dotenv>=1.2.4
4
+
5
+ [test]
6
+ pytest-xdist>=3.8.0
7
+ pytest>=9.1.1
8
+ pytest-asyncio>=1.4.0
9
+ pytest-cov>=7.1.0
@@ -4,40 +4,29 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "dockerhub-api"
7
- version = "1.3.3"
7
+ version = "1.3.6"
8
8
  description = "Docker Hub API + MCP Server"
9
9
  readme = "README.md"
10
10
  classifiers = [ "Development Status :: 5 - Production/Stable", "License :: OSI Approved :: MIT License", "Environment :: Console", "Operating System :: POSIX :: Linux", "Programming Language :: Python :: 3",]
11
11
  requires-python = ">=3.12, <3.15"
12
- dependencies = [ "agent-connector-sdk[mcp]>=0.3.18,<1.0.0", "httpx>=0.28.1", "python-dotenv>=1.2.4",]
12
+ dependencies = [ "agent-connector-sdk[mcp]>=0.5.4,<0.6.0", "httpx>=0.28.1", "python-dotenv>=1.2.4",]
13
13
  [[project.authors]]
14
- name = "Project Maintainers"
15
- email = "maintainers@users.noreply.github.com"
14
+ name = "Repository Maintainers"
15
+ email = "maintainers@knuckles.team"
16
16
 
17
17
  [project.license]
18
18
  text = "MIT"
19
19
 
20
20
  [project.optional-dependencies]
21
- mcp = [ "agent-connector-sdk[mcp]>=0.3.18,<1.0.0",]
22
- all = [ "dockerhub-api[mcp]>=1.0.1",]
23
21
  test = [
24
22
  "pytest-xdist>=3.8.0", "pytest>=9.1.1", "pytest-asyncio>=1.4.0", "pytest-cov>=7.1.0",]
25
23
 
26
24
  [project.scripts]
27
- dockerhub-mcp = "dockerhub_api.mcp_server:mcp_server"
28
-
29
- [project.entry-points."agent_connector_sdk.skill_providers"]
30
- dockerhub-api = "dockerhub_api.skills"
31
-
32
- [project.entry-points."agent_connector_sdk.ontology_providers"]
33
- dockerhub-api = "dockerhub_api.ontology"
34
-
35
- [project.entry-points."agent_connector_sdk.source_connector_providers"]
36
- dockerhub-api = "dockerhub_api.connectors"
25
+ dockerhub-mcp = "agent_connector_sdk.cli:serve"
37
26
 
38
27
  # The one declared connector identity: the fleet name (SDK-CONNECTOR-CONTROL-R071).
39
28
  [project.entry-points."agent_connector_sdk.connector"]
40
- dockerhub-mcp = "dockerhub_api"
29
+ dockerhub-mcp = "dockerhub_api:connector"
41
30
 
42
31
  [tool.uv.workspace]
43
32
  members = ["."]
@@ -51,6 +40,7 @@ override-dependencies = [
51
40
  ]
52
41
 
53
42
  [tool.ruff]
43
+ extend-exclude = ["tests", "scripts"]
54
44
  line-length = 88
55
45
  target-version = "py312"
56
46
 
@@ -80,3 +70,10 @@ ignore_names = ["request", "config", "cls", "exc_info"]
80
70
 
81
71
  [tool.pipelines_hooks.ste]
82
72
  exempt = ["specs/*", "specs/**/*"]
73
+
74
+ [tool.pipelines.container]
75
+ debug_apt = ["default-jre", "ripgrep", "tree", "fd-find", "curl", "nano", "build-essential", "cmake", "libssl-dev", "libcurl4-openssl-dev", "pkg-config", "cargo", "rustc"]
76
+ install_extras = {"mcp" = []}
77
+
78
+ [tool.pipelines.codespell]
79
+ ignore_words = ["nd"]
@@ -50,9 +50,9 @@ def mcp_instance(hub, registry, scout, monkeypatch):
50
50
  hub_auth_module, "get_scout_client", lambda **_k: make_scout_api(scout)
51
51
  )
52
52
  monkeypatch.setattr(sys, "argv", ["dockerhub-mcp"])
53
- from dockerhub_api.mcp_server import get_mcp_instance
53
+ from agent_connector_sdk.connector import build_server
54
54
 
55
- mcp, _args, _middlewares, registered = get_mcp_instance()
55
+ _, mcp = build_server("dockerhub_api", command_args=[])
56
56
  return mcp
57
57
 
58
58
 
@@ -2,9 +2,8 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
+ from agent_connector_sdk.connector_identity import connector_name
5
6
  import ast
6
- import json
7
- import re
8
7
  import tomllib
9
8
  from pathlib import Path
10
9
 
@@ -36,18 +35,8 @@ def _call_connectors(path: Path) -> list[str]:
36
35
  def test_connector_name_is_the_fleet_name() -> None:
37
36
  pyproject = tomllib.loads((ROOT / "pyproject.toml").read_text(encoding="utf-8"))
38
37
  assert pyproject["project"]["entry-points"]["agent_connector_sdk.connector"] == {
39
- FLEET: "dockerhub_api"
38
+ FLEET: "dockerhub_api:connector"
40
39
  }
41
- manifest_path = PACKAGE / "connector_manifest.yml"
42
- if not manifest_path.is_file():
43
- manifest_path = ROOT / "connector_manifest.yml"
44
- manifest = manifest_path.read_text(encoding="utf-8")
45
- match = re.search(r'^\s*"?connector"?\s*:\s*"?([^"\s,]+)', manifest, re.MULTILINE)
46
- assert match is not None and match.group(1) == FLEET
47
- fingerprints = PACKAGE / "connectors" / "tool_schema_fingerprints.json"
48
- if fingerprints.is_file():
49
- assert (
50
- json.loads(fingerprints.read_text(encoding="utf-8"))["connector"] == FLEET
51
- )
40
+ assert connector_name("dockerhub_api") == FLEET
52
41
  for module in sorted(PACKAGE.glob("*.py")):
53
42
  assert all(name == FLEET for name in _call_connectors(module)), module.name
@@ -69,7 +69,7 @@ async def test_ingest_entities_writes_nodes_and_edges(ingest):
69
69
  a_record = next(r for r in request.records if r.record_id == "a")
70
70
  assert a_record.payload["name"] == "r"
71
71
  assert request.relationships[0].relation_reference.endswith(
72
- "resources/Repository/relations/inNamespace"
72
+ "relations/Repository/inNamespace"
73
73
  )
74
74
 
75
75
 
@@ -1,4 +0,0 @@
1
- include LICENSE
2
- include README.md
3
- include requirements.txt
4
- recursive-include dockerhub_api *.py *.json *.md *.yaml *.yml
@@ -1,4 +0,0 @@
1
- from dockerhub_api.mcp_server import mcp_server
2
-
3
- if __name__ == "__main__":
4
- mcp_server()
File without changes
@@ -1,18 +0,0 @@
1
- {
2
- "_comment": "Tier-1 mcp_tool source presets for dockerhub-api (AU-KG.ingest.mcp-tool-connector). Syncs Docker Hub repositories into the KG as repository documents via the dockerhub-api MCP server hub_repos tool. Contributed presets win over the central MCP_TOOL_PRESETS. The native dockerhub_ingest_repositories tool + kg_ingest.py provide the typed :Repository/:ContainerImage graph nodes.",
3
- "dockerhub-repositories": {
4
- "server": "dockerhub-mcp",
5
- "tool": "dockerhub_get_repositories",
6
- "records_path": "data.results",
7
- "id_field": "name",
8
- "title_field": "name",
9
- "text_field": "description",
10
- "updated_field": "last_updated",
11
- "pagination": "page",
12
- "page_kind": "number",
13
- "page_param": "page",
14
- "page_size_param": "page_size",
15
- "doc_type": "repository",
16
- "params_style": "args"
17
- }
18
- }
@@ -1,8 +0,0 @@
1
- {
2
- "algorithm": "agent-connector-sdk:mcp-tool-contract-compat:v2",
3
- "connector": "dockerhub-mcp",
4
- "schema_version": "1",
5
- "tools": {
6
- "dockerhub_get_repositories": "c6fb6018860f39159633a23ca0b19a3555daa371598111e280e753ef80ca0595"
7
- }
8
- }
@@ -1,121 +0,0 @@
1
- #!/usr/bin/python
2
- """Docker Hub MCP server entry point.
3
-
4
- CONCEPT:DH-OS.audit.action-routed-mcp-surface — 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, hub_registry, hub_scout) on an agent-connector-sdk FastMCP
7
- server.
8
- """
9
-
10
- import warnings
11
-
12
- with warnings.catch_warnings():
13
- warnings.simplefilter("ignore")
14
-
15
- warnings.filterwarnings("ignore", message=".*urllib3.*or chardet.*")
16
- warnings.filterwarnings("ignore", message=".*urllib3.*or charset_normalizer.*")
17
-
18
- import logging
19
- import os
20
- import sys
21
- from typing import Any
22
-
23
- from agent_connector_sdk.config import load_config
24
- from agent_connector_sdk.mcp.server import create_mcp_server
25
- from agent_connector_sdk.mcp.tool_surface import register_tool_surface
26
- from fastmcp.utilities.logging import get_logger
27
-
28
- from dockerhub_api.api.api_client_registry import RegistryApi
29
- from dockerhub_api.api.api_client_scout import ScoutApi
30
- from dockerhub_api.api_client import Api
31
- from dockerhub_api.mcp import (
32
- get_hub_client,
33
- get_registry_client,
34
- get_scout_client,
35
- redact_secrets,
36
- register_admin_tools, # noqa: F401
37
- register_audit_tools, # noqa: F401
38
- register_auth_tools, # noqa: F401
39
- register_kg_tools, # noqa: F401
40
- register_org_tools, # noqa: F401
41
- register_registry_tools, # noqa: F401
42
- register_repos_tools, # noqa: F401
43
- register_scim_tools, # noqa: F401
44
- register_scout_tools, # noqa: F401
45
- register_teams_tools, # noqa: F401
46
- )
47
-
48
- __version__ = "1.3.3"
49
- print(f"Docker Hub MCP v{__version__}", file=sys.stderr)
50
-
51
- logger = get_logger(name="mcp_server")
52
- logger.setLevel(logging.DEBUG)
53
-
54
-
55
- def get_mcp_instance() -> tuple[Any, Any, Any, Any]:
56
- """Initialize and return the Docker Hub MCP instance, args, and middlewares."""
57
- load_config()
58
- os.environ["FASTMCP_LOG_LEVEL"] = "ERROR"
59
- os.environ["TERM"] = "dumb"
60
- os.environ["NO_COLOR"] = "1"
61
-
62
- args, mcp, middlewares = create_mcp_server(
63
- name="DockerHub",
64
- version=__version__,
65
- instructions=(
66
- "Docker Hub API MCP Server - Manage repositories, tags, access "
67
- "tokens, organizations, teams, audit logs, and SCIM provisioning; "
68
- "plus Registry v2 image operations (manifests, blobs, digests, "
69
- "multi-arch inspect, OCI referrers, gated push/delete) and Docker "
70
- "Scout CVE/SBOM/policy intelligence."
71
- ),
72
- )
73
-
74
- registered_tags = register_tool_surface(
75
- mcp,
76
- client_cls=Api,
77
- get_client=get_hub_client,
78
- service="dockerhub-api",
79
- tools_module=sys.modules[__name__],
80
- verbose_targets=[
81
- {
82
- "client_cls": RegistryApi,
83
- "get_client": get_registry_client,
84
- "prefix": "dockerhub_registry",
85
- },
86
- {
87
- "client_cls": ScoutApi,
88
- "get_client": get_scout_client,
89
- "prefix": "dockerhub_scout",
90
- },
91
- ],
92
- result_coercer=redact_secrets,
93
- )
94
-
95
- for mw in middlewares:
96
- mcp.add_middleware(mw)
97
-
98
- return mcp, args, middlewares, registered_tags
99
-
100
-
101
- def mcp_server() -> None:
102
- mcp, args, middlewares, registered_tags = get_mcp_instance()
103
- print(f"{'dockerhub-api'} MCP v{__version__}", file=sys.stderr)
104
- print("\nStarting MCP Server", file=sys.stderr)
105
- print(f" Transport: {args.transport.upper()}", file=sys.stderr)
106
- print(f" Auth: {args.auth_type}", file=sys.stderr)
107
- print(f" Dynamic Tags Loaded: {len(set(registered_tags))}", file=sys.stderr)
108
-
109
- if args.transport == "stdio":
110
- mcp.run(transport="stdio")
111
- elif args.transport == "streamable-http":
112
- mcp.run(transport="streamable-http", host=args.host, port=args.port)
113
- elif args.transport == "sse":
114
- mcp.run(transport="sse", host=args.host, port=args.port)
115
- else:
116
- logger.error("Invalid transport", extra={"transport": args.transport})
117
- sys.exit(1)
118
-
119
-
120
- if __name__ == "__main__":
121
- mcp_server()
File without changes
File without changes
@@ -1,14 +0,0 @@
1
- [agent_connector_sdk.connector]
2
- dockerhub-mcp = dockerhub_api
3
-
4
- [agent_connector_sdk.ontology_providers]
5
- dockerhub-api = dockerhub_api.ontology
6
-
7
- [agent_connector_sdk.skill_providers]
8
- dockerhub-api = dockerhub_api.skills
9
-
10
- [agent_connector_sdk.source_connector_providers]
11
- dockerhub-api = dockerhub_api.connectors
12
-
13
- [console_scripts]
14
- dockerhub-mcp = dockerhub_api.mcp_server:mcp_server
@@ -1,15 +0,0 @@
1
- agent-connector-sdk[mcp]<1.0.0,>=0.3.18
2
- httpx>=0.28.1
3
- python-dotenv>=1.2.4
4
-
5
- [all]
6
- dockerhub-api[mcp]>=1.0.1
7
-
8
- [mcp]
9
- agent-connector-sdk[mcp]<1.0.0,>=0.3.18
10
-
11
- [test]
12
- pytest-xdist>=3.8.0
13
- pytest>=9.1.1
14
- pytest-asyncio>=1.4.0
15
- pytest-cov>=7.1.0
@@ -1,3 +0,0 @@
1
- agent-connector-sdk[mcp]>=0.2.1,<1.0.0
2
- httpx>=0.27.0
3
- python-dotenv>=1.0.0
@@ -1,43 +0,0 @@
1
- """CONN-DOCKERHUB-API-CONNECTOR-CONTENT-R001: the server lists its packaged skills, ontology and prompts by default."""
2
-
3
- from __future__ import annotations
4
-
5
- import asyncio
6
- import importlib
7
- from pathlib import Path
8
-
9
- import pytest
10
- from fastmcp import Client
11
-
12
- PACKAGE = "dockerhub_api"
13
- ROOT = Path(list(importlib.import_module(PACKAGE).__path__)[0])
14
-
15
- pytestmark = pytest.mark.spec("CONN-DOCKERHUB-API-CONNECTOR-CONTENT-R001")
16
-
17
-
18
- def _server():
19
- namespace = {"__name__": PACKAGE + ".mcp_server"}
20
- exec(
21
- "from agent_connector_sdk.mcp.server import create_mcp_server\n"
22
- "result = create_mcp_server('dockerhub-mcp', version='0', command_args=[])",
23
- namespace,
24
- )
25
- return namespace["result"][1]
26
-
27
-
28
- async def _listings():
29
- async with Client(_server()) as client:
30
- resources = {str(r.uri) for r in await client.list_resources()}
31
- prompts = {p.name for p in await client.list_prompts()}
32
- return resources, prompts
33
-
34
-
35
- def test_default_content_surfaces() -> None:
36
- resources, prompts = asyncio.run(_listings())
37
- if list(ROOT.glob("skills/*/SKILL.md")):
38
- assert any(u.startswith("skill://") for u in resources)
39
- if list(ROOT.glob("ontology/*.ttl")):
40
- assert any(u.startswith("ontology://dockerhub-mcp/") for u in resources)
41
- for path in ROOT.glob("prompts/*.json"):
42
- if not path.name.startswith("_"):
43
- assert path.stem in prompts
File without changes
File without changes