claudepod 1.0.2 โ†’ 1.1.1

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.
@@ -8,26 +8,8 @@ echo "๐Ÿš€ Starting ClaudePod MCP server setup..."
8
8
 
9
9
  # Initial NVM setup will be handled in main() to avoid conflicts
10
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
- }
11
+ # Source shared utility functions
12
+ source "/workspace/.devcontainer/scripts/utils.sh"
31
13
 
32
14
  # Function to install uv via pipx
33
15
  install_uv() {
@@ -82,177 +64,284 @@ install_uv() {
82
64
  fi
83
65
  }
84
66
 
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"
67
+ # Function to validate MCP configuration
68
+ validate_mcp_configuration() {
69
+ echo "๐Ÿ” Validating MCP configuration..."
70
+
71
+ local mcp_config="/workspace/.devcontainer/config/claude/mcp.json"
72
+
73
+ # Check if file exists
74
+ if [ ! -f "$mcp_config" ]; then
75
+ echo "โš ๏ธ MCP configuration file not found at $mcp_config"
76
+ return 1
102
77
  fi
103
- }
104
-
105
- # Function to install MCP servers
106
- install_mcp_servers() {
107
- echo "๐Ÿ“ฆ Installing core MCP servers..."
108
78
 
109
- local servers_installed=0
110
- local servers_failed=0
79
+ # Basic JSON validation
80
+ if ! node -e "JSON.parse(require('fs').readFileSync('$mcp_config', 'utf8'))" 2>/dev/null; then
81
+ echo "โŒ MCP configuration is not valid JSON"
82
+ # Restore from backup if available
83
+ if [ -f "${mcp_config}.backup" ]; then
84
+ echo "๐Ÿ“ฆ Restoring from backup..."
85
+ cp "${mcp_config}.backup" "$mcp_config"
86
+ fi
87
+ return 1
88
+ fi
111
89
 
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++))
90
+ # Test if Claude can read the configuration (if Claude is available)
91
+ if command -v claude &> /dev/null; then
92
+ echo "๐Ÿงช Testing Claude MCP integration..."
93
+ if timeout 10 claude --mcp-config "$mcp_config" --print "test" &>/dev/null; then
94
+ echo "โœ… Claude MCP configuration valid"
95
+ else
96
+ echo "โš ๏ธ Claude cannot load MCP configuration (authentication may be needed)"
97
+ fi
121
98
  fi
122
99
 
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++))
100
+ echo "โœ… MCP configuration validation completed"
101
+ return 0
102
+ }
103
+
104
+ # Function to verify MCP configuration
105
+ verify_mcp_config() {
106
+ echo "๐Ÿ“ฆ Verifying MCP server configuration..."
107
+
108
+ # Check if MCP configuration file exists
109
+ local mcp_config="/workspace/.claude/mcp.json"
110
+ if [ ! -f "$mcp_config" ]; then
111
+ echo "โš ๏ธ MCP configuration file not found at $mcp_config"
112
+ echo " This should have been copied during post-create phase"
113
+ return 1
132
114
  fi
133
115
 
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++))
116
+ echo "โœ… MCP configuration file found"
117
+
118
+ # Verify Docker is available for GitHub MCP server
119
+ if [ -n "$GITHUB_PERSONAL_ACCESS_TOKEN" ] && command -v docker &> /dev/null; then
120
+ echo "๐Ÿณ Pre-pulling GitHub MCP server Docker image..."
121
+ if docker pull ghcr.io/github/github-mcp-server:latest; then
122
+ echo "โœ… GitHub MCP server image ready"
141
123
  else
142
- echo "โš ๏ธ Tavily Search MCP server installation failed"
143
- ((servers_failed++))
124
+ echo "โš ๏ธ Failed to pull GitHub MCP server Docker image"
144
125
  fi
145
- else
146
- echo ""
147
- echo "โ„น๏ธ Skipping Tavily Search MCP server (no TAVILY_API_KEY set)"
148
126
  fi
149
127
 
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++))
128
+ # Verify and setup SearXNG MCP server files when enabled (including container rebuilds)
129
+ if [ "${ENABLE_SEARXNG_ENHANCED_MCP:-true}" = "true" ]; then
130
+ echo "๐Ÿ” Verifying SearXNG MCP server installation..."
131
+ local searxng_server="/usr/local/mcp-servers/searxng/mcp_server.py"
132
+ local searxng_config="/home/node/.claude/ods_config.json"
133
+ local config_template="/workspace/.devcontainer/config/searxng/ods_config.json"
134
+
135
+ if [ -f "$searxng_server" ]; then
136
+ echo "โœ… SearXNG MCP server files found"
137
+
138
+ # Handle configuration during container rebuilds with existence check
139
+ if [ -f "$searxng_config" ]; then
140
+ echo "โœ… SearXNG configuration file ready"
141
+ else
142
+ echo "๐Ÿ“‹ SearXNG configuration not found, copying from template..."
143
+
144
+ # Source searxng script to get setup functions
145
+ if [ -f "/workspace/.devcontainer/scripts/config/searxng.sh" ]; then
146
+ source "/workspace/.devcontainer/scripts/config/searxng.sh"
147
+
148
+ # Call configuration setup function
149
+ setup_searxng_config || {
150
+ echo "โš ๏ธ Failed to setup SearXNG configuration during container rebuild"
151
+ echo " You can manually copy with: cp $config_template $searxng_config"
152
+ }
153
+ else
154
+ echo "โš ๏ธ SearXNG setup script not found, performing basic copy..."
155
+
156
+ # Ensure Claude directory exists
157
+ mkdir -p "/home/node/.claude"
158
+
159
+ # Copy configuration file if template exists
160
+ if [ -f "$config_template" ]; then
161
+ cp "$config_template" "$searxng_config"
162
+ chown node:node "$searxng_config"
163
+ chmod 600 "$searxng_config"
164
+ echo "๐Ÿ“‹ SearXNG configuration copied from template"
165
+ else
166
+ echo "โš ๏ธ SearXNG configuration template not found at $config_template"
167
+ fi
168
+ fi
169
+ fi
157
170
  else
158
- echo "โš ๏ธ Ref.Tools MCP server installation failed"
159
- ((servers_failed++))
171
+ echo "โŒ SearXNG MCP server not found at $searxng_server"
172
+ echo " Installation may have failed during post-create phase"
173
+ echo " Try running: bash /workspace/.devcontainer/scripts/config/searxng.sh"
160
174
  fi
161
- else
162
- echo ""
163
- echo "โ„น๏ธ Skipping Ref.Tools MCP server (no REF_TOOLS_API_KEY set)"
164
175
  fi
165
176
 
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++))
177
+ return 0
178
+ }
179
+
180
+ # Function to validate environment variables and provide feedback
181
+ validate_environment_variables() {
182
+ echo "๐Ÿ” Validating environment configuration..."
183
+
184
+ local missing_keys=()
185
+ local optional_keys=()
186
+
187
+ # Check optional API keys and track status
188
+ if [ "${ENABLE_TAVILY_MCP:-false}" = "true" ]; then
189
+ if [ -z "$TAVILY_API_KEY" ]; then
190
+ missing_keys+=("TAVILY_API_KEY")
191
+ fi
175
192
  fi
176
193
 
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++))
194
+ if [ "${ENABLE_REF_TOOLS_MCP:-false}" = "true" ]; then
195
+ if [ -z "$REF_TOOLS_API_KEY" ]; then
196
+ missing_keys+=("REF_TOOLS_API_KEY")
197
+ fi
186
198
  fi
187
199
 
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++))
200
+ if [ "${ENABLE_GITHUB_MCP:-false}" = "true" ]; then
201
+ if [ -z "$GITHUB_PERSONAL_ACCESS_TOKEN" ]; then
202
+ missing_keys+=("GITHUB_PERSONAL_ACCESS_TOKEN")
203
+ fi
204
+ fi
205
+
206
+ # Report validation results
207
+ if [ ${#missing_keys[@]} -eq 0 ]; then
208
+ echo "โœ… All required environment variables configured"
194
209
  else
195
- echo "โš ๏ธ ccusage MCP server installation failed"
196
- ((servers_failed++))
210
+ echo "โš ๏ธ Missing API keys for enabled services:"
211
+ for key in "${missing_keys[@]}"; do
212
+ echo " โ€ข $key"
213
+ done
214
+ echo " ๐Ÿ“ Add missing keys to .devcontainer/.env or disable services"
197
215
  fi
216
+ }
217
+
218
+ # Function to display startup status summary
219
+ display_startup_status() {
220
+ echo ""
221
+ echo "โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—"
222
+ echo "โ•‘ ๐Ÿ“Š ClaudePod Status Summary โ•‘"
223
+ echo "โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•"
198
224
 
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++))
225
+ # Core tools status
226
+ echo ""
227
+ echo "๐Ÿ› ๏ธ Core Tools:"
228
+ local claude_version=$(claude --version 2>/dev/null || echo "Not available")
229
+ echo " Claude Code: $claude_version"
230
+
231
+ local ccusage_version=$(ccusage --version 2>/dev/null || echo "Not available")
232
+ echo " ccusage: $ccusage_version"
233
+
234
+ # Check Node.js with proper environment sourcing
235
+ local node_version="Not available"
236
+ if command -v node &>/dev/null; then
237
+ node_version=$(node --version 2>/dev/null || echo "Not available")
238
+ elif [ -s "/usr/local/share/nvm/nvm.sh" ]; then
239
+ # Try sourcing NVM if Node.js not found in PATH (permissions should now be fixed)
240
+ if source "/usr/local/share/nvm/nvm.sh"; then
241
+ if command -v node &>/dev/null; then
242
+ node_version=$(node --version 2>/dev/null || echo "Not available")
216
243
  fi
217
244
  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)"
245
+ node_version="NVM sourcing failed"
227
246
  fi
228
247
  fi
248
+ echo " Node.js: $node_version"
249
+
250
+ local uvx_status=$(command -v uvx &>/dev/null && echo "Available" || echo "Not available")
251
+ echo " uvx: $uvx_status"
229
252
 
253
+ # MCP servers status
254
+ echo ""
255
+ echo "๐Ÿ”Œ MCP Servers:"
256
+ local enabled_count=0
257
+ local disabled_count=0
258
+
259
+ # Core servers (enabled by default)
260
+ # for server in "serena:ENABLE_SERENA_MCP:semantic code analysis" \
261
+ # "deepwiki:ENABLE_DEEPWIKI_MCP:documentation search" \
262
+ # "taskmaster:ENABLE_TASKMASTER_MCP:project management" \
263
+ # "sequential-thinking:ENABLE_SEQUENTIAL_THINKING_MCP:structured analysis" \
264
+ # "ccusage:ENABLE_CCUSAGE_MCP:usage analytics"; do
265
+ # IFS=':' read -r name var desc <<< "$server"
266
+ # if [ "${!var:-true}" = "true" ]; then
267
+ # echo " โœ… $name ($desc)"
268
+ # ((enabled_count++))
269
+ # else
270
+ # echo " โŒ $name (disabled)"
271
+ # ((disabled_count++))
272
+ # fi
273
+ # done
274
+
275
+ # Optional servers (require API keys)
276
+ # for server in "tavily:ENABLE_TAVILY_MCP:TAVILY_API_KEY:web search" \
277
+ # "ref-tools:ENABLE_REF_TOOLS_MCP:REF_TOOLS_API_KEY:reference docs" \
278
+ # "github:ENABLE_GITHUB_MCP:GITHUB_PERSONAL_ACCESS_TOKEN:repository integration"; do
279
+ # IFS=':' read -r name var key desc <<< "$server"
280
+ # if [ "${!var:-false}" = "true" ] && [ -n "${!key}" ]; then
281
+ # echo " โœ… $name ($desc)"
282
+ # ((enabled_count++))
283
+ # elif [ "${!var:-false}" = "true" ]; then
284
+ # echo " โš ๏ธ $name (missing $key)"
285
+ # ((disabled_count++))
286
+ # else
287
+ # echo " โŒ $name (disabled)"
288
+ # ((disabled_count++))
289
+ # fi
290
+ # done
291
+
292
+ # Shell shortcuts
293
+ echo ""
294
+ echo "โŒจ๏ธ Shell Shortcuts:"
295
+ echo " gs (git status) gd (git diff) gc (git commit)"
296
+ echo " gp (git push) gl (git log) ll (list files)"
297
+
298
+ # Summary and next steps
299
+ echo ""
300
+ echo "๐Ÿ“ˆ Summary: $enabled_count servers enabled, $disabled_count disabled"
301
+ echo ""
302
+ echo "๐Ÿš€ Ready to start:"
303
+ echo " claude # Start Claude Code with MCP servers"
304
+ echo " claude mcp list # Verify MCP server connectivity"
305
+ echo " ccusage # View usage analytics"
306
+
307
+ # Add SearXNG info if it exists
308
+ local searxng_local_dir="${SEARXNG_LOCAL_INSTALL_DIR:-/opt/searxng-local}"
309
+ if [ "${ENABLE_SEARXNG_LOCAL:-true}" = "true" ] && [ -d "$searxng_local_dir" ] && [ -f "$searxng_local_dir/docker-compose.yaml" ]; then
310
+ echo ""
311
+ echo "๐Ÿ” Local SearXNG Instance:"
312
+ echo " http://localhost:8080 # SearXNG web interface"
313
+ echo " MCP server configured for zero rate limiting"
314
+ echo " Location: $searxng_local_dir (persistent volume)"
315
+ fi
230
316
  echo ""
231
317
  echo "โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•"
232
- echo "๐Ÿ“Š MCP Server Installation Summary:"
233
- echo " โœ… Installed: $servers_installed servers"
234
- echo " โš ๏ธ Failed: $servers_failed servers"
235
- echo "โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•"
318
+ }
319
+
320
+ # Function to start local SearXNG containers if configured
321
+ start_local_searxng() {
322
+ # Check if SearXNG local instance is enabled
323
+ if [ "${ENABLE_SEARXNG_LOCAL:-true}" != "true" ]; then
324
+ echo " โ„น๏ธ SearXNG local instance is disabled (using public instances)"
325
+ return 0
326
+ fi
327
+
328
+ # Source the searxng configuration functions
329
+ source "/workspace/.devcontainer/scripts/config/searxng.sh"
236
330
 
237
- # Return success if we have any servers installed
238
- [ $servers_installed -gt 0 ]
331
+ # Use the new function to start the persistent local instance
332
+ start_searxng_local_instance
239
333
  }
240
334
 
241
335
  # Function to display completion message
242
336
  display_completion_message() {
337
+ # Validate environment first
338
+ validate_environment_variables
339
+
243
340
  echo ""
244
- echo "โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•"
245
341
  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 "โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•"
342
+
343
+ # Display comprehensive startup status
344
+ display_startup_status
256
345
  }
257
346
 
258
347
  # Main execution
@@ -261,47 +350,97 @@ main() {
261
350
  echo "๐Ÿณ ClaudePod Post-Start Setup - Phase 3: MCP Servers"
262
351
  echo "โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•"
263
352
 
264
- # Create .claude directory and settings.json
353
+ # Ensure .claude directory exists and preserve optimized settings
265
354
  echo "๐Ÿ”ง Configuring Claude Code settings..."
266
355
  mkdir -p /workspace/.claude
267
- cat > /workspace/.claude/settings.json << 'EOF'
356
+
357
+ # Only create basic settings if optimized settings don't exist
358
+ if [ ! -f "/workspace/.claude/settings.json" ]; then
359
+ echo " Creating basic Claude settings..."
360
+ cat > /workspace/.claude/settings.json << 'EOF'
268
361
  {
269
362
  "includeCoAuthoredBy": false,
270
363
  "model": "claude-sonnet-4-0",
271
364
  "forceLoginMethod": "claudeai"
272
365
  }
273
366
  EOF
367
+ echo " โ„น๏ธ Basic settings created (optimized settings not found)"
368
+ else
369
+ # Check if settings contain the optimized permissions
370
+ if grep -q '"permissions"' "/workspace/.claude/settings.json" 2>/dev/null; then
371
+ local allowed_count=$(grep -o '"allow"' "/workspace/.claude/settings.json" | wc -l)
372
+ local denied_count=$(grep -o '"deny"' "/workspace/.claude/settings.json" | wc -l)
373
+ echo " โœ… Preserving optimized Claude settings (permissions configured)"
374
+ else
375
+ echo " โš ๏ธ Existing settings found but no optimized permissions detected"
376
+ fi
377
+ fi
378
+
274
379
  echo "โœ… Claude Code settings configured"
275
380
 
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"
381
+ # Ensure Serena configuration exists and preserve optimized settings
382
+ echo "๐Ÿ”ง Configuring Serena settings..."
383
+ mkdir -p /workspace/.serena
384
+
385
+ if [ ! -f "/workspace/.serena/serena_config.yml" ]; then
386
+ echo " โ„น๏ธ No existing Serena configuration found (will use defaults)"
387
+ else
388
+ echo " โœ… Preserving existing Serena configuration"
283
389
  fi
284
390
 
285
- # Fix NVM permissions and conflicts
286
- echo "๐Ÿ”ง Resolving NVM configuration conflicts..."
391
+ # Ensure TaskMaster configuration exists and preserve optimized settings
392
+ echo "๐Ÿ”ง Configuring TaskMaster settings..."
393
+ mkdir -p /workspace/.taskmaster
287
394
 
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
395
+ if [ ! -f "/workspace/.taskmaster/config.json" ]; then
396
+ echo " โ„น๏ธ No existing TaskMaster configuration found (will use defaults)"
397
+ else
398
+ # Check if settings contain the optimized model configuration
399
+ if grep -q '"claude-code"' "/workspace/.taskmaster/config.json" 2>/dev/null; then
400
+ echo " โœ… Preserving optimized TaskMaster configuration (Claude Code integration)"
401
+ else
402
+ echo " โš ๏ธ Existing TaskMaster configuration found but no Claude Code integration detected"
403
+ fi
291
404
  fi
292
405
 
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
406
+ echo "โœ… MCP configurations ready"
297
407
 
298
- # Source NVM without conflicts
299
- export NVM_DIR="/usr/local/share/nvm"
300
- [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
408
+ # Environment variables already loaded in post-create.sh
409
+ # Set environment for proper Node.js and Claude Code operation
410
+ echo "๐Ÿ”ง Configuring Node.js environment..."
301
411
 
302
- # Restore .npmrc after NVM is sourced
303
- if [ -f "/home/node/.npmrc.bak" ]; then
304
- mv "/home/node/.npmrc.bak" "/home/node/.npmrc"
412
+ # Source NVM to make Node.js and npm available (needed for MCP config generation)
413
+ export NVM_DIR="/usr/local/share/nvm"
414
+ if [ -s "$NVM_DIR/nvm.sh" ]; then
415
+ echo "๐Ÿ”ง Sourcing NVM in post-start..."
416
+ . "$NVM_DIR/nvm.sh"
417
+
418
+ # Handle potential npm prefix conflicts with NVM
419
+ if command -v nvm &> /dev/null && command -v node &> /dev/null; then
420
+ echo "๐Ÿ”ง Checking NVM/npm prefix conflicts..."
421
+ # Only run nvm use if there's actually a prefix conflict, not just because Node.js exists
422
+ local current_prefix=$(npm config get prefix 2>/dev/null || echo "")
423
+ local expected_prefix="/home/node/.local"
424
+
425
+ if [ -n "$current_prefix" ] && [ "$current_prefix" != "$expected_prefix" ]; then
426
+ echo "๐Ÿ”ง Resolving npm prefix conflict by removing conflicting settings"
427
+ # Remove prefix settings that conflict with NVM instead of setting them
428
+ npm config delete prefix 2>/dev/null || true
429
+ npm config delete globalconfig 2>/dev/null || true
430
+ echo "โœ… Removed conflicting npm prefix settings for NVM compatibility"
431
+ else
432
+ echo "โœ… NVM/npm prefix already correct"
433
+ fi
434
+ fi
435
+
436
+ # Verify Node.js is now available
437
+ if command -v node &> /dev/null; then
438
+ echo "โœ… Node.js available for MCP generation: $(node --version)"
439
+ else
440
+ echo "โš ๏ธ Node.js still not available after sourcing NVM"
441
+ fi
442
+ else
443
+ echo "โš ๏ธ NVM not found at $NVM_DIR/nvm.sh"
305
444
  fi
306
445
 
307
446
  # Set PATH and HOME for proper Claude Code operation
@@ -311,6 +450,46 @@ EOF
311
450
  # Ensure proper ownership of .local directory
312
451
  chown -R node:node /home/node/.local 2>/dev/null || true
313
452
 
453
+ # CRITICAL: Re-load environment variables from .devcontainer/.env
454
+ # Why this is needed AGAIN after post-create.sh:
455
+ # - Environment variables set in post-create.sh are only available during that shell session
456
+ # - Container restarts/rebuilds lose those environment variables since they're not persisted
457
+ # - MCP config generation happens during post-start phase and requires API keys from .env
458
+ # - Without this re-loading, MCP servers requiring API keys will be disabled due to missing env vars
459
+ if [ -f "/workspace/.devcontainer/.env" ]; then
460
+ echo "๐Ÿ“‹ Re-loading environment variables from .devcontainer/.env (required after container rebuild)"
461
+ set -a # Export all variables
462
+ source "/workspace/.devcontainer/.env"
463
+ set +a # Stop exporting
464
+ echo "โœ… Environment variables reloaded for MCP server configuration"
465
+ else
466
+ echo "โš ๏ธ .devcontainer/.env file not found - MCP servers requiring API keys will be disabled"
467
+ fi
468
+
469
+ # Generate MCP configuration from template
470
+ echo "๐Ÿ”ง Generating MCP configuration from template..."
471
+ if [ -f "/workspace/.devcontainer/config/claude/mcp.json.template" ]; then
472
+ # Use Node.js to generate configuration with environment loaded
473
+ if command -v node &> /dev/null; then
474
+ # Ensure script is executable and run with explicit node
475
+ # Note: The script now uses dotenv to load environment variables directly
476
+ chmod +x /workspace/.devcontainer/scripts/generate-mcp-config.js
477
+ if node /workspace/.devcontainer/scripts/generate-mcp-config.js; then
478
+ echo "โœ… MCP configuration generated successfully"
479
+ # Validate generated configuration
480
+ validate_mcp_configuration
481
+ else
482
+ echo "โš ๏ธ Failed to generate MCP configuration from template"
483
+ echo " Fallback: using existing mcp.json if available"
484
+ fi
485
+ else
486
+ echo "โš ๏ธ Node.js not available - cannot generate MCP configuration"
487
+ echo " Using existing mcp.json configuration"
488
+ fi
489
+ else
490
+ echo "โ„น๏ธ No MCP template found - using existing configuration"
491
+ fi
492
+
314
493
  # Check if Claude is available with detailed debugging
315
494
  echo "๐Ÿ” Checking Claude Code availability..."
316
495
  echo " PATH: $PATH"
@@ -347,24 +526,26 @@ EOF
347
526
  echo " This is normal for first run - continuing with installation..."
348
527
  fi
349
528
 
350
- echo "โœ… NVM configuration resolved"
529
+ echo "โœ… Node.js environment configured"
351
530
 
352
531
  # Install uv (for future MCP servers that might need it)
353
532
  install_uv || echo "โš ๏ธ Continuing without uv/uvx..."
354
533
 
355
- # Clean up any existing MCP server configurations
356
- cleanup_mcp_servers
534
+ # Start SearXNG containers if configured for local instance
535
+ echo "๐Ÿ” Checking SearXNG container setup..."
536
+ start_local_searxng
357
537
 
358
- # Install MCP servers fresh
359
- if install_mcp_servers; then
538
+ # Verify MCP configuration instead of installing servers
539
+ if verify_mcp_config; then
360
540
  display_completion_message
361
541
  exit 0
362
542
  else
363
- echo "โš ๏ธ No MCP servers were installed."
364
- echo " You can try installing them manually later."
543
+ echo "โš ๏ธ MCP configuration verification failed."
544
+ echo " MCP servers are configured via mcp.json file."
545
+ echo " Check that the file was copied correctly during post-create phase."
365
546
  exit 0
366
547
  fi
367
548
  }
368
549
 
369
550
  # Execute main function
370
- main
551
+ main