github_secrets_set
Securely set GitHub Actions secrets to manage sensitive data in CI/CD pipelines. This tool helps configure environment variables and authentication tokens for automated workflows.
Instructions
Set a GitHub Actions secret (value will be securely stored)
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||
Implementation Reference
- src/index.js:1887-1962 (handler)The main execution logic for the github_secrets_set tool. Validates the secret name format, masks the value for logging, constructs the gh secret set command, executes it using runCommand, and returns success/error messages with guidance.async ({ name, value, repo, env }) => { // Validate secret name if (!/^[A-Z][A-Z0-9_]*$/.test(name)) { return { content: [{ type: "text", text: `Invalid secret name: "${name}" Rules: - Must be UPPERCASE - Must start with a letter - Can only contain A-Z, 0-9, and _ Examples: API_KEY, DATABASE_URL, AWS_ACCESS_KEY_ID` }] }; } // Warn about potentially sensitive values being logged const maskedValue = value.substring(0, 3) + "***" + value.substring(value.length - 3); const repoFlag = repo ? `-R ${repo}` : ""; const envFlag = env ? `--env ${env}` : ""; // Use echo with pipe to avoid showing value in process list const result = await runCommand( `echo "${value.replace(/"/g, '\\"')}" | gh secret set ${name} ${repoFlag} ${envFlag}`, { timeout: 30000 } ); if (!result.success) { let help = ""; if (result.stderr?.includes("unauthorized") || result.stderr?.includes("401")) { help = "\n\nAuthentication issue. Try: gh auth login"; } else if (result.stderr?.includes("404") || result.stderr?.includes("not found")) { help = "\n\nRepository not found. Check the repo name or make sure you have access."; } return { content: [{ type: "text", text: `Failed to set secret!\n\nError: ${result.stderr || result.error}${help}` }] }; } const location = env ? `environment "${env}"` : "repository"; return { content: [{ type: "text", text: `Secret set successfully! Name: ${name} Value: ${maskedValue} Location: ${location}${repo ? ` (${repo})` : ""} TO USE IN GITHUB ACTIONS: \`\`\`yaml env: MY_VAR: \${{ secrets.${name} }} # Or in a step: - name: Use secret run: echo "Using secret" env: ${name}: \${{ secrets.${name} }} \`\`\` SECURITY NOTES: - Secrets are encrypted and never shown in logs - Secrets are not passed to workflows from forks - Use environment secrets for production credentials` }] }; }
- src/index.js:1881-1886 (schema)Input schema defining the parameters for the github_secrets_set tool: name (required string), value (required string), repo (optional string), env (optional string).{ name: { type: "string", description: "Secret name (uppercase with underscores, e.g., API_KEY)" }, value: { type: "string", description: "Secret value" }, repo: { type: "string", description: "Repository (owner/repo format)", default: "" }, env: { type: "string", description: "Environment name (optional, for environment-specific secrets)", default: "" } },
- src/index.js:1878-1964 (registration)MCP server.tool registration for the github_secrets_set tool, including name, description, input schema, and handler function.server.tool( "github_secrets_set", "Set a GitHub Actions secret (value will be securely stored)", { name: { type: "string", description: "Secret name (uppercase with underscores, e.g., API_KEY)" }, value: { type: "string", description: "Secret value" }, repo: { type: "string", description: "Repository (owner/repo format)", default: "" }, env: { type: "string", description: "Environment name (optional, for environment-specific secrets)", default: "" } }, async ({ name, value, repo, env }) => { // Validate secret name if (!/^[A-Z][A-Z0-9_]*$/.test(name)) { return { content: [{ type: "text", text: `Invalid secret name: "${name}" Rules: - Must be UPPERCASE - Must start with a letter - Can only contain A-Z, 0-9, and _ Examples: API_KEY, DATABASE_URL, AWS_ACCESS_KEY_ID` }] }; } // Warn about potentially sensitive values being logged const maskedValue = value.substring(0, 3) + "***" + value.substring(value.length - 3); const repoFlag = repo ? `-R ${repo}` : ""; const envFlag = env ? `--env ${env}` : ""; // Use echo with pipe to avoid showing value in process list const result = await runCommand( `echo "${value.replace(/"/g, '\\"')}" | gh secret set ${name} ${repoFlag} ${envFlag}`, { timeout: 30000 } ); if (!result.success) { let help = ""; if (result.stderr?.includes("unauthorized") || result.stderr?.includes("401")) { help = "\n\nAuthentication issue. Try: gh auth login"; } else if (result.stderr?.includes("404") || result.stderr?.includes("not found")) { help = "\n\nRepository not found. Check the repo name or make sure you have access."; } return { content: [{ type: "text", text: `Failed to set secret!\n\nError: ${result.stderr || result.error}${help}` }] }; } const location = env ? `environment "${env}"` : "repository"; return { content: [{ type: "text", text: `Secret set successfully! Name: ${name} Value: ${maskedValue} Location: ${location}${repo ? ` (${repo})` : ""} TO USE IN GITHUB ACTIONS: \`\`\`yaml env: MY_VAR: \${{ secrets.${name} }} # Or in a step: - name: Use secret run: echo "Using secret" env: ${name}: \${{ secrets.${name} }} \`\`\` SECURITY NOTES: - Secrets are encrypted and never shown in logs - Secrets are not passed to workflows from forks - Use environment secrets for production credentials` }] }; } );
- src/index.js:18-25 (helper)Helper function runCommand used by the tool to execute shell commands safely, including timeout and error handling.async function runCommand(cmd, options = {}) { try { const { stdout, stderr } = await execAsync(cmd, { timeout: 30000, ...options }); return { success: true, stdout: stdout.trim(), stderr: stderr.trim() }; } catch (error) { return { success: false, error: error.message, stdout: error.stdout?.trim(), stderr: error.stderr?.trim() }; } }
- src/tools.js:302-338 (handler)Exported handler function in tools.js (noted for testing), identical logic to the main handler.export async function githubSecretsSet({ name, value, repo, env }) { if (!/^[A-Z][A-Z0-9_]*$/.test(name)) { return { content: [{ type: "text", text: `Invalid secret name: "${name}"\n\nRules:\n- Must be UPPERCASE\n- Must start with a letter\n- Can only contain A-Z, 0-9, and _` }] }; } const maskedValue = value.substring(0, 3) + "***" + value.substring(value.length - 3); const repoFlag = repo ? `-R ${repo}` : ""; const envFlag = env ? `--env ${env}` : ""; const result = await commandRunner( `echo "${value.replace(/"/g, '\\"')}" | gh secret set ${name} ${repoFlag} ${envFlag}`, { timeout: 30000 } ); if (!result.success) { return { content: [{ type: "text", text: `Failed to set secret!\n\nError: ${result.stderr || result.error}` }] }; } const location = env ? `environment "${env}"` : "repository"; return { content: [{ type: "text", text: `Secret set successfully!\n\nName: ${name}\nValue: ${maskedValue}\nLocation: ${location}` }] }; }