Files
claude-code-gitea-action/src/mcp/install-mcp-server.ts
T
Ashwin Bhat e409c57d90 feat: add mcp_config input that merges with existing mcp server (#96)
* feat: add mcp_config input that merges with existing mcp server

- Add mcp_config input parameter to action.yml 
- Modify prepareMcpConfig() to accept and merge additional config
- Provided config overrides built-in servers in case of naming collisions
- Pass MCP_CONFIG environment variable from action to prepare step

Co-authored-by: ashwin-ant <ashwin-ant@users.noreply.github.com>

* refactor: improve MCP config validation and merging logic

- Add JSON validation to ensure parsed config is an object
- Simplify merge logic with explicit mcpServers merging
- Enhance error logging with config preview for debugging

Co-authored-by: ashwin-ant <ashwin-ant@users.noreply.github.com>

* refactor: improve MCP config logging per review feedback

- Remove configPreview from error logging to avoid cluttering output
- Add informational log when merging MCP server configurations
- Simplify error message for failed config parsing

Co-authored-by: ashwin-ant <ashwin-ant@users.noreply.github.com>

* test: add comprehensive unit tests for prepareMcpConfig

Add tests covering:
- Basic functionality with no additional config
- Valid JSON merging scenarios
- Invalid JSON handling
- Empty/null config handling
- Server name collision scenarios
- Complex nested configurations
- Environment variable handling

Co-authored-by: ashwin-ant <ashwin-ant@users.noreply.github.com>

* docs: add mcp_config example with sequential-thinking server

- Add mcp_config to inputs table
- Add example section showing how to use mcp_config with sequential-thinking MCP server
- Include clear explanation that custom servers override built-in servers

Co-authored-by: ashwin-ant <ashwin-ant@users.noreply.github.com>

* readme

---------

Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com>
Co-authored-by: ashwin-ant <ashwin-ant@users.noreply.github.com>
2025-06-02 09:03:45 -07:00

82 lines
2.2 KiB
TypeScript

import * as core from "@actions/core";
export async function prepareMcpConfig(
githubToken: string,
owner: string,
repo: string,
branch: string,
additionalMcpConfig?: string,
): Promise<string> {
try {
const baseMcpConfig = {
mcpServers: {
github: {
command: "docker",
args: [
"run",
"-i",
"--rm",
"-e",
"GITHUB_PERSONAL_ACCESS_TOKEN",
"ghcr.io/anthropics/github-mcp-server:sha-7382253",
],
env: {
GITHUB_PERSONAL_ACCESS_TOKEN: githubToken,
},
},
github_file_ops: {
command: "bun",
args: [
"run",
`${process.env.GITHUB_ACTION_PATH}/src/mcp/github-file-ops-server.ts`,
],
env: {
GITHUB_TOKEN: githubToken,
REPO_OWNER: owner,
REPO_NAME: repo,
BRANCH_NAME: branch,
REPO_DIR: process.env.GITHUB_WORKSPACE || process.cwd(),
},
},
},
};
// Merge with additional MCP config if provided
if (additionalMcpConfig && additionalMcpConfig.trim()) {
try {
const additionalConfig = JSON.parse(additionalMcpConfig);
// Validate that parsed JSON is an object
if (typeof additionalConfig !== "object" || additionalConfig === null) {
throw new Error("MCP config must be a valid JSON object");
}
core.info(
"Merging additional MCP server configuration with built-in servers",
);
// Merge configurations with user config overriding built-in servers
const mergedConfig = {
...baseMcpConfig,
...additionalConfig,
mcpServers: {
...baseMcpConfig.mcpServers,
...additionalConfig.mcpServers,
},
};
return JSON.stringify(mergedConfig, null, 2);
} catch (parseError) {
core.warning(
`Failed to parse additional MCP config: ${parseError}. Using base config only.`,
);
}
}
return JSON.stringify(baseMcpConfig, null, 2);
} catch (error) {
core.setFailed(`Install MCP server failed with error: ${error}`);
process.exit(1);
}
}