ข้ามไปที่เนื้อหา

External MCP Server Integration

OpenJarvis ขยายความสามารถของเอเจนต์ได้ด้วยการเชื่อมต่อกับเซิร์ฟเวอร์ Model Context Protocol (MCP) ภายนอก วิธีนี้ทำให้เอเจนต์ใช้ tool ที่มาจากบริการอย่าง Home Assistant, ฐานข้อมูล, API แบบกำหนดเอง หรือเซิร์ฟเวอร์ที่เข้ากันได้กับ MCP ใดๆ ได้ -- โดยไม่ต้องเขียนโค้ด tool เอง

ทำงานอย่างไร

เมื่อ OpenJarvis เริ่มทำงาน มันจะอ่านหมวด [tools.mcp] ใน config.toml สำหรับแต่ละเซิร์ฟเวอร์ที่ตั้งค่าไว้ มันจะ:

  1. เปิดการเชื่อมต่อโดยใช้ transport ที่เหมาะสม (Streamable HTTP หรือ stdio)
  2. ทำ MCP initialize handshake (การเจรจาเวอร์ชัน protocol และการแจ้ง initialized)
  3. ค้นหา tool ที่มีผ่าน tools/list
  4. ห่อ tool แต่ละตัวที่ค้นพบให้เป็น BaseTool มาตรฐาน เพื่อให้เอเจนต์เรียกใช้ได้เหมือน tool ในตัวทั่วไป

หากเซิร์ฟเวอร์ตัวใดเข้าถึงไม่ได้หรือคืน error OpenJarvis จะบันทึก warning และโหลดเซิร์ฟเวอร์ที่เหลือต่อไป เซิร์ฟเวอร์ที่เสียหนึ่งตัวจะไม่ทำให้ tool อื่นๆ ใช้งานไม่ได้

Configuration

เซิร์ฟเวอร์ MCP ภายนอกตั้งค่าใน config.toml ใต้ [tools.mcp]:

[tools.mcp]
enabled = true
servers = '[{"name": "homeassistant", "url": "http://172.16.3.1:9583/private_abc123"}]'

ค่า servers เป็น สตริงแบบ JSON-encoded ที่มี array ของ object เซิร์ฟเวอร์ แต่ละ object กำหนดเซิร์ฟเวอร์ MCP ภายนอกหนึ่งตัว

Note

ค่านี้ต้องเป็นสตริง JSON (มีเครื่องหมาย single-quote ของ TOML ล้อมรอบ) ไม่ใช่ array แบบเนทีฟของ TOML เพราะระบบ configuration ส่งค่านี้ผ่านเป็นฟิลด์สตริงเดียว

Schema การตั้งค่าเซิร์ฟเวอร์

แต่ละ object เซิร์ฟเวอร์รองรับฟิลด์ดังนี้:

ฟิลด์ ชนิด จำเป็น คำอธิบาย
name string ไม่ ชื่อที่มนุษย์อ่านได้ ใช้ในข้อความ log ค่าเริ่มต้นคือ <unnamed>
url string ไม่* URL สำหรับ transport แบบ Streamable HTTP
command string ไม่* คำสั่งสำหรับเปิดเซิร์ฟเวอร์ MCP แบบ stdio
args list of strings ไม่ Argument ที่ส่งให้คำสั่ง stdio
include_tools list of strings ไม่ Whitelist ของชื่อ tool ที่จะนำเข้า จะโหลดเฉพาะ tool เหล่านี้เท่านั้น
exclude_tools list of strings ไม่ Blacklist ของชื่อ tool ที่จะข้าม tool อื่นทั้งหมดจะถูกโหลด

*ต้องระบุ url หรือ command อย่างใดอย่างหนึ่ง หากไม่ตั้งค่าทั้งคู่ เซิร์ฟเวอร์นั้นจะถูกข้ามพร้อม warning

เมื่อระบุทั้ง include_tools และ exclude_tools whitelist จะถูกใช้ก่อน แล้วจึงกรองผลลัพธ์ด้วย blacklist

ตัวอย่าง

Home Assistant ผ่าน Streamable HTTP

เชื่อมต่อกับ add-on Home Assistant ha-mcp:

[tools.mcp]
enabled = true
servers = '[{"name": "homeassistant", "url": "http://172.16.3.1:9583/private_abc123"}]'

ค่านี้จะค้นพบ tool ของ HA ทั้งหมด (ควบคุม entity, automation, ประวัติ ฯลฯ) และเปิดให้เอเจนต์ใช้งานได้

เซิร์ฟเวอร์แบบ Stdio

เปิดเซิร์ฟเวอร์ MCP ในเครื่องเป็น subprocess:

[tools.mcp]
enabled = true
servers = '[{"name": "myserver", "command": "python", "args": ["-m", "my_mcp_server"]}]'

OpenJarvis จะเริ่ม process นี้โดยอัตโนมัติ สื่อสารผ่าน JSON-RPC ทาง stdin/stdout และปิดมันตอน shutdown

หลายเซิร์ฟเวอร์

[tools.mcp]
enabled = true
servers = '[{"name": "homeassistant", "url": "http://172.16.3.1:9583/private_abc123"}, {"name": "database", "command": "db-mcp-server", "args": ["--db", "postgres://localhost/mydb"]}]'

การกรอง Tool

เมื่อเซิร์ฟเวอร์ expose tool หลายตัวแต่คุณต้องการแค่บางส่วน ใช้ include_tools เพื่อ whitelist:

[tools.mcp]
enabled = true
servers = '[{"name": "ha", "url": "http://172.16.3.1:9583/private_abc123", "include_tools": ["hassTurnOn", "hassTurnOff", "hassGetState"]}]'

หากต้องการโหลดทุกอย่างยกเว้น tool บางตัว ใช้ exclude_tools:

[tools.mcp]
enabled = true
servers = '[{"name": "ha", "url": "http://172.16.3.1:9583/private_abc123", "exclude_tools": ["hassCreateBackup", "hassDeleteBackup"]}]'

ประเภทของ Transport

Streamable HTTP

ใช้เมื่อตั้งค่าฟิลด์ url transport นี้ส่งคำขอ JSON-RPC เป็น HTTP POST ไปยัง URL ที่ระบุ โดยใช้ httpx มันติดตาม header Mcp-Session-Id ข้ามคำขอต่างๆ ตามที่ MCP Streamable HTTP specification กำหนด

ควรใช้เมื่อ: เซิร์ฟเวอร์ MCP ระยะไกล, บริการที่รันเป็น HTTP endpoint (เช่น Home Assistant MCP add-on, เซิร์ฟเวอร์ MCP ที่โฮสต์บน cloud)

พารามิเตอร์การเชื่อมต่อ:

  • Connect timeout: 10 วินาที
  • Request timeout: 60 วินาที

Stdio

ใช้เมื่อตั้งค่าฟิลด์ command OpenJarvis จะสร้างคำสั่งนี้เป็น subprocess และสื่อสารผ่านบรรทัด JSON-RPC ทาง stdin/stdout

ควรใช้เมื่อ: เซิร์ฟเวอร์ MCP ในเครื่องที่แจกจ่ายเป็นเครื่องมือ CLI, การพัฒนา/ทดสอบ, เซิร์ฟเวอร์ที่ต้องเข้าถึงไฟล์ระบบบนเครื่องเดียวกัน

Alias ของ SSETransport

SSETransport เป็น alias ที่เข้ากันได้ย้อนหลังของ StreamableHTTPTransport ทั้งสองอ้างอิงถึง implementation เดียวกัน

การจัดการ Error

OpenJarvis จัดการความล้มเหลวของเซิร์ฟเวอร์ MCP อย่างสุภาพ:

  • เซิร์ฟเวอร์เข้าถึงไม่ได้: บันทึก warning และข้ามเซิร์ฟเวอร์นั้น เซิร์ฟเวอร์อื่นและ tool ในตัวยังคงโหลดตามปกติ
  • Timeout: คำขอ HTTP จะ timeout หลัง 60 วินาที เซิร์ฟเวอร์นั้นจะถูกข้ามพร้อม warning
  • Config ไม่ถูกต้อง: หาก JSON ของ servers มีรูปแบบผิด หรือ entry ของเซิร์ฟเวอร์ไม่มีทั้ง url และ command จะบันทึก warning และข้าม entry นั้น
  • การค้นหา Tool ล้มเหลว: หาก tools/list ล้มเหลวบนเซิร์ฟเวอร์ใด error จะถูกจับและข้ามเซิร์ฟเวอร์นั้น
  • การเรียกใช้ Tool ล้มเหลวตอน Runtime: หากการเรียก tool ไปยังเซิร์ฟเวอร์ MCP ภายนอกล้มเหลวตอน runtime จะคืนค่า ToolResult พร้อม success=False และข้อความ error

ความล้มเหลวของเซิร์ฟเวอร์ตัวเดียวจะไม่ทำให้ OpenJarvis crash หรือทำให้ tool อื่นใช้งานไม่ได้

การแก้ปัญหา

เซิร์ฟเวอร์ไม่ถูกค้นพบ

  1. ตรวจสอบว่า [tools.mcp] ตั้งค่า enabled = true แล้ว
  2. ตรวจสอบว่า JSON ของ servers ถูกต้อง ข้อผิดพลาดที่พบบ่อยคือใช้ array แบบ TOML แทนสตริง JSON
  3. ตรวจสอบ log ของ OpenJarvis หา warning เช่น Failed to discover external MCP tools

Connection refused / Timeout

  1. ตรวจสอบว่าเซิร์ฟเวอร์กำลังรันอยู่และเข้าถึงได้จาก host ของ OpenJarvis: curl -v http://host:port/
  2. ตรวจสอบกฎ firewall ระหว่าง container ของ OpenJarvis กับเซิร์ฟเวอร์ MCP
  3. สำหรับการ deploy ด้วย Docker ตรวจสอบว่าทั้งสอง container อยู่บน network เดียวกัน หรือใช้ host IP

Tool ไม่ปรากฏขึ้น

  1. รันพร้อม debug logging เพื่อดูว่า tool ตัวไหนถูกค้นพบ
  2. ตรวจสอบว่า filter include_tools หรือ exclude_tools เข้มงวดเกินไปหรือไม่
  3. ตรวจสอบว่าเซิร์ฟเวอร์ MCP นั้น expose tool จริงผ่าน tools/list (บางเซิร์ฟเวอร์ expose แค่ resource หรือ prompt)

เซิร์ฟเวอร์ Stdio Crash ทันที

  1. ทดสอบคำสั่งด้วยตนเอง: python -m my_mcp_server ควรเริ่มทำงานและรอ input ทาง stdin
  2. ตรวจสอบผลลัพธ์ stderr ใน log ของ OpenJarvis หาข้อความ error จาก subprocess
  3. ตรวจสอบว่า dependency ทั้งหมดของเซิร์ฟเวอร์ MCP ติดตั้งอยู่ใน environment เดียวกัน