Skip to content

Commit b53cc72

Browse files
abdoutclaude
andcommitted
docs: comprehensive Claude Code team setup guide
- Complete one-liner setup with secrets - Directory structure documentation - Product agent references (hogwarts, souq, mkan, shifa) - Secrets management via private gist - Repository sync scripts - MCP server documentation - Troubleshooting guide Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 3821869 commit b53cc72

4 files changed

Lines changed: 678 additions & 222 deletions

File tree

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
{
2+
"$schema": "databayt-secrets",
3+
"description": "Team secrets for Claude Code MCP servers",
4+
"updated": "2026-01-17",
5+
6+
"required": {
7+
"GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_xxxxxxxxxxxxxxxxxxxx",
8+
"NEON_API_KEY": "neon_api_xxxxxxxxxxxx",
9+
"DATABASE_URL": "postgresql://user:pass@host/db"
10+
},
11+
12+
"optional": {
13+
"ANTHROPIC_API_KEY": "",
14+
"OPENAI_API_KEY": "",
15+
"POSTHOG_API_KEY": "",
16+
"POSTHOG_PROJECT_ID": "",
17+
"NOTION_API_KEY": "",
18+
"SLACK_BOT_TOKEN": "",
19+
"SLACK_WORKSPACE_ID": "",
20+
"AIRTABLE_API_KEY": "",
21+
"ALGOLIA_APP_ID": "",
22+
"ALGOLIA_API_KEY": "",
23+
"ALGOLIA_INDEX_NAME": "",
24+
"ALGOLIA_WRITE_API_KEY": "",
25+
"REF_API_KEY": "",
26+
"VERCEL_TOKEN": "",
27+
"STRIPE_SECRET_KEY": "",
28+
"SENTRY_AUTH_TOKEN": "",
29+
"LINEAR_API_KEY": "",
30+
"FIGMA_ACCESS_TOKEN": ""
31+
},
32+
33+
"notes": {
34+
"GITHUB_PERSONAL_ACCESS_TOKEN": "GitHub > Settings > Developer settings > Personal access tokens > Fine-grained tokens",
35+
"NEON_API_KEY": "Neon Console > Account > API Keys",
36+
"DATABASE_URL": "Neon Console > Project > Connection Details"
37+
}
38+
}

.claude/scripts/setup-secrets.ps1

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
# Setup secrets from private GitHub gist (Windows PowerShell)
2+
# Usage: & "$env:USERPROFILE\.claude\scripts\setup-secrets.ps1" -GistId "<GIST_ID>"
3+
# Or: irm https://raw.githubusercontent.com/databayt/codebase/main/.claude/scripts/setup-secrets.ps1 | iex; Setup-Secrets -GistId "<GIST_ID>"
4+
5+
param(
6+
[Parameter(Mandatory=$false)]
7+
[string]$GistId
8+
)
9+
10+
$ErrorActionPreference = "Stop"
11+
12+
$ClaudeDir = "$env:USERPROFILE\.claude"
13+
$EnvFile = "$ClaudeDir\.env"
14+
15+
Write-Host "=== Claude Code Secrets Setup ===" -ForegroundColor Cyan
16+
Write-Host ""
17+
18+
# Check for gist ID
19+
if (-not $GistId) {
20+
Write-Host "Error: Gist ID required" -ForegroundColor Red
21+
Write-Host ""
22+
Write-Host "Usage:"
23+
Write-Host " .\setup-secrets.ps1 -GistId <GIST_ID>"
24+
Write-Host ""
25+
Write-Host "Get the Gist ID from your team lead."
26+
exit 1
27+
}
28+
29+
# Ensure claude directory exists
30+
if (-not (Test-Path $ClaudeDir)) {
31+
New-Item -ItemType Directory -Path $ClaudeDir -Force | Out-Null
32+
}
33+
34+
# Fetch secrets from gist
35+
Write-Host "Fetching secrets from gist..." -ForegroundColor Yellow
36+
$GistUrl = "https://gist.githubusercontent.com/raw/$GistId"
37+
38+
try {
39+
$Secrets = Invoke-RestMethod -Uri $GistUrl
40+
} catch {
41+
Write-Host "Error: Could not fetch gist. Check the ID and try again." -ForegroundColor Red
42+
exit 1
43+
}
44+
45+
Write-Host "Secrets fetched successfully" -ForegroundColor Green
46+
Write-Host ""
47+
48+
# Write environment file
49+
Write-Host "Writing environment file..." -ForegroundColor Yellow
50+
51+
$EnvContent = @"
52+
# Claude Code Environment Variables
53+
# Auto-generated by setup-secrets.ps1
54+
# DO NOT COMMIT THIS FILE
55+
56+
# Required
57+
"@
58+
59+
foreach ($key in $Secrets.required.PSObject.Properties.Name) {
60+
$value = $Secrets.required.$key
61+
if ($value -and -not $value.StartsWith("ghp_xxx") -and -not $value.StartsWith("neon_api_xxx")) {
62+
$EnvContent += "`n$key=$value"
63+
}
64+
}
65+
66+
$EnvContent += "`n`n# Optional"
67+
68+
foreach ($key in $Secrets.optional.PSObject.Properties.Name) {
69+
$value = $Secrets.optional.$key
70+
if ($value) {
71+
$EnvContent += "`n$key=$value"
72+
}
73+
}
74+
75+
$EnvContent | Out-File -FilePath $EnvFile -Encoding UTF8
76+
77+
Write-Host "Environment file created: $EnvFile" -ForegroundColor Green
78+
Write-Host ""
79+
80+
# Add to PowerShell profile
81+
$ProfileDir = Split-Path $PROFILE
82+
if (-not (Test-Path $ProfileDir)) {
83+
New-Item -ItemType Directory -Path $ProfileDir -Force | Out-Null
84+
}
85+
86+
$ProfileContent = @'
87+
88+
# Claude Code secrets
89+
if (Test-Path "$env:USERPROFILE\.claude\.env") {
90+
Get-Content "$env:USERPROFILE\.claude\.env" | ForEach-Object {
91+
if ($_ -and -not $_.StartsWith("#")) {
92+
$parts = $_ -split "=", 2
93+
if ($parts.Length -eq 2) {
94+
[Environment]::SetEnvironmentVariable($parts[0], $parts[1], "Process")
95+
}
96+
}
97+
}
98+
}
99+
'@
100+
101+
if (-not (Test-Path $PROFILE) -or -not (Select-String -Path $PROFILE -Pattern "claude.*\.env" -Quiet)) {
102+
Add-Content -Path $PROFILE -Value $ProfileContent
103+
Write-Host "Added auto-load to PowerShell profile" -ForegroundColor Green
104+
}
105+
106+
# Load now
107+
Get-Content $EnvFile | ForEach-Object {
108+
if ($_ -and -not $_.StartsWith("#")) {
109+
$parts = $_ -split "=", 2
110+
if ($parts.Length -eq 2) {
111+
[Environment]::SetEnvironmentVariable($parts[0], $parts[1], "Process")
112+
}
113+
}
114+
}
115+
116+
Write-Host ""
117+
Write-Host "=== Setup Complete ===" -ForegroundColor Green
118+
Write-Host ""
119+
Write-Host "Secrets are now configured. Either:"
120+
Write-Host " 1. Restart PowerShell"
121+
Write-Host " 2. Run: . `$PROFILE"
122+
Write-Host ""
123+
Write-Host "Then run 'claude' to start."
124+
125+
# Function for one-liner install
126+
function Setup-Secrets {
127+
param([string]$GistId)
128+
& "$env:USERPROFILE\.claude\scripts\setup-secrets.ps1" -GistId $GistId
129+
}

.claude/scripts/setup-secrets.sh

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
#!/bin/bash
2+
# Setup secrets from private GitHub gist
3+
# Usage: curl -fsSL https://raw.githubusercontent.com/databayt/codebase/main/.claude/scripts/setup-secrets.sh | bash -s -- <GIST_ID>
4+
5+
set -e
6+
7+
GIST_ID="${1:-}"
8+
CLAUDE_DIR="$HOME/.claude"
9+
ENV_FILE="$CLAUDE_DIR/.env"
10+
11+
# Colors
12+
RED='\033[0;31m'
13+
GREEN='\033[0;32m'
14+
YELLOW='\033[1;33m'
15+
BLUE='\033[0;34m'
16+
NC='\033[0m'
17+
18+
echo -e "${BLUE}=== Claude Code Secrets Setup ===${NC}"
19+
echo ""
20+
21+
# Check for gist ID
22+
if [ -z "$GIST_ID" ]; then
23+
echo -e "${RED}Error: Gist ID required${NC}"
24+
echo ""
25+
echo "Usage:"
26+
echo " ~/.claude/scripts/setup-secrets.sh <GIST_ID>"
27+
echo ""
28+
echo "Or with curl:"
29+
echo " curl -fsSL https://raw.githubusercontent.com/databayt/codebase/main/.claude/scripts/setup-secrets.sh | bash -s -- <GIST_ID>"
30+
echo ""
31+
echo "Get the Gist ID from your team lead."
32+
exit 1
33+
fi
34+
35+
# Ensure claude directory exists
36+
mkdir -p "$CLAUDE_DIR"
37+
38+
# Fetch secrets from gist
39+
echo -e "${YELLOW}Fetching secrets from gist...${NC}"
40+
GIST_URL="https://gist.githubusercontent.com/raw/$GIST_ID"
41+
42+
# Try to fetch the gist
43+
SECRETS=$(curl -fsSL "$GIST_URL" 2>/dev/null) || {
44+
echo -e "${RED}Error: Could not fetch gist. Check the ID and try again.${NC}"
45+
exit 1
46+
}
47+
48+
# Validate JSON
49+
if ! echo "$SECRETS" | python3 -c "import sys, json; json.load(sys.stdin)" 2>/dev/null; then
50+
echo -e "${RED}Error: Invalid JSON in gist${NC}"
51+
exit 1
52+
fi
53+
54+
echo -e "${GREEN}Secrets fetched successfully${NC}"
55+
echo ""
56+
57+
# Extract and write environment variables
58+
echo -e "${YELLOW}Writing environment file...${NC}"
59+
60+
# Create .env file
61+
cat > "$ENV_FILE" << 'HEADER'
62+
# Claude Code Environment Variables
63+
# Auto-generated by setup-secrets.sh
64+
# DO NOT COMMIT THIS FILE
65+
66+
HEADER
67+
68+
# Parse required secrets
69+
echo "# Required" >> "$ENV_FILE"
70+
echo "$SECRETS" | python3 -c "
71+
import sys, json
72+
data = json.load(sys.stdin)
73+
for key, value in data.get('required', {}).items():
74+
if value and not value.startswith('ghp_xxx') and not value.startswith('neon_api_xxx'):
75+
print(f'{key}={value}')
76+
" >> "$ENV_FILE"
77+
78+
# Parse optional secrets (only non-empty)
79+
echo "" >> "$ENV_FILE"
80+
echo "# Optional" >> "$ENV_FILE"
81+
echo "$SECRETS" | python3 -c "
82+
import sys, json
83+
data = json.load(sys.stdin)
84+
for key, value in data.get('optional', {}).items():
85+
if value:
86+
print(f'{key}={value}')
87+
" >> "$ENV_FILE"
88+
89+
# Set permissions
90+
chmod 600 "$ENV_FILE"
91+
92+
echo -e "${GREEN}Environment file created: $ENV_FILE${NC}"
93+
echo ""
94+
95+
# Add to shell profile
96+
SHELL_RC="$HOME/.zshrc"
97+
[ -f "$HOME/.bashrc" ] && SHELL_RC="$HOME/.bashrc"
98+
99+
EXPORT_LINE='[ -f "$HOME/.claude/.env" ] && export $(grep -v "^#" "$HOME/.claude/.env" | xargs)'
100+
101+
if ! grep -q ".claude/.env" "$SHELL_RC" 2>/dev/null; then
102+
echo "" >> "$SHELL_RC"
103+
echo "# Claude Code secrets" >> "$SHELL_RC"
104+
echo "$EXPORT_LINE" >> "$SHELL_RC"
105+
echo -e "${GREEN}Added auto-load to $SHELL_RC${NC}"
106+
fi
107+
108+
# Load now
109+
export $(grep -v "^#" "$ENV_FILE" | xargs) 2>/dev/null
110+
111+
echo ""
112+
echo -e "${GREEN}=== Setup Complete ===${NC}"
113+
echo ""
114+
echo "Secrets are now configured. Either:"
115+
echo " 1. Restart your terminal"
116+
echo " 2. Run: source $SHELL_RC"
117+
echo ""
118+
echo "Then run 'claude' to start."

0 commit comments

Comments
 (0)