fix(tag): no such tool available mcp__github_* (#556)

Signed-off-by: Kevin Cui <bh@bugs.cc>

# Conflicts:
#	src/mcp/install-mcp-server.ts
#	src/modes/tag/index.ts
#	test/modes/agent.test.ts
This commit is contained in:
Kevin Cui
2025-09-13 03:33:34 +08:00
committed by GitHub
parent a5528eec74
commit 2e92922dd6
4 changed files with 36 additions and 27 deletions

View File

@@ -3,6 +3,7 @@ import { GITHUB_API_URL, GITHUB_SERVER_URL } from "../github/api/config";
import type { GitHubContext } from "../github/context"; import type { GitHubContext } from "../github/context";
import { isEntityContext } from "../github/context"; import { isEntityContext } from "../github/context";
import { Octokit } from "@octokit/rest"; import { Octokit } from "@octokit/rest";
import type { AutoDetectedMode } from "../modes/detector";
type PrepareConfigParams = { type PrepareConfigParams = {
githubToken: string; githubToken: string;
@@ -12,8 +13,8 @@ type PrepareConfigParams = {
baseBranch: string; baseBranch: string;
claudeCommentId?: string; claudeCommentId?: string;
allowedTools: string[]; allowedTools: string[];
mode: AutoDetectedMode;
context: GitHubContext; context: GitHubContext;
mode: "tag" | "agent";
}; };
async function checkActionsReadPermission( async function checkActionsReadPermission(
@@ -65,8 +66,13 @@ export async function prepareMcpConfig(
try { try {
const allowedToolsList = allowedTools || []; const allowedToolsList = allowedTools || [];
// Detect if we're in agent mode (explicit prompt provided)
const isAgentMode = mode === "agent"; const isAgentMode = mode === "agent";
const hasGitHubCommentTools = allowedToolsList.some((tool) =>
tool.startsWith("mcp__github_comment__"),
);
const hasGitHubMcpTools = allowedToolsList.some((tool) => const hasGitHubMcpTools = allowedToolsList.some((tool) =>
tool.startsWith("mcp__github__"), tool.startsWith("mcp__github__"),
); );
@@ -86,7 +92,7 @@ export async function prepareMcpConfig(
// Include comment server: // Include comment server:
// - Always in tag mode (for updating Claude comments) // - Always in tag mode (for updating Claude comments)
// - Only with explicit tools in agent mode // - Only with explicit tools in agent mode
const shouldIncludeCommentServer = !isAgentMode; const shouldIncludeCommentServer = !isAgentMode || hasGitHubCommentTools;
if (shouldIncludeCommentServer) { if (shouldIncludeCommentServer) {
baseMcpConfig.mcpServers.github_comment = { baseMcpConfig.mcpServers.github_comment = {

View File

@@ -135,8 +135,8 @@ export const agentMode: Mode = {
baseBranch: baseBranch, baseBranch: baseBranch,
claudeCommentId: undefined, // No tracking comment in agent mode claudeCommentId: undefined, // No tracking comment in agent mode
allowedTools, allowedTools,
context,
mode: "agent", mode: "agent",
context,
}); });
// Build final claude_args with multiple --mcp-config flags // Build final claude_args with multiple --mcp-config flags

View File

@@ -14,6 +14,7 @@ import { createPrompt, generateDefaultPrompt } from "../../create-prompt";
import { isEntityContext } from "../../github/context"; import { isEntityContext } from "../../github/context";
import type { PreparedContext } from "../../create-prompt/types"; import type { PreparedContext } from "../../create-prompt/types";
import type { FetchDataResult } from "../../github/data/fetcher"; import type { FetchDataResult } from "../../github/data/fetcher";
import { parseAllowedTools } from "../agent/parse-tools";
/** /**
* Tag mode implementation. * Tag mode implementation.
@@ -112,20 +113,10 @@ export const tagMode: Mode = {
await createPrompt(tagMode, modeContext, githubData, context); await createPrompt(tagMode, modeContext, githubData, context);
// Get our GitHub MCP servers configuration const userClaudeArgs = process.env.CLAUDE_ARGS || "";
const ourMcpConfig = await prepareMcpConfig({ const userAllowedMCPTools = parseAllowedTools(userClaudeArgs).filter(
githubToken, (tool) => tool.startsWith("mcp__github_"),
owner: context.repository.owner, );
repo: context.repository.repo,
branch: branchInfo.claudeBranch || branchInfo.currentBranch,
baseBranch: branchInfo.baseBranch,
claudeCommentId: commentId.toString(),
allowedTools: [],
context,
mode: "tag",
});
// Don't output mcp_config separately anymore - include in claude_args
// Build claude_args for tag mode with required tools // Build claude_args for tag mode with required tools
// Tag mode REQUIRES these tools to function properly // Tag mode REQUIRES these tools to function properly
@@ -141,6 +132,7 @@ export const tagMode: Mode = {
"mcp__github_ci__get_ci_status", "mcp__github_ci__get_ci_status",
"mcp__github_ci__get_workflow_run_details", "mcp__github_ci__get_workflow_run_details",
"mcp__github_ci__download_job_log", "mcp__github_ci__download_job_log",
...userAllowedMCPTools,
]; ];
// Add git commands when not using commit signing // Add git commands when not using commit signing
@@ -162,7 +154,18 @@ export const tagMode: Mode = {
); );
} }
const userClaudeArgs = process.env.CLAUDE_ARGS || ""; // Get our GitHub MCP servers configuration
const ourMcpConfig = await prepareMcpConfig({
githubToken,
owner: context.repository.owner,
repo: context.repository.repo,
branch: branchInfo.claudeBranch || branchInfo.currentBranch,
baseBranch: branchInfo.baseBranch,
claudeCommentId: commentId.toString(),
allowedTools: Array.from(new Set(tagModeTools)),
mode: "tag",
context,
});
// Build complete claude_args with multiple --mcp-config flags // Build complete claude_args with multiple --mcp-config flags
let claudeArgs = ""; let claudeArgs = "";

View File

@@ -106,8 +106,8 @@ describe("prepareMcpConfig", () => {
branch: "test-branch", branch: "test-branch",
baseBranch: "main", baseBranch: "main",
allowedTools: [], allowedTools: [],
context: mockContextWithSigning,
mode: "tag", mode: "tag",
context: mockContextWithSigning,
}); });
const parsed = JSON.parse(result); const parsed = JSON.parse(result);
@@ -130,8 +130,8 @@ describe("prepareMcpConfig", () => {
branch: "test-branch", branch: "test-branch",
baseBranch: "main", baseBranch: "main",
allowedTools: ["mcp__github__create_issue", "mcp__github__create_pr"], allowedTools: ["mcp__github__create_issue", "mcp__github__create_pr"],
context: mockContext,
mode: "tag", mode: "tag",
context: mockContext,
}); });
const parsed = JSON.parse(result); const parsed = JSON.parse(result);
@@ -151,8 +151,8 @@ describe("prepareMcpConfig", () => {
branch: "test-branch", branch: "test-branch",
baseBranch: "main", baseBranch: "main",
allowedTools: ["mcp__github_inline_comment__create_inline_comment"], allowedTools: ["mcp__github_inline_comment__create_inline_comment"],
context: mockPRContext,
mode: "tag", mode: "tag",
context: mockPRContext,
}); });
const parsed = JSON.parse(result); const parsed = JSON.parse(result);
@@ -172,8 +172,8 @@ describe("prepareMcpConfig", () => {
branch: "test-branch", branch: "test-branch",
baseBranch: "main", baseBranch: "main",
allowedTools: [], allowedTools: [],
context: mockContext,
mode: "tag", mode: "tag",
context: mockContext,
}); });
const parsed = JSON.parse(result); const parsed = JSON.parse(result);
@@ -193,8 +193,8 @@ describe("prepareMcpConfig", () => {
branch: "test-branch", branch: "test-branch",
baseBranch: "main", baseBranch: "main",
allowedTools: [], allowedTools: [],
context: mockContextWithSigning,
mode: "tag", mode: "tag",
context: mockContextWithSigning,
}); });
const parsed = JSON.parse(result); const parsed = JSON.parse(result);
@@ -213,8 +213,8 @@ describe("prepareMcpConfig", () => {
branch: "test-branch", branch: "test-branch",
baseBranch: "main", baseBranch: "main",
allowedTools: [], allowedTools: [],
context: mockContextWithSigning,
mode: "tag", mode: "tag",
context: mockContextWithSigning,
}); });
const parsed = JSON.parse(result); const parsed = JSON.parse(result);
@@ -231,8 +231,8 @@ describe("prepareMcpConfig", () => {
branch: "test-branch", branch: "test-branch",
baseBranch: "main", baseBranch: "main",
allowedTools: [], allowedTools: [],
context: mockPRContext,
mode: "tag", mode: "tag",
context: mockPRContext,
}); });
const parsed = JSON.parse(result); const parsed = JSON.parse(result);
@@ -251,8 +251,8 @@ describe("prepareMcpConfig", () => {
branch: "test-branch", branch: "test-branch",
baseBranch: "main", baseBranch: "main",
allowedTools: [], allowedTools: [],
context: mockContext,
mode: "tag", mode: "tag",
context: mockContext,
}); });
const parsed = JSON.parse(result); const parsed = JSON.parse(result);
@@ -269,8 +269,8 @@ describe("prepareMcpConfig", () => {
branch: "test-branch", branch: "test-branch",
baseBranch: "main", baseBranch: "main",
allowedTools: [], allowedTools: [],
context: mockPRContext,
mode: "tag", mode: "tag",
context: mockPRContext,
}); });
const parsed = JSON.parse(result); const parsed = JSON.parse(result);