Skip to main content
Glama

credentials

Analyze credential requirements for workflows without exposing actual values, generate environment templates, or display setup instructions for secure workflow configuration.

Instructions

Analyze credential requirements for workflows (secure - never exposes actual values)

Input Schema

NameRequiredDescriptionDefault
actionYesAction to perform: analyze requirements, show setup instructions, or generate .env.example

Input Schema (JSON Schema)

{ "properties": { "action": { "description": "Action to perform: analyze requirements, show setup instructions, or generate .env.example", "enum": [ "analyze", "instructions", "generate-env" ], "type": "string" } }, "required": [ "action" ], "type": "object" }

Implementation Reference

  • Registers the 'credentials' MCP tool with its name, description, and input schema defining the 'action' parameter.
    name: 'credentials', description: 'Analyze credential requirements for workflows (secure - never exposes actual values)', inputSchema: { type: 'object', properties: { action: { type: 'string', enum: ['analyze', 'instructions', 'generate-env'], description: 'Action to perform: analyze requirements, show setup instructions, or generate .env.example', }, }, required: ['action'], }, },
  • ToolHandler.handleTool switch case for 'credentials': dispatches to CredentialHelper methods based on the 'action' input.
    case 'credentials': const credAction = args?.action as string; switch (credAction) { case 'analyze': return await this.credentialHelper.analyzeCredentialRequirements(); case 'instructions': return await this.credentialHelper.getCredentialSetupInstructions(); case 'generate-env': return await this.credentialHelper.generateSecureEnvExample(); default: throw new Error(`Unknown credential action: ${credAction}`); }
  • CredentialHelper.analyzeCredentialRequirements(): Scans all workflow files for required credentials, checks .env file for presence, returns detailed analysis report.
    async analyzeCredentialRequirements(): Promise<any> { try { const flowsDir = path.join(this.workflowsPath, 'flows'); const files = await fs.readdir(flowsDir); const requirements = new Map<string, CredentialRequirement>(); const workflowCredentials = new Map<string, string[]>(); // Analyze each workflow for (const file of files) { if (!file.endsWith('.json') || file.includes('package.json')) continue; const content = await fs.readFile(path.join(flowsDir, file), 'utf-8'); const workflow = JSON.parse(content); const workflowName = file.replace('.json', ''); const credTypes: string[] = []; if (workflow.nodes) { for (const node of workflow.nodes) { // Check for credential requirements if (node.credentials) { Object.keys(node.credentials).forEach(credType => { credTypes.push(credType); // Map credential types to environment variables switch (credType) { case 'openAiApi': requirements.set('OPENAI_API_KEY', { envVar: 'OPENAI_API_KEY', n8nType: 'OpenAI API', displayName: 'OpenAI API Key', instructions: '1. Go to https://platform.openai.com/api-keys\n2. Create a new API key\n3. Add to .env: OPENAI_API_KEY=sk-...', }); break; case 'replicateApi': requirements.set('REPLICATE_API_TOKEN', { envVar: 'REPLICATE_API_TOKEN', n8nType: 'Replicate API', displayName: 'Replicate API Token', instructions: '1. Go to https://replicate.com/account/api-tokens\n2. Create a new token\n3. Add to .env: REPLICATE_API_TOKEN=...', }); break; case 'airtableApi': requirements.set('AIRTABLE_API_KEY', { envVar: 'AIRTABLE_API_KEY', n8nType: 'Airtable API', displayName: 'Airtable API Key or Personal Access Token', instructions: '1. Go to https://airtable.com/create/tokens\n2. Create a personal access token\n3. Add to .env: AIRTABLE_API_KEY=pat...', }); break; case 'slackApi': requirements.set('SLACK_WEBHOOK_URL', { envVar: 'SLACK_WEBHOOK_URL', n8nType: 'Slack Webhook', displayName: 'Slack Webhook URL', instructions: '1. Go to https://api.slack.com/apps\n2. Create an app and add Incoming Webhook\n3. Add to .env: SLACK_WEBHOOK_URL=https://hooks.slack.com/...', }); break; case 'githubApi': requirements.set('GITHUB_TOKEN', { envVar: 'GITHUB_TOKEN', n8nType: 'GitHub API', displayName: 'GitHub Personal Access Token', instructions: '1. Go to https://github.com/settings/tokens\n2. Generate new token (classic)\n3. Add to .env: GITHUB_TOKEN=ghp_...', }); break; } }); } } } if (credTypes.length > 0) { workflowCredentials.set(workflowName, credTypes); } } // Check which credentials exist in .env const envVars = await this.checkEnvFile(); // Format output let output = 'πŸ” Credential Requirements Analysis\n\n'; if (requirements.size === 0) { output += 'βœ… No credentials required for these workflows.\n'; } else { output += `πŸ“‹ Required Credentials (${requirements.size}):\n\n`; for (const [envVar, req] of requirements) { const hasEnv = envVars.has(envVar); const status = hasEnv ? 'βœ…' : '❌'; output += `${status} ${req.displayName}\n`; output += ` Environment Variable: ${envVar}\n`; output += ` n8n Credential Type: ${req.n8nType}\n`; if (!hasEnv) { output += ` ⚠️ Not found in .env\n`; } output += '\n'; } // Show which workflows need which credentials output += 'πŸ“Š Workflows and Their Credential Requirements:\n\n'; for (const [workflow, creds] of workflowCredentials) { output += `β€’ ${workflow}: ${creds.join(', ')}\n`; } // Instructions for missing credentials const missing = Array.from(requirements.entries()).filter(([env]) => !envVars.has(env)); if (missing.length > 0) { output += '\n⚠️ Missing Credentials Setup Instructions:\n\n'; for (const [, req] of missing) { output += `### ${req.displayName}\n${req.instructions}\n\n`; } output += 'πŸ”’ Security Best Practices:\n'; output += '1. Never commit .env files to git\n'; output += '2. Use strong, unique API keys\n'; output += '3. Rotate keys regularly\n'; output += '4. Limit API key permissions to minimum required\n'; output += '5. Add credentials through n8n UI at http://localhost:5678\n'; } } return { content: [ { type: 'text', text: output, }, ], }; } catch (error: any) { throw new Error(`Failed to analyze credentials: ${error.message}`); } }
  • CredentialHelper.generateSecureEnvExample(): Generates a secure .env.example file with required credential placeholders and instructions.
    async generateSecureEnvExample(): Promise<any> { try { const requirements = await this.getRequirementsFromWorkflows(); let content = '# n8n Workflow Credentials\n'; content += '# SECURITY: Never commit this file with real values to git!\n'; content += '# Copy to .env and add your actual API keys\n\n'; content += '# === Required API Credentials ===\n'; content += '# Get these from the respective service providers\n\n'; for (const req of requirements) { content += `# ${req.displayName}\n`; content += `# ${req.instructions.split('\n')[0]}\n`; // First line of instructions content += `${req.envVar}=\n\n`; } content += '# === Security Reminders ===\n'; content += '# 1. Add .env to .gitignore\n'; content += '# 2. Never share or log these values\n'; content += '# 3. Rotate keys regularly\n'; content += '# 4. Use environment-specific keys (dev/prod)\n'; const envExamplePath = path.join(this.workflowsPath, '.env.example'); await fs.writeFile(envExamplePath, content, 'utf-8'); return { content: [ { type: 'text', text: 'βœ… Generated secure .env.example\n\n' + 'πŸ“ Location: workflows/.env.example\n\n' + 'Next steps:\n' + '1. Copy .env.example to .env\n' + '2. Add your API keys to .env\n' + '3. Never commit .env to git\n' + '4. Add credentials in n8n UI at http://localhost:5678', }, ], }; } catch (error: any) { throw new Error(`Failed to generate .env.example: ${error.message}`); }
  • CredentialHelper.getCredentialSetupInstructions(): Returns comprehensive step-by-step instructions for securely setting up n8n credentials.
    async getCredentialSetupInstructions(): Promise<any> { return { content: [ { type: 'text', text: `πŸ” Secure Credential Setup for n8n 1️⃣ **Prepare Your Credentials** β€’ Copy workflows/.env.example to workflows/.env β€’ Add your API keys to the .env file β€’ Never commit .env to version control 2️⃣ **Add Credentials in n8n UI** β€’ Open http://localhost:5678 β€’ Go to Credentials (left sidebar) β€’ Click "Add Credential" β€’ Select the credential type β€’ Enter your API key/token β€’ Save the credential 3️⃣ **Link Credentials to Workflows** β€’ Open each workflow β€’ Click on nodes that need credentials β€’ Select the credential from dropdown β€’ Save the workflow 4️⃣ **Security Best Practices** βœ… Use environment-specific credentials (dev/staging/prod) βœ… Rotate API keys regularly βœ… Use minimal required permissions βœ… Enable 2FA where available βœ… Monitor API usage for anomalies ❌ Never log or print credentials ❌ Never commit credentials to git ❌ Never share credentials in messages 5️⃣ **Troubleshooting** β€’ If a workflow fails with "Credentials not found": - Check the credential exists in n8n - Verify the credential name matches - Ensure the credential has correct permissions β€’ If API calls fail: - Test credentials directly with the service - Check rate limits - Verify API endpoint URLs For detailed setup per service: β€’ OpenAI: https://platform.openai.com/docs/api-reference/authentication β€’ GitHub: https://docs.github.com/en/authentication β€’ Slack: https://api.slack.com/authentication β€’ Airtable: https://airtable.com/developers/web/api/authentication`, }, ], }; }

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/mckinleymedia/mcflow-mcp'

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