Skip to content

Commit 4e7f6fb

Browse files
fidgetcodingruvnet
andcommitted
refactor(github-mcp): move GitHub MCP from step-6 to new step-10
GitHub is a developer tool, not a productivity tool — it has no place alongside Notion/Granola/Morgen in step-6. Pulls it out cleanly and creates step-10 (Developer Tools) as a dedicated pre-status-line step. The new script follows the same pattern as all other step installers and includes a Python shim to inject the PAT into ~/.claude.json since claude mcp add --scope user -e has inconsistent support. Co-Authored-By: claude-flow <ruv@ruv.net>
1 parent cfa7623 commit 4e7f6fb

2 files changed

Lines changed: 289 additions & 70 deletions

File tree

step-10/step-10-install.sh

Lines changed: 288 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,288 @@
1+
#!/usr/bin/env bash
2+
set -uo pipefail
3+
4+
# =============================================================================
5+
# Step 10 — Developer Tools
6+
# Installs GitHub MCP server. More developer tools may be added here.
7+
# Run after completing Steps 1-9. Run this in your terminal.
8+
# =============================================================================
9+
10+
RED='\033[0;31m'
11+
GREEN='\033[0;32m'
12+
YELLOW='\033[1;33m'
13+
BLUE='\033[0;34m'
14+
NC='\033[0m'
15+
16+
ERRORS=0
17+
18+
info() { echo -e "${BLUE}[INFO]${NC} $1"; }
19+
success() { echo -e "${GREEN}[OK]${NC} $1"; }
20+
warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
21+
fail() { echo -e "${RED}[FAIL]${NC} $1"; exit 1; }
22+
soft_fail() { echo -e "${RED}[FAIL]${NC} $1 (non-critical, continuing...)"; ERRORS=$((ERRORS + 1)); }
23+
24+
# Track what was installed this run
25+
INSTALLED_GITHUB=false
26+
27+
# -----------------------------------------------------------------------------
28+
# Detect OS
29+
# -----------------------------------------------------------------------------
30+
detect_os() {
31+
case "$(uname -s)" in
32+
Darwin) OS="mac" ;;
33+
Linux) OS="linux" ;;
34+
MINGW*|MSYS*|CYGWIN*) fail "Windows is not supported. This script is for macOS and Linux only." ;;
35+
*) fail "Unsupported OS: $(uname -s). This script supports macOS and Linux only." ;;
36+
esac
37+
info "Detected OS: $OS"
38+
}
39+
40+
# -----------------------------------------------------------------------------
41+
# Verify prerequisites
42+
# -----------------------------------------------------------------------------
43+
verify_prerequisites() {
44+
if ! command -v node &>/dev/null; then
45+
fail "Node.js not found. Run Step 1 first."
46+
fi
47+
if ! command -v claude &>/dev/null; then
48+
fail "Claude Code not found. Run Step 1 first."
49+
fi
50+
success "Prerequisites verified"
51+
}
52+
53+
# -----------------------------------------------------------------------------
54+
# Interactive menu — let the user pick which tools to install
55+
# -----------------------------------------------------------------------------
56+
choose_tools() {
57+
# Detect non-interactive mode (stdin is a pipe, not a terminal)
58+
if [ ! -t 0 ]; then
59+
info "Non-interactive mode detected (running via curl pipe)"
60+
CHOICES=""
61+
62+
# Auto-detect already-installed tools
63+
if claude mcp list 2>/dev/null | grep -q "github" 2>/dev/null; then
64+
CHOICES="$CHOICES 1"
65+
INSTALLED_GITHUB=true
66+
fi
67+
68+
if [ -n "$CHOICES" ]; then
69+
info "Found already-installed tools — verifying configuration"
70+
return
71+
else
72+
echo ""
73+
echo -e "${YELLOW} Step 10 requires interactive input for API credentials.${NC}"
74+
echo -e "${YELLOW} Run it directly in your terminal:${NC}"
75+
echo ""
76+
echo " bash <(curl -fsSL https://raw.githubusercontent.com/lorecraft-io/cli-maxxing/main/step-10/step-10-install.sh)"
77+
echo ""
78+
print_summary
79+
exit 0
80+
fi
81+
fi
82+
83+
echo ""
84+
echo -e "${BLUE} Which developer tools do you use?${NC}"
85+
echo -e "${BLUE} (enter numbers separated by spaces)${NC}"
86+
echo ""
87+
echo " 1) GitHub — repos, issues, PRs, code search (requires Personal Access Token)"
88+
echo ""
89+
echo -e "${YELLOW} This step is for developers. If you don't use GitHub with Claude,${NC}"
90+
echo -e "${YELLOW} you can skip it — all earlier steps work without it.${NC}"
91+
echo ""
92+
read -rp " Enter your choices (e.g. \"1\"): " CHOICES
93+
echo ""
94+
95+
if [ -z "$CHOICES" ]; then
96+
warn "No tools selected. Nothing to install."
97+
print_summary
98+
exit 0
99+
fi
100+
}
101+
102+
# -----------------------------------------------------------------------------
103+
# Install GitHub MCP
104+
# -----------------------------------------------------------------------------
105+
install_github() {
106+
info "Installing GitHub MCP server..."
107+
108+
if claude mcp list 2>/dev/null | grep -q "github"; then
109+
success "GitHub MCP already installed"
110+
INSTALLED_GITHUB=true
111+
return
112+
fi
113+
114+
echo ""
115+
echo -e "${BLUE} GitHub MCP gives Claude read/write access to your repos,${NC}"
116+
echo -e "${BLUE} issues, pull requests, and code search via the GitHub API.${NC}"
117+
echo ""
118+
echo -e "${BLUE} You need a Personal Access Token (classic PAT). Create one at:${NC}"
119+
echo -e "${BLUE} https://github.com/settings/tokens/new${NC}"
120+
echo ""
121+
echo " Suggested settings:"
122+
echo " - Token name: claude-github-mcp"
123+
echo " - Expiration: No expiration"
124+
echo " - Scopes: repo, read:org, gist"
125+
echo ""
126+
echo -e "${YELLOW} Use a classic token (not fine-grained) for full repo access.${NC}"
127+
echo -e "${YELLOW} Check only: repo (top checkbox), read:org (under admin:org), gist.${NC}"
128+
echo ""
129+
130+
read -sp " GitHub Personal Access Token (ghp_...): " GITHUB_TOKEN
131+
echo " [saved]"
132+
echo ""
133+
134+
if [ -z "$GITHUB_TOKEN" ]; then
135+
warn "No GitHub token provided. Skipping GitHub setup."
136+
warn "Re-run Step 10 when you have a token ready."
137+
return
138+
fi
139+
140+
if [[ ! "$GITHUB_TOKEN" =~ ^gh[ps]_ ]]; then
141+
warn "Token doesn't look like a GitHub PAT (expected ghp_ or ghs_ prefix)."
142+
warn "Proceeding anyway — registration will fail if the token is invalid."
143+
echo ""
144+
fi
145+
146+
# Register with the token injected via env var into the MCP server process.
147+
# Credentials live in Claude's MCP config only — not written to disk here.
148+
claude mcp add --scope user github -- npx -y @modelcontextprotocol/server-github 2>/dev/null
149+
150+
# Inject the token directly into the config entry (claude mcp add --scope user
151+
# does not support -e flags in all CLI versions, so we patch the env block).
152+
python3 - "$GITHUB_TOKEN" <<'PYEOF'
153+
import sys, json, os
154+
155+
token = sys.argv[1]
156+
config_path = os.path.expanduser("~/.claude.json")
157+
158+
with open(config_path) as f:
159+
config = json.load(f)
160+
161+
mcpServers = config.get("mcpServers", {})
162+
if "github" in mcpServers:
163+
mcpServers["github"].setdefault("env", {})
164+
mcpServers["github"]["env"]["GITHUB_PERSONAL_ACCESS_TOKEN"] = token
165+
config["mcpServers"] = mcpServers
166+
with open(config_path, "w") as f:
167+
json.dump(config, f, indent=2)
168+
print("Token injected into GitHub MCP config.")
169+
else:
170+
print("WARNING: github entry not found in MCP config — token not injected.")
171+
PYEOF
172+
173+
if claude mcp list 2>/dev/null | grep -q "github"; then
174+
success "GitHub MCP installed"
175+
INSTALLED_GITHUB=true
176+
else
177+
soft_fail "GitHub MCP installation could not be verified"
178+
fi
179+
}
180+
181+
# -----------------------------------------------------------------------------
182+
# Self-test — check each installed tool is registered
183+
# -----------------------------------------------------------------------------
184+
run_self_test() {
185+
echo ""
186+
echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
187+
echo -e "${BLUE} Running Self-Test${NC}"
188+
echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
189+
echo ""
190+
191+
TEST_PASS=0
192+
TEST_FAIL=0
193+
TEST_SKIP=0
194+
195+
check_registered() {
196+
local label="$1"
197+
local needle="$2"
198+
if claude mcp list 2>/dev/null | grep -q "$needle"; then
199+
success "TEST: $label MCP registered"
200+
TEST_PASS=$((TEST_PASS + 1))
201+
else
202+
soft_fail "TEST: $label MCP not registered"
203+
TEST_FAIL=$((TEST_FAIL + 1))
204+
fi
205+
}
206+
207+
if $INSTALLED_GITHUB; then check_registered "GitHub" "github"; else info "TEST: GitHub — skipped"; TEST_SKIP=$((TEST_SKIP + 1)); fi
208+
209+
echo ""
210+
if [ "$TEST_FAIL" -eq 0 ]; then
211+
echo -e " ${GREEN}All $TEST_PASS tests passed.${NC} ($TEST_SKIP skipped)"
212+
else
213+
echo -e " ${GREEN}$TEST_PASS passed${NC}, ${RED}$TEST_FAIL failed${NC}, $TEST_SKIP skipped."
214+
echo -e " ${YELLOW}Scroll up to see what went wrong.${NC}"
215+
fi
216+
echo ""
217+
echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
218+
}
219+
220+
# -----------------------------------------------------------------------------
221+
# Summary
222+
# -----------------------------------------------------------------------------
223+
print_summary() {
224+
echo ""
225+
echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
226+
echo -e "${GREEN} Step 10 Complete — Developer Tools${NC}"
227+
echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
228+
echo ""
229+
230+
INSTALLED_COUNT=0
231+
232+
if $INSTALLED_GITHUB; then echo " GitHub — repos, issues, PRs, code search"; INSTALLED_COUNT=$((INSTALLED_COUNT + 1)); fi
233+
234+
if [ "$INSTALLED_COUNT" -eq 0 ]; then
235+
echo " No tools were installed."
236+
else
237+
echo ""
238+
echo " $INSTALLED_COUNT tool(s) installed and ready in Claude Code."
239+
echo ""
240+
echo " What you can do now:"
241+
242+
if $INSTALLED_GITHUB; then
243+
echo " - Ask Claude to list open PRs or issues on any of your repos"
244+
echo " - Ask Claude to search code across your GitHub organizations"
245+
echo " - Ask Claude to create issues, review diffs, or push commits"
246+
fi
247+
fi
248+
249+
echo ""
250+
if [ "$ERRORS" -gt 0 ]; then
251+
echo -e " ${YELLOW}Warnings: $ERRORS issue(s) detected.${NC}"
252+
echo -e " ${YELLOW}Scroll up to see details.${NC}"
253+
echo ""
254+
fi
255+
echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
256+
echo ""
257+
echo " Continue to the Final Step to install your status line."
258+
echo ""
259+
}
260+
261+
# -----------------------------------------------------------------------------
262+
# Main
263+
# -----------------------------------------------------------------------------
264+
main() {
265+
echo ""
266+
echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
267+
echo -e "${BLUE} Step 10 — Developer Tools${NC}"
268+
echo -e "${BLUE} GitHub and other dev-facing MCP tools • macOS + Linux${NC}"
269+
echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
270+
echo ""
271+
272+
detect_os
273+
verify_prerequisites
274+
choose_tools
275+
276+
# Process each selection in the canonical order
277+
for CHOICE in $CHOICES; do
278+
case "$CHOICE" in
279+
1) if ! $INSTALLED_GITHUB; then install_github; else success "GitHub already configured"; fi ;;
280+
*) warn "Unknown choice: $CHOICE (skipping)" ;;
281+
esac
282+
done
283+
284+
run_self_test
285+
print_summary
286+
}
287+
288+
main "$@"

0 commit comments

Comments
 (0)