Skip to main content
Glama

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
NameRequiredDescriptionDefault

No arguments

Implementation Reference

  • 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`
          }]
        };
      }
  • 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`
          }]
        };
      }
    );
  • 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() };
      }
    }
  • 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}`
        }]
      };
    }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/rideRTD/RTD-DevOps'

If you have feedback or need assistance with the MCP directory API, please join our Discord server