- Enhanced README with new MCP features and setup instructions - Updated MCP_INTEGRATION.md with Claude Desktop configuration - Added network deployment options and security considerations - Fixed README encoding from UTF-16 to UTF-8 - Comprehensive guide for both local and network MCP deployments - Example usage patterns for Claude Desktop integration 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
334 lines
10 KiB
Markdown
334 lines
10 KiB
Markdown
# Nomad MCP
|
|
|
|
A service that enables AI agents (like Claude) to manage HashiCorp Nomad jobs via MCP (Machine Control Protocol).
|
|
|
|
## Features
|
|
|
|
- **🚀 Enhanced MCP Integration**: Two powerful integration options
|
|
- **Zero-Config FastAPI MCP**: All API endpoints automatically exposed as MCP tools
|
|
- **Standalone MCP Server**: Dedicated server with advanced Nomad workflow capabilities
|
|
- **📁 Job File Management**: Submit and manage Nomad jobs from JSON/HCL files
|
|
- **📊 Complete Job Lifecycle**: Submit → Monitor → Debug → Retry workflow
|
|
- **🔍 Advanced Debugging**: Allocation status, evaluations, and placement analysis
|
|
- **🔄 Smart Recovery**: Force job evaluation and retry capabilities
|
|
- **📋 Comprehensive Logging**: Real-time stdout/stderr retrieval
|
|
- Associate code repositories with Nomad job definitions
|
|
- Start, stop, and update Nomad jobs with enhanced controls
|
|
- Simple configuration system for mapping repositories to jobs
|
|
- RESTful API for AI agent interaction
|
|
- Gitea integration for repository validation and discovery
|
|
- **Web UI for job management and monitoring**
|
|
- **Claude Desktop native integration**
|
|
|
|
## Getting Started
|
|
|
|
### Prerequisites
|
|
|
|
- Python 3.8+
|
|
- HashiCorp Nomad cluster
|
|
- Nomad ACL token with appropriate permissions
|
|
- (Optional) Gitea instance for repository integration
|
|
|
|
### Installation
|
|
|
|
1. Clone this repository
|
|
2. Install dependencies:
|
|
```bash
|
|
uv venv
|
|
uv pip install -r requirements.txt
|
|
```
|
|
3. Set environment variables:
|
|
```bash
|
|
export NOMAD_ADDR="http://your-nomad-server:4646"
|
|
export NOMAD_NAMESPACE="development" # optional
|
|
```
|
|
4. Run the service:
|
|
```bash
|
|
# FastAPI server with web UI and zero-config MCP
|
|
uv run uvicorn app.main:app --reload --host 0.0.0.0 --port 8000
|
|
|
|
# Or standalone MCP server for Claude Desktop
|
|
uv run python mcp_server.py
|
|
```
|
|
|
|
## MCP Integration
|
|
|
|
### Claude Desktop Setup
|
|
|
|
1. **Configure Claude Desktop** (`~/Library/Application Support/Claude/claude_desktop_config.json`):
|
|
```json
|
|
{
|
|
"mcpServers": {
|
|
"nomad-mcp": {
|
|
"command": "/path/to/nomad_mcp/run_mcp_server.sh",
|
|
"env": {
|
|
"NOMAD_ADDR": "http://your-nomad-server:4646"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
2. **Restart Claude Desktop** to load the MCP server
|
|
|
|
### Available MCP Tools
|
|
|
|
The enhanced MCP integration provides these capabilities:
|
|
|
|
- **`list_nomad_jobs`** - List all jobs in a namespace
|
|
- **`get_job_status`** - Get detailed job status and health
|
|
- **`submit_job_file`** ⭐ - Submit Nomad job files (JSON/HCL)
|
|
- **`get_allocation_status`** ⭐ - Detailed allocation monitoring
|
|
- **`get_job_evaluations`** ⭐ - Placement failure analysis
|
|
- **`get_job_logs`** - Retrieve stdout/stderr logs
|
|
- **`force_evaluate_job`** ⭐ - Retry failed placements
|
|
- **`stop_job`** / **`restart_job`** - Job lifecycle management
|
|
|
|
### Example Usage in Claude
|
|
|
|
```
|
|
Please submit this Nomad job file:
|
|
[paste your job JSON/HCL here]
|
|
|
|
Then check the status and show me the logs if anything fails.
|
|
```
|
|
|
|
For complete setup instructions, see [MCP_INTEGRATION.md](MCP_INTEGRATION.md).
|
|
|
|
### Docker Deployment
|
|
|
|
You can also run the service using Docker:
|
|
|
|
```bash
|
|
# Build and run with docker-compose
|
|
docker-compose up -d
|
|
|
|
# Or build and run manually
|
|
docker build -t nomad-mcp .
|
|
docker run -p 8000:8000 --env-file .env -v ./configs:/app/configs nomad-mcp
|
|
```
|
|
|
|
## Configuration
|
|
|
|
### Environment Variables
|
|
|
|
Key environment variables to configure:
|
|
|
|
#### Nomad Configuration
|
|
- `NOMAD_ADDR` - URL of your Nomad server (e.g., `http://nomad.internal:4646`)
|
|
- `NOMAD_TOKEN` - ACL token for Nomad API authentication
|
|
- `NOMAD_NAMESPACE` - Default namespace for Nomad operations (e.g., `development`)
|
|
- `NOMAD_SKIP_VERIFY` - Set to `true` to skip SSL verification (for self-signed certs)
|
|
|
|
#### Gitea Configuration
|
|
- `GITEA_API_URL` - URL of your Gitea API (e.g., `http://gitea.internal/api/v1`)
|
|
- `GITEA_API_TOKEN` - Personal access token for Gitea API
|
|
- `GITEA_VERIFY_SSL` - Set to `false` to skip SSL verification for internal Gitea
|
|
|
|
#### MCP Configuration
|
|
- `BASE_URL` - Base URL where this service will be accessible (e.g., `http://localhost:8000`)
|
|
|
|
### Repository-Job Mappings
|
|
|
|
Job configurations are stored in YAML files in the `configs` directory. Each configuration maps a repository to a Nomad job.
|
|
|
|
Example configuration file (`configs/my-service.yaml`):
|
|
|
|
```yaml
|
|
repository: http://gitea.internal.example.com/username/repo-name
|
|
repository_alias: my-service
|
|
job_id: my-service
|
|
description: Example service managed by MCP
|
|
meta:
|
|
owner: ai-team
|
|
environment: development
|
|
```
|
|
|
|
## Web UI
|
|
|
|
The service includes a web-based user interface for managing Nomad jobs. The UI provides the following features:
|
|
|
|
- View all jobs across different namespaces
|
|
- Check job status and details
|
|
- View job logs (stdout and stderr)
|
|
- Restart and stop jobs
|
|
- Filter jobs by namespace
|
|
|
|
To access the UI, navigate to the root URL of the service (e.g., `http://localhost:8000`).
|
|
|
|

|
|
|
|
## AI Integration with Model Context Protocol (MCP)
|
|
|
|
Nomad MCP provides seamless integration with AI assistants through the Model Context Protocol (MCP) in two ways:
|
|
|
|
### 1. Zero-Config MCP Integration (New!)
|
|
|
|
The service now uses FastAPI MCP to automatically expose all API endpoints as MCP tools with zero configuration. This makes all endpoints immediately available to any AI assistant that supports the MCP protocol.
|
|
|
|
AI assistants can connect to the MCP endpoint at:
|
|
```
|
|
http://your-server:8000/mcp/sse
|
|
```
|
|
|
|
No manual tool definitions or configurations are needed - all API endpoints are automatically converted to MCP tools with proper schemas and documentation.
|
|
|
|
For detailed information on using the MCP integration, see the [MCP Integration Guide](MCP_INTEGRATION.md).
|
|
|
|
### 2. Claude-Specific API
|
|
|
|
The service also includes a specialized API for Claude AI to interact with Nomad jobs using natural language. This allows Claude to:
|
|
|
|
1. List all jobs in a namespace
|
|
2. Get the status of specific jobs
|
|
3. Start, stop, and restart jobs
|
|
4. Create new jobs with simplified specifications
|
|
5. Retrieve job logs
|
|
|
|
#### Claude Tool Configuration
|
|
|
|
To configure Claude to use the Nomad MCP service, use the provided `claude_nomad_tool.json` configuration file. This file defines the API endpoints and parameters that Claude can use to interact with the service.
|
|
|
|
For detailed instructions on setting up Claude with the Nomad MCP service, see the [Claude API Integration Documentation](CLAUDE_API_INTEGRATION.md).
|
|
|
|
## API Documentation
|
|
|
|
Once running, API documentation is available at:
|
|
- Swagger UI: http://localhost:8000/docs
|
|
- ReDoc: http://localhost:8000/redoc
|
|
|
|
## API Usage Examples
|
|
|
|
### Manage Jobs
|
|
|
|
```bash
|
|
# List all jobs
|
|
curl http://localhost:8000/api/jobs
|
|
|
|
# Get a specific job
|
|
curl http://localhost:8000/api/jobs/my-service
|
|
|
|
# Start a job
|
|
curl -X POST http://localhost:8000/api/jobs/my-service/restart
|
|
|
|
# Stop a job
|
|
curl -X DELETE http://localhost:8000/api/jobs/my-service
|
|
```
|
|
|
|
### Manage Configurations
|
|
|
|
```bash
|
|
# List all configurations
|
|
curl http://localhost:8000/api/configs
|
|
|
|
# Create a configuration
|
|
curl -X POST http://localhost:8000/api/configs/link \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"repository": "http://gitea.internal.example.com/username/repo-name", "job_id": "service", "repository_alias": "service"}'
|
|
```
|
|
|
|
### Repository Management
|
|
|
|
```bash
|
|
# List available repositories
|
|
curl http://localhost:8000/api/repositories
|
|
|
|
# Get repository information
|
|
curl http://localhost:8000/api/repositories/my-service
|
|
|
|
# Get repository branches
|
|
curl http://localhost:8000/api/repositories/my-service/branches
|
|
```
|
|
|
|
### Get Logs
|
|
|
|
```bash
|
|
# Get logs for a job
|
|
curl http://localhost:8000/api/logs/job/my-service?plain_text=true
|
|
|
|
# Get build logs for a job
|
|
curl http://localhost:8000/api/logs/build/my-service?plain_text=true
|
|
```
|
|
|
|
### Claude API Endpoints
|
|
|
|
```bash
|
|
# List all jobs in a namespace
|
|
curl http://localhost:8000/api/claude/list-jobs?namespace=development
|
|
|
|
# Get job status
|
|
curl -X POST http://localhost:8000/api/claude/jobs \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"job_id": "my-service", "action": "status", "namespace": "development"}'
|
|
|
|
# Create a new job
|
|
curl -X POST http://localhost:8000/api/claude/create-job \
|
|
-H "Content-Type: application/json" \
|
|
-d '{
|
|
"job_id": "test-nginx",
|
|
"docker_image": "nginx:latest",
|
|
"memory": 256,
|
|
"cpu": 200,
|
|
"ports": [{"Label": "http", "Value": 0, "To": 80}]
|
|
}'
|
|
|
|
# Get job logs
|
|
curl http://localhost:8000/api/claude/job-logs/my-service?namespace=development
|
|
```
|
|
|
|
## Troubleshooting
|
|
|
|
### Common Issues
|
|
|
|
1. **Connection to Nomad fails**:
|
|
- Verify that the `NOMAD_ADDR` environment variable is correct
|
|
- Check that the Nomad server is accessible from the service
|
|
- Ensure that the `NOMAD_TOKEN` has appropriate permissions
|
|
|
|
2. **Jobs fail to start**:
|
|
- Check the job specification format
|
|
- Verify that the namespace exists and is accessible
|
|
- Look for resource constraints or policy violations
|
|
|
|
3. **UI doesn't load**:
|
|
- Ensure that the service is running with the correct host and port
|
|
- Check browser console for JavaScript errors
|
|
- Verify that the static files are being served correctly
|
|
|
|
### Logs
|
|
|
|
The service logs provide detailed information about operations and errors. By default, logs are output to the console. You can adjust the log level using the `LOG_LEVEL` environment variable.
|
|
|
|
## For AI Agents
|
|
|
|
If you're an AI agent (like Claude) using this API, here are the main endpoints you'll likely use:
|
|
|
|
1. **Repository Management**:
|
|
- `GET /api/repositories` - List available repositories
|
|
- `GET /api/repositories/{repository}` - Get repository details
|
|
|
|
2. **Job Management**:
|
|
- `GET /api/jobs/by-repository/{repository}` - Get job info by repository
|
|
- `POST /api/jobs/by-repository/{repository}/start` - Start a job
|
|
- `POST /api/jobs/by-repository/{repository}/stop` - Stop a job
|
|
- `POST /api/jobs/by-repository/{repository}/restart` - Restart a job
|
|
|
|
3. **Logs**:
|
|
- `GET /api/logs/repository/{repository}` - Get logs for a repository's job
|
|
- `GET /api/logs/build/{job_id}` - Get build logs for a job
|
|
|
|
4. **Configuration**:
|
|
- `POST /api/configs/link` - Link a repository to a job
|
|
|
|
5. **Claude-Specific API**:
|
|
- `GET /api/claude/list-jobs` - List all jobs in a namespace
|
|
- `POST /api/claude/jobs` - Manage existing jobs
|
|
- `POST /api/claude/create-job` - Create a new job
|
|
- `GET /api/claude/job-logs/{job_id}` - Get logs for a job
|
|
|
|
The repository parameter can be either the full repository URL or the repository alias configured in the mapping.
|
|
|
|
## License
|
|
|
|
This project is licensed under the MIT License - see the LICENSE file for details.
|