{
  "markdown": "# harbor-registry-mcp\n\n<!-- mcp-name: io.github.mshegolev/harbor-registry-mcp -->\n\n[![PyPI](https://img.shields.io/pypi/v/harbor-registry-mcp.svg?logo=pypi&logoColor=white)](https://pypi.org/project/harbor-registry-mcp/)\n[![Python](https://img.shields.io/pypi/pyversions/harbor-registry-mcp.svg?logo=python&logoColor=white)](https://pypi.org/project/harbor-registry-mcp/)\n[![License: MIT](https://img.shields.io/pypi/l/harbor-registry-mcp.svg)](LICENSE)\n\nMCP server for [Harbor Registry](https://goharbor.io/). Lets an LLM agent (Claude Code, Cursor, OpenCode, etc.) list projects, repositories and artifacts, run **storage reports**, find **cleanup candidates**, and delete untagged or old artifacts — all with safety rails (dry-run by default for bulk delete).\n\nPython, [FastMCP](https://github.com/modelcontextprotocol/python-sdk), stdio transport.\n\nWorks with any Harbor 2.x instance — SaaS or self-hosted / on-prem.\n\n## Why another Harbor MCP?\n\nA couple of community Harbor MCPs exist ([`nomagicln/mcp-harbor`](https://github.com/nomagicln/mcp-harbor), [`bupd/harbor-mcp-server`](https://github.com/bupd/harbor-mcp-server)) but they expose only the basic list/get endpoints. This one adds **storage reports, cleanup candidates, delete untagged, and delete old artifacts with dry-run** — the operations DevOps engineers actually need to reclaim disk space.\n\n## Design highlights\n\n- **Tool annotations** — read-only tools get `readOnlyHint: True`; destructive ones (`harbor_delete_*`) carry `destructiveHint: True` so MCP clients ask for confirmation.\n- **Dry-run by default** on both bulk cleanups (`harbor_delete_untagged`, `harbor_delete_old_artifacts`) — the agent must pass `dry_run=False` to execute.\n- **Structured output** — every tool returns a typed payload (TypedDict) + a markdown summary.\n- **Structured errors** — 401 / 403 / 404 / 429 / 5xx mapped to actionable hints.\n- **Pydantic input validation** for every argument.\n- **Vulnerability snapshot** — `harbor_list_artifacts` surfaces scan status and counts if `with_scan_overview` is enabled.\n\n## Features (8 tools)\n\n**Discovery & inspection**\n- `harbor_list_projects` — projects with repo counts and visibility\n- `harbor_list_repos` — repositories in a project\n- `harbor_list_artifacts` — artifacts in a repository with tags/size/scan status\n- `harbor_storage_report` — full project storage breakdown (all repos × all artifacts)\n\n**Cleanup planning**\n- `harbor_cleanup_candidates` — suggest what to delete (untagged, never-pulled, old versions)\n\n**Cleanup execution (destructive)**\n- `harbor_delete_artifact` — delete a single artifact by tag or digest\n- `harbor_delete_untagged` — delete all untagged artifacts in a project/repo (dry-run default)\n- `harbor_delete_old_artifacts` — keep N latest per repo, delete the rest (dry-run default)\n\n## Installation\n\nRequires Python 3.10+.\n\n```bash\n# via uvx (recommended)\nuvx --from harbor-registry-mcp harbor-registry-mcp\n\n# or via pipx\npipx install harbor-registry-mcp\n```\n\n## Configuration\n\n```bash\nclaude mcp add harbor -s project \\\n  --env HARBOR_URL=https://harbor.example.com \\\n  --env HARBOR_USERNAME='robot$your-robot' \\\n  --env HARBOR_PASSWORD=your-robot-token \\\n  --env HARBOR_SSL_VERIFY=true \\\n  -- uvx --from harbor-registry-mcp harbor-registry-mcp\n```\n\nOr in `.mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"harbor\": {\n      \"type\": \"stdio\",\n      \"command\": \"uvx\",\n      \"args\": [\"--from\", \"harbor-registry-mcp\", \"harbor-registry-mcp\"],\n      \"env\": {\n        \"HARBOR_URL\": \"https://harbor.example.com\",\n        \"HARBOR_USERNAME\": \"robot$your-robot\",\n        \"HARBOR_PASSWORD\": \"${HARBOR_PASSWORD}\",\n        \"HARBOR_SSL_VERIFY\": \"true\"\n      }\n    }\n  }\n}\n```\n\nCheck:\n\n```bash\nclaude mcp list\n# harbor: uvx --from harbor-registry-mcp harbor-registry-mcp - ✓ Connected\n```\n\n## Environment variables\n\n| Variable | Required | Description |\n|---|---|---|\n| `HARBOR_URL` | yes | Harbor URL (no trailing slash) |\n| `HARBOR_USERNAME` | yes | Harbor username — robot account recommended |\n| `HARBOR_PASSWORD` | yes | Password or robot token |\n| `HARBOR_SSL_VERIFY` | no | `true`/`false`. Default: `true`. |\n\n## Example usage\n\n- \"Storage report for project `einvy-pub`\"\n- \"Find cleanup candidates in `qa-assistant` — keep latest 3\"\n- \"Delete all untagged artifacts in `qa-assistant`\"\n- \"Dry-run delete of old artifacts in `qa-assistant/pgvector-rag`, keep 1 latest\"\n- \"What's in `einvy-pub/my-image`?\"\n\n## Safety\n\n- Read tools use `readOnlyHint: True` — no confirmation needed.\n- Delete tools use `destructiveHint: True` — clients should confirm.\n- `harbor_delete_untagged` and `harbor_delete_old_artifacts` both default to `dry_run=True`; the agent must explicitly set `dry_run=False` to actually delete.\n- `harbor_cleanup_candidates` is **read-only** — it only suggests candidates, never deletes.\n\n## Development\n\n```bash\ngit clone https://github.com/mshegolev/harbor-registry-mcp.git\ncd harbor-registry-mcp\npip install -e '.[dev]'\npytest\n```\n\n## License\n\nMIT © Mikhail Shchegolev\n",
  "bytes": 4999,
  "sha": "df377e794bd11d8fd6347957deedf1ee9b903b756e0b51b674cd8a5c232fd3dd",
  "repo_slug": "mshegolev/harbor-registry-mcp",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_mshegolev_harbor_registry_mcp_4ec7b212/readme"
}