bug(parity): the CLI redirect steers to MCP tools that cannot reach the same target (madt_labels has no dir=) #485
Labels
No labels
breaking
bug
documentation
enhancement
epic
good first issue
help wanted
refactoring
resolution/duplicate
resolution/invalid
resolution/wontfix
security
severity/critical
severity/high
severity/low
severity/medium
status/abandoned
status/blocked
status/needs-decision
status/needs-info
status/needs-verification
testing
upstream
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
sixfold-space/madtea#485
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What happens
I work from an agent session whose MCP server is anchored to forge A. I have a local clone of a repo on forge B. I want that repo's label list.
madt_labels action=list owner_repo=<owner>/<repo>returns404.owner_repohas no host (ParseOwnerRepo,internal/util/repo.go:67), so the lookup goes to forge A.madt_labelshas nodir=, so I cannot point it at the forge-B clone.cd <forge-B clone> && madtea labels listwould work, because the CLI resolves forge B from the clone's origin. But the plugin hookhooks/scripts/check-git-cli.shdenies it and steers tomadt_labels(labels -> madt_labelsat line 43, steer set at lines 199-203).So the hook steers to a tool that cannot do the job, and no sanctioned path is left. The hook's own rule (line 198) is "Steer only verbs with a one-call MCP equivalent". For this target,
madt_labelsis not an equivalent.madt_reposandmadt_api_callhave the same gap: nodir=.madtea org-labels list <org>still works, but only becauseorg-labelsis outside the steer set (line 57).Ask
Audit every steered verb (lines 200-202) for capability parity. #441 and #444 cover name parity. This issue covers reach.
dir=to a clone, a clone on another forge,owner_repo=).dir=(reads, and writes within the foreign-repo rules), or make the hook stay silent (or print a remedy that works) when the CLI target is a clone whose forge is not the session's forge.Acceptance
Related
status --json .hostuses the cwd origin.Another live case, 2026-09-15. In a clone of a repo on a second forge (Gitea 1.27.3), I wanted that repo's Actions runs and job list.
madt_actionshas nodir=, so it only reaches the session's forge.madt_api_callhas nodir=either.madtea actions ...in the clone was denied by the plugin hook, which steered tomadt_actions: "Manage CI/Actions with madt_actions instead ofmadtea actions".Only
madtea api GET ...in the clone worked, becauseapiis outside the steer set.actionsbelongs in the capability audit withlabels.madt_adrand other MCP tools cannot target a nested repo, because they take nodir=#638Two more live cases, 2026-09-28.
releases: from a session anchored to forge A, I wanted the release asset download counts of a repo on forge B.madt_releaseshas nodir=and no host, soowner_repo=OWNER/REPOresolves on forge A.madtea release listin the forge-B clone was denied by the plugin hook, which steered tomadt_releases: "Manage releases with madt_releases instead ofmadtea release". Only an anonymous read of forge B's public API worked.files:madt_files action=get owner_repo=OWNER/REPOreads from the forge of the session's working directory. The host comes fromconfig.GetConfig(internal/mcp/helpers.go:801-809), andowner_repoonly fills/repos/OWNER/REPO. From a session anchored to forge B, the same call aimed at a mirror on forge A fails. The clone shorthand has the same shape (internal/service/git/clone.go:178-185). A full clone URL works, because it names its own host (clone.go:49-52).releasesandfilesbelong in the capability audit withlabelsandactions.