Files
ai-stack-deployer/docs/MCP_SERVER_GUIDE.md
Oussama Douhou 19845880e3 fix(ci): trigger workflow on main branch to enable :latest tag
Changes:
- Create Gitea workflow for ai-stack-deployer
- Trigger on main branch (default branch)
- Use oussamadouhou + REGISTRY_TOKEN for authentication
- Build from ./Dockerfile

This enables :latest tag creation via {{is_default_branch}}.

Tags created:
- git.app.flexinit.nl/oussamadouhou/ai-stack-deployer:latest
- git.app.flexinit.nl/oussamadouhou/ai-stack-deployer:<sha>

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-09 23:33:39 +01:00

470 lines
12 KiB
Markdown

# AI Stack Deployer - MCP Server Guide
## Overview
This project now includes a **Model Context Protocol (MCP) Server** that exposes deployment functionality to Claude Code and other MCP-compatible clients.
### What is MCP?
The Model Context Protocol is a standardized way for AI assistants to interact with external tools and services. By implementing an MCP server, this project allows Claude Code to:
- Deploy new AI stacks programmatically
- Check deployment status
- Verify name availability
- Test API connections
- List all deployments
---
## Architecture
```
┌──────────────────────────────────────────────────────────────┐
│ CLAUDE CODE (MCP Client) │
│ - Discovers available tools │
│ - Calls tools with parameters │
│ - Receives structured responses │
└────────────────────────┬─────────────────────────────────────┘
│ MCP Protocol (stdio)
┌────────────────────────▼─────────────────────────────────────┐
│ AI Stack Deployer MCP Server │
│ (src/mcp-server.ts) │
│ │
│ Available Tools: │
│ ✓ deploy_stack │
│ ✓ check_deployment_status │
│ ✓ list_deployments │
│ ✓ check_name_availability │
│ ✓ test_api_connections │
└────────────────────────┬─────────────────────────────────────┘
│ Uses existing API clients
┌────────────────────────▼─────────────────────────────────────┐
│ Existing Infrastructure │
│ - Hetzner DNS API (src/api/hetzner.ts) │
│ - Dokploy API (src/api/dokploy.ts) │
└───────────────────────────────────────────────────────────────┘
```
---
## What Was Created
### 1. MCP Server Implementation (`src/mcp-server.ts`)
A fully-functional MCP server that:
- Integrates with existing Hetzner and Dokploy API clients
- Validates stack names according to project rules
- Tracks deployment state in memory
- Handles errors gracefully
- Returns structured JSON responses
### 2. Project Configuration (`.mcp.json`)
```json
{
"mcpServers": {
"ai-stack-deployer": {
"command": "bun",
"args": ["run", "src/mcp-server.ts"],
"env": {}
}
}
}
```
This file tells Claude Code how to start the MCP server.
### 3. Package Script (`package.json`)
Added `"mcp": "bun run src/mcp-server.ts"` to scripts for easy testing.
---
## How to Enable in Claude Code
### Step 1: Restart Claude Code
After creating the `.mcp.json` file, you need to restart Claude Code for it to discover the MCP server.
```bash
# If Claude Code is running, exit and restart
opencode
```
### Step 2: Approve the MCP Server
When Claude Code starts in this directory, it will detect the `.mcp.json` file and prompt you to approve the MCP server.
**You'll see a prompt like:**
```
Found MCP server configuration:
- ai-stack-deployer
Would you like to enable this MCP server? (y/n)
```
Type `y` to approve.
### Step 3: Verify MCP Server is Running
Claude Code will automatically start the MCP server when needed. You can verify it's working by asking Claude Code:
```
Can you list the available MCP tools?
```
You should see the 5 tools from the AI Stack Deployer.
---
## Available Tools
### 1. `deploy_stack`
Deploys a new AI coding assistant stack.
**Parameters:**
- `name` (string, required): Username for the stack (3-20 chars, lowercase alphanumeric and hyphens)
**Returns:**
```json
{
"success": true,
"deploymentId": "dep_1704830000000_abc123",
"name": "john",
"status": "completed",
"url": "https://john.ai.flexinit.nl",
"message": "Stack successfully deployed at https://john.ai.flexinit.nl"
}
```
**Example usage in Claude Code:**
```
Deploy an AI stack for user "alice"
```
---
### 2. `check_deployment_status`
Check the status of a deployment.
**Parameters:**
- `deploymentId` (string, required): The deployment ID from `deploy_stack`
**Returns:**
```json
{
"success": true,
"deployment": {
"id": "dep_1704830000000_abc123",
"name": "john",
"status": "completed",
"url": "https://john.ai.flexinit.nl",
"createdAt": "2026-01-09T17:30:00.000Z"
}
}
```
**Possible statuses:**
- `initializing` - Starting deployment
- `creating_dns` - Creating DNS records
- `creating_project` - Creating Dokploy project
- `creating_application` - Creating application
- `deploying` - Deploying container
- `completed` - Successfully deployed
- `failed` - Deployment failed
---
### 3. `list_deployments`
List all recent deployments.
**Parameters:** None
**Returns:**
```json
{
"success": true,
"deployments": [
{
"id": "dep_1704830000000_abc123",
"name": "john",
"status": "completed",
"url": "https://john.ai.flexinit.nl",
"createdAt": "2026-01-09T17:30:00.000Z"
}
],
"total": 1
}
```
---
### 4. `check_name_availability`
Check if a stack name is available and valid.
**Parameters:**
- `name` (string, required): The name to check
**Returns:**
```json
{
"available": true,
"valid": true,
"name": "john"
}
```
Or if invalid:
```json
{
"available": false,
"valid": false,
"error": "Name must be between 3 and 20 characters"
}
```
---
### 5. `test_api_connections`
Test connections to Hetzner DNS and Dokploy APIs.
**Parameters:** None
**Returns:**
```json
{
"hetzner": {
"success": true,
"message": "Connected to Hetzner Cloud DNS API. Zone \"flexinit.nl\" has 75 RRSets.",
"recordCount": 75,
"zoneName": "flexinit.nl"
},
"dokploy": {
"success": true,
"message": "Connected to Dokploy API. Found 12 projects.",
"projectCount": 12
},
"overall": true
}
```
---
## Testing the MCP Server
### Manual Test (Direct Invocation)
You can test the MCP server directly:
```bash
# Start the MCP server
bun run mcp
# It will wait for JSON-RPC messages on stdin
# Press Ctrl+C to exit
```
### Test via Claude Code
Once enabled in Claude Code, you can test it by asking:
```
Test the API connections for the AI Stack Deployer
```
Claude Code will invoke the `test_api_connections` tool and show you the results.
---
## Troubleshooting
### MCP Server Not Appearing in Claude Code
1. **Check `.mcp.json` exists** in the project root
2. **Restart Claude Code** completely
3. **Check for syntax errors** in `.mcp.json`
4. **Ensure Bun is installed** and in PATH
### Tools Not Working
1. **Check environment variables** in `.env`:
```bash
cat .env
```
2. **Test API connections**:
```bash
bun run src/test-clients.ts
```
3. **Check Dokploy token** (common issue):
- Navigate to https://deploy.intra.flexinit.nl
- Settings → Profile → API Tokens
- Generate new token if expired
### Deployment Fails
1. **DNS issues**: Verify Hetzner API token is valid
2. **Dokploy issues**: Verify Dokploy API token and URL
3. **Name conflicts**: Check if name already exists
4. **Permissions**: Ensure API tokens have required permissions
---
## Security Considerations
### Environment Variables
The MCP server inherits environment variables from the parent process. The `.mcp.json` file has an empty `env` object, which means it will use:
1. Variables from `.env` file (loaded by Bun)
2. Variables from the shell environment
**Never commit** `.env` file to version control!
### API Token Safety
- Hetzner and Dokploy API tokens are read from environment variables
- Tokens are never exposed in MCP responses
- All API calls are authenticated
---
## Integration Examples
### Example 1: Deploy Stack from Claude Code
```
User: Deploy an AI stack for user "bob"
Claude: I'll deploy an AI stack for "bob" using the deploy_stack tool.
[Calls deploy_stack with name="bob"]
Result:
✓ Deployment successful!
- Deployment ID: dep_1704830000000_xyz789
- URL: https://bob.ai.flexinit.nl
- Status: completed
```
### Example 2: Check All Deployments
```
User: Show me all recent deployments
Claude: I'll list all deployments using the list_deployments tool.
[Calls list_deployments]
Result:
Total: 3 deployments
1. alice - https://alice.ai.flexinit.nl (completed)
2. bob - https://bob.ai.flexinit.nl (completed)
3. charlie - https://charlie.ai.flexinit.nl (failed)
```
### Example 3: Validate Name Before Deploying
```
User: Can I use the name "test" for a new stack?
Claude: Let me check if "test" is available.
[Calls check_name_availability with name="test"]
Result: ❌ Name "test" is reserved and cannot be used.
Reserved names: admin, api, www, root, system, test, demo, portal
```
---
## Next Steps
### Enhance the MCP Server
Consider adding these tools:
1. **`delete_stack`** - Remove a deployed stack
2. **`get_stack_logs`** - Retrieve application logs
3. **`restart_stack`** - Restart a deployed stack
4. **`list_available_images`** - Show available Docker images
5. **`get_stack_metrics`** - Show resource usage
### Production Deployment
1. **Add authentication** to the MCP server
2. **Rate limiting** for deployments
3. **Persistent storage** for deployment state (currently in-memory)
4. **Webhooks** for deployment status updates
5. **Audit logging** for all operations
---
## Technical Details
### Protocol Used
- **Transport**: stdio (standard input/output)
- **Message Format**: JSON-RPC 2.0
- **SDK**: `@modelcontextprotocol/sdk` v1.25.2
### State Management
Currently, deployment state is stored in-memory using a `Map`:
- ✅ Fast access
- ✅ Simple implementation
- ❌ Lost on server restart
- ❌ Not shared across instances
For production, consider:
- Redis for distributed state
- PostgreSQL for persistent storage
- File-based storage for simplicity
### Error Handling
The MCP server wraps all tool calls in try-catch blocks and returns structured errors:
```json
{
"success": false,
"error": "Name already taken"
}
```
This ensures Claude Code always receives parseable responses.
---
## Summary
✅ **MCP Server**: Fully implemented in `src/mcp-server.ts`
✅ **Configuration**: Added `.mcp.json` for Claude Code
✅ **Tools**: 5 tools for deployment management
✅ **Integration**: Uses existing API clients
✅ **Testing**: Server starts successfully
✅ **Documentation**: This guide
**You can now use Claude Code to deploy and manage AI stacks through natural language commands!**
---
## Support
For issues or questions:
1. Check this guide first
2. Review `TESTING.md` for API connection issues
3. Check Claude Code logs: `~/.config/claude/debug/`
4. Test API clients directly: `bun run src/test-clients.ts`
---
**Built with ❤️ by Oussama Douhou**