MCP: owner_repo / foreign dir= API calls resolve against one default forge — can't target a second forge in a multi-forge workspace #29

Closed
opened 2026-07-12 23:35:21 +00:00 by hexajon · 1 comment
hexajon commented 2026-07-12 23:35:21 +00:00 (Migrated from codeberg.org)

Summary

When local clones span two forges (e.g. a self-hosted Gitea/Forgejo as the
default, and Codeberg) under one parent directory, and the madtea MCP server
is launched in that parent, forge-API operations that take owner_repo (or a
foreign dir=) resolve the server + token from the MCP server's single
default forge — not from the target repository's own config. Operations
against a repo on the non-default forge fail even though that clone's origin
already points at the correct forge.

What works

Directory-aware git operations honor the per-repo forge. madt_push(dir=<repoB>)
authenticates to forge B correctly (GIT_ASKPASS is host-scoped to the remote)
and the branch lands on forge B.

What fails

  • madt_prs(action=create, owner_repo=<orgB>/<repoB>, …)API error 404: GetUserByName. The call is sent to forge A's API, where <orgB> doesn't exist.
  • madt_issues(action=create, owner_repo=<orgB>/<repoB>, …) → same 404.
  • madt_finish(dir=<repoB>, branch=…) → "cannot resolve the default branch …
    the forge API was unreachable" — the default-branch lookup / token for forge B
    is not resolved from that repo's own config.
  • The CLI redirects madtea issue / madtea finish to the MCP tools, so there
    is no CLI fallback that reaches forge B either.

Root cause (best guess)

API base-URL + token resolution uses the process-wide default (env → secure
backend → global git config), while the git layer resolves per-remote /
per-repo. So the API layer targets the default forge regardless of which repo
the operation names. git config includeIf "gitdir:<treeB>/" can set
[madtea] url per directory tree and the dir-aware git ops respect it, but the
MCP API layer does not re-resolve the server from the target repo's
(include-aware) config.

Request

For owner_repo- and dir=-targeted operations, resolve the forge base URL +
credentials from the target repository's own config (honoring
includeIf "gitdir:"), so one MCP server can drive repos across multiple
forges. Failing that, document a supported multi-forge pattern (per-forge env
scoping, or one MCP server instance per forge).

Impact

In a multi-forge local workspace, only git-layer operations (push / commit /
branch) work against the non-default forge; issues, PRs, and finish on that
forge must be done by hand.

## Summary When local clones span two forges (e.g. a self-hosted Gitea/Forgejo as the default, and Codeberg) under one parent directory, and the madtea MCP server is launched in that parent, forge-API operations that take `owner_repo` (or a foreign `dir=`) resolve the server + token from the MCP server's single default forge — not from the target repository's own config. Operations against a repo on the non-default forge fail even though that clone's `origin` already points at the correct forge. ## What works Directory-aware git operations honor the per-repo forge. `madt_push(dir=<repoB>)` authenticates to forge B correctly (GIT_ASKPASS is host-scoped to the remote) and the branch lands on forge B. ## What fails - `madt_prs(action=create, owner_repo=<orgB>/<repoB>, …)` → `API error 404: GetUserByName`. The call is sent to forge A's API, where `<orgB>` doesn't exist. - `madt_issues(action=create, owner_repo=<orgB>/<repoB>, …)` → same 404. - `madt_finish(dir=<repoB>, branch=…)` → "cannot resolve the default branch … the forge API was unreachable" — the default-branch lookup / token for forge B is not resolved from that repo's own config. - The CLI redirects `madtea issue` / `madtea finish` to the MCP tools, so there is no CLI fallback that reaches forge B either. ## Root cause (best guess) API base-URL + token resolution uses the process-wide default (env → secure backend → global git config), while the *git* layer resolves per-remote / per-repo. So the API layer targets the default forge regardless of which repo the operation names. `git config includeIf "gitdir:<treeB>/"` can set `[madtea] url` per directory tree and the dir-aware git ops respect it, but the MCP API layer does not re-resolve the server from the target repo's (include-aware) config. ## Request For `owner_repo`- and `dir=`-targeted operations, resolve the forge base URL + credentials from the *target repository's* own config (honoring `includeIf "gitdir:"`), so one MCP server can drive repos across multiple forges. Failing that, document a supported multi-forge pattern (per-forge env scoping, or one MCP server instance per forge). ## Impact In a multi-forge local workspace, only git-layer operations (push / commit / branch) work against the non-default forge; issues, PRs, and `finish` on that forge must be done by hand.
hexajon commented 2026-07-14 22:20:37 +00:00 (Migrated from codeberg.org)

Fixed by the ADR 0025 epic (#30), merged to main via PR #41 (7f874f80): owner_repo/dir= API calls now resolve base URL + credentials from the target repo's own config — GetConfigForDir/GetConfigForURL (T5, #31) wired through every dir=/owner_repo forge-contacting path (T8, #34), with the repo-less session-forge scan failing closed on ambiguity (T7, #33) and a conformance probe asserting it (T9, #35). Integration tests cover the exact reported scenario (sibling repo on a second forge resolves its own forge while the process cache stays on the cwd forge). If your live multi-forge workspace still misbehaves on a current build, reopen with the failing call.

Fixed by the ADR 0025 epic (#30), merged to main via PR #41 (7f874f80): owner_repo/dir= API calls now resolve base URL + credentials from the target repo's own config — GetConfigForDir/GetConfigForURL (T5, #31) wired through every dir=/owner_repo forge-contacting path (T8, #34), with the repo-less session-forge scan failing closed on ambiguity (T7, #33) and a conformance probe asserting it (T9, #35). Integration tests cover the exact reported scenario (sibling repo on a second forge resolves its own forge while the process cache stays on the cwd forge). If your live multi-forge workspace still misbehaves on a current build, reopen with the failing call.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
sixfold-space/madtea#29
No description provided.