@mcp-use/cli 3.5.2-canary.3 → 3.5.2-canary.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1550,37 +1550,51 @@ var McpUseAPI = class _McpUseAPI {
1550
1550
  }))
1551
1551
  };
1552
1552
  }
1553
- async getGitHubRepos(_refresh) {
1554
- const orgId = await this.resolveOrganizationId();
1555
- const installResp = await this.request(`/github/installations?organizationId=${orgId}`);
1556
- if (installResp.installations.length === 0) {
1557
- return { user: { login: "", id: 0, avatar_url: "" }, repos: [] };
1553
+ /**
1554
+ * Returns true if the GitHub App can access `${owner}/${repo}` via any of the
1555
+ * organization's installations.
1556
+ *
1557
+ * An organization can have multiple GitHub installations (e.g. a personal
1558
+ * account and one or more GitHub orgs), so we check across all of them.
1559
+ *
1560
+ * Each check is a single authoritative backend call (`repos.get` with the
1561
+ * installation token) rather than listing repos. The old listing approach
1562
+ * only returned the first page — so a repo on a later page was wrongly
1563
+ * reported inaccessible — and fully paginating it hung on very large orgs.
1564
+ * We try the installation whose account matches the repo owner first to
1565
+ * minimize GitHub calls.
1566
+ */
1567
+ async checkGitHubRepoAccess(owner, repo) {
1568
+ const status = await this.getGitHubConnectionStatus();
1569
+ const installations = status.installations ?? [];
1570
+ if (installations.length === 0) return false;
1571
+ const ownerLower = owner.toLowerCase();
1572
+ const ordered = [...installations].sort((a, b) => {
1573
+ const aMatch = a.account_login.toLowerCase() === ownerLower ? 0 : 1;
1574
+ const bMatch = b.account_login.toLowerCase() === ownerLower ? 0 : 1;
1575
+ return aMatch - bMatch;
1576
+ });
1577
+ for (const installation of ordered) {
1578
+ const hasAccess = await this.installationCanAccessRepo(
1579
+ installation.installation_id,
1580
+ owner,
1581
+ repo
1582
+ );
1583
+ if (hasAccess) return true;
1584
+ }
1585
+ return false;
1586
+ }
1587
+ async installationCanAccessRepo(installationId, owner, repo) {
1588
+ try {
1589
+ const resp = await this.request(
1590
+ `/github/installations/${installationId}/repos/${encodeURIComponent(
1591
+ owner
1592
+ )}/${encodeURIComponent(repo)}/access`
1593
+ );
1594
+ return resp.hasAccess;
1595
+ } catch {
1596
+ return false;
1558
1597
  }
1559
- const inst = installResp.installations[0];
1560
- const repoLists = await Promise.all(
1561
- installResp.installations.map(async (installation) => {
1562
- try {
1563
- const reposResp = await this.request(`/github/installations/${installation.installationId}/repos`);
1564
- return reposResp.repos;
1565
- } catch {
1566
- return [];
1567
- }
1568
- })
1569
- );
1570
- return {
1571
- user: {
1572
- login: inst.account?.login ?? "",
1573
- id: 0,
1574
- avatar_url: inst.account?.avatar_url ?? ""
1575
- },
1576
- repos: repoLists.flat().map((r) => ({
1577
- id: r.id,
1578
- name: r.name,
1579
- full_name: r.fullName,
1580
- private: r.private,
1581
- owner: { login: r.fullName.split("/")[0] ?? "" }
1582
- }))
1583
- };
1584
1598
  }
1585
1599
  async getGitHubAppName() {
1586
1600
  if (process.env.MCP_GITHUB_APP_NAME) return process.env.MCP_GITHUB_APP_NAME;
@@ -5236,12 +5250,7 @@ async function getGitHubConnectionStatusWith401Retry(api, options, orgIdToRestor
5236
5250
  throw new Error("Unreachable");
5237
5251
  }
5238
5252
  async function checkRepoAccess(api, owner, repo) {
5239
- try {
5240
- const resp = await api.getGitHubRepos(true);
5241
- return resp.repos.some((r) => r.full_name === `${owner}/${repo}`);
5242
- } catch {
5243
- return false;
5244
- }
5253
+ return api.checkGitHubRepoAccess(owner, repo);
5245
5254
  }
5246
5255
  async function promptGitHubInstallation(api, reason, repoName, opts) {
5247
5256
  const yes = !!opts?.yes;