# AI Stack Deployer - Claude Code MCP Configuration Guide

## Overview

This guide explains how to configure the AI Stack Deployer MCP server to work with **Claude Code** (not OpenCode). The two systems use different configuration formats.

---

## Key Differences: OpenCode vs Claude Code

### OpenCode Configuration
```json
{
  "mcp": {
    "graphiti-memory": {
      "type": "remote",
      "url": "http://10.100.0.17:8080/mcp/",
      "enabled": true,
      "oauth": false,
      "timeout": 30000,
      "headers": {
        "X-API-Key": "0c1ab2355207927cf0ca255cfb9dfe1ed15d68eacb0d6c9f5cb9f08494c3a315"
      }
    }
  }
}
```

### Claude Code Configuration
```json
{
  "graphiti-memory": {
    "type": "sse",
    "url": "http://10.100.0.17:8080/mcp/",
    "headers": {
      "X-API-Key": "${GRAPHITI_API_KEY}"
    }
  }
}
```

**Key differences:**
- ✅ OpenCode: Nested under `"mcp"` key
- ✅ Claude Code: Direct server definitions (no `"mcp"` wrapper)
- ✅ OpenCode: Uses `"type": "remote"` with `enabled`, `oauth`, `timeout` fields
- ✅ Claude Code: Uses `"type": "sse"` (for HTTP) or stdio config (for local)
- ✅ OpenCode: API keys in plaintext
- ✅ Claude Code: API keys via environment variables (`${VAR_NAME}`)

---

## MCP Server Types

### 1. **stdio-based** (What we have)
- Communication via standard input/output
- Server runs as a subprocess
- Used for local MCP servers
- No HTTP/network involved

### 2. **SSE-based** (What graphiti-memory uses)
- Communication via HTTP Server-Sent Events
- Server runs remotely
- Requires URL and optional headers

---

## Current Configuration Analysis

### Project's `.mcp.json` (CORRECT for stdio)
```json
{
  "mcpServers": {
    "ai-stack-deployer": {
      "command": "bun",
      "args": ["run", "src/mcp-server.ts"],
      "env": {}
    }
  }
}
```

This configuration is **already correct for Claude Code!** 🎉

### Why it's correct:
1. ✅ Uses `"mcpServers"` wrapper (Claude Code standard)
2. ✅ Defines `command` and `args` (stdio transport)
3. ✅ Empty `env` object (will inherit from shell)
4. ✅ Server uses `StdioServerTransport` (matches config)

---

## Setup Instructions

### Option 1: Project-Level MCP Server (Recommended)

**This is already configured!** The `.mcp.json` in your project root enables the MCP server for **this project only**.

**How to use:**
1. Navigate to this project directory:
   ```bash
   cd ~/locale-projects/ai-stack-deployer
   ```

2. Start Claude Code:
   ```bash
   claude
   ```

3. Claude Code will detect `.mcp.json` and prompt you to approve the MCP server

4. Accept the prompt, and the tools will be available!

**Test it:**
```
Can you list the available MCP tools?
```

You should see:
- `deploy_stack`
- `check_deployment_status`
- `list_deployments`
- `check_name_availability`
- `test_api_connections`

---

### Option 2: Global MCP Plugin (Always available)

If you want the AI Stack Deployer tools available in **all Claude Code sessions**, install it as a global plugin.

**Steps:**

1. Create plugin directory:
   ```bash
   mkdir -p ~/.claude/plugins/ai-stack-deployer/.claude-plugin
   ```

2. Create `.mcp.json`:
   ```bash
   cat > ~/.claude/plugins/ai-stack-deployer/.mcp.json << 'EOF'
   {
     "ai-stack-deployer": {
       "command": "bun",
       "args": [
         "run",
         "/home/odouhou/locale-projects/ai-stack-deployer/src/mcp-server.ts"
       ],
       "env": {
         "HETZNER_API_TOKEN": "${HETZNER_API_TOKEN}",
         "DOKPLOY_API_TOKEN": "${DOKPLOY_API_TOKEN}",
         "DOKPLOY_URL": "http://10.100.0.20:3000",
         "HETZNER_ZONE_ID": "343733",
         "STACK_DOMAIN_SUFFIX": "ai.flexinit.nl",
         "STACK_IMAGE": "git.app.flexinit.nl/oussamadouhou/oh-my-opencode-free:latest",
         "TRAEFIK_IP": "144.76.116.169"
       }
     }
   }
   EOF
   ```

3. Create `plugin.json`:
   ```bash
   cat > ~/.claude/plugins/ai-stack-deployer/.claude-plugin/plugin.json << 'EOF'
   {
     "name": "ai-stack-deployer",
     "description": "Self-service portal for deploying personal OpenCode AI stacks. Deploy, check status, and manage AI coding assistant deployments.",
     "author": {
       "name": "Oussama Douhou"
     }
   }
   EOF
   ```

4. Set environment variables in your shell profile (`~/.bashrc` or `~/.zshrc`):
   ```bash
   export HETZNER_API_TOKEN="your-token-here"
   export DOKPLOY_API_TOKEN="your-token-here"
   ```

5. Restart Claude Code:
   ```bash
   # Exit current session
   claude
   ```

The plugin is now available globally!

---

## Environment Variables

The MCP server needs these environment variables:

| Variable | Value | Description |
|----------|-------|-------------|
| `HETZNER_API_TOKEN` | From BWS | Hetzner Cloud DNS API token |
| `DOKPLOY_API_TOKEN` | From BWS | Dokploy API token |
| `DOKPLOY_URL` | `http://10.100.0.20:3000` | Dokploy API URL |
| `HETZNER_ZONE_ID` | `343733` | flexinit.nl zone ID |
| `STACK_DOMAIN_SUFFIX` | `ai.flexinit.nl` | Domain suffix for stacks |
| `STACK_IMAGE` | `git.app.flexinit.nl/...` | Docker image |
| `TRAEFIK_IP` | `144.76.116.169` | Traefik IP address |

**Best practice:** Use environment variables instead of hardcoding in `.mcp.json`!

---

## Comparison Table

| Feature | Project-Level | Global Plugin |
|---------|---------------|---------------|
| **Scope** | Current project only | All Claude sessions |
| **Config location** | `./mcp.json` | `~/.claude/plugins/*/` |
| **Environment** | Inherits from shell | Defined in config |
| **Updates** | Automatic (uses local code) | Manual path updates |
| **Use case** | Development | Production use |

---

## Troubleshooting

### MCP server not appearing

1. **Check `.mcp.json` syntax:**
   ```bash
   cat .mcp.json | jq .
   ```

2. **Verify Bun is installed:**
   ```bash
   which bun
   bun --version
   ```

3. **Test MCP server directly:**
   ```bash
   bun run src/mcp-server.ts
   # Press Ctrl+C to exit
   ```

4. **Check environment variables:**
   ```bash
   cat .env
   ```

5. **Restart Claude Code completely:**
   ```bash
   pkill -f claude
   claude
   ```

### Tools not working

1. **Test API connections:**
   ```bash
   bun run src/test-clients.ts
   ```

2. **Check Dokploy token is valid:**
   - Visit https://deploy.intra.flexinit.nl
   - Settings → Profile → API Tokens
   - Generate new token if needed

3. **Check Hetzner token:**
   - Visit https://console.hetzner.cloud
   - Security → API Tokens
   - Verify token has DNS permissions

### Deployment fails

Check the Claude Code debug logs:
```bash
tail -f ~/.claude/debug/*.log
```

---

## Converting Between Formats

If you need to convert this to OpenCode format later:

**From Claude Code (stdio):**
```json
{
  "mcpServers": {
    "ai-stack-deployer": {
      "command": "bun",
      "args": ["run", "src/mcp-server.ts"],
      "env": {}
    }
  }
}
```

**To OpenCode (stdio):**
```json
{
  "mcp": {
    "ai-stack-deployer": {
      "type": "stdio",
      "command": "bun",
      "args": ["run", "src/mcp-server.ts"],
      "env": {}
    }
  }
}
```

The main difference is the `"mcp"` wrapper and explicit `"type": "stdio"`.

---

## Summary

✅ **Your current `.mcp.json` is already correct for Claude Code!**

✅ **No changes needed** - just start Claude Code in this directory

✅ **Optional:** Install as global plugin for use everywhere

✅ **Key insight:** stdio-based MCP servers use `command`/`args`, not `url`/`headers`

---

## Next Steps

1. **Test the MCP server:**
   ```bash
   cd ~/locale-projects/ai-stack-deployer
   claude
   ```

2. **Ask Claude Code:**
   ```
   Test the API connections for the AI Stack Deployer
   ```

3. **Deploy a test stack:**
   ```
   Is the name "test-user" available?
   Deploy an AI stack for "test-user"
   ```

4. **Check deployment status:**
   ```
   Show me all recent deployments
   ```

---

**Ready to use! 🚀**
