claudepod 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,370 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+
4
+ # ClaudePod Post-Start Script - Phase 3: MCP Server Installation
5
+ # This script handles MCP server installations that don't require API keys
6
+
7
+ echo "๐Ÿš€ Starting ClaudePod MCP server setup..."
8
+
9
+ # Initial NVM setup will be handled in main() to avoid conflicts
10
+
11
+ # Retry function for resilient installations
12
+ retry_command() {
13
+ local max_attempts=${1:-3}
14
+ local delay=${2:-5}
15
+ shift 2
16
+ local attempt=1
17
+
18
+ while [ $attempt -le $max_attempts ]; do
19
+ if "$@"; then
20
+ return 0
21
+ fi
22
+ echo "โš ๏ธ Command failed (attempt $attempt/$max_attempts): $*"
23
+ if [ $attempt -lt $max_attempts ]; then
24
+ echo " Retrying in ${delay}s..."
25
+ sleep $delay
26
+ fi
27
+ ((attempt++))
28
+ done
29
+ return 1
30
+ }
31
+
32
+ # Function to install uv via pipx
33
+ install_uv() {
34
+ echo "๐Ÿ“ฆ Installing uv package manager..."
35
+
36
+ # Ensure we have the user's local bin in PATH
37
+ export PATH="$HOME/.local/bin:$PATH"
38
+
39
+ # Check if uv/uvx is already available
40
+ if command -v uvx &> /dev/null; then
41
+ echo "โœ… uvx already available"
42
+ return 0
43
+ fi
44
+
45
+ # Set PIPX_HOME and PIPX_BIN_DIR to user-writable locations
46
+ export PIPX_HOME="$HOME/.local/pipx"
47
+ export PIPX_BIN_DIR="$HOME/.local/bin"
48
+
49
+ # Create directories if they don't exist
50
+ mkdir -p "$PIPX_HOME" "$PIPX_BIN_DIR"
51
+
52
+ # Check if pipx is available from Python feature
53
+ if ! command -v pipx &> /dev/null; then
54
+ echo "โš ๏ธ pipx not found. Checking if it's installed via Python feature..."
55
+
56
+ # The Python feature should install pipx, but it might not be in PATH yet
57
+ if [ -f "/usr/local/py-utils/bin/pipx" ]; then
58
+ # Use the pipx from Python feature but with user directories
59
+ alias pipx="/usr/local/py-utils/bin/pipx"
60
+ echo "โœ… Found pipx in Python feature directory"
61
+ else
62
+ echo "โš ๏ธ pipx not available. Skipping uv installation."
63
+ return 1
64
+ fi
65
+ fi
66
+
67
+ # Install uv with user directories
68
+ if retry_command 3 5 /usr/local/py-utils/bin/pipx install uv; then
69
+ echo "โœ… uv installed successfully"
70
+
71
+ # Verify uvx is available
72
+ if [ -f "$HOME/.local/bin/uvx" ] || command -v uvx &> /dev/null; then
73
+ echo "โœ… uvx command available"
74
+ return 0
75
+ else
76
+ echo "โš ๏ธ uvx command not found after uv installation"
77
+ return 1
78
+ fi
79
+ else
80
+ echo "โŒ Failed to install uv"
81
+ return 1
82
+ fi
83
+ }
84
+
85
+ # Function to clean up existing MCP servers
86
+ cleanup_mcp_servers() {
87
+ echo "๐Ÿงน Cleaning up existing MCP server configurations..."
88
+
89
+ # Get list of existing servers
90
+ local existing_servers=$(claude mcp list 2>/dev/null | grep -E "^(serena|deepwiki|tavily-search|ref-tools|taskmaster-ai|sequential-thinking):" | cut -d: -f1 || true)
91
+
92
+ if [ -n "$existing_servers" ]; then
93
+ echo "$existing_servers" | while read -r server; do
94
+ if [ -n "$server" ]; then
95
+ echo " Removing $server..."
96
+ claude mcp remove "$server" 2>/dev/null || true
97
+ fi
98
+ done
99
+ echo "โœ… Cleanup complete"
100
+ else
101
+ echo "โœ… No existing servers to clean up"
102
+ fi
103
+ }
104
+
105
+ # Function to install MCP servers
106
+ install_mcp_servers() {
107
+ echo "๐Ÿ“ฆ Installing core MCP servers..."
108
+
109
+ local servers_installed=0
110
+ local servers_failed=0
111
+
112
+ # Install Serena MCP server
113
+ echo ""
114
+ echo "๐Ÿ”ง Installing Serena MCP server..."
115
+ if retry_command 2 3 claude mcp add serena -- uvx --from git+https://github.com/oraios/serena serena start-mcp-server --context ide-assistant --project /workspace --enable-web-dashboard false; then
116
+ echo "โœ… Serena MCP server installed"
117
+ ((servers_installed++))
118
+ else
119
+ echo "โš ๏ธ Serena MCP server installation failed"
120
+ ((servers_failed++))
121
+ fi
122
+
123
+ # Install DeepWiki HTTP MCP server
124
+ echo ""
125
+ echo "๐Ÿ”ง Installing DeepWiki MCP server..."
126
+ if retry_command 2 3 claude mcp add --transport http deepwiki https://mcp.deepwiki.com/mcp; then
127
+ echo "โœ… DeepWiki MCP server installed"
128
+ ((servers_installed++))
129
+ else
130
+ echo "โš ๏ธ DeepWiki MCP server installation failed"
131
+ ((servers_failed++))
132
+ fi
133
+
134
+ # Install Tavily Search MCP server (if API key provided)
135
+ if [ -n "$TAVILY_API_KEY" ]; then
136
+ echo ""
137
+ echo "๐Ÿ”ง Installing Tavily Search MCP server..."
138
+ if retry_command 2 3 claude mcp add --transport http tavily-search "https://mcp.tavily.com/mcp/?tavilyApiKey=$TAVILY_API_KEY"; then
139
+ echo "โœ… Tavily Search MCP server installed"
140
+ ((servers_installed++))
141
+ else
142
+ echo "โš ๏ธ Tavily Search MCP server installation failed"
143
+ ((servers_failed++))
144
+ fi
145
+ else
146
+ echo ""
147
+ echo "โ„น๏ธ Skipping Tavily Search MCP server (no TAVILY_API_KEY set)"
148
+ fi
149
+
150
+ # Install Ref.Tools MCP server (if API key provided)
151
+ if [ -n "$REF_TOOLS_API_KEY" ]; then
152
+ echo ""
153
+ echo "๐Ÿ”ง Installing Ref.Tools MCP server..."
154
+ if retry_command 2 3 claude mcp add --transport http ref-tools "https://api.ref.tools/mcp?apiKey=$REF_TOOLS_API_KEY"; then
155
+ echo "โœ… Ref.Tools MCP server installed"
156
+ ((servers_installed++))
157
+ else
158
+ echo "โš ๏ธ Ref.Tools MCP server installation failed"
159
+ ((servers_failed++))
160
+ fi
161
+ else
162
+ echo ""
163
+ echo "โ„น๏ธ Skipping Ref.Tools MCP server (no REF_TOOLS_API_KEY set)"
164
+ fi
165
+
166
+ # Install Task Master MCP server (no API key required for Claude Code)
167
+ echo ""
168
+ echo "๐Ÿ”ง Installing Task Master MCP server..."
169
+ if retry_command 2 3 claude mcp add taskmaster-ai -- npx -y --package=task-master-ai task-master-ai; then
170
+ echo "โœ… Task Master MCP server installed"
171
+ ((servers_installed++))
172
+ else
173
+ echo "โš ๏ธ Task Master MCP server installation failed"
174
+ ((servers_failed++))
175
+ fi
176
+
177
+ # Install Sequential Thinking MCP server (no API key required)
178
+ echo ""
179
+ echo "๐Ÿ”ง Installing Sequential Thinking MCP server..."
180
+ if retry_command 2 3 claude mcp add sequential-thinking -- uvx --from git+https://github.com/arben-adm/mcp-sequential-thinking.git --with portalocker mcp-sequential-thinking; then
181
+ echo "โœ… Sequential Thinking MCP server installed"
182
+ ((servers_installed++))
183
+ else
184
+ echo "โš ๏ธ Sequential Thinking MCP server installation failed"
185
+ ((servers_failed++))
186
+ fi
187
+
188
+ # Install ccusage MCP server (no API key required)
189
+ echo ""
190
+ echo "๐Ÿ”ง Installing ccusage MCP server..."
191
+ if retry_command 2 3 claude mcp add ccusage -- ccusage mcp; then
192
+ echo "โœ… ccusage MCP server installed"
193
+ ((servers_installed++))
194
+ else
195
+ echo "โš ๏ธ ccusage MCP server installation failed"
196
+ ((servers_failed++))
197
+ fi
198
+
199
+ # Install GitHub MCP server (if GitHub PAT is provided and Docker is available)
200
+ if [ -n "$GITHUB_PERSONAL_ACCESS_TOKEN" ] && command -v docker &> /dev/null; then
201
+ echo ""
202
+ echo "๐Ÿ”ง Installing GitHub MCP server..."
203
+ # Pull the Docker image first to ensure it's available
204
+ if docker pull ghcr.io/github/github-mcp-server:latest; then
205
+ # Install using the complete Docker command
206
+ if retry_command 2 3 claude mcp add github -- docker run --rm -i \
207
+ -e GITHUB_PERSONAL_ACCESS_TOKEN="$GITHUB_PERSONAL_ACCESS_TOKEN" \
208
+ ${GITHUB_API_URL:+-e GITHUB_API_URL="$GITHUB_API_URL"} \
209
+ ${GITHUB_TOOLSET:+-e GITHUB_TOOLSET="$GITHUB_TOOLSET"} \
210
+ ghcr.io/github/github-mcp-server:latest; then
211
+ echo "โœ… GitHub MCP server installed"
212
+ ((servers_installed++))
213
+ else
214
+ echo "โš ๏ธ GitHub MCP server installation failed"
215
+ ((servers_failed++))
216
+ fi
217
+ else
218
+ echo "โš ๏ธ Failed to pull GitHub MCP server Docker image"
219
+ ((servers_failed++))
220
+ fi
221
+ else
222
+ echo ""
223
+ if [ -z "$GITHUB_PERSONAL_ACCESS_TOKEN" ]; then
224
+ echo "โ„น๏ธ Skipping GitHub MCP server (no GITHUB_PERSONAL_ACCESS_TOKEN set)"
225
+ elif ! command -v docker &> /dev/null; then
226
+ echo "โ„น๏ธ Skipping GitHub MCP server (Docker not available)"
227
+ fi
228
+ fi
229
+
230
+ echo ""
231
+ echo "โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•"
232
+ echo "๐Ÿ“Š MCP Server Installation Summary:"
233
+ echo " โœ… Installed: $servers_installed servers"
234
+ echo " โš ๏ธ Failed: $servers_failed servers"
235
+ echo "โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•"
236
+
237
+ # Return success if we have any servers installed
238
+ [ $servers_installed -gt 0 ]
239
+ }
240
+
241
+ # Function to display completion message
242
+ display_completion_message() {
243
+ echo ""
244
+ echo "โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•"
245
+ echo "โœ… ClaudePod Phase 3 MCP setup complete!"
246
+ echo "โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•"
247
+ echo ""
248
+ echo "๐Ÿ“‹ Available MCP servers:"
249
+ claude mcp list 2>/dev/null || echo " Run 'claude mcp list' to see installed servers"
250
+ echo ""
251
+ echo "๐Ÿ’ก Tips:"
252
+ echo " - Use 'claude' to start working with MCP servers"
253
+ echo " - Add API keys to enable additional servers"
254
+ echo " - Check 'claude mcp list' to verify installations"
255
+ echo "โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•"
256
+ }
257
+
258
+ # Main execution
259
+ main() {
260
+ echo "โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•"
261
+ echo "๐Ÿณ ClaudePod Post-Start Setup - Phase 3: MCP Servers"
262
+ echo "โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•"
263
+
264
+ # Create .claude directory and settings.json
265
+ echo "๐Ÿ”ง Configuring Claude Code settings..."
266
+ mkdir -p /workspace/.claude
267
+ cat > /workspace/.claude/settings.json << 'EOF'
268
+ {
269
+ "includeCoAuthoredBy": false,
270
+ "model": "claude-sonnet-4-0",
271
+ "forceLoginMethod": "claudeai"
272
+ }
273
+ EOF
274
+ echo "โœ… Claude Code settings configured"
275
+
276
+ # Source .env file if it exists
277
+ if [ -f "/workspace/.env" ]; then
278
+ echo "๐Ÿ”ง Loading environment variables from .env file..."
279
+ set -a # automatically export all variables
280
+ source /workspace/.env
281
+ set +a # disable automatic export
282
+ echo "โœ… Environment variables loaded"
283
+ fi
284
+
285
+ # Fix NVM permissions and conflicts
286
+ echo "๐Ÿ”ง Resolving NVM configuration conflicts..."
287
+
288
+ # Remove the problematic NVM current symlink if it exists (requires sudo)
289
+ if [ -L "/usr/local/share/nvm/current" ]; then
290
+ sudo rm -f "/usr/local/share/nvm/current" 2>/dev/null || true
291
+ fi
292
+
293
+ # Temporarily rename .npmrc to avoid NVM conflicts during sourcing
294
+ if [ -f "/home/node/.npmrc" ]; then
295
+ mv "/home/node/.npmrc" "/home/node/.npmrc.bak"
296
+ fi
297
+
298
+ # Source NVM without conflicts
299
+ export NVM_DIR="/usr/local/share/nvm"
300
+ [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
301
+
302
+ # Restore .npmrc after NVM is sourced
303
+ if [ -f "/home/node/.npmrc.bak" ]; then
304
+ mv "/home/node/.npmrc.bak" "/home/node/.npmrc"
305
+ fi
306
+
307
+ # Set PATH and HOME for proper Claude Code operation
308
+ export PATH="/home/node/.local/bin:$PATH"
309
+ export HOME="/home/node"
310
+
311
+ # Ensure proper ownership of .local directory
312
+ chown -R node:node /home/node/.local 2>/dev/null || true
313
+
314
+ # Check if Claude is available with detailed debugging
315
+ echo "๐Ÿ” Checking Claude Code availability..."
316
+ echo " PATH: $PATH"
317
+ echo " Current user: $(whoami)"
318
+ echo " Home directory: $HOME"
319
+
320
+ if command -v claude &> /dev/null; then
321
+ echo "โœ… Claude Code found in PATH: $(which claude)"
322
+ elif [ -f "/home/node/.local/bin/claude" ]; then
323
+ echo "โœ… Claude Code found at: /home/node/.local/bin/claude"
324
+ # Ensure it's executable
325
+ chmod +x /home/node/.local/bin/claude
326
+ else
327
+ echo "โŒ Claude Code not found. Checking installation..."
328
+ echo " Contents of /home/node/.local/bin/:"
329
+ ls -la /home/node/.local/bin/ 2>/dev/null || echo " Directory not found"
330
+ echo " Searching for claude binary:"
331
+ find /home/node/.local -name "claude*" -type f 2>/dev/null || echo " No claude binary found"
332
+ echo ""
333
+ echo " Please ensure Phase 2 (post-create) completed successfully."
334
+ echo " You can manually install Claude Code with:"
335
+ echo " npm install -g @anthropic-ai/claude-code"
336
+ exit 1
337
+ fi
338
+
339
+ echo "โœ… Claude Code is available"
340
+
341
+ # Test Claude MCP functionality
342
+ echo "๐Ÿงช Testing Claude MCP functionality..."
343
+ if claude mcp list &>/dev/null; then
344
+ echo "โœ… Claude MCP commands working"
345
+ else
346
+ echo "โš ๏ธ Claude MCP commands may not be fully initialized"
347
+ echo " This is normal for first run - continuing with installation..."
348
+ fi
349
+
350
+ echo "โœ… NVM configuration resolved"
351
+
352
+ # Install uv (for future MCP servers that might need it)
353
+ install_uv || echo "โš ๏ธ Continuing without uv/uvx..."
354
+
355
+ # Clean up any existing MCP server configurations
356
+ cleanup_mcp_servers
357
+
358
+ # Install MCP servers fresh
359
+ if install_mcp_servers; then
360
+ display_completion_message
361
+ exit 0
362
+ else
363
+ echo "โš ๏ธ No MCP servers were installed."
364
+ echo " You can try installing them manually later."
365
+ exit 0
366
+ fi
367
+ }
368
+
369
+ # Execute main function
370
+ main