mirror of
https://github.com/anthropics/claude-code-action.git
synced 2026-01-23 06:54:13 +08:00
* Remove mcp_config input in favor of --mcp-config in claude_args
BREAKING CHANGE: The mcp_config input has been removed. Users should now use --mcp-config flag in claude_args instead.
This simplifies the action's input surface area and aligns better with the Claude Code CLI interface. Users can still add multiple MCP configurations by using multiple --mcp-config flags.
Migration:
- Before: mcp_config: '{"mcpServers": {...}}'
- After: claude_args: '--mcp-config {"mcpServers": {...}}'
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Add outer action MCP tests to workflow
- Add test-outer-action-inline-mcp job to test inline MCP config via claude_args
- Add test-outer-action-file-mcp job to test file-based MCP config via claude_args
- Keep base-action tests unchanged (they still use mcp_config parameter)
- Test that MCP tools are properly discovered and can be executed through the outer action
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Fix: Add Bun setup to outer action MCP test jobs
The test jobs for the outer action were failing because Bun wasn't installed.
Added Setup Bun step to both test-outer-action-inline-mcp and test-outer-action-file-mcp jobs.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Add id-token permission to outer action MCP test jobs
The outer action needs id-token: write permission for OIDC authentication
when using the GitHub App. Added full permissions block to both
test-outer-action-inline-mcp and test-outer-action-file-mcp jobs.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Use github_token parameter instead of id-token permission
Replace id-token: write permission with explicit github_token parameter
for both outer action MCP test jobs. This simplifies authentication by
using the provided GitHub token directly.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Use RUNNER_TEMP environment variable consistently
Changed from GitHub Actions expression syntax to environment variable
for consistency with the rest of the workflow file.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Use execution_file output from action instead of hardcoded path
Updated outer action test jobs to:
- Add step IDs (claude-inline-test, claude-file-test)
- Use the execution_file output from the action steps
- This is more reliable than hardcoding the output file path
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* tmp
* Fix MCP test assertions to match actual output format
Updated the test assertions to match the actual JSON structure:
- Tool calls are in assistant messages with type='tool_use'
- Tool results are in user messages with type='tool_result'
- The test tool returns 'Test tool response' not 'Hello from test tool'
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Make inline MCP test actually use the tool instead of just listing
Changed the inline MCP test to:
- Request that Claude uses the test tool (not just list it)
- Add --allowedTools to ensure the tool can be used
- Check that the tool was actually called and returned expected result
- Output the full JSON for debugging
This makes both tests (inline and file-based) consistent in their approach.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
---------
Co-authored-by: Claude <noreply@anthropic.com>
153 lines
4.6 KiB
TypeScript
153 lines
4.6 KiB
TypeScript
import * as core from "@actions/core";
|
|
import { mkdir, writeFile } from "fs/promises";
|
|
import type { Mode, ModeOptions, ModeResult } from "../types";
|
|
import type { PreparedContext } from "../../create-prompt/types";
|
|
import { prepareMcpConfig } from "../../mcp/install-mcp-server";
|
|
import { parseAllowedTools } from "./parse-tools";
|
|
import { configureGitAuth } from "../../github/operations/git-config";
|
|
|
|
/**
|
|
* Agent mode implementation.
|
|
*
|
|
* This mode runs whenever an explicit prompt is provided in the workflow configuration.
|
|
* It bypasses the standard @claude mention checking and comment tracking used by tag mode,
|
|
* providing direct access to Claude Code for automation workflows.
|
|
*/
|
|
export const agentMode: Mode = {
|
|
name: "agent",
|
|
description: "Direct automation mode for explicit prompts",
|
|
|
|
shouldTrigger(context) {
|
|
// Only trigger when an explicit prompt is provided
|
|
return !!context.inputs?.prompt;
|
|
},
|
|
|
|
prepareContext(context) {
|
|
// Agent mode doesn't use comment tracking or branch management
|
|
return {
|
|
mode: "agent",
|
|
githubContext: context,
|
|
};
|
|
},
|
|
|
|
getAllowedTools() {
|
|
return [];
|
|
},
|
|
|
|
getDisallowedTools() {
|
|
return [];
|
|
},
|
|
|
|
shouldCreateTrackingComment() {
|
|
return false;
|
|
},
|
|
|
|
async prepare({
|
|
context,
|
|
githubToken,
|
|
octokit,
|
|
}: ModeOptions): Promise<ModeResult> {
|
|
// Configure git authentication for agent mode (same as tag mode)
|
|
if (!context.inputs.useCommitSigning) {
|
|
try {
|
|
// Get the authenticated user (will be claude[bot] when using Claude App token)
|
|
const { data: authenticatedUser } =
|
|
await octokit.rest.users.getAuthenticated();
|
|
const user = {
|
|
login: authenticatedUser.login,
|
|
id: authenticatedUser.id,
|
|
};
|
|
|
|
// Use the shared git configuration function
|
|
await configureGitAuth(githubToken, context, user);
|
|
} catch (error) {
|
|
console.error("Failed to configure git authentication:", error);
|
|
// Continue anyway - git operations may still work with default config
|
|
}
|
|
}
|
|
|
|
// Create prompt directory
|
|
await mkdir(`${process.env.RUNNER_TEMP || "/tmp"}/claude-prompts`, {
|
|
recursive: true,
|
|
});
|
|
|
|
// Write the prompt file - use the user's prompt directly
|
|
const promptContent =
|
|
context.inputs.prompt ||
|
|
`Repository: ${context.repository.owner}/${context.repository.repo}`;
|
|
|
|
await writeFile(
|
|
`${process.env.RUNNER_TEMP || "/tmp"}/claude-prompts/claude-prompt.txt`,
|
|
promptContent,
|
|
);
|
|
|
|
// Parse allowed tools from user's claude_args
|
|
const userClaudeArgs = process.env.CLAUDE_ARGS || "";
|
|
const allowedTools = parseAllowedTools(userClaudeArgs);
|
|
|
|
// Check for branch info from environment variables (useful for auto-fix workflows)
|
|
const claudeBranch = process.env.CLAUDE_BRANCH || undefined;
|
|
const baseBranch =
|
|
process.env.BASE_BRANCH || context.inputs.baseBranch || "main";
|
|
|
|
// Detect current branch from GitHub environment
|
|
const currentBranch =
|
|
claudeBranch ||
|
|
process.env.GITHUB_HEAD_REF ||
|
|
process.env.GITHUB_REF_NAME ||
|
|
"main";
|
|
|
|
// Get our GitHub MCP servers config
|
|
const ourMcpConfig = await prepareMcpConfig({
|
|
githubToken,
|
|
owner: context.repository.owner,
|
|
repo: context.repository.repo,
|
|
branch: currentBranch,
|
|
baseBranch: baseBranch,
|
|
claudeCommentId: undefined, // No tracking comment in agent mode
|
|
allowedTools,
|
|
context,
|
|
});
|
|
|
|
// Build final claude_args with multiple --mcp-config flags
|
|
let claudeArgs = "";
|
|
|
|
// Add our GitHub servers config if we have any
|
|
const ourConfig = JSON.parse(ourMcpConfig);
|
|
if (ourConfig.mcpServers && Object.keys(ourConfig.mcpServers).length > 0) {
|
|
const escapedOurConfig = ourMcpConfig.replace(/'/g, "'\\''");
|
|
claudeArgs = `--mcp-config '${escapedOurConfig}'`;
|
|
}
|
|
|
|
// Append user's claude_args (which may have more --mcp-config flags)
|
|
claudeArgs = `${claudeArgs} ${userClaudeArgs}`.trim();
|
|
|
|
core.setOutput("claude_args", claudeArgs);
|
|
|
|
return {
|
|
commentId: undefined,
|
|
branchInfo: {
|
|
baseBranch: baseBranch,
|
|
currentBranch: baseBranch, // Use base branch as current when creating new branch
|
|
claudeBranch: claudeBranch,
|
|
},
|
|
mcpConfig: ourMcpConfig,
|
|
};
|
|
},
|
|
|
|
generatePrompt(context: PreparedContext): string {
|
|
// Agent mode uses prompt field
|
|
if (context.prompt) {
|
|
return context.prompt;
|
|
}
|
|
|
|
// Minimal fallback - repository is a string in PreparedContext
|
|
return `Repository: ${context.repository}`;
|
|
},
|
|
|
|
getSystemPrompt() {
|
|
// Agent mode doesn't need additional system prompts
|
|
return undefined;
|
|
},
|
|
};
|