diff --git a/.gitignore b/.gitignore
index fbeaa6d47d..bc0c047453 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,3 +3,4 @@ __pycache__
.serena
.claude/settings.local.json
PRPs/local
+/logs/
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000000..1c18b5addb
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,99 @@
+# Archon Makefile - Simple, Secure, Cross-Platform
+SHELL := /bin/bash
+.SHELLFLAGS := -ec
+
+.PHONY: help dev dev-docker stop test test-fe test-be lint lint-fe lint-be clean install check
+
+help:
+ @echo "Archon Development Commands"
+ @echo "==========================="
+ @echo " make dev - Backend in Docker, frontend local (recommended)"
+ @echo " make dev-docker - Everything in Docker"
+ @echo " make stop - Stop all services"
+ @echo " make test - Run all tests"
+ @echo " make test-fe - Run frontend tests only"
+ @echo " make test-be - Run backend tests only"
+ @echo " make lint - Run all linters"
+ @echo " make lint-fe - Run frontend linter only"
+ @echo " make lint-be - Run backend linter only"
+ @echo " make clean - Remove containers and volumes"
+ @echo " make install - Install dependencies"
+ @echo " make check - Check environment setup"
+
+# Install dependencies
+install:
+ @echo "Installing dependencies..."
+ @cd archon-ui-main && npm install
+ @cd python && uv sync
+ @echo "✓ Dependencies installed"
+
+# Check environment
+check:
+ @echo "Checking environment..."
+ @node check-env.js
+ @echo "Checking Docker..."
+ @docker --version > /dev/null 2>&1 && echo "✓ Docker installed" || echo "✗ Docker not found"
+ @docker-compose --version > /dev/null 2>&1 && echo "✓ Docker Compose installed" || echo "✗ Docker Compose not found"
+
+# Hybrid development (recommended)
+dev: check
+ @echo "Starting hybrid development..."
+ @echo "Backend: Docker | Frontend: Local with hot reload"
+ @docker-compose --profile backend up -d --build
+ @echo "Backend running at http://localhost:8181"
+ @echo "Starting frontend..."
+ @cd archon-ui-main && npm run dev
+
+# Full Docker development
+dev-docker: check
+ @echo "Starting full Docker environment..."
+ @docker-compose --profile full up -d --build
+ @echo "✓ All services running"
+ @echo "Frontend: http://localhost:3737"
+ @echo "API: http://localhost:8181"
+
+# Stop all services
+stop:
+ @echo "Stopping all services..."
+ @docker-compose --profile backend --profile frontend --profile full down
+ @echo "✓ Services stopped"
+
+# Run all tests
+test: test-fe test-be
+
+# Run frontend tests
+test-fe:
+ @echo "Running frontend tests..."
+ @cd archon-ui-main && npm test
+
+# Run backend tests
+test-be:
+ @echo "Running backend tests..."
+ @cd python && uv run pytest
+
+# Run all linters
+lint: lint-fe lint-be
+
+# Run frontend linter
+lint-fe:
+ @echo "Linting frontend..."
+ @cd archon-ui-main && npm run lint
+
+# Run backend linter
+lint-be:
+ @echo "Linting backend..."
+ @cd python && uv run ruff check --fix
+
+# Clean everything (with confirmation)
+clean:
+ @echo "⚠️ This will remove all containers and volumes"
+ @read -p "Are you sure? (y/N) " -n 1 -r; \
+ echo; \
+ if [[ $$REPLY =~ ^[Yy]$$ ]]; then \
+ docker-compose down -v --remove-orphans; \
+ echo "✓ Cleaned"; \
+ else \
+ echo "Cancelled"; \
+ fi
+
+.DEFAULT_GOAL := help
\ No newline at end of file
diff --git a/README.md b/README.md
index 6f9efa9e30..e18f3df701 100644
--- a/README.md
+++ b/README.md
@@ -43,8 +43,10 @@ This new vision for Archon replaces the old one (the agenteer). Archon used to b
### Prerequisites
- [Docker Desktop](https://www.docker.com/products/docker-desktop/)
+- [Node.js 18+](https://nodejs.org/) (for hybrid development mode)
- [Supabase](https://supabase.com/) account (free tier or local Supabase both work)
- [OpenAI API key](https://platform.openai.com/api-keys) (Gemini and Ollama are supported too!)
+- [Make](https://www.gnu.org/software/make/) (see [Installing Make](#installing-make) below)
### Setup Instructions
@@ -70,13 +72,17 @@ This new vision for Archon replaces the old one (the agenteer). Archon used to b
3. **Database Setup**: In your [Supabase project](https://supabase.com/dashboard) SQL Editor, copy, paste, and execute the contents of `migration/complete_setup.sql`
-4. **Start Services**:
+4. **Start Services** (choose one):
+
+ **Full Docker Mode (Recommended for Normal Archon Usage)**
```bash
- docker-compose up --build -d
+ docker-compose --profile full up --build -d
+ # or
+ make dev-docker
```
- This starts the core microservices:
+ This starts all core microservices in Docker:
- **Server**: Core API and business logic (Port: 8181)
- **MCP Server**: Protocol interface for AI clients (Port: 8051)
- **Agents (coming soon!)**: AI operations and streaming (Port: 8052)
@@ -89,6 +95,19 @@ This new vision for Archon replaces the old one (the agenteer). Archon used to b
- Go to **Settings** → Select your LLM/embedding provider and set the API key (OpenAI is default)
- Test by uploading a document or crawling a website
+### 🚀 Quick Command Reference
+
+| Command | Description |
+| ----------------- | ------------------------------------------------------- |
+| `make dev` | Start hybrid dev (backend in Docker, frontend local) ⭐ |
+| `make dev-docker` | Everything in Docker |
+| `make stop` | Stop all services |
+| `make test` | Run all tests |
+| `make lint` | Run linters |
+| `make install` | Install dependencies |
+| `make check` | Check environment setup |
+| `make clean` | Remove containers and volumes (with confirmation) |
+
## 🔄 Database Reset (Start Fresh if Needed)
If you need to completely reset your database and start fresh:
@@ -105,7 +124,7 @@ If you need to completely reset your database and start fresh:
3. **Restart Services**:
```bash
- docker-compose up -d
+ docker-compose --profile full up -d
```
4. **Reconfigure**:
@@ -116,6 +135,41 @@ The reset script safely removes all tables, functions, triggers, and policies wi
+## 🛠️ Installing Make
+
+Make is required for the development workflow. Installation varies by platform:
+
+### Windows
+
+```bash
+# Option 1: Using Chocolatey
+choco install make
+
+# Option 2: Using Scoop
+scoop install make
+
+# Option 3: Using WSL2
+wsl --install
+# Then in WSL: sudo apt-get install make
+```
+
+### macOS
+
+```bash
+# Make comes pre-installed on macOS
+# If needed: brew install make
+```
+
+### Linux
+
+```bash
+# Debian/Ubuntu
+sudo apt-get install make
+
+# RHEL/CentOS/Fedora
+sudo yum install make
+```
+
## ⚡ Quick Test
Once everything is running:
@@ -221,11 +275,11 @@ Archon uses true microservices architecture with clear separation of concerns:
By default, Archon services run on the following ports:
-- **Archon-UI**: 3737
-- **Archon-Server**: 8181
-- **Archon-MCP**: 8051
-- **Archon-Agents**: 8052
-- **Archon-Docs**: 3838 (optional)
+- **archon-ui**: 3737
+- **archon-server**: 8181
+- **archon-mcp**: 8051
+- **archon-agents**: 8052
+- **archon-docs**: 3838 (optional)
### Changing Ports
@@ -269,27 +323,136 @@ This is useful when:
After changing hostname or ports:
-1. Restart Docker containers: `docker-compose down && docker-compose up -d`
+1. Restart Docker containers: `docker-compose down && docker-compose --profile full up -d`
2. Access the UI at: `http://${HOST}:${ARCHON_UI_PORT}`
3. Update your AI client configuration with the new hostname and MCP port
## 🔧 Development
-For development with hot reload:
+### Quick Start
+
+```bash
+# Install dependencies
+make install
+
+# Start development (recommended)
+make dev # Backend in Docker, frontend local with hot reload
+
+# Alternative: Everything in Docker
+make dev-docker # All services in Docker
+
+# Stop everything (local FE needs to be stopped manually)
+make stop
+```
+
+### Development Modes
+
+#### Hybrid Mode (Recommended) - `make dev`
+
+Best for active development with instant frontend updates:
+
+- Backend services run in Docker (isolated, consistent)
+- Frontend runs locally with hot module replacement
+- Instant UI updates without Docker rebuilds
+
+#### Full Docker Mode - `make dev-docker`
+
+For all services in Docker environment:
+
+- All services run in Docker containers
+- Better for integration testing
+- Slower frontend updates
+
+### Testing & Code Quality
```bash
-# Backend services (with auto-reload)
-docker-compose up archon-server archon-mcp archon-agents --build
+# Run tests
+make test # Run all tests
+
+# Run linters
+make lint # Lint all code
-# Frontend (with hot reload)
-cd archon-ui-main && npm run dev
+# Check environment
+make check # Verify environment setup
-# Documentation (with hot reload)
-cd docs && npm start
+# Clean up
+make clean # Remove containers and volumes (asks for confirmation)
+```
+
+### Viewing Logs
+
+```bash
+# View logs using Docker Compose directly
+docker-compose logs -f # All services
+docker-compose logs -f archon-server # API server
+docker-compose logs -f archon-mcp # MCP server
+docker-compose logs -f archon-ui # Frontend
```
**Note**: The backend services are configured with `--reload` flag in their uvicorn commands and have source code mounted as volumes for automatic hot reloading when you make changes.
+## 🔍 Troubleshooting
+
+### Common Issues and Solutions
+
+#### Port Conflicts
+
+If you see "Port already in use" errors:
+
+```bash
+# Check what's using a port (e.g., 3737)
+lsof -i :3737
+
+# Stop all containers and local services
+make stop
+
+# Change the port in .env
+```
+
+#### Docker Permission Issues (Linux)
+
+If you encounter permission errors with Docker:
+
+```bash
+# Add your user to the docker group
+sudo usermod -aG docker $USER
+
+# Log out and back in, or run
+newgrp docker
+```
+
+#### Windows-Specific Issues
+
+- **Make not found**: Install Make via Chocolatey, Scoop, or WSL2 (see [Installing Make](#installing-make))
+- **Line ending issues**: Configure Git to use LF endings:
+ ```bash
+ git config --global core.autocrlf false
+ ```
+
+#### Frontend Can't Connect to Backend
+
+- Check backend is running: `curl http://localhost:8181/health`
+- Verify port configuration in `.env`
+- For custom ports, ensure both `ARCHON_SERVER_PORT` and `VITE_ARCHON_SERVER_PORT` are set
+
+#### Docker Compose Hangs
+
+If `docker-compose` commands hang:
+
+```bash
+# Reset Docker Compose
+docker-compose down --remove-orphans
+docker system prune -f
+
+# Restart Docker Desktop (if applicable)
+```
+
+#### Hot Reload Not Working
+
+- **Frontend**: Ensure you're running in hybrid mode (`make dev`) for best HMR experience
+- **Backend**: Check that volumes are mounted correctly in `docker-compose.yml`
+- **File permissions**: On some systems, mounted volumes may have permission issues
+
## 📈 Progress
diff --git a/archon-ui-main/Dockerfile b/archon-ui-main/Dockerfile
index 2ad5d5ff0f..2a1efe8224 100644
--- a/archon-ui-main/Dockerfile
+++ b/archon-ui-main/Dockerfile
@@ -18,8 +18,8 @@ RUN mkdir -p /app/coverage && chmod 777 /app/coverage
# Copy source code
COPY . .
-# Expose Vite's default port
-EXPOSE 5173
+# Expose the port configured in package.json (3737)
+EXPOSE 3737
-# Start Vite dev server with host binding for Docker
-CMD ["npm", "run", "dev", "--", "--host", "0.0.0.0"]
+# Start Vite dev server (already configured with --port 3737 --host in package.json)
+CMD ["npm", "run", "dev"]
diff --git a/archon-ui-main/src/components/BackendStartupError.tsx b/archon-ui-main/src/components/BackendStartupError.tsx
index a7a1e78241..8d6447eae2 100644
--- a/archon-ui-main/src/components/BackendStartupError.tsx
+++ b/archon-ui-main/src/components/BackendStartupError.tsx
@@ -28,12 +28,12 @@ export const BackendStartupError: React.FC = () => {
Check Docker Logs
- Check the Archon-Server logs in Docker Desktop for detailed error information.
+ Check the Archon API server container logs in Docker Desktop for detailed error information.
1. Open Docker Desktop
2. Go to Containers tab
-
3. Click on Archon-Server
+
3. Look for the Archon server container (typically named archon-server or similar)
4. View the logs for the specific error message
diff --git a/archon-ui-main/src/config/api.ts b/archon-ui-main/src/config/api.ts
index 6b7799b380..ec3eb2510c 100644
--- a/archon-ui-main/src/config/api.ts
+++ b/archon-ui-main/src/config/api.ts
@@ -20,14 +20,11 @@ export function getApiUrl(): string {
// For development, construct from window location
const protocol = window.location.protocol;
const host = window.location.hostname;
- const port = import.meta.env.ARCHON_SERVER_PORT;
+ // Use configured port or default to 8181
+ const port = import.meta.env.VITE_ARCHON_SERVER_PORT || '8181';
- if (!port) {
- throw new Error(
- 'ARCHON_SERVER_PORT environment variable is required. ' +
- 'Please set it in your environment variables. ' +
- 'Default value: 8181'
- );
+ if (!import.meta.env.VITE_ARCHON_SERVER_PORT) {
+ console.info('[Archon] Using default ARCHON_SERVER_PORT: 8181');
}
return `${protocol}//${host}:${port}`;
diff --git a/archon-ui-main/test/config/api.test.ts b/archon-ui-main/test/config/api.test.ts
index ac06c78ef3..bbf58f5b92 100644
--- a/archon-ui-main/test/config/api.test.ts
+++ b/archon-ui-main/test/config/api.test.ts
@@ -41,23 +41,33 @@ describe('API Configuration', () => {
expect(getApiUrl()).toBe('');
});
- it('should throw error when ARCHON_SERVER_PORT is not set in development', async () => {
- // Development mode without port
+ it('should use default port 8181 when no port environment variables are set in development', async () => {
+ // Development mode without any port variables
delete (import.meta.env as any).PROD;
delete (import.meta.env as any).VITE_API_URL;
+ delete (import.meta.env as any).VITE_ARCHON_SERVER_PORT;
+ delete (import.meta.env as any).VITE_PORT;
delete (import.meta.env as any).ARCHON_SERVER_PORT;
+ // Mock window.location
+ Object.defineProperty(window, 'location', {
+ value: {
+ protocol: 'http:',
+ hostname: 'localhost'
+ },
+ writable: true
+ });
+
const { getApiUrl } = await import('../../src/config/api');
- expect(() => getApiUrl()).toThrow('ARCHON_SERVER_PORT environment variable is required');
- expect(() => getApiUrl()).toThrow('Default value: 8181');
+ expect(getApiUrl()).toBe('http://localhost:8181');
});
- it('should use ARCHON_SERVER_PORT when set in development', async () => {
- // Development mode with custom port
+ it('should use VITE_ARCHON_SERVER_PORT when set in development', async () => {
+ // Development mode with custom port via VITE_ prefix
delete (import.meta.env as any).PROD;
delete (import.meta.env as any).VITE_API_URL;
- (import.meta.env as any).ARCHON_SERVER_PORT = '9191';
+ (import.meta.env as any).VITE_ARCHON_SERVER_PORT = '9191';
// Mock window.location
Object.defineProperty(window, 'location', {
@@ -73,10 +83,10 @@ describe('API Configuration', () => {
});
it('should use custom port with https protocol', async () => {
- // Development mode with custom port and https
+ // Development mode with custom port and https via VITE_ prefix
delete (import.meta.env as any).PROD;
delete (import.meta.env as any).VITE_API_URL;
- (import.meta.env as any).ARCHON_SERVER_PORT = '8443';
+ (import.meta.env as any).VITE_ARCHON_SERVER_PORT = '8443';
// Mock window.location with https
Object.defineProperty(window, 'location', {
@@ -139,7 +149,7 @@ describe('API Configuration', () => {
vi.resetModules();
delete (import.meta.env as any).PROD;
delete (import.meta.env as any).VITE_API_URL;
- (import.meta.env as any).ARCHON_SERVER_PORT = port;
+ (import.meta.env as any).VITE_ARCHON_SERVER_PORT = port;
Object.defineProperty(window, 'location', {
value: {
@@ -174,11 +184,10 @@ describe('MCP Client Service Configuration', () => {
it('should throw error when ARCHON_MCP_PORT is not set', async () => {
delete (import.meta.env as any).ARCHON_MCP_PORT;
- const { MCPClientService } = await import('../../src/services/mcpClientService');
- const service = new MCPClientService();
+ const { mcpClientService } = await import('../../src/services/mcpClientService');
- await expect(service.createArchonClient()).rejects.toThrow('ARCHON_MCP_PORT environment variable is required');
- await expect(service.createArchonClient()).rejects.toThrow('Default value: 8051');
+ await expect(mcpClientService.createArchonClient()).rejects.toThrow('ARCHON_MCP_PORT environment variable is required');
+ await expect(mcpClientService.createArchonClient()).rejects.toThrow('Default value: 8051');
});
it('should use ARCHON_MCP_PORT when set', async () => {
@@ -205,11 +214,10 @@ describe('MCP Client Service Configuration', () => {
})
});
- const { MCPClientService } = await import('../../src/services/mcpClientService');
- const service = new MCPClientService();
+ const { mcpClientService } = await import('../../src/services/mcpClientService');
try {
- await service.createArchonClient();
+ await mcpClientService.createArchonClient();
// Verify the fetch was called with the correct URL
expect(global.fetch).toHaveBeenCalledWith(
diff --git a/archon-ui-main/vite.config.ts b/archon-ui-main/vite.config.ts
index 0c812614b5..f6b7563f22 100644
--- a/archon-ui-main/vite.config.ts
+++ b/archon-ui-main/vite.config.ts
@@ -15,7 +15,7 @@ export default defineConfig(({ mode }: ConfigEnv): UserConfig => {
// Get host and port from environment variables or use defaults
// For internal Docker communication, use the service name
// For external access, use the HOST from environment
- const isDocker = process.env.DOCKER_ENV === 'true' || !!process.env.HOSTNAME;
+ const isDocker = process.env.DOCKER_ENV === 'true' || existsSync('/.dockerenv');
const internalHost = 'archon-server'; // Docker service name for internal communication
const externalHost = process.env.HOST || 'localhost'; // Host for external access
const host = isDocker ? internalHost : externalHost;
@@ -278,7 +278,7 @@ export default defineConfig(({ mode }: ConfigEnv): UserConfig => {
],
server: {
host: '0.0.0.0', // Listen on all network interfaces with explicit IP
- port: 5173, // Match the port expected in Docker
+ port: parseInt(process.env.ARCHON_UI_PORT || env.ARCHON_UI_PORT || '3737'), // Use configurable port
strictPort: true, // Exit if port is in use
proxy: {
'/api': {
diff --git a/check-env.js b/check-env.js
new file mode 100644
index 0000000000..938084db27
--- /dev/null
+++ b/check-env.js
@@ -0,0 +1,73 @@
+#!/usr/bin/env node
+
+const fs = require('fs');
+const path = require('path');
+
+// Secure path resolution
+const projectRoot = process.cwd();
+const envPath = path.resolve(projectRoot, '.env');
+
+// Security: Validate path is within project
+if (!envPath.startsWith(projectRoot)) {
+ console.error('Security error: Invalid .env path');
+ process.exit(1);
+}
+
+// Check if .env exists
+if (!fs.existsSync(envPath)) {
+ console.error('ERROR: .env file not found!');
+ console.error('Copy .env.example to .env and add your credentials:');
+ console.error(' cp .env.example .env');
+ process.exit(1);
+}
+
+// Parse .env file
+const envContent = fs.readFileSync(envPath, 'utf8');
+const envVars = {};
+
+envContent.split('\n').forEach(line => {
+ const trimmed = line.trim();
+ if (!trimmed || trimmed.startsWith('#')) return;
+
+ const [key, ...valueParts] = trimmed.split('=');
+ if (key) {
+ const value = valueParts.join('=').trim().replace(/^["']|["']$/g, '');
+ envVars[key.trim()] = value;
+ }
+});
+
+// Only check ESSENTIAL variables
+const required = ['SUPABASE_URL', 'SUPABASE_SERVICE_KEY'];
+const errors = [];
+
+required.forEach(varName => {
+ if (!envVars[varName] || envVars[varName] === '') {
+ errors.push(`Missing: ${varName}`);
+ }
+});
+
+if (errors.length > 0) {
+ console.error('ERROR: Required environment variables missing:');
+ errors.forEach(err => console.error(` - ${err}`));
+ console.error('\nPlease add these to your .env file');
+ process.exit(1);
+}
+
+// Validate URL format
+try {
+ new URL(envVars['SUPABASE_URL']);
+} catch (e) {
+ console.error('ERROR: SUPABASE_URL is not a valid URL');
+ console.error(` Found: ${envVars['SUPABASE_URL']}`);
+ console.error(' Expected format: https://your-project.supabase.co');
+ process.exit(1);
+}
+
+// Basic validation for service key
+if (envVars['SUPABASE_SERVICE_KEY'].length < 10) {
+ console.error('ERROR: SUPABASE_SERVICE_KEY appears to be invalid (too short)');
+ console.error(' Please check your Supabase project settings');
+ process.exit(1);
+}
+
+console.log('✓ Environment configured correctly');
\ No newline at end of file
diff --git a/docker-compose.yml b/docker-compose.yml
index 62338d2a04..0155726e5d 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -1,13 +1,22 @@
+# Docker Compose Profiles Strategy:
+# - "backend": Starts only backend services (server, mcp, agents) for hybrid development
+# - "frontend": Starts only the frontend UI service
+# - "full": Starts all services for complete Docker deployment
+# Use --profile flag with docker-compose to control which services start:
+# docker-compose --profile backend up # Backend only for hybrid dev
+# docker-compose --profile full up # Everything in Docker
+
services:
# Server Service (FastAPI + Socket.IO + Crawling)
archon-server:
+ profiles: ["backend", "full"]
build:
context: ./python
dockerfile: Dockerfile.server
args:
BUILDKIT_INLINE_CACHE: 1
ARCHON_SERVER_PORT: ${ARCHON_SERVER_PORT:-8181}
- container_name: Archon-Server
+ container_name: archon-server
ports:
- "${ARCHON_SERVER_PORT:-8181}:${ARCHON_SERVER_PORT:-8181}"
environment:
@@ -55,13 +64,14 @@ services:
# Lightweight MCP Server Service (HTTP-based)
archon-mcp:
+ profiles: ["backend", "full"]
build:
context: ./python
dockerfile: Dockerfile.mcp
args:
BUILDKIT_INLINE_CACHE: 1
ARCHON_MCP_PORT: ${ARCHON_MCP_PORT:-8051}
- container_name: Archon-MCP
+ container_name: archon-mcp
ports:
- "${ARCHON_MCP_PORT:-8051}:${ARCHON_MCP_PORT:-8051}"
environment:
@@ -99,13 +109,14 @@ services:
# AI Agents Service (ML/Reranking)
archon-agents:
+ profiles: ["backend", "full"]
build:
context: ./python
dockerfile: Dockerfile.agents
args:
BUILDKIT_INLINE_CACHE: 1
ARCHON_AGENTS_PORT: ${ARCHON_AGENTS_PORT:-8052}
- container_name: Archon-Agents
+ container_name: archon-agents
ports:
- "${ARCHON_AGENTS_PORT:-8052}:${ARCHON_AGENTS_PORT:-8052}"
environment:
@@ -133,18 +144,20 @@ services:
# Frontend
frontend:
+ profiles: ["frontend", "full"]
build: ./archon-ui-main
- container_name: Archon-UI
+ container_name: archon-ui
ports:
- - "${ARCHON_UI_PORT:-3737}:5173"
+ - "${ARCHON_UI_PORT:-3737}:3737"
environment:
- VITE_API_URL=http://${HOST:-localhost}:${ARCHON_SERVER_PORT:-8181}
+ - VITE_ARCHON_SERVER_PORT=${ARCHON_SERVER_PORT:-8181}
- ARCHON_SERVER_PORT=${ARCHON_SERVER_PORT:-8181}
- HOST=${HOST:-localhost}
networks:
- app-network
healthcheck:
- test: ["CMD", "curl", "-f", "http://localhost:5173"]
+ test: ["CMD", "curl", "-f", "http://localhost:3737"]
interval: 30s
timeout: 10s
retries: 3
diff --git a/python/src/server/api_routes/mcp_api.py b/python/src/server/api_routes/mcp_api.py
index 84021d6dec..db43496cdb 100644
--- a/python/src/server/api_routes/mcp_api.py
+++ b/python/src/server/api_routes/mcp_api.py
@@ -49,7 +49,7 @@ class MCPServerManager:
"""Manages the MCP Docker container lifecycle."""
def __init__(self):
- self.container_name = "Archon-MCP" # Container name from docker-compose.yml
+ self.container_name = None # Will be resolved dynamically
self.docker_client = None
self.container = None
self.status: str = "stopped"
@@ -62,16 +62,29 @@ def __init__(self):
self._min_operation_interval = 2.0 # Minimum 2 seconds between operations
self._initialize_docker_client()
+ def _resolve_container(self):
+ """Simple container resolution - just use fixed name."""
+ if not self.docker_client:
+ return None
+
+ try:
+ # Simple: Just look for the fixed container name
+ container = self.docker_client.containers.get("archon-mcp")
+ self.container_name = "archon-mcp"
+ mcp_logger.info("Found MCP container")
+ return container
+ except NotFound:
+ mcp_logger.warning("MCP container not found - is it running?")
+ self.container_name = "archon-mcp"
+ return None
+
def _initialize_docker_client(self):
"""Initialize Docker client and get container reference."""
try:
self.docker_client = docker.from_env()
- try:
- self.container = self.docker_client.containers.get(self.container_name)
- mcp_logger.info(f"Found Docker container: {self.container_name}")
- except NotFound:
- mcp_logger.warning(f"Docker container {self.container_name} not found")
- self.container = None
+ self.container = self._resolve_container()
+ if not self.container:
+ mcp_logger.warning("MCP container not found during initialization")
except Exception as e:
mcp_logger.error(f"Failed to initialize Docker client: {str(e)}")
self.docker_client = None
@@ -85,10 +98,17 @@ def _get_container_status(self) -> str:
if self.container:
self.container.reload() # Refresh container info
else:
- self.container = self.docker_client.containers.get(self.container_name)
+ # Try to resolve container again if we don't have it
+ self.container = self._resolve_container()
+ if not self.container:
+ return "not_found"
return self.container.status
except NotFound:
+ # Try to resolve again in case container was recreated
+ self.container = self._resolve_container()
+ if self.container:
+ return self.container.status
return "not_found"
except Exception as e:
mcp_logger.error(f"Error getting container status: {str(e)}")