Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
d917e7b
feat(base-action): default enableAllProjectMcpServers to false
OctavianGuzu Apr 23, 2026
cf66f1d
ci: opt test-mcp-integration into enable_all_project_mcp_servers
OctavianGuzu Apr 23, 2026
9d2286e
ci: opt test-mcp-config-flag into enable_all_project_mcp_servers
OctavianGuzu Apr 23, 2026
52fafff
docs: add enable_all_project_mcp_servers to usage.md inputs table
OctavianGuzu Apr 23, 2026
9452710
feat(action): enable project MCP only after config restored from base…
OctavianGuzu Apr 23, 2026
7942438
fix: move resolveEnableAllProjectMcpServers below restoreConfigFromBase
OctavianGuzu Apr 23, 2026
47f4332
docs: qualify .mcp.json auto-detect note in Custom Tools section
OctavianGuzu Apr 23, 2026
219a2de
Pin bun config in base-action and add bunfig.toml to base-ref restore
OctavianGuzu Apr 23, 2026
591af54
Gate base-action enableAllProjectMcpServers default on event type
OctavianGuzu Apr 23, 2026
2d2c068
Include issue_comment in event-gated default; add PRT checkout guidan…
OctavianGuzu Apr 23, 2026
9926436
chore: prettier formatting
OctavianGuzu Apr 23, 2026
70ce159
fix(action): re-gate wrapper enableAllProjectMcpServers on configRest…
OctavianGuzu Apr 23, 2026
e6633c9
Gate wrapper enableAllProjectMcpServers on restore; pin setting-sourc…
OctavianGuzu Apr 23, 2026
4ac01f0
docs: fix PRT/workflow_run guidance — root checkout + workflow_run ref
OctavianGuzu Apr 23, 2026
c280b05
docs: clarify install-plugins --setting-sources comment
OctavianGuzu Apr 23, 2026
fa0de7b
fix(action): trust project config for non-PR entity events too
OctavianGuzu Apr 23, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .github/workflows/test-mcp-servers.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ jobs:
with:
prompt: "List all available tools"
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
enable_all_project_mcp_servers: "true"
env:
# Change to test directory so it finds .mcp.json
CLAUDE_WORKING_DIR: ${{ github.workspace }}/base-action/test/mcp-test
Expand Down Expand Up @@ -109,6 +110,10 @@ jobs:
prompt: "List all available tools"
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
mcp_config: '{"mcpServers":{"test-server":{"type":"stdio","command":"bun","args":["simple-mcp-server.ts"],"env":{}}}}'
# TODO: mcp_config is not currently plumbed through base-action/action.yml,
# so this step only passes via .mcp.json in CLAUDE_WORKING_DIR. Remove this
# opt-in once mcp_config is wired up and the test exercises what it claims.
enable_all_project_mcp_servers: "true"
env:
# Change to test directory so bun can find the MCP server script
CLAUDE_WORKING_DIR: ${{ github.workspace }}/base-action/test/mcp-test
Expand Down
5 changes: 5 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ inputs:
description: "Claude Code settings as JSON string or path to settings JSON file"
required: false
default: ""
enable_all_project_mcp_servers:
description: "Auto-enable every MCP server defined in the checkout's .mcp.json. Defaults to 'true' — safe here because .mcp.json is restored from the PR base branch before execution. Set to 'false' to ignore in-repo MCP servers entirely."
required: false
default: "true"
Comment thread
OctavianGuzu marked this conversation as resolved.
Outdated

# Auth configuration
anthropic_api_key:
Expand Down Expand Up @@ -279,6 +283,7 @@ runs:
# Base-action inputs
INPUT_PROMPT_FILE: ${{ runner.temp }}/claude-prompts/claude-prompt.txt
INPUT_SETTINGS: ${{ inputs.settings }}
INPUT_ENABLE_ALL_PROJECT_MCP_SERVERS: ${{ inputs.enable_all_project_mcp_servers }}
INPUT_EXPERIMENTAL_SLASH_COMMANDS_DIR: ${{ github.action_path }}/slash-commands
INPUT_PATH_TO_CLAUDE_CODE_EXECUTABLE: ${{ inputs.path_to_claude_code_executable }}
INPUT_PATH_TO_BUN_EXECUTABLE: ${{ inputs.path_to_bun_executable }}
Expand Down
45 changes: 23 additions & 22 deletions base-action/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,27 +85,28 @@ Add the following to your workflow file:

## Inputs

| Input | Description | Required | Default |
| ------------------------- | ----------------------------------------------------------------------------------------------------------------------- | -------- | ---------------------------- |
| `prompt` | The prompt to send to Claude Code | No\* | '' |
| `prompt_file` | Path to a file containing the prompt to send to Claude Code | No\* | '' |
| `allowed_tools` | Comma-separated list of allowed tools for Claude Code to use | No | '' |
| `disallowed_tools` | Comma-separated list of disallowed tools that Claude Code cannot use | No | '' |
| `max_turns` | Maximum number of conversation turns (default: no limit) | No | '' |
| `mcp_config` | Path to the MCP configuration JSON file, or MCP configuration JSON string | No | '' |
| `settings` | Path to Claude Code settings JSON file, or settings JSON string | No | '' |
| `system_prompt` | Override system prompt | No | '' |
| `append_system_prompt` | Append to system prompt | No | '' |
| `claude_env` | Custom environment variables to pass to Claude Code execution (YAML multiline format) | No | '' |
| `model` | Model to use (provider-specific format required for Bedrock/Vertex) | No | 'claude-4-0-sonnet-20250219' |
| `anthropic_model` | DEPRECATED: Use 'model' instead | No | 'claude-4-0-sonnet-20250219' |
| `fallback_model` | Enable automatic fallback to specified model when default model is overloaded | No | '' |
| `anthropic_api_key` | Anthropic API key (required for direct Anthropic API) | No | '' |
| `claude_code_oauth_token` | Claude Code OAuth token (alternative to anthropic_api_key) | No | '' |
| `use_bedrock` | Use Amazon Bedrock with OIDC authentication instead of direct Anthropic API | No | 'false' |
| `use_vertex` | Use Google Vertex AI with OIDC authentication instead of direct Anthropic API | No | 'false' |
| `use_node_cache` | Whether to use Node.js dependency caching (set to true only for Node.js projects with lock files) | No | 'false' |
| `show_full_output` | Show full JSON output (⚠️ May expose secrets - see [security docs](../docs/security.md#️-full-output-security-warning)) | No | 'false'\*\* |
| Input | Description | Required | Default |
| -------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | -------- | ---------------------------- |
| `prompt` | The prompt to send to Claude Code | No\* | '' |
| `prompt_file` | Path to a file containing the prompt to send to Claude Code | No\* | '' |
| `allowed_tools` | Comma-separated list of allowed tools for Claude Code to use | No | '' |
| `disallowed_tools` | Comma-separated list of disallowed tools that Claude Code cannot use | No | '' |
| `max_turns` | Maximum number of conversation turns (default: no limit) | No | '' |
| `mcp_config` | Path to the MCP configuration JSON file, or MCP configuration JSON string | No | '' |
| `settings` | Path to Claude Code settings JSON file, or settings JSON string | No | '' |
| `enable_all_project_mcp_servers` | Auto-enable every MCP server in the checkout's `.mcp.json`. Off by default because `.mcp.json` is PR-controlled. | No | 'false' |
Comment thread
claude[bot] marked this conversation as resolved.
Outdated
| `system_prompt` | Override system prompt | No | '' |
| `append_system_prompt` | Append to system prompt | No | '' |
| `claude_env` | Custom environment variables to pass to Claude Code execution (YAML multiline format) | No | '' |
| `model` | Model to use (provider-specific format required for Bedrock/Vertex) | No | 'claude-4-0-sonnet-20250219' |
| `anthropic_model` | DEPRECATED: Use 'model' instead | No | 'claude-4-0-sonnet-20250219' |
| `fallback_model` | Enable automatic fallback to specified model when default model is overloaded | No | '' |
| `anthropic_api_key` | Anthropic API key (required for direct Anthropic API) | No | '' |
| `claude_code_oauth_token` | Claude Code OAuth token (alternative to anthropic_api_key) | No | '' |
| `use_bedrock` | Use Amazon Bedrock with OIDC authentication instead of direct Anthropic API | No | 'false' |
| `use_vertex` | Use Google Vertex AI with OIDC authentication instead of direct Anthropic API | No | 'false' |
| `use_node_cache` | Whether to use Node.js dependency caching (set to true only for Node.js projects with lock files) | No | 'false' |
| `show_full_output` | Show full JSON output (⚠️ May expose secrets - see [security docs](../docs/security.md#️-full-output-security-warning)) | No | 'false'\*\* |

\*Either `prompt` or `prompt_file` must be provided, but not both.

Expand Down Expand Up @@ -251,7 +252,7 @@ The settings file supports all Claude Code settings options including:
- `includeCoAuthoredBy`: Include co-authored-by in git commits
- And more...

**Note**: The `enableAllProjectMcpServers` setting is always set to `true` by this action to ensure MCP servers work correctly.
**Note**: The `enableAllProjectMcpServers` setting is controlled by the `enable_all_project_mcp_servers` input (default `false`) and overrides any value provided via `settings`. Set the input to `true` only when the checkout's `.mcp.json` is trusted.

## Using MCP Config

Expand Down
5 changes: 5 additions & 0 deletions base-action/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ inputs:
description: "Claude Code settings as JSON string or path to settings JSON file"
required: false
default: ""
enable_all_project_mcp_servers:
description: "Auto-enable every MCP server defined in the checkout's .mcp.json. Defaults to 'false' because .mcp.json is PR-controlled in pull_request workflows; set to 'true' only when the checkout is trusted."
required: false
default: "false"
Comment thread
OctavianGuzu marked this conversation as resolved.
Outdated
Comment thread
claude[bot] marked this conversation as resolved.
Outdated

# Action settings
claude_args:
Expand Down Expand Up @@ -165,6 +169,7 @@ runs:
INPUT_PROMPT: ${{ inputs.prompt }}
INPUT_PROMPT_FILE: ${{ inputs.prompt_file }}
INPUT_SETTINGS: ${{ inputs.settings }}
INPUT_ENABLE_ALL_PROJECT_MCP_SERVERS: ${{ inputs.enable_all_project_mcp_servers }}
INPUT_CLAUDE_ARGS: ${{ inputs.claude_args }}
INPUT_PATH_TO_CLAUDE_CODE_EXECUTABLE: ${{ inputs.path_to_claude_code_executable }}
INPUT_PATH_TO_BUN_EXECUTABLE: ${{ inputs.path_to_bun_executable }}
Expand Down
1 change: 1 addition & 0 deletions base-action/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ async function run() {
await setupClaudeCodeSettings(
process.env.INPUT_SETTINGS,
undefined, // homeDir
process.env.INPUT_ENABLE_ALL_PROJECT_MCP_SERVERS === "true",
);

// Install Claude Code plugins if specified
Expand Down
11 changes: 8 additions & 3 deletions base-action/src/setup-claude-code-settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { readFile } from "fs/promises";
export async function setupClaudeCodeSettings(
settingsInput?: string,
homeDir?: string,
enableAllProjectMcpServers: boolean = false,
) {
const home = homeDir ?? homedir();
const settingsPath = `${home}/.claude/settings.json`;
Expand Down Expand Up @@ -59,9 +60,13 @@ export async function setupClaudeCodeSettings(
console.log(`Merged settings with input settings`);
}

// Always set enableAllProjectMcpServers to true
settings.enableAllProjectMcpServers = true;
console.log(`Updated settings with enableAllProjectMcpServers: true`);
// enableAllProjectMcpServers controls whether Claude Code auto-loads every
// server in the checkout's .mcp.json. Default false so workflow authors opt
// in explicitly via the enable_all_project_mcp_servers action input.
settings.enableAllProjectMcpServers = enableAllProjectMcpServers;
console.log(
`Updated settings with enableAllProjectMcpServers: ${enableAllProjectMcpServers}`,
);

await $`echo ${JSON.stringify(settings, null, 2)} > ${settingsPath}`.quiet();
console.log(`Settings saved successfully`);
Expand Down
29 changes: 19 additions & 10 deletions base-action/test/setup-claude-code-settings.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,21 @@ describe("setupClaudeCodeSettings", () => {
await rm(testHomeDir, { recursive: true, force: true });
});

test("should always set enableAllProjectMcpServers to true when no input", async () => {
test("should default enableAllProjectMcpServers to false when no input", async () => {
await setupClaudeCodeSettings(undefined, testHomeDir);

const settingsContent = await readFile(settingsPath, "utf-8");
const settings = JSON.parse(settingsContent);

expect(settings.enableAllProjectMcpServers).toBe(false);
});

test("should set enableAllProjectMcpServers to true when explicitly opted in", async () => {
await setupClaudeCodeSettings(undefined, testHomeDir, true);

const settingsContent = await readFile(settingsPath, "utf-8");
const settings = JSON.parse(settingsContent);

expect(settings.enableAllProjectMcpServers).toBe(true);
});

Expand All @@ -47,7 +56,7 @@ describe("setupClaudeCodeSettings", () => {
const settingsContent = await readFile(settingsPath, "utf-8");
const settings = JSON.parse(settingsContent);

expect(settings.enableAllProjectMcpServers).toBe(true);
expect(settings.enableAllProjectMcpServers).toBe(false);
expect(settings.model).toBe("claude-sonnet-4-20250514");
expect(settings.env).toEqual({ API_KEY: "test-key" });
});
Expand All @@ -74,23 +83,23 @@ describe("setupClaudeCodeSettings", () => {
const settingsContent = await readFile(settingsPath, "utf-8");
const settings = JSON.parse(settingsContent);

expect(settings.enableAllProjectMcpServers).toBe(true);
expect(settings.enableAllProjectMcpServers).toBe(false);
expect(settings.hooks).toEqual(testSettings.hooks);
expect(settings.permissions).toEqual(testSettings.permissions);
});

test("should override enableAllProjectMcpServers even if false in input", async () => {
test("should override enableAllProjectMcpServers from settings input with action input", async () => {
const inputSettings = JSON.stringify({
enableAllProjectMcpServers: false,
enableAllProjectMcpServers: true,
model: "test-model",
});

await setupClaudeCodeSettings(inputSettings, testHomeDir);
await setupClaudeCodeSettings(inputSettings, testHomeDir, false);

const settingsContent = await readFile(settingsPath, "utf-8");
const settings = JSON.parse(settingsContent);

expect(settings.enableAllProjectMcpServers).toBe(true);
expect(settings.enableAllProjectMcpServers).toBe(false);
expect(settings.model).toBe("test-model");
});

Expand All @@ -112,7 +121,7 @@ describe("setupClaudeCodeSettings", () => {
const settingsContent = await readFile(settingsPath, "utf-8");
const settings = JSON.parse(settingsContent);

expect(settings.enableAllProjectMcpServers).toBe(true);
expect(settings.enableAllProjectMcpServers).toBe(false);
});

test("should handle whitespace-only input", async () => {
Expand All @@ -121,7 +130,7 @@ describe("setupClaudeCodeSettings", () => {
const settingsContent = await readFile(settingsPath, "utf-8");
const settings = JSON.parse(settingsContent);

expect(settings.enableAllProjectMcpServers).toBe(true);
expect(settings.enableAllProjectMcpServers).toBe(false);
});

test("should merge with existing settings", async () => {
Expand All @@ -142,7 +151,7 @@ describe("setupClaudeCodeSettings", () => {
const settingsContent = await readFile(settingsPath, "utf-8");
const settings = JSON.parse(settingsContent);

expect(settings.enableAllProjectMcpServers).toBe(true);
expect(settings.enableAllProjectMcpServers).toBe(false);
expect(settings.existingKey).toBe("existingValue");
expect(settings.newKey).toBe("newValue");
expect(settings.model).toBe("claude-opus-4-1-20250805");
Expand Down
2 changes: 1 addition & 1 deletion docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ For a complete list of available settings and their descriptions, see the [Claud

**Notes**:

- The `enableAllProjectMcpServers` setting is always set to `true` by this action to ensure MCP servers work correctly.
- The `enableAllProjectMcpServers` setting is controlled by the `enable_all_project_mcp_servers` input (default `true` for this action) and overrides any value provided via `settings`.
- The `claude_args` input provides direct access to Claude Code CLI arguments and takes precedence over settings.
- We recommend using `claude_args` for simple configurations and `settings` for complex configurations with hooks and environment variables.

Expand Down
1 change: 1 addition & 0 deletions docs/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ jobs:
| `trigger_phrase` | The trigger phrase to look for in comments, issue/PR bodies, and issue titles | No | `@claude` |
| `branch_prefix` | The prefix to use for Claude branches (defaults to 'claude/', use 'claude-' for dash format) | No | `claude/` |
| `settings` | Claude Code settings as JSON string or path to settings JSON file | No | "" |
| `enable_all_project_mcp_servers` | Auto-enable every MCP server in the checkout's `.mcp.json` | No | `true` |
| `additional_permissions` | Additional permissions to enable. Currently supports 'actions: read' for viewing workflow results | No | "" |
| `use_commit_signing` | Enable commit signing using GitHub's API. Simple but cannot perform complex git operations like rebasing. See [Security](./security.md#commit-signing) | No | `false` |
| `ssh_signing_key` | SSH private key for signing commits. Enables signed commits with full git CLI support (rebasing, etc.). See [Security](./security.md#commit-signing) | No | "" |
Expand Down
Loading
Loading