fortigate-mcp
# FortiGate MCP Server (Safe Write Capable)
Write tools are dry-run by default and require explicit environment and per-call confirmation. See [SAFE_WRITE_MODE.md](SAFE_WRITE_MODE.md).
MCP Server สำหรับให้ Claude Desktop เชื่อมต่อกับ FortiGate ผ่าน REST API
ใช้ได้เฉพาะอ่าน config (read-only) ปลอดภัย ไม่สามารถแก้ไขได้
## ✨ Features
- 🔐 Read-only — แม้ token หลุดก็แก้ config ไม่ได้
- 🐳 Docker — isolated environment
- 📡 stdio transport — ไม่ต้องเปิด port
- 🛡️ Trusted host enforcement บน FortiGate
## 🛠️ Tools ที่ใช้ได้
| Tool | หน้าที่ |
|---|---|
| `fortigate_get_system_status` | ดู firmware version, hostname, etc. |
| `fortigate_list_address_groups` | ดูรายชื่อ address group ทั้งหมด |
| `fortigate_get_address_group` | ดู member ใน group |
| `fortigate_list_addresses` | ดูรายชื่อ address object |
| `fortigate_get_address` | ดู IP จริงของ address object |
| `fortigate_list_policies` | ดู policy ทั้งหมด |
| `fortigate_get_policy` | ดู policy ตัวเดียวละเอียด |
| `fortigate_list_webfilter_profiles` | ดู web filter profile |
| `fortigate_get_webfilter_profile` | ดู URL allow/block ใน profile |
| `fortigate_list_services` | ดู custom service |
| `fortigate_create_policy` | Safely create firewall policy, dry-run by default |
| `fortigate_update_policy` | Safely update firewall policy after reading current state |
## 📦 Setup
### 1. Clone/copy โปรเจกต์ลงเครื่อง
วาง folder `fortigate-mcp` ไว้ที่ไหนก็ได้ เช่น:
- Windows: `C:\mcp\fortigate-mcp`
- Mac/Linux: `~/mcp/fortigate-mcp`
### 2. ตั้งค่า .env
```bash
cp .env.example .env
```
แก้ `.env`:
```env
FORTIGATE_HOST=172.16.1.X # IP ของ FortiGate
FORTIGATE_TOKEN=xxxxxxxxxxxx # token จาก REST API admin
FORTIGATE_VERIFY_SSL=false # true ถ้ามี valid cert
FORTIGATE_TIMEOUT=10000
```
### 3. Build Docker image
```bash
cd fortigate-mcp
docker compose build
```
### 4. ทดสอบ container ทำงาน
```bash
# ทดสอบ run แบบ interactive (Ctrl+C เพื่อออก)
docker compose run --rm fortigate-mcp
```
ถ้าเห็น log:
```
[FortiGate MCP] Server running on stdio
[FortiGate MCP] Connected to: 172.16.1.X
[FortiGate MCP] Mode: READ-ONLY
```
แสดงว่า container ทำงานได้ ✅
> หมายเหตุ: server จะรอ MCP protocol input จาก stdin — ถ้าไม่มี input ก็ปกติ Ctrl+C ปิดได้เลย
### 5. Register กับ Claude Desktop
แก้ไฟล์ config ของ Claude Desktop:
**Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
**Mac**: `~/Library/Application Support/Claude/claude_desktop_config.json`
เพิ่ม `mcpServers`:
```json
{
"mcpServers": {
"fortigate": {
"command": "docker",
"args": [
"run",
"--rm",
"-i",
"--env-file",
"C:\\path\\to\\fortigate-mcp\\.env",
"fortigate-mcp:latest"
]
}
}
}
```
> ⚠️ Windows: ใช้ `\\` แทน `\` ในเส้นทางไฟล์
> Mac/Linux: ใช้ `/path/to/fortigate-mcp/.env`
### 6. Restart Claude Desktop
ปิดเปิด Claude Desktop ใหม่ทั้งหมด (ไม่ใช่แค่ปิดหน้าต่าง — quit จาก system tray)
### 7. ทดสอบ
ถาม Claude ว่า:
> "ลอง fortigate_get_system_status FortiGate ของฉันหน่อย"
ถ้าได้ข้อมูล hostname `ETTFAC` กลับมา = สำเร็จ! 🎉
## 🔍 ตัวอย่างคำถาม
- "ip068 อยู่ใน address group ไหนบ้าง?"
- "Web filter profile 'Only Use AI' allow domain อะไรบ้าง?"
- "Custom service 'Everest_default' ใช้ port อะไร?"
- "policy ไหนที่ใช้ source 'Wifi'?"
## 🛡️ Security Notes
- ✅ Token เก็บใน `.env` ไม่ถูก commit (มี `.gitignore`)
- ✅ Container รันด้วย non-root user
- ✅ Trusted host enforcement บน FortiGate
- ✅ Read-only profile บน FortiGate (defense in depth)
- ⚠️ อย่า commit `.env` ลง git
- ⚠️ อย่า share token กับใคร (รวมถึงในแชต Claude)
## 🐛 Troubleshooting
### `Error: connect ECONNREFUSED`
- เช็คว่า FortiGate IP ถูกต้องใน `.env`
- เช็คว่าเครื่องที่รัน Docker เข้าถึง FortiGate ได้ (ลอง `ping`)
### `FortiGate API error (401)`
- Token ผิด หรือ expire — regenerate ใหม่ที่ FortiGate
### `FortiGate API error (403)`
- Trusted host ไม่ตรง — เช็ค IP ของเครื่องที่รัน Docker
- Container อาจใช้ IP ต่างจาก host (ลอง `network_mode: host` ใน docker-compose)
### Claude Desktop ไม่เห็น tool
- เช็คว่า restart Claude Desktop แล้วจริงหรือยัง (quit จาก tray)
- เช็ค path ใน `claude_desktop_config.json` ถูกต้อง
- ดู log ที่ `%APPDATA%\Claude\logs\` (Windows)
TDQS
Scored across 18 tools
Each tool has a clear, distinct purpose targeting specific resources (address, address group, policy, service, web filter profile, system status). No overlapping functionality; get and list are appropriately separated.
All tools follow the consistent pattern 'fortigate_verb_noun' with lowercase and underscores. Verbs are uniform: create, delete, get, list, update. No mixing of conventions.
18 tools is slightly above the typical 3-15 range but still well-scoped for managing a FortiGate firewall. Each tool serves a necessary function without redundancy.
Covers CRUD for addresses and address groups, and list/get for policies, services, and web filter profiles. Notable gaps: missing delete for policies, and no create/update/delete for services and web filter profiles.