thai-legal

Research layer กฎหมายไทยสำหรับ AI — เชื่อมข่าว/ข้อเท็จจริงเข้ากับตัวบทกฎหมาย ราชกิจจานุเบกษา ความเห็นกฤษฎีกา และคำพิพากษาศาลฎีกาเทียบเคียง…

Community: Submitted by a user or imported; check the owner before granting accessDegradedNo sign-inGlobalFreeRead-only

What it can do

  • Search Law: ค้นกฎหมายไทย (hybrid: semantic + keyword) จาก 4 แหล่ง: - ตัวบทกฎหมายรายมาตรา (กฤษฎีกา) — corpus='law' - ราชกิจจานุเบกษา + ประกาศ/แจ้งความ — corpus='gazette' - ความเห็นคณะกรรมการกฤษฎีกา (เร
  • Research Dossier: รวบรวม "สำนวนวิจัย" ข้ามกฎหมาย/คำพิพากษา/ความเห็นกฤษฎีกาในคำเรียกเดียว — ประกอบผลจาก search_law (corpus='law'/'deka'/'opinion') + deka_by_section (pivot จากมาตราตัวบทที่เจอ ผ่าน cita
  • Get Gazette Document: ดึงเอกสารเต็มจากราชกิจจานุเบกษาตามเล่ม/ตอน (เฉพาะ corpus='gazette'). (เล่ม, ตอน) = ราชกิจจาฯ หนึ่งฉบับซึ่งมีหลายเอกสาร — ใส่ category/no เพื่อเจาะจง. ใช้กับตัวบทกฎหมาย (corpus='l

What data it sees

Do you need an account

No: the server works without sign-in

Research layer กฎหมายไทยสำหรับ AI — เชื่อมข่าว/ข้อเท็จจริงเข้ากับตัวบทกฎหมาย ราชกิจจานุเบกษา ความเห็นกฤษฎีกา และคำพิพากษาศาลฎีกาเทียบเคียง พร้อมตรวจสอบแหล่งอ้างอิงได้จริงทุกคำตอบ กันไม่ให้ AI สรุปกฎหมายผิดจากพาดหัวข่าว

How to connect

How to connect thai-legal to Claude

The server address to paste into Claude settings:

https://thai-legal--legaltech.run.tools

  1. Open Claude (claude.ai or the desktop app).
  2. Go to Settings → Connectors.
  3. Click Add custom connector.
  4. Paste the server address copied below into Remote MCP server URL and click Add.
  5. In a chat, click + → Connectors and switch the new connector on.

Custom connectors are available on Free, Pro, Max, Team and Enterprise plans (Free is limited to one). On Team and Enterprise an organization Owner adds the connector first under Organization settings → Connectors.

Authorization

After you click Add, a sign-in window for the service opens. Sign in with your own account and approve access. Claude never sees your password.

How to connect thai-legal to ChatGPT

The server address to paste into ChatGPT settings:

https://thai-legal--legaltech.run.tools

  1. Open ChatGPT in a browser (chatgpt.com). A Plus, Pro, Business, Enterprise or Edu plan is required.
  2. Turn on developer mode once: Settings → Apps → Advanced settings → Developer mode.
  3. Open Settings → Connectors and click Create.
  4. Fill in the form: Name (anything), Description (one line about what the service does), MCP server URL (copy it below).
  5. Under Authentication choose OAuth if the service requires sign-in, otherwise None. Click Create.
  6. In a new chat open + → Apps/Connectors and enable the connector.

OpenAI has renamed this section before (Connectors → Apps/Plugins). If the label differs, search settings for "developer mode". On Business/Enterprise workspaces an admin must allow custom connectors first.

Authorization

On first use ChatGPT opens the service's sign-in window. Sign in and approve access.

How to connect thai-legal to Cursor

The server address to paste into Cursor settings:

https://thai-legal--legaltech.run.tools

Fastest: click Open in Cursor below and confirm the prompt.

Manually:

  1. In Cursor open Settings → Cursor Settings → MCP and click Add new global MCP server.
  2. Paste the JSON copied below into ~/.cursor/mcp.json (per project: .cursor/mcp.json in the repo root).
  3. Save the file. The server appears in the MCP list; authorize it there if asked.

Authorization

If the service needs sign-in, an authorize button appears next to the server in the MCP list.

Server tool list (12)

Raw names from tools/list. Only developers need these.

search_lawค้นกฎหมายไทย (hybrid: semantic + keyword) จาก 4 แหล่ง: - ตัวบทกฎหมายรายมาตรา (กฤษฎีกา) — corpus='law' - ราชกิจจานุเบกษา + ประกาศ/แจ้งความ — corpus='gazette' - ความเห็นคณะกรรมการกฤษฎีกา (เรื่องเสร็จ) — corpus='opinion' ⚠️ เป็น metadata (ชื่อเรื่อง+หมวด+คณะ+ปี+ลิงก์ PDF) ไม่มีเนื้อหาเต็ม → อ่านฉบับเต็มที่ source_url (PDF) - คำพิพากษาศาลฎีกา — corpus="deka" ⚠️ full_text อาจมีชื่อจริงคู่ความหลุด — ดู deka_privacy_note ในผลลัพธ์ **ไม่ระบุ corpus = ค้นทั้ง 4 แหล่งปนกัน** — ระบุ corpus เจาะจงถ้าต้องการเฉพาะแหล่งเดียว แต่ละผลมี citation["corpus"] บอกชนิด: 'law' (title+มาตรา+reference_url), 'gazette' (เล่ม/ตอน/หน้า/วันที่ + ลิงก์ PDF), 'opinion' (เลขเรื่องเสร็จ + ลิงก์ PDF), หรือ 'deka' (เลขฎีกา+ผลคดี+cited_sections). ผลของ corpus='law' คืน **ฉบับชำระ (consolidated) ล่าสุดเท่าที่มีในฐานข้อมูล** ต่อมาตรา — เป็น snapshot จากกฤษฎีกา (OCS) ที่ **อาจยังไม่รวมการแก้ไขล่าสุดที่เพิ่งประกาศในราชกิจจาฯ** (consolidated text may lag gazette amendments) → เคสสำคัญต้อง cross-check ตัวบททางการ. ฟิลด์ "version_count" บอกว่ามาตรานั้นมีกี่ฉบับแก้ไข (>1 = เคยถูกแก้, แสดงฉบับล่าสุด) citation["is_repealed"]=True บอกว่าฉบับนี้ถูกยกเลิกแล้ว (ยังคืนผลได้แต่ควรระวังก่อนอ้างอิง) citation["law_abbrev"]/["section_no"] (corpus=law เท่านั้น, อาจเป็น None) ใช้ pivot ตรงไป deka_by_section(law=citation.law_abbrev, section=citation.section_no) โดยไม่ต้อง parse doctitle เอง — ครอบคลุมแค่ประมวลกฎหมายหลักที่ยืนยันแล้ว (ป.อ./ป.พ.พ./ป.วิ.อ./ป.วิ.พ.) Args: query: คำค้นภาษาไทย เช่น "ลูกจ้างมีสิทธิลาคลอดกี่วัน" top_k: จำนวนผลลัพธ์สูงสุด (ค่าเริ่มต้น 5) category: กรองประเภทราชกิจจาฯ — "ก"=กฎหมาย, "ข"=ฐานันดร, "ค"=ทะเบียนการค้า, "ง"=ประกาศ corpus: "law"=ตัวบทกฎหมาย | "gazette"=ราชกิจจาฯ | "opinion"=ความเห็นกฤษฎีกา | "deka"=คำพิพากษาศาลฎีกา | ไม่ระบุ=ทั้งหมด include_all_versions: False (ดีฟอลต์)=เฉพาะฉบับล่าสุด; True=ทุกฉบับแก้ไข (วิจัย/คดีเก่า) year_from: ปี ค.ศ. เริ่มต้น (เช่น 2020) year_to: ปี ค.ศ. สิ้นสุด subject: กรองสาขากฎหมาย (corpus=law) เช่น "แรงงาน" "ภาษี" "ที่ดิน" "อาญา" — ดูรายการจาก browse(kind="subjects") law_type: กรองประเภท เช่น "พระราชบัญญัติ" "ประมวลกฎหมาย" "พระราชกฤษฎีกา" "กฎกระทรวง" Returns: results: รายการ chunk + unit_label + version_count + citation + dense_sim/fusion_score/margin (สัญญาณ confidence; None ถ้าไม่มี dense) expanded_terms: ศัพท์ทางการที่ query ถูกแปลง (None ถ้าไม่มีการแปลง) — ความโปร่งใสของ retrieval disclaimer + attribution (ตามแหล่งที่ปรากฏจริง) + quota (used/limit; null ถ้า service token/dev) law_freshness_note: เตือน consolidated text อาจ lag (มีเมื่อผลมี corpus='law') deka_privacy_note: เตือน PDPA residual leak (มีเมื่อผลมี corpus='deka') feedback_hint: มีเมื่อไม่พบผลลัพธ์เลย หรือคะแนนความใกล้เคียงต่ำกว่าเกณฑ์ที่ตั้งไว้ (`FEEDBACK_HINT_MAX_DENSE_SIM` — ไม่ตั้ง = ปิดเกณฑ์นี้) — บอกว่ามี submit_feedback ให้ผู้ใช้รายงานได้ · ปิดทั้งหมดด้วย env FEEDBACK_HINT_ENABLED=0
research_dossierรวบรวม "สำนวนวิจัย" ข้ามกฎหมาย/คำพิพากษา/ความเห็นกฤษฎีกาในคำเรียกเดียว — ประกอบผลจาก search_law (corpus='law'/'deka'/'opinion') + deka_by_section (pivot จากมาตราตัวบทที่เจอ ผ่าน citation.law_abbrev/section_no) เข้าด้วยกัน ไม่ใช่ tool ใหม่ที่มี ranking/scoring ของตัวเอง — เป็นแค่ทางลัดเรียก sub-call หลายตัวในคำเดียวแทนที่ต้องเรียก search_law + deka_by_section เองทีละมาตรา ⚠️ **ไม่จัดกลุ่ม/ตีความคำพิพากษาเป็น "สนับสนุน"/"คัดค้าน" จุดยืนใดๆ** — `verdict`/ `department`/`doctitle` เป็นข้อมูลดิบ ต้องให้ host LLM ตีความเอง (เหมือน search_law/ deka_by_section ทุกประการ ไม่ได้เพิ่ม stance-classification logic ใหม่) ไม่ใช่ตัวแทน search_law เมื่อต้องกรองเจาะจง (category/year/subject/law_type) — กรณีนั้น เรียก search_law ตรงๆ แทน dossier นี้ค้นแบบกว้างไม่มี filter พวกนี้ Args: query: คำค้นภาษาไทย เช่น "ค่าไถ่การเรียกร้องประกันตัว" top_k_statutes: จำนวนมาตราตัวบทสูงสุด (ค่าเริ่มต้น 5, สูงสุด 20) top_k_deka_semantic: จำนวนคำพิพากษาฎีกา (ค้นเชิงความหมาย) สูงสุด (ค่าเริ่มต้น 5, สูงสุด 20) top_k_opinions: จำนวนความเห็นกฤษฎีกาสูงสุด (ค่าเริ่มต้น 3, สูงสุด 20) Returns: statute_sections: ผล search_law(corpus='law') — เหมือน search_law["results"] case_law_by_section: [{law, section, cases}] ต่อมาตราที่เจอ (สูงสุด 3 มาตราแรก, dedup) — cases มาจาก deka_by_section (summary field เท่านั้น ไม่มี full_text) case_law_by_semantic_search: ผล search_law(corpus='deka') — full_text อาจมี (ดู deka_privacy_note) — เป็นการจับคู่เชิงความหมายกับ query โดยตรง **ไม่ใช่**คำพิพากษา ที่ยืนยันแล้วว่าอ้างอิงมาตราใน statute_sections (ต่างจาก case_law_by_section ที่เป็น citation pivot แบบ deterministic) — ห้ามตีความว่าทั้งสอง list มีน้ำหนักหลักฐานเท่ากัน related_opinions: ผล search_law(corpus='opinion') evidence_gaps: {statute_sections_found, sections_checked_for_citing_cases, cases_found_by_citation, cases_found_by_semantic_search, related_opinions_found, notes} — notes เตือนเมื่อบาง sub-call ล้มเหลวชั่วคราว หรือเจอมาตราแต่ไม่เจอคำพิพากษา ที่อ้างถึงเลย quota / disclaimer / attribution: เหมือน search_law law_freshness_note: มีเมื่อ statute_sections ไม่ว่าง (เหมือน search_law) deka_privacy_note: มีเมื่อ case_law_by_semantic_search มีผล (full_text เสี่ยง PDPA) — **ไม่**นับ case_law_by_section เพราะมีแค่ summary field ไม่มี full_text ให้หลุด
get_gazette_documentดึงเอกสารเต็มจากราชกิจจานุเบกษาตามเล่ม/ตอน (เฉพาะ corpus='gazette'). (เล่ม, ตอน) = ราชกิจจาฯ หนึ่งฉบับซึ่งมีหลายเอกสาร — ใส่ category/no เพื่อเจาะจง. ใช้กับตัวบทกฎหมาย (corpus='law') หรือคำพิพากษาฎีกาไม่ได้ — ใช้ get_law_document/get_deka แทน นับโควตารายเดือน 1 ครั้งต่อการเรียก (เท่ากับ search_law) Args: book_no: เลขเล่ม (bookNo) เช่น "142" section: เลขตอน (section) เช่น "1" category: ประเภท เช่น "ก" (กรองให้แคบลง) no: เลขลำดับเอกสาร (จาก field "no" ในผล search_law) เพื่อระบุเอกสารเดียว Returns: documents: เอกสาร + full_text + citation; disclaimer + attribution quota: used/limit (null ถ้า service token/dev)
get_law_documentดึงเอกสารกฎหมายเต็มด้วย law_code — แก้ช่องว่างเดิมที่ไม่มีทางดึงตัวบทเต็มด้วย ID ตรงๆ (get_gazette_document ใช้กับ law ไม่ได้: ingest เขียน book_no/section เป็น NULL เสมอสำหรับ ตัวบท เหมือนปัญหาเดียวกับ deka ก่อน get_deka มีขึ้น) นับโควตารายเดือน 1 ครั้งต่อการเรียก (เท่ากับ search_law) Args: law_code: รหัสกฎหมาย จาก citation.law_code ของผล search_law unit_label: ระบุ = เฉพาะมาตรานั้น (เช่น "มาตรา 288", จาก citation ของผล search_law); ไม่ระบุ = ทั้งฉบับ (มี guard ด้านล่างกัน context blow-up สำหรับประมวลกฎหมายใหญ่) timeline_code: ระบุ = ฉบับแก้ไขนั้นเจาะจง (จาก get_law_versions); ไม่ระบุ = ฉบับล่าสุด Returns: found: False ถ้าไม่เจอ law_code/unit_label/timeline_code นี้ citation, full_text (None ถ้าฉบับมีมาตรามากเกินไปและไม่ระบุ unit_label — ดู section_index แทนแล้วเรียกซ้ำพร้อม unit_label เจาะจง) section_index: รายชื่อ unit_label ทั้งหมดของฉบับนี้ (มีเฉพาะตอน full_text=None) quota: used/limit (null ถ้า service token/dev) disclaimer + law_freshness_note + attribution
get_law_versionsฉบับแก้ไขทั้งหมดของมาตรานี้ เรียงเก่า→ใหม่ — ใช้เลือก timeline_code ไปเรียก get_law_document (แก้ช่องว่างเดิมที่ include_all_versions=True ของ search_law แค่ปิด dedup ทำให้ผลลัพธ์ปนทุกฉบับ ตามอันดับ relevance ไม่ใช่รายการที่เลือกฉบับเจาะจงได้) Args: law_code: รหัสกฎหมาย จาก citation.law_code ของผล search_law unit_label: เลขมาตรา จาก citation ของผล search_law (เช่น "มาตรา 288") Returns: versions: [{timeline_code, version_seq, is_current}] เรียงเก่า→ใหม่ (ว่าง = ไม่เจอ) count, disclaimer, attribution
verify_citationตรวจการอ้างอิงกฎหมายไทยแบบ deterministic — **ไม่ใช่ AI judge ตัดสินถูก/ผิดเชิงเนื้อหา** (server นี้ไม่มี LLM client ภายใน) แค่ตรวจว่า: (1) คดี/มาตรานี้มีอยู่จริงในคลังไหม (2) ถ้าอ้างว่า คดีนี้อ้างมาตราอะไร ตรวจกับข้อมูล citation ที่เก็บไว้จริง (3) ถ้ามีข้อความอ้างว่าเป็น quote ตรวจว่ามีอยู่ใน full_text จริงแบบ exact match. **ไม่ตัดสินทิศทางคำวินิจฉัย (holding)** — อ่าน full_text/section_text ที่ส่งกลับมาเองเสมอเพื่อสรุปว่าคำตอบที่จะให้ผู้ใช้ตรงทิศจริงไหม ระบุได้ 2 โหมด (เลือกอย่างใดอย่างหนึ่ง ห้ามผสมกัน): - ฎีกา: deka_no (+ cited_law/cited_section/quoted_text เสริมได้) - มาตราตัวบท: law_code + unit_label (+ quoted_text เสริมได้) — unit_label บังคับเสมอ นับโควตารายเดือน 1 ครั้งต่อการเรียก (เท่ากับ tool อื่น) Args: deka_no: เลขฎีกา เช่น "1729/2569" (รับ "ฎีกาที่ 1729/2569"/"คำพิพากษาศาลฎีกาที่ 1729/2569" /เลขไทยได้ — normalize ให้เอง) คดีรวมสำนวน (รูป "N-M/ปี") คืน cannot_verify เสมอ (ต้องตรวจมือ ไม่ verify อัตโนมัติ) law_code: รหัสกฎหมาย จาก citation.law_code ของผล search_law — ใช้คู่กับ unit_label เสมอ unit_label: เลขมาตรา เช่น "มาตรา 420 ทวิ" — บังคับถ้าระบุ law_code (ตรวจมาตราเจาะจง ไม่ใช่ทั้งฉบับ — ใช้ get_law_document แทนถ้าต้องการทั้งฉบับ) cited_law: ตัวย่อกฎหมายที่อ้างว่าฎีกานี้อ้างถึง เช่น "ป.อ." (คู่กับ deka_no+cited_section) cited_section: เลขมาตราที่อ้างว่าฎีกานี้อ้างถึง (คู่กับ deka_no+cited_law) quoted_text: ข้อความที่อ้างว่ามาจากคดี/มาตรานี้ — ตรวจ exact substring (ไม่ fuzzy/embedding) Returns: case_status (โหมดฎีกา) หรือ statute_status (โหมดมาตรา): "verified" | "not_found_in_corpus" | "cannot_verify" reason: เหตุผลเมื่อไม่ verified (None ถ้า verified) duplicate_count: จำนวนแถวที่ตรงเลขฎีกา (เฉพาะโหมดฎีกา, 1=ไม่ซ้ำ) citation_attribution: "verified"|"not_found"|"unknown"|"cannot_verify"|None — None ถ้า ไม่ได้ส่ง cited_law มาเลย; "cannot_verify" ถ้าส่งมาแต่ case_status ไม่ verified (ไม่มี ข้อมูล cited sections ให้เช็คตั้งแต่แรก) quote_grounding: "verified"|"not_found"|"cannot_verify"|None (None = ไม่ได้ส่ง quoted_text) matched_snippet: context รอบข้อความที่เจอ (มีเฉพาะตอน quote_grounding="verified") full_text/section_text: เนื้อหาเต็ม — อ่านเองเพื่อตัดสิน holding direction title_marked_repealed: doctitle มีคำว่า "(ยกเลิก)" ไหม (แค่ title marker ไม่ใช่สถานะ ทางกฎหมายที่ยืนยันแล้ว) law_code/timeline_code/source_url: statute mode ที่ verified เท่านั้น (null โหมด/สถานะอื่น) — timeline_code คือฉบับที่ resolve จริง (ฉบับล่าสุดเสมอเมื่อไม่ระบุ timeline_code เอง) warnings: คำเตือนเพิ่มเติม (ซ้ำ/ไม่มี holding field/sync อาจ lag/ฯลฯ) quota: used/limit (null ถ้า service token/dev หรือข้าม quota ระหว่าง incident) deka_privacy_note: แนบเฉพาะตอนมี full_text ของ deka จริง (เหมือน get_deka) disclaimer, attribution
batch_citation_auditตรวจการอ้างอิงกฎหมาย/คำพิพากษาฎีกาทุกจุดในเอกสารเดียวรวดเดียว — **Pro-tier เท่านั้น** (นับโควตา 1 หน่วย/call คงที่เสมอ ไม่ว่าจะเจอกี่ citation ข้างในก็ตาม). สแกนหา "มาตรา N" (รองรับ chained list เช่น "มาตรา 288, 289 และ 297 ประกอบมาตรา 83") + "ฎีกาที่ N/ปี" แล้วตรวจ แต่ละจุดแบบ deterministic ด้วย verify_citation() ภายใน — **ไม่ใช่ AI judge** เหมือนกันทุกประการ (ดู verify_citation docstring) ชื่อกฎหมายที่ตามด้วยมาตราเปล่าๆ ต่อเนื่องหลายจุด/หลายย่อหน้า ("sticky" carry-forward) ยังผูก กับชื่อกฎหมายที่ระบุไว้ล่าสุดถูกต้อง — **รองรับ 21 ฉบับ**: · **ประมวลกฎหมายไทยทั้ง 8 ฉบับ** — ป.พ.พ. · ป.วิ.พ. · ป.อ. · ป.วิ.อ. · ประมวลรัษฎากร · ประมวลกฎหมายที่ดิน · ประมวลกฎหมายยาเสพติด · ประมวลกฎหมายอาญาทหาร (รับทั้งชื่อเต็มและตัวย่อที่คำพิพากษาใช้จริง เช่น "ป.รัษฎากร"/"ป.ที่ดิน") · **พ.ร.บ. ที่คำพิพากษาอ้างบ่อยและไม่กำกวมอีก 13 ฉบับ** — ล้มละลาย · จัดตั้งศาลแรงงานและวิธีพิจารณาคดีแรงงาน · แรงงานสัมพันธ์ · คุ้มครองแรงงาน · ป่าไม้ · ควบคุมอาคาร · จัดตั้งศาลแขวงฯ · จัดตั้งศาลภาษีอากรฯ · ภาษีโรงเรือนและที่ดิน · การเช่าที่ดินเพื่อเกษตรกรรม · การรับขนของทางทะเล · มาตรการในการปราบปรามฯ ยาเสพติด · จัดตั้งศาลเยาวชนและครอบครัวฯ (รับทั้ง "พระราชบัญญัติ..." และ "พ.ร.บ...." มีปีหรือไม่มีก็ได้) ⚠️ **3 ใน 13 ฉบับนี้ doctitle มี marker "(ยกเลิก)"** — ภาษีโรงเรือนและที่ดิน 2475 · มาตรการในการปราบปรามฯ ยาเสพติด 2534 · จัดตั้งศาลเยาวชนและครอบครัวฯ 2534 — การอ้างมาตรา ของ 3 ฉบับนี้จะคืน status="verified_title_marked_repealed" แทน "verified" ซึ่ง**ยังแปลว่า พบมาตรานั้นจริง** แค่มี signal ว่าชื่อฉบับถูก mark ไว้ (ไม่ใช่สถานะทางกฎหมายที่ยืนยันแล้ว ดู title_marked_repealed) — คงไว้ในรายการโดยตั้งใจเพราะคำพิพากษาเก่าอ้างฉบับเหล่านี้จริง (ภาษีโรงเรือนฯ 367 ครั้ง) เวลาสรุปให้ผู้ใช้ต้องแนะนำให้ตรวจ source_url ว่ายังใช้บังคับไหม ⚠️ **พ.ร.บ. ที่มีหลายฉบับต่างปีและคำพิพากษาอ้างจริงทั้งคู่ จงใจไม่รองรับ** — ศุลกากร 2469/2560 · เช็ค 2497/2534 · ลิขสิทธิ์ 2537/2521 · จราจรทางบก 2522/2477 · อนุญาโตตุลาการ 2545/2530 · เครื่องหมายการค้า 2474/2534 · อาวุธปืน 2477/2490 ฯลฯ ต้องรู้ปีถึงชี้ชัดได้ ปล่อยเป็น unresolved ปลอดภัยกว่าเดา มาตราที่ไม่มีชื่อกฎหมายกำกับเลยก่อนหน้าในเอกสาร **หรือกำกับด้วยกฎหมายนอก 21 ฉบับนี้** → ไม่เดา (status="cannot_verify", reason="unresolved_law_name", law=None) — เรียก verify_citation(law_code=...) ตรงๆ เองถ้ารู้ law_code ที่แน่ชัดอยู่แล้ว (verify_citation รับกฎหมาย**ฉบับใดก็ได้ในคลัง** ไม่จำกัด 21 ฉบับนี้) ⚠️ **ชื่อฉบับแก้ไขไม่ใช่ฉบับแม่**: "พ.ร.บ.คุ้มครองแรงงาน (ฉบับที่ 7) พ.ศ. 2562 มาตรา 4" → unresolved โดยตั้งใจ (มาตรา 4 เป็นของฉบับแก้ไข ไม่ใช่ของฉบับแม่ซึ่งมีมาตรา 4 อยู่จริง) เช่นเดียวกับ "ออกตามความใน<ชื่อกฎหมาย>" (กฎหมายลำดับรอง) และ "แก้ไขเพิ่มเติม<ชื่อกฎหมาย>" ⚠️ `law` ที่คืนมาเป็น string เดียวกับที่ `deka_citations.law` เก็บจริง จึงส่งต่อไป deka_by_section(law=...) ได้ตรงๆ — **ต่างจาก citation.law_abbrev ของ search_law ที่ยัง ครอบแค่ 4 ประมวลหลัก** (คนละตาราง คนละหน้าที่ ดู core/config.py) ⚠️ ผลลัพธ์คือ "batch existence + currency check" ไม่ใช่ full legal-reasoning audit — ไม่ตัดสิน ทิศทางคำวินิจฉัย/เนื้อหาทางกฎหมายใดๆ เหมือน verify_citation ทุกประการ ⚠️ **ต่างจาก get_deka/verify_citation ตรงนี้โดยตั้งใจ**: tool นี้หักโควตาก่อนเช็ค `deka_guard.blocked()` เสมอ (ไม่ skip quota ตอน gate ปิดเหมือน 2 tool นั้น) เพราะเอกสาร 1 ฉบับ มักมีทั้ง citation มาตรา+ฎีกาปนกัน — ตอน deka gate ปิดชั่วคราว citation มาตรายังตรวจได้ปกติ (ไม่ได้รับผลกระทบเลย) การ skip โควตาทั้ง call เพราะฎีกาบางจุดตรวจไม่ได้ชั่วคราวจะทำให้เอกสารที่ มีแต่มาตราล้วนก็โดน skip ไปด้วยอย่างไม่ถูกต้อง (ต่างจาก get_deka/verify_citation ที่รู้ล่วงหน้า ว่า call นั้นเป็นฎีกาล้วนๆ ก่อนหักโควตา) — เอกสารที่มีแต่ citation ฎีกาแล้วเจอ deka gate ปิดพอดี จะได้ status="cannot_verify" ทุกจุดแต่ยังเสีย 1 credit ตามปกติ (ไม่มี partial-refund path) Args: document_text: เนื้อหาเอกสารเต็ม — สูงสุด 50,000 ตัวอักษร Returns: citations: [{type: "law"|"deka", law, section, deka_no, positions (char offset ทุกจุดที่ เจอ citation นี้ซ้ำในเอกสาร — ตรวจครั้งเดียวแต่รายงานทุกตำแหน่ง), status: "verified"| "not_found"|"cannot_verify"|"verified_title_marked_repealed", reason, retryable, evidence_snippet (≤1200 ตัวอักษร, มีเฉพาะตอน status ขึ้นต้นด้วย "verified")}] reason/retryable: มีเฉพาะตอน status ไม่ใช่ "verified"/"verified_title_marked_repealed" (เป็น null ตอน verified เสมอ) — reason ที่พบได้: "unresolved_law_name" (เอกสารไม่ได้ระบุ ชื่อกฎหมายกำกับไว้ก่อนหน้า หรือระบุเป็นกฎหมายนอก 21 ฉบับที่ระบบตรวจได้, retryable=false ต้องแก้เอกสาร/ตรวจเอง), "section_not_found_in_this_version" (มาตรานี้ไม่มีในฉบับล่าสุด อาจมีในฉบับแก้ไขเก่ากว่า — เรียก get_law_versions ต่อ, retryable=false), "merged_case_needs_manual_review"/"exists_but_not_servable" (ลักษณะ ถาวรของคดี ต้องตรวจมือ, retryable=false), "law_code_unknown"/"not_found_in_corpus" (deka)/"temporarily_unavailable"/"lookup_failed" (ระบบ/ParadeDB sync-lag ชั่วคราว — retryable=true, ลองเรียกใหม่ได้) ⚠️ **status="not_found" ไม่ใช่ข้อสรุปว่าการอ้างอิงนั้นเป็นของปลอม/ถูกแต่งขึ้น** — แปลว่า "ไม่พบในคลังที่ตรวจได้" เท่านั้น — มาจาก **3 reason คนละกลไก** ที่ `_status_from()` map เป็น status เดียวกันหมด (retryable ต่างกันได้แม้เป็น citation ประเภทเดียวกัน): · **ฎีกา** reason="not_found_in_corpus" (retryable=true) — คลังฎีกาไม่ได้ครอบทุกฉบับ (harvest scope เริ่มปี 2500) หรือเป็น ParadeDB sync-lag ชั่วคราว · **ตัวบท** reason="section_not_found_in_this_version" (retryable=false) — พบฉบับกฎหมาย แล้ว แต่ไม่มีมาตรานี้ใน**ฉบับล่าสุด** ซึ่ง **อาจมีอยู่ในฉบับแก้ไขเก่ากว่าที่คลังมีอยู่ แล้ว** (เรียก get_law_versions(law_code, unit_label="มาตรา " + section) ตรวจต่อ — **ต้องเติม "มาตรา " นำหน้าเสมอ** เพราะ section ที่คืนไปเป็นเลขเปล่า แต่การเทียบฝั่ง เซิร์ฟเวอร์เก็บ prefix ไว้ ส่งเลขเปล่าจะได้ count=0 ทั้งที่มาตรานั้นมีอยู่จริง — ไม่ใช่รอ sync และไม่ใช่การยืนยันว่ามาตรานี้ไม่เคยมีอยู่จริง) · **ตัวบท** reason="law_code_unknown" (retryable=true) — ไม่รู้จักตัวฉบับกฎหมายเลย (`_law_code_exists()` เป็นเท็จ) เป็น sync-lag ด้วยกลไกเดียวกับกรณีฎีกา เวลาสรุปให้ผู้ใช้ต้องบอกตามนี้ ห้ามสรุปว่า "ฎีกา/มาตรานี้ไม่มีอยู่จริง" — ผู้ใช้อาจตัด การอ้างอิงที่ถูกต้องทิ้งจากคำฟ้อง ให้แนะนำให้ตรวจกับต้นฉบับก่อนเสมอ law_code/timeline_code/source_url: null เสมอสำหรับ deka (ประเภท "law" เท่านั้น) — law_code มีค่าทันทีที่ resolve จาก abbrev ได้ (ไม่ต้องรอ verified — ใช้เรียก get_law_versions(law_code, unit_label="มาตรา " + section) ต่อได้เลยเมื่อ reason="section_not_found_in_this_version") timeline_code/source_url ต้อง status ขึ้นต้นด้วย "verified" เท่านั้น (ครอบทั้ง "verified" และ "verified_title_marked_repealed" — กรณีหลังยิ่งสำคัญเพราะต้องใช้ source_url ตรวจเองว่ายกเลิกจริงไหม) — timeline_code คือฉบับที่ resolve จริง (เสมอเป็น ฉบับล่าสุด ไม่ใช่ฉบับที่ตรงวันที่เอกสารต้นฉบับอ้างถึงเสมอไป — เทียบกับ get_law_versions ถ้าเอกสารเก่า), source_url ให้ตรวจต้นฉบับเองได้ตรงๆ total_citations_found: จำนวน unique citation ที่เจอทั้งหมด (ก่อน cap) citations_checked: จำนวนที่ตรวจจริง (≤50 เสมอ, น้อยกว่านั้นถ้าหยุดก่อนกำหนดเวลา) unique_citation_limit_exceeded: True ถ้าเจอ unique citation เกิน 50 (cap ตามลำดับที่ปรากฏ ในเอกสาร, deterministic — เรียกซ้ำกับส่วนที่เหลือของเอกสารเองถ้าต้องการ) extractor_capped: True ถ้า raw citation ในเอกสารเกิน 200 จุด — สัญญาณคนละตัวจาก unique_citation_limit_exceeded (extractor เองก็มี safety cap ของมันแยกต่างหาก) stopped_early + stopped_early_message: True เมื่อหยุดตรวจก่อนกำหนดเวลาภายใน (คืนผลบางส่วน ที่ตรวจสำเร็จแล้วจริงเสมอ ไม่ใช่แค่ raise timeout เปล่าๆ) quota: used/limit ของโควตา Pro (null ถ้า service token/dev) deka_privacy_note: มีเมื่อ citation ฎีกาอย่างน้อย 1 จุด verified (full_text หลุดมาบางส่วนใน evidence_snippet — เหมือน get_deka/verify_citation) not_found_note: มีเมื่อมี citation status="not_found" อย่างน้อย 1 รายการ — ย้ำ caveat ⚠️ ด้านบนให้อยู่ใน payload จริงตอนสรุปผล ไม่ใช่แค่ใน docstring นี้ (issue #501) **ไม่แนบ**กับ status="cannot_verify" ซึ่งมาจากเหตุคนละกลไก disclaimer, attribution
browseไล่ดูข้อมูลอ้างอิง/สถิติ — รวม list_categories เดิม + /stats + ตัวย่อกฎหมายที่ deka อ้างจริง. Args: kind: "law_types" | "subjects" | "law_abbreviations" | "coverage_stats" - law_types: ประเภทตัวบทกฎหมาย (พระราชบัญญัติ/ประมวลกฎหมาย/...) + count — กรองใน search_law - subjects: สาขาตัวบทกฎหมาย (แพ่ง/อาญา/ภาษี/ที่ดิน/แรงงาน/...) + count — กรองใน search_law (หมวดมาจากการจำแนกชื่อกฎหมายอัตโนมัติ — best-effort; บางฉบับไม่ถูกจัดสาขา) - law_abbreviations: ตัวย่อกฎหมาย (เช่น "ป.อ.") ที่คำพิพากษาฎีกาอ้างจริง + จำนวนครั้ง เรียงมาก→น้อย — ใช้เลือกค่าไปกรองใน deka_by_section(law=...) แทนการเดา/parse doctitle เอง - coverage_stats: จำนวนเอกสารรวมต่อ corpus + ช่วงปีที่ครอบคลุม (ราชกิจจาฯ) Returns: ขึ้นกับ kind (ดู Args ด้านบน) + disclaimer + attribution
get_dekaดึงคำพิพากษาศาลฎีกาฉบับเต็มด้วย **เลขฎีกา**. นับโควตารายเดือน 1 ครั้งต่อการเรียก (เท่ากับ search_law) Args: deka_no: เลขฎีกา เช่น "1729/2569" (คดีรวมสำนวนใช้รูป "257-258/2463") Returns: citation: เลขฎีกา/ปี/ผลคดี (ยืน/กลับ/แก้/…)/แผนกคดี/คู่ความ/องค์คณะ/ appellant (ผู้ยื่นฎีกา: "โจทก์"/"จำเลย"/"ทั้งสองฝ่าย"/"ผู้ร้อง"/"ผู้คัดค้าน"/ None ถ้าไม่พบ pattern) ⚠️ `verdict` เป็น **None** ได้ตามปกติเมื่อคำบังคับไม่ระบุผลเทียบศาลล่าง — เช่น "พิพากษาให้จำเลยชำระเงิน…" (โจทก์ชนะ) หรือ "พิพากษาใหม่ตามรูปคดี" (ย้อนสำนวน) **None ≠ ไม่มีคำบังคับ** (ดู `has_verdict_order`) แต่แปลว่าสรุปเป็นคำเดียวไม่ได้ → ต้องอ่าน `full_text` เอง ห้ามตีความว่าคดีไม่มีผล full_text: เนื้อคำพิพากษาเต็ม cited: มาตราที่อ้าง **แบบ structured** [{law, section, law_code, …}] quota: used/limit (null ถ้า service token/dev) (ไม่เจอ → found=False; gate ปิดชั่วคราว (self-check invariant trip) → found=False + reason="temporarily_unavailable" — แยกจาก "ไม่เจอจริง")
deka_by_sectionหาคำพิพากษาฎีกาที่อ้างมาตรานี้ — "มาตรานี้ถูกตีความยังไงบ้าง". นับโควตารายเดือน 1 ครั้งต่อการเรียก (เท่ากับ search_law) Args: law: ชื่อย่อกฎหมาย เช่น "ป.อ." "ป.พ.พ." "ป.วิ.อ." "ป.วิ.พ." section: เลขมาตรา เช่น "288" (มาตราขยายใช้รูป "193 ทวิ") limit: จำนวนสูงสุด (ค่าเริ่มต้น 20) Returns: results: [{no, year_be, verdict, department, doctitle}] เรียงใหม่→เก่า (เรียงด้วยเลขฎีกา เพราะต้นทางไม่มีวันที่คำพิพากษา) `verdict` เป็น **None** ได้ตามปกติ = คำบังคับไม่ระบุผลเทียบศาลล่าง (ยืน/กลับ/แก้/ยก…) ไม่ใช่ "ไม่มีผลคดี" — ดึง `get_deka(no)` อ่าน `full_text` ต่อถ้าต้องการผลจริง quota: used/limit (null ถ้า service token/dev) (gate ปิดชั่วคราว (self-check invariant trip) → count=0 + reason="temporarily_unavailable")
whoamiระบุตัวตนของผู้เรียก (จาก OAuth token) — ใช้ยืนยันว่า MCP รู้ว่าเป็น user ไหน. Returns: authenticated: True ถ้ามี token; user_id (subject) + scopes ถ้ามี support_email: อีเมลติดต่อทีมงาน (ใช้ได้แม้ผู้ใช้ยังไม่มีบัญชี)
submit_feedbackส่งความเห็น/รายงานปัญหาของ **ผู้ใช้** กลับให้ทีมงาน Thai Legal (ต้องเชื่อมต่อบัญชีแล้ว). **เรียกเมื่อไหร่** (เรียงจากชัดเจนที่สุด → คลุมเครือที่สุด): 1. ผู้ใช้ขอส่งตรงๆ — "ส่ง feedback" / "แจ้งปัญหา" / "รายงานให้ทีมงาน" ← ต้องไม่พลาด 2. ผู้ใช้ยืนยันว่ากฎหมาย/เอกสารที่ควรมีอยู่แต่ค้นไม่เจอ · เนื้อหาผิด · ขอความสามารถใหม่ 3. ผู้ใช้บอกว่าผลไม่ตรง **และเห็นชอบให้รายงาน** — ไม่ใช่แค่บ่นแล้วให้ค้นใหม่ **ห้ามเรียกเอง**เมื่อผู้ใช้เพียงเปลี่ยนคำค้นหรือถามคำถามใหม่ — รายงานที่ไม่ได้มาจากเจตนา ของผู้ใช้ทำให้ข้อมูลเป็นขยะและทำให้ทีมงานไล่ปัญหาที่ไม่มีอยู่ ข้อกำกับ: - **ส่งเฉพาะสิ่งที่ผู้ใช้พูดจริง ห้ามแต่งขึ้นเอง ห้ามสรุปให้นุ่มลง** — ใส่คำของผู้ใช้ใน message ให้ใกล้เคียงที่สุด - **ส่ง `query` ที่ใช้ค้นจริงมาด้วยเสมอ** — เป็นสิ่งเดียวที่ทำให้ทีมงาน reproduce ได้ ถ้าไม่มี รายงานนั้นแทบไร้ประโยชน์ - **ห้ามใส่ข้อมูลที่ระบุตัวบุคคล ชื่อลูกความ เลขคดี หรือข้อเท็จจริงของคดี** — เขียนเป็น ประเด็นกฎหมายเท่านั้น (ถ้าผู้ใช้พิมพ์มา ให้เรียบเรียงตัดส่วนที่ระบุตัวตนออกก่อน) Args: kind: ประเภทปัญหา — "data_gap" (ควรมีแต่หาไม่เจอ) | "wrong_result" (เจอแต่ไม่ตรง/ อันดับแย่) | "wrong_content" (เนื้อหาผิด/OCR เพี้ยน) | "stale_text" (ตัวบทล้าสมัย) | "feature_request" | "bug" | "other" (ค่าที่ไม่รู้จักจะถูกเก็บเป็น "other") message: เนื้อหารายงานด้วยคำของผู้ใช้ (บังคับ) query: คำค้นที่นำมาสู่ปัญหา — ควรใส่เสมอเมื่อเกี่ยวกับผลค้น expected: สิ่งที่ผู้ใช้คาดว่าควรเจอ เช่น "ควรเจอ ป.พ.พ. มาตรา 420" citations: อ้างอิงผลที่มีปัญหา (คัดจาก citation ของผล search_law เช่น law_code) Returns: ok: True = บันทึกแล้ว (มี reference ให้อ้างอิง) · False = ยังไม่บันทึก ดู reason reason: "auth_required" (ยังไม่เชื่อมบัญชี) | "rate_limited" | "empty_message" | "unavailable" (ระบบขัดข้องชั่วคราว) — ทุกกรณีมี support_email ให้ส่งตรงได้ reply: ข้อความที่ใช้บอกผู้ใช้ได้ทันที · duplicate: True ถ้าเคยรายงานเรื่องเดียวกันแล้ว