Skip to main content

project-hub

Multi-repo workspace manager that unifies local git state and forge data (MRs, issues, pipelines, vulnerabilities) into a single MCP server + web dashboard.

Designed for engineers managing many repos under one parent directory — across multiple forges.

Dashboard

Killer features

aka why I built this

GitLab, GitHub, Bitbucket in a single interface. No more context-switching between forges. project-hub auto-detects which forge hosts your repos and talks to all of them — MRs, issues, pipelines, everything in one dashboard. Add a repo on Bitbucket, another on GitLab, a third on GitHub: same view, same tools, same agent.

Vulnerabilities that make sense. GitLab's vulnerability report is per-repo, noisy, and doesn't tell you what's already being fixed. project-hub aggregates vulns across all your repos, cross-references them with open MR branches to flag what's already fixed but not yet merged ("fixed in branch"), and lets you filter by severity, state, or hide already-handled ones. You see what actually needs work, not what's already in flight.

Stale branch detection. After merging an MR you often forget to switch back to the default branch locally. project-hub detects repos still sitting on stale feature branches and shows ahead/behind relative to the default branch — with a one-click checkout to clean up.

Events, not inbox. Stop reminding yourself to check your cluttered GitLab inbox. project-hub diffs state on every refresh cycle and surfaces what changed: new MR, issue opened/closed, pipeline failure, new vuln, auth expiry. Events live in a slide-in panel on the dashboard and persist across sessions until dismissed.

MCP-powered multi-repo agent. Everything visible in the dashboard is exposed as MCP tools. Claude Code sees your repos, MRs, issues, pipelines, vulns, and events — and can act on them. Events surface as MCP notifications, making the agent proactive instead of reactive.

Features

  • Unified dashboard — git status, MRs, issues, pipelines, vulns across all repos in one view
  • Merge request, issue & pipeline views — cross-repo tables with filters (mine/all, failed only, current branches only)
  • Per-repo detail page — MRs, issues, pipelines, active vulns for a single repo
  • Web UI (htmx) with real-time sync, sortable tables, persistent filters
  • Non-destructive pull — conflict detection via git merge-tree, no worktree mutations
  • Pin & reorder repos, drag-and-drop card layout
  • Bulk actions — pull all, unstale all in one click

Quick start

cd ~/Projects                    # parent dir containing your repos
uvx project-hub init             # creates .project-hub/
uvx project-hub auth login gitlab.com     # store your GitLab PAT
uvx project-hub auth login github.com     # store your GitHub token
uvx project-hub auth login bitbucket.org  # store your Bitbucket token
uvx project-hub                  # launch dashboard (opens browser)

Use as MCP server (Claude Code)

From PyPI:

claude mcp add --scope user project-hub -- uvx project-hub --mcp

From source (picks up local changes without cache issues):

claude mcp add --scope user project-hub -- \
  uv run --project /path/to/project-hub project-hub --mcp

Installing with --scope user is safe — the server adapts to the current directory:

Directory state Behavior
Has .project-hub/ Active — full tools + refresh
Parent has .project-hub/ Disabled — zero tools (sub-repo)
Has .no-project-hub Disabled — zero tools (opt-out)
Neither Dormant — only init tool
touch ~/some-project/.no-project-hub   # force disable in a specific dir

Then in Claude Code, the agent can call tools like list_repos, get_vulnerabilities, pull_safe, etc.

MCP tools

Tool Description
init Bootstrap .project-hub/ workspace
list_repos List discovered repos with forge info and annotation status
repo_status Git status (branch, ahead/behind, dirty)
fetch_all Trigger full refresh cycle
pull_safe Pull with conflict detection
list_mrs Merge requests (repo, state, author filters)
list_issues Issues (repo, state, author, label filters)
list_pipelines Pipelines (repo, status, ref filters)
get_vulnerabilities Vulns — defaults to high/critical + detected, includes solutions
get_pipeline_jobs Jobs for a specific pipeline
get_job_log Fetch log output for a specific CI job
annotate_repo Set per-repo annotations (role, domain, links, notes)
acknowledge_alerts Mark events as seen
rescan Re-scan workspace for new/removed repos
auth_status Check forge authentication
auth_login Store PAT for a forge instance
configure_forge Configure forge host mapping

Web dashboard

Route Description
/ Dashboard with repo cards, pinning, drag-and-drop, events panel
/mrs Merge requests table (mine/all filter)
/issues Issues table (mine/all filter)
/pipelines Pipelines table (failed only, current branches only)
/vulns Vulnerabilities (severity, state, fixed-in-branch filters)
/repo/{name} Per-repo detail: MRs, issues, pipelines, active vulns
/settings Exclude/include repos, rescan workspace

All filters and table sort are persisted in localStorage.

Architecture

Single Python process, dual interfaces: MCP (stdio) + HTTP (FastAPI/htmx). Background asyncio task refreshes git+forge data on a TTL cycle, diffs with SQLite cache to generate events.

project_hub/
  cli.py              # Click entry points
  core/
    workspace.py       # Orchestrator: discover -> refresh loop -> stop
    cache.py           # SQLite (WAL mode, aiosqlite)
    config.py          # YAML config with defaults
    discovery.py       # Scan for .git/ repos, classify forges
    models.py          # Dataclasses: Repo, MR, Issue, Pipeline, Vulnerability, Event
    events.py          # Diff old vs new state -> Event list
  forge/
    provider.py        # ForgeProvider ABC (shared interface for all forges)
    auth.py            # Token resolution: auth.json -> env vars -> config files
    gitlab.py          # python-gitlab + GraphQL
    github.py          # PyGithub
    bitbucket.py       # atlassian-python-api (Cloud)
  git/
    ops.py             # fetch, status, pull_safe (merge-tree conflict detection)
  mcp/
    server.py          # FastMCP tools + resources
  web/
    app.py             # FastAPI factory, routes, htmx fragments
    templates/         # Jinja2 templates
    static/            # CSS + vendored JS

Requirements

  • Python 3.10+
  • Git 2.38+ (for git merge-tree --write-tree)
  • A token for each forge you use:
    • GitLab: PAT with read_api scope
    • GitHub: PAT with repo scope
    • Bitbucket Cloud: API token (app passwords deprecated June 2026)

Testing

uv run pytest tests/ -v

License

Unlicense — public domain.

Release files for project-hub 0.17.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for project-hub 0.17.0
File Size Uploaded
project_hub-0.17.0.tar.gz 445.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for project-hub 0.17.0
File Interpreter ABI Platform
project_hub-0.17.0-py3-none-any.whl Python 3 none any Details

Total release size: 617.0 kB

Release files / project_hub-0.17.0.tar.gz

Download URL project_hub-0.17.0.tar.gz
Size 445.5 kB
Tags Source
SHA-256 checksum
How to use checksums
9115f90eff84363b71fbf09a3444285ab381b2049b13312b694153319a417416
BLAKE2b-256 checksum
How to use checksums
0c23d6ee1a9eb7b504e65b2c5b7cbb3df2dea1768e71828751d570819a5cb24c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.19 {"installer":{"name":"uv","version":"0.12.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / project_hub-0.17.0-py3-none-any.whl

Download URL project_hub-0.17.0-py3-none-any.whl
Size 171.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
8213efc776aac5b79ac918e3a2d730406d41428723427081159055ada2387885
BLAKE2b-256 checksum
How to use checksums
da8d4ebe9f57ea1ca4583bb78b1d726d52a2238519fa947ad75b3abeaf88f8d0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.19 {"installer":{"name":"uv","version":"0.12.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

This release

0.17.0 This release

2 release files

0.15.0

2 release files

0.14.5

2 release files

0.14.4

2 release files

0.14.3

2 release files

0.12.4

2 release files

0.12.3

2 release files

0.12.2

2 release files

0.12.1

2 release files

0.12.0

2 release files

0.11.2

2 release files

0.11.1

2 release files

0.11.0

2 release files

0.10.0

2 release files

0.9.2

2 release files

0.9.1

2 release files

0.9.0

2 release files

0.8.2

2 release files

0.8.1

2 release files

0.8.0

2 release files

0.7.0

2 release files

0.6.0

2 release files

0.5.1

2 release files

0.5.0

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.3.2

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page