EST. 2026 — บันทึกงานเซิร์ฟเวอร์จริง SYSADMIN · SECURITY · AI · DIRECTADMIN เล่มที่ 01
THE SYSADMIN ALMANAC
หน้าหลัก / AI / ขับ SketchUp ด้วย Claude Code ตอน 2 — ติดตั้งปลั๊กอิน MCP กันบั๊ก
AI — ขับ SketchUp ด้วย Claude Code [2]

ขับ SketchUp ด้วย Claude Code ตอน 2 — ติดตั้งปลั๊กอิน MCP กันบั๊ก

โดย Ton-Or ·5 มิ.ย. 2026·อ่าน 9 นาที
ขับ SketchUp ด้วย Claude Code ตอน 2 — ติดตั้งปลั๊กอิน MCP กันบั๊ก

ตอนที่แล้วเราเตรียมเครื่องไว้พร้อมแล้ว ตอนนี้ผมจะทำให้ Claude มองเห็นและบังคับ SketchUp ได้จริง ผ่านปลั๊กอิน MCP ของชุมชน — แต่ของเดิมมันมีบั๊กอยู่สองตัวที่ผมขอเล่ากันไว้ตั้งแต่ต้น คุณจะได้ไม่ต้องไปเจอทีละจุดเหมือนผม

ตอนที่ 1 (เตรียมเครื่อง) เราจัดสภาพแวดล้อมไว้เรียบร้อยแล้ว ทั้ง Claude Code, Python และ engine คำนวณ ตอนนี้เหลือชิ้นส่วนสำคัญที่สุดของชุด — สะพานเชื่อมที่ทำให้ Claude "เห็น" และ "ขับ" SketchUp ได้จริง

ตัวเชื่อมที่ผมใช้คือปลั๊กอินของชุมชนชื่อ mhyrr/sketchup-mcp มันทำหน้าที่เป็น MCP server ที่ฝั่ง Claude เรียกเข้ามาสั่งงาน SketchUp ได้ ปัญหาคือถ้าหยิบมาใช้ตรงๆ ตามคู่มือ มันมีบั๊กอยู่ 2 จุดที่ทำผมเสียเวลาตอนแรกอยู่พักใหญ่ แถมตอนนั้นผมยังวาง layout ไฟล์ผิดชั้นไปอีก กว่าจะรันผ่าน

ผมเลยเลือกเล่าวิธีกันบั๊กไว้ตั้งแต่ต้น แล้วสั่งให้ Claude จัดการทุกอย่างในทีเดียว คุณจะได้ข้ามขั้นตอนเจ็บตัวที่ผมเคยผ่านไปได้เลย

ภาพรวมการเชื่อมClaude CodeMCP client->sketchup-mcpMCP server->SketchUpปลั๊กอิน .rbz

1. สร้างปลั๊กอินให้ถูก ไม่ติดบั๊ก — สั่งทีเดียวจบ

หลักของผมคือไม่ไล่แก้ทีละจุดเอง เพราะรู้อยู่แล้วว่าปัญหามีกี่จุด อยู่ตรงไหนบ้าง ผมเลยเขียน prompt ละเอียดแล้วสั่ง Claude รวบจัดการให้หมดในรอบเดียว แบบนี้

ติดตั้งปลั๊กอิน sketchup-mcp (mhyrr) ให้ใช้กับ Claude Code ได้ถูกต้อง
จัดการประเด็นที่รู้แล้วทั้งหมดในทีเดียว:
1) โคลน repo mhyrr/sketchup-mcp branch main มาที่ D:\tools\sketchup-mcp-repo
2) อย่าใช้ wheel จาก PyPI (0.1.17 มันพังที่ FastMCP(description=...)) — ให้รัน server
   จาก source เสมอด้วย uvx --from <repo> sketchup-mcp
3) patch main.rb ของ extension กัน UI freeze: เปลี่ยน socket loop จาก client.gets (blocking)
   เป็น non-blocking — เขียนเมธอด read_line_bounded ที่ใช้ IO.select + read_nonblock มี deadline
   ราว 2 วินาที, ห่อการรับ client ด้วย handle_client ที่ rescue ทุก error + ensure client.close,
   แล้วปิด log ที่ spam console (gate ด้วย @verbose = false)
4) จัด layout ให้ถูก: su_mcp.rb (loader) + su_mcp/main.rb + su_mcp/extension.json —
   repo ต้นทางวาง main.rb ซ้อนผิดชั้น (su_mcp/su_mcp/main.rb) ต้องย้ายมาให้ตรง
5) build เป็น extension-build/su_mcp.rbz พร้อมติดตั้ง
เสร็จแล้วลองรัน server ว่า startup ผ่าน (ถ้ายังไม่เปิด SketchUp จะขึ้น Could not connect to Sketchup = ปกติ)

prompt นี้บอกเป้าหมายและข้อจำกัดที่ผมรู้ครบ Claude จะโคลน repo, แก้โค้ด, จัดไฟล์ และ build ให้เองทั้งหมด สิ่งที่ผมเน้นย้ำคือบรรทัดเดียว — ต้องรัน server จาก source เสมอ ไม่ใช่จาก wheel ของ PyPI คำสั่งที่ใช้รันจริงหน้าตาแบบนี้

uvx --from "D:\tools\sketchup-mcp-repo" sketchup-mcp

จุดที่ต้องสังเกตคือ --from ที่ชี้ไปยังโฟลเดอร์ repo ที่เพิ่งโคลนมา ไม่ใช่ uvx sketchup-mcp เปล่าๆ ที่จะไปดึง wheel ตัวพังจาก PyPI มาใช้

สองบั๊กที่ prompt นี้กันไว้

ผมอยากให้เข้าใจว่าทำไมถึงต้องกันสองจุดนี้ เพราะถ้าเข้าใจสาเหตุ เวลาเจออาการแปลกๆ คุณจะวินิจฉัยได้เร็ว

Claude CodeMCP clientstdiosketchup-mcpMCP serverTCP :9876ปลั๊กอินใน SketchUpRuby ทำงานบน UI threadบั๊ก 1: wheel 0.1.17 จาก PyPI พังทางแก้: uvx --from โฟลเดอร์ repoบั๊ก 2: client.gets ค้าง UI threadทางแก้: IO.select + read_nonblock ราว 2 วิ
บั๊กทั้งสองอยู่คนละชั้น บั๊ก 1 อยู่ที่ตัว MCP server ที่ดึงมาจาก PyPI ส่วนบั๊ก 2 อยู่ที่ปลั๊กอินฝั่ง SketchUp ซึ่งรอ client ค้างจนทั้งโปรแกรม freeze

บั๊ก 1 — wheel จาก PyPI พัง

ถ้ารัน uvx sketchup-mcp ตรงๆ จะดึง wheel เวอร์ชัน 0.1.17 จาก PyPI มา ตัวนี้ค้างโค้ดเก่าไว้ พอ start จะเด้ง error ทันที

TypeError: FastMCP.__init__() got an unexpected keyword argument 'description'

สาเหตุคือ wheel ตัวนั้นยังเรียก FastMCP(description=...) ซึ่ง API รุ่นใหม่ของ FastMCP ตัดออกไปแล้ว (เปลี่ยนไปใช้ instructions= แทน) ส่วนโค้ดใน source branch main เขาแก้ตามแล้ว นี่คือเหตุผลที่ต้องรันจาก repo ด้วย --from แทนที่จะปล่อยให้ดึง wheel มาเอง

บั๊ก 2 — ปลั๊กอินค้าง UI freeze (ตัวนี้สำคัญสุด)

บั๊กนี้คือตัวที่เจ็บที่สุดและหาสาเหตุยากที่สุด ของเดิมใช้ client.gets แบบ blocking อยู่ใน callback ของ UI.start_timer ปัญหาคือถ้ามี client ต่อเข้ามาแต่ส่งข้อมูลมาไม่ครบ บรรทัด client.gets จะค้างรอข้อมูลที่ไม่มีวันมา และเพราะมันรันอยู่บน UI thread ตัว SketchUp ทั้งโปรแกรมจะ freeze ทันที — ขึ้น "Ruby Console Not Responding" จนต้องปิดทิ้งแล้วเปิดใหม่

อาการ UI freeze

socket loop ที่ใช้ client.gets แบบ blocking ทำให้ UI thread ของ SketchUp ค้างทั้งโปรแกรมถ้า client ส่งข้อมูลมาไม่ครบ ต้องรีสตาร์ท SketchUp อย่างเดียว ข้อนี้คือเหตุผลหลักที่ต้อง patch ก่อนใช้งาน

วิธีแก้คือเปลี่ยน socket loop ให้เป็น non-blocking ด้วยเมธอด read_line_bounded ที่ใช้ IO.select คู่กับ read_nonblock และตั้ง deadline ไว้ราว 2 วินาที ถ้าครบเวลาแล้วข้อมูลยังไม่มาก็ปล่อยไป ไม่ค้างรอ พร้อมห่อการรับ client ด้วย handle_client ที่ rescue ทุก error และมี ensure client.close ปิด socket เสมอไม่ว่าจะเกิดอะไรขึ้น และปิด log ที่ spam console ทิ้งด้วยการ gate ด้วย @verbose = false

ของเดิม

client.gets (blocking)

  • ค้าง UI thread ถ้าข้อมูลมาไม่ครบ
  • SketchUp freeze ทั้งโปรแกรม
  • ต้องรีสตาร์ทอย่างเดียว
  • log spam เต็ม console
หลัง patch

read_line_bounded (non-blocking)

  • IO.select + read_nonblock มี deadline ~2 วินาที
  • handle_client rescue ทุก error + ensure close
  • ไม่ค้าง UI
  • ปิด log ด้วย @verbose = false

มีจุดที่ต้องจำให้แม่น — หลัง patch แล้ว อย่าเผลอเอา .rbz ตัว upstream มาลงทับ เพราะมันจะคืนบั๊ก UI freeze กลับมาทันที ของที่ลงต้องเป็นตัวที่ build จาก source ที่ patch แล้วเท่านั้น

อย่าลงทับด้วย .rbz upstream

ถ้าอนาคตอัปเดตปลั๊กอินจาก repo ต้นทางตรงๆ บั๊ก UI freeze จะกลับมา ให้ build จาก source ที่ patch แล้วเสมอ และลงตัวนั้นทับแทน

2. ลงทะเบียน MCP เข้า Claude Code (user scope)

พอได้ปลั๊กอินที่ build แล้ว ขั้นต่อไปคือบอก Claude Code ว่ามี MCP server ตัวนี้อยู่ ผมเลือกใช้ add-json ไม่ใช้ claude mcp add ตรงๆ เพราะตัวหลังมันจะไปตีความ --from เป็น option ของคำสั่งตัวเอง ทำให้ลงทะเบียนไม่ถูก ส่วน add-json เรายัด config เป็น JSON ก้อนเดียวให้ทั้งดุ้น มันจะไม่ไปยุ่งกับ arguments ข้างใน

$json = '{"command":"C:\\Users\\<user>\\.local\\bin\\uvx.exe","args":["--from","D:\\tools\\sketchup-mcp-repo","sketchup-mcp"]}'
claude mcp add-json sketchup $json --scope user
claude mcp list          # ได้ sketchup ... Connected

ที่ใช้ --scope user เพราะอยากให้ใช้ได้ทุกโปรเจกต์ ทั้งฝั่ง CLI และใน VS Code ไม่ต้องลงทะเบียนซ้ำทุกครั้งที่เปิดงานใหม่ ถ้าลงทะเบียนแล้วแต่ยังไม่เห็น tool mcp__sketchup__* ให้ Reload Window เสียก่อน (กด Ctrl+Shift+P แล้วเลือก Reload Window) เพราะ MCP มันโหลดตอนเริ่ม session ถ้าลงทะเบียนหลังเปิด session ไปแล้วมันจะยังไม่เห็น

3. ลง .rbz ใน SketchUp

ฝั่ง Claude พร้อมแล้ว ทีนี้มาฝั่ง SketchUp การลงปลั๊กอินทำผ่าน Extension Manager ตรงๆ

  • เปิด SketchUp ไปที่ Window → Extension Manager → Install แล้วเลือกไฟล์ extension-build\su_mcp.rbz ที่ build ไว้
  • รีสตาร์ท SketchUp 1 รอบ เพื่อให้มันโหลดปลั๊กอินที่เพิ่งลงเข้าไป

หลังลงและรีสตาร์ทแล้ว เมนู Extensions → MCP Server จะโผล่ขึ้นมา นั่นแปลว่าปลั๊กอินติดเรียบร้อย

4. เปิด MCP server ให้พร้อมใช้งาน

ลงปลั๊กอินเสร็จไม่ได้แปลว่าใช้งานได้ทันที ก่อนจะสั่ง Claude สร้างโมเดล ต้องเปิด SketchUp แล้วกด Start Server ก่อนเสมอ ไม่งั้น Claude จะต่อไม่ติด

ผมแนะนำให้เปิด Ruby Console ค้างไว้ดู log ก่อน (เมนู Extensions → Developer → Ruby Console) จะได้เห็นสถานะตอน server เริ่มทำงาน

จากนั้นกด Start Server (เมนู Extensions → MCP Server → Start Server มี Stop Server ไว้ปิดเวลาเลิกใช้) แล้วดูที่ Ruby Console ต้องขึ้นบรรทัดสุดท้ายว่า server listening แบบนี้ถึงจะพร้อม

MCP Extension loading...
MCP: Starting server on localhost:9876...
MCP: Server created on port 9876
MCP: Server started and listening      <- พร้อมให้ Claude เชื่อมต่อ
ลำดับก่อนสั่งงานเปิด SketchUp->เปิด Ruby Console->Start Server->server listening->สั่ง Claude

ขอย้ำไว้ตรงนี้ — ทุกครั้งที่จะใช้งาน ต้องเปิด SketchUp แล้ว Start Server ก่อนเสมอ ถ้าลืมกด Claude จะต่อไม่ติด ขึ้น WinError 10061 connection refused ซึ่งแปลตรงตัวว่าไม่มีใครฟังอยู่ที่ port นั้น มักเป็นเพราะลืม Start Server หรือ SketchUp ปิดอยู่

WinError 10061

ถ้า Claude ต่อไม่ติดแล้วขึ้น connection refused ให้เช็คก่อนว่าเปิด SketchUp อยู่หรือเปล่า และกด Start Server แล้วหรือยัง เกือบทุกครั้งที่เจอ error นี้คือลืม Start Server

ถึงตรงนี้ Claude ขับ SketchUp ได้แล้ว

พอครบทั้งสี่ขั้นนี้ — build ปลั๊กอินที่ patch บั๊กแล้ว, ลงทะเบียน MCP เข้า Claude, ลง .rbz, และ Start Server — Claude ก็พร้อมสั่งงาน SketchUp ได้จริงแล้ว ตอนหน้าจะเป็นของจริง สั่งสร้างโรงเหล็กทั้งหลังทีละชั้น แล้วส่งไปคำนวณ FEA ลงสี heatmap ตามแรงที่เกิดขึ้นจริง มีคลิปตอน build ให้ดูด้วย

ใครจะวาง path หรือชื่อโฟลเดอร์ต่างจากผมก็ตามสะดวก หลักการเหมือนกันหมด ขอแค่รัน server จาก source ที่ patch แล้ว และอย่าลืม Start Server ก่อนสั่งงานทุกครั้ง

เคยเจองานแบบนี้ไหม? ติดตรงไหน?

มาแลกวิธีกันต่อในบอร์ด LinuxThai

→ คุยต่อในบอร์ด

ความคิดเห็น 0

ยังไม่มีความคิดเห็น — เป็นคนแรกเลย