Skip to content

[SPEC] GitBucket API Capability Map & MCP Plugin Roadmap #10

Description

@michael-conrad

Overview

Comprehensive map of GitBucket v4.46.0 REST API capabilities based on empirical probing, with a prioritized MCP plugin implementation roadmap to expose GitBucket's internal services to AI agents via MCP protocol.

Cross-references:

Problem

AI coding agents operating against GitBucket-hosted repositories cannot complete standard planning/issue workflows because GitBucket's REST API is missing critical endpoints. This plugin closes the gap by exposing GitBucket's internal Scala services directly via MCP tools — bypassing the broken REST API entirely.

Scope: MCP protocol only. REST API fixes are a separate concern, outside the scope of this plugin.

Empirical API Probe — Methodology

Two GitBucket versions probed against 51 endpoints on live local instances (host JDK 21, .war direct execution):

Version Port Test Date Probe Script
v4.45.0 8090 2026-04-15 ./tmp/gitbucket-test-v445/probe_all.py
v4.46.0 8080 2026-04-15 ./tmp/gitbucket-test/probe_api.py

Both used root:root basic auth on fresh instances with auto-initialized test repo.

Empirical API Probe Results — v4.46.0 Only

The v4.46.0 table below reflects the current target version. For diff with v4.45.0, see the "Version Comparison" section.

Working Endpoints (26/51)

Category Endpoint Method Status Notes
Issues List issues GET /repos/{o}/{r}/issues 200 Supports direction=desc&sort=created for search fallback
Issues Get issue GET /repos/{o}/{r}/issues/{n} 200 Full issue data
Issues Create issue POST /repos/{o}/{r}/issues 200 Title + body + labels at creation time
Issues Get comments GET /repos/{o}/{r}/issues/{n}/comments 200
Issues Add comment POST /repos/{o}/{r}/issues/{n}/comments 200
Issues Update comment PATCH /repos/{o}/{r}/issues/comments/{id} 200
Labels List labels GET /repos/{o}/{r}/labels 200
Labels Get label GET /repos/{o}/{r}/labels/{name} 200
Labels Create label POST /repos/{o}/{r}/labels 201
Labels Delete label DELETE /repos/{o}/{r}/labels/{name} 204
Labels Add labels to issue POST /repos/{o}/{r}/issues/{n}/labels 200
Labels Replace issue labels PUT /repos/{o}/{r}/issues/{n}/labels 200
Labels Remove label from issue DELETE /repos/{o}/{r}/issues/{n}/labels/{name} 200
PRs List PRs GET /repos/{o}/{r}/pulls 200
PRs Create PR POST /repos/{o}/{r}/pulls 200
PRs Get PR GET /repos/{o}/{r}/pulls/{n} 200 Includes merged boolean
PRs Update PR PATCH /repos/{o}/{r}/pulls/{n} 200 Title, body, state updates
PRs Merge PR PUT /repos/{o}/{r}/pulls/{n}/merge 200
PRs PR diff GET /repos/{o}/{r}/pulls/{n} (Accept: diff) 200 Via Accept header
Repos List user repos GET /users/{u}/repos 200
Repos Get repo GET /repos/{o}/{r} 200
Repos List branches GET /repos/{o}/{r}/branches 200
Releases List releases GET /repos/{o}/{r}/releases 200
Releases Create release POST /repos/{o}/{r}/releases 200
Tags List tags GET /repos/{o}/{r}/tags 200
Auth Get authenticated user GET /user 200

Not Working Endpoints (25/51)

Category Endpoint Method Status Error Type Notes
Issues Update issue (PATCH) PATCH /repos/{o}/{r}/issues/{n} 404 Unimplemented route Scalatra never reaches controller. No log output.
Issues Delete comment DELETE /repos/{o}/{r}/issues/comments/{id} 500 Runtime bug Internal server error
Sub-issues Get sub-issues GET /repos/{o}/{r}/issues/{n}/sub_issues 404 Unimplemented route GitHub-only concept
Sub-issues Add sub-issue POST /repos/{o}/{r}/issues/{n}/sub_issues 404 Unimplemented route GitHub-only concept
Issues Issue timeline GET /repos/{o}/{r}/issues/{n}/timeline 404 Unimplemented route
PRs List PR comments GET /repos/{o}/{r}/pulls/{n}/comments 404 Unimplemented route
PRs Create PR comment POST /repos/{o}/{r}/pulls/{n}/comments 404 Unimplemented route
PRs List PR reviews GET /repos/{o}/{r}/pulls/{n}/reviews 404 Unimplemented route
PRs Create PR review POST /repos/{o}/{r}/pulls/{n}/reviews 404 Unimplemented route
PRs PR files GET /repos/{o}/{r}/pulls/{n}/files 404 Unimplemented route
PRs PR commits GET /repos/{o}/{r}/pulls/{n}/commits 404 Unimplemented route
Files Get file contents GET /repos/{o}/{r}/contents/{path} 404 Unimplemented route REGRESSION from v4.45.0 where it returned 200
Files Create/update file PUT /repos/{o}/{r}/contents/{path} 500 Runtime bug REGRESSION from v4.45.0 where it returned 200
Git Push files (blob API) POST /repos/{o}/{r}/git/blobs 404 Unimplemented route
Git List commits GET /repos/{o}/{r}/commits 500 Runtime bug REGRESSION from v4.45.0 where it returned 200 — JGit NullPointerException
Git Get commit GET /repos/{o}/{r}/commits/{sha} 500 Runtime bug JGit NullPointerException
Search Search issues GET /search/issues?q=... 404 Unimplemented route All 5 search endpoints absent
Search Search code GET /search/code?q=... 404 Unimplemented route
Search Search repos GET /search/repositories?q=... 404 Unimplemented route
Search Search users GET /search/users?q=... 404 Unimplemented route
Search Search PRs GET /search/issues?q=type:pr... 404 Unimplemented route
Branches Create branch POST /repos/{o}/{r}/branches 404 Unimplemented route
Teams List user teams GET /user/teams 404 Unimplemented route
Teams Get repo teams GET /repos/{o}/{r}/teams 404 Unimplemented route
Orgs List org members GET /orgs/{o}/members 404 Unimplemented route

Error Classification

Broken endpoints split into two categories:

Category Behavior Relevance
Unimplemented routes (404) Scalatra never reaches controller. No log output at all — the route simply doesn't exist. This plugin bypasses these by calling GitBucket internal services directly via MCP tools. A separate API-fix plugin could add these routes.
Runtime bugs (500) Controller exists and is reached, but hits JGit/database error. Stack trace visible in logs. This plugin sidesteps these by using internal services. These bugs need fixing in GitBucket core — out of scope here.

The 404/500 distinction matters because:

  • 404 = route never existed → No code to fix in GitBucket core. A separate API-fix plugin could add these routes.
  • 500 = route exists but broken → GitBucket core has a bug. Fixing it upstream would make the endpoint work for all consumers.

Runtime bugs confirmed via SLF4J DEBUG logging on host JDK (Java 21 + .war):

  • list_commits / get_commit: JGit NullPointerException in org.eclipse.jgit.lib.ObjectId.toString()
  • create_or_update_file: JGit error during blob creation
  • delete_issue_comment: Internal server error (unconfirmed root cause)

Version Comparison — v4.45.0 vs v4.46.0 (Empirically Verified)

Both versions tested on local instances with identical probe methodology.

Differences

Endpoint v4.45.0 v4.46.0 Change Type
GET /repos/{o}/{r}/contents/{path} 200 ✅ 404 ❌ REGRESSION — file contents worked in v4.45, route removed or broken in v4.46
PUT /repos/{o}/{r}/contents/{path} 200 ✅ 500 ❌ REGRESSION — file create/update worked in v4.45, JGit error in v4.46
GET /repos/{o}/{r}/commits 200 ✅ 500 ❌ REGRESSION — commits listing worked in v4.45, JGit NPE in v4.46
GET /repos/{o}/{r}/pulls/{n} (diff) N/A 200 ✅ IMPROVEMENT — PR diff via Accept header new in v4.46

Identical Results (no change between versions)

All label endpoints (add/replace/remove) work identically in both v4.45.0 and v4.46.0. The PATCH /issues/{n} 404 is present in both versions. All search endpoints (404), sub-issue endpoints (404), and PR review endpoints (404) are identical across both versions.

Full Endpoint Matrix

Endpoint v4.45.0 v4.46.0
Issues
List issues 200 ✅ 200 ✅
Get issue 200 ✅ 200 ✅
Create issue 200 ✅ 200 ✅
PATCH issue 404 ❌ 404 ❌
Get comments 200 ✅ 200 ✅
Add comment 200 ✅ 200 ✅
Update comment 200 ✅ 200 ✅
Delete comment 500 ❌ 500 ❌
Labels
List labels 200 ✅ 200 ✅
Get label 200 ✅ 200 ✅
Create label 201 ✅ 201 ✅
Delete label 204 ✅ 204 ✅
Add labels to issue 200 ✅ 200 ✅
Replace issue labels 200 ✅ 200 ✅
Remove label from issue 200 ✅ 200 ✅
Sub-issues / Timeline
Get sub-issues 404 ❌ 404 ❌
Add sub-issue 404 ❌ 404 ❌
Issue timeline 404 ❌ 404 ❌
PRs
List PRs 200 ✅ 200 ✅
Create PR 200 ✅ 200 ✅
Get PR 200 ✅ 200 ✅
Update PR 200 ✅ 200 ✅
Merge PR 200 ✅ 200 ✅
List PR comments 404 ❌ 404 ❌
Create PR comment 404 ❌ 404 ❌
List PR reviews 404 ❌ 404 ❌
Create PR review 404 ❌ 404 ❌
PR files 404 ❌ 404 ❌
PR commits 404 ❌ 404 ❌
Files / Git
Get file contents 200 ✅ 404 ❌
Create/update file 200 ✅ 500 ❌
Push files (blobs) 404 ❌ 404 ❌
List commits 200 ✅ 500 ❌
Get commit 500 ❌ 500 ❌
Create branch 404 ❌ 404 ❌
Search
Search issues 404 ❌ 404 ❌
Search code 404 ❌ 404 ❌
Search repos 404 ❌ 404 ❌
Search users 404 ❌ 404 ❌
Search PRs 404 ❌ 404 ❌
Repos / Releases / Tags
List repos 200 ✅ 200 ✅
Get repo 200 ✅ 200 ✅
List branches 200 ✅ 200 ✅
List releases 200 ✅ 200 ✅
Create release 200 ✅ 200 ✅
List tags 200 ✅ 200 ✅
Auth / Teams / Orgs
Get auth user 200 ✅ 200 ✅
List user teams 404 ❌ 404 ❌
Get repo teams 404 ❌ 404 ❌
List org members 404 ❌ 404 ❌

Summary: v4.45.0: 28 working / 22 broken. v4.46.0: 26 working / 25 broken. v4.46.0 regresses 3 endpoints that worked in v4.45.0 (file contents, file create/update, commit listing).

Versions Not Tested

Version Status Reason
v4.42.1 Not probed Java 21 incompatibility — v4.42.1 targets Java 11, crashes on JDK 21
v4.43.0 Not probed No JDK 11/17 available on host
v4.44.0 Not probed No JDK 11/17 available on host

Label behavior claims for v4.42.1 (from README.md and API-DEFICIENCIES.md) remain unverified — we cannot confirm or deny whether labels were broken in v4.42.1 without probing on a compatible JDK.

Why MCP Tools — Not REST API Fixes

This plugin's sole purpose is to expose GitBucket's internal Scala services via MCP protocol so AI agents can operate against GitBucket-hosted repos.

REST API fixes are a separate concern. They would require implementing Scalatra routes under /api/v3/ to patch missing endpoints — a different architectural goal that benefits all HTTP consumers, not just AI agents. That work belongs in a separate plugin or in GitBucket core itself.

This plugin's strategy: bypass the broken REST API entirely by calling IssueService, PullRequestService, LabelService, etc. directly from within the GitBucket JVM. MCP tools communicate over STDIO/SSE, not HTTP, so the REST API is irrelevant to the plugin's operation.

REST API Fallbacks (For Agent Platform Sub-Skills Without This Plugin)

When this plugin is NOT installed, the parent repo's issue-operations dispatcher falls back to REST API with workarounds. These are documented here so the MCP tools know what they're replacing.

Search Fallback — Iterative Listing

Since GitBucket has no Search API, the fallback is iterative listing with client-side filtering:

GET /repos/{owner}/{repo}/issues?direction=desc&sort=created

Empirically validated on v4.46.0: This parameter works for both issues and PRs. The agent lists issues/PRs in reverse chronological order and performs client-side match against the search criteria, stopping on first match.

Sub-Issue Fallback — Comment-Based Linking

Since GitBucket has no sub-issues API, the fallback is comment-based linking:

  1. add_sub_issue(parent, child): Post a comment on the parent: Sub-issue: #{child_number}
  2. get_sub_issues(parent): Parse parent comments for Sub-issue: #N patterns
  3. remove_sub_issue(parent, child): Post a comment on the parent: Removed sub-issue: #{child_number}

PATCH Issue Fallback — Comment + Create-New Pattern

Since PATCH /repos/{o}/{r}/issues/{n} returns 404 in both v4.45.0 and v4.46.0, the REST API fallback is:

  1. Title/body changes: Post a comment on the original issue stating the change. Create a new issue if the change is significant (spec revision pattern).
  2. State changes (close/reopen): No REST API mechanism available — this is a hard blocker for agent workflows without this plugin.

This plugin eliminates all fallbacks by calling IssueService.updateIssue() directly.

File Contents Fallback — Version-Dependent

Version GET /contents/{path} Workaround
v4.45.0 200 ✅ Use directly
v4.46.0 404 ❌ Use git clone + local file read

This regression means agents on v4.46.0 cannot read files via API — another gap this plugin fills.

MCP Plugin Implementation Roadmap

GitBucket Internal Services Available

The plugin runs inside the GitBucket JVM with compile-only access to:

Service Capabilities Used By
IssueService Create, get, update, close, reopen, search issues All P0/P1 issue tools
PullRequestService Create, get, update, merge PRs P2 PR tools
LabelService Full CRUD + add/replace/remove on issues P1 label tools
RepositoryService Get repo info, list repos Repo tools
MergeService Merge with issue auto-close P2 merge tool
AccountService User info, authentication Auth tools
Slick DB queries Direct database access for search P1 search tool
JGit File contents, commits, branches, diffs P2 git tools

Phase 1: MCP Core — Issue Operations (P0)

Priority MCP Tool Name Description Internal Service
P0 gitbucket_create_issue Create issue with title, body, labels IssueService.createIssue()
P0 gitbucket_get_issue Get issue details IssueService.getIssue()
P0 gitbucket_update_issue Update title, body (bypasses broken PATCH) IssueService.updateIssue()
P0 gitbucket_close_issue Close an issue IssueService.updateIssue() state change
P0 gitbucket_reopen_issue Reopen an issue IssueService.updateIssue() state change
P0 gitbucket_add_comment Add comment to issue Issue comment API
P0 gitbucket_get_comments List issue comments Issue comment API

Phase 2: MCP Extended — Filtering & Labels (P1)

Priority MCP Tool Name Description Internal Service
P1 gitbucket_list_issues List issues with filters (state, labels, assignee) IssueService + Slick queries
P1 gitbucket_search_issues Search issues by keyword Direct Slick DB query
P1 gitbucket_add_labels Add labels to issue LabelService
P1 gitbucket_replace_labels Replace all labels on issue LabelService
P1 gitbucket_remove_label Remove label from issue LabelService
P1 gitbucket_create_label Create a new label LabelService
P1 gitbucket_delete_label Delete a label LabelService

Phase 3: MCP PR & Git Operations (P2)

Priority MCP Tool Name Description Internal Service
P2 gitbucket_create_pr Create pull request PullRequestService
P2 gitbucket_get_pr Get PR details (including diff, files, commits) PullRequestService + JGit
P2 gitbucket_merge_pr Merge a PR with auto-close MergeService
P2 gitbucket_list_pr_commits List commits in a PR JGit revwalk
P2 gitbucket_list_pr_files List changed files in a PR JGit diff
P2 gitbucket_get_file_contents Read file at ref (fixes v4.46.0 regression) JGit blob read
P2 gitbucket_create_branch Create a branch JGit branch create
P2 gitbucket_list_commits List repo commits (fixes v4.46.0 regression) JGit revwalk

Capability Detection

When this plugin is installed, the parent repo's issue-operations dispatcher detects it via MCP tool probing:

1. Check for MCP tools matching "gitbucket_*" prefix
2. If found → use MCP protocol (full capabilities, no REST API fallbacks)
3. If not found → use REST API with documented fallbacks

The parent spec (#964) defines a "capability manifest" approach: static by default (probed per GitBucket version), with dynamic MCP query override when this plugin is present.

GitBucket Version → Capability Summary

GitBucket Labels PATCH Issue Search Contents Commits MCP Plugin Needed?
≤4.42.1 Unknown (unverified) Unknown (unverified) Unknown (unverified) Unknown Unknown Yes — probe first
v4.45.0 Works ✅ 404 ❌ 404 ❌ 200 ✅ 200 ✅ Yes — PATCH, search
v4.46.0 Works ✅ 404 ❌ 404 ❌ 404 ❌ (regression) 500 ❌ (regression) Yes — PATCH, search, contents, commits

Acceptance Criteria

  • API capability tables match empirical probe results for both v4.45.0 and v4.46.0
  • Version diff table shows regressions and improvements
  • MCP tool roadmap maps to GitBucket internal services (not REST API)
  • REST API fallbacks documented for agents without this plugin installed
  • Unprobed versions clearly marked as unverified
  • No REST API fix content — that's a separate plugin/concern

Out of Scope

  • REST API endpoint fixes (PATCH issue route, search API routes, etc.) — separate concern
  • GitBucket core bug fixes (JGit NullPointerException, v4.46.0 regressions) — upstream
  • PR operations dispatcher (future spec in parent repo)
  • CI/CD for plugin distribution
  • Probing versions ≤4.42.1 (requires JDK 11/17 not available on host)

Related

🤖 OpenCode (ollama-cloud/glm-5.1) revised

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions