Skip to main content
Glama

lsth-mcp

Hệ thống MCP server giảm workload khối BU — Lucky Star LSTH.

Dựng theo Tài liệu hợp nhất v2.0 (09/09/2026) và Kiến trúc giải pháp MCP v1.0 (08/09/2026). Toàn bộ 17 thành phần đã có chỗ đứng trong cây thư mục; phần nền và lớp đọc/ghi đã chạy được, các server nghiệp vụ có hợp đồng tool đã chốt và ghi rõ khoảng trống dữ liệu đang chặn.

Cài và chạy

python3 -m pip install -e .          # cần Python 3.10+ cho MCP SDK
make test                            # 43 kiểm thử, không cần thư viện ngoài
make status                          # bức tranh 17 thành phần
make run                             # MCP server, chế độ stdio
make run-http                        # chế độ HTTP cho máy chủ nội bộ

Lớp đọc/ghi (lsth_mcp.io) chạy được trên Python 3.9 mà không cần MCP SDK — đủ để dùng như thư viện hoặc chạy script trước khi hạ tầng sẵn sàng.

Related MCP server: Office MCP Server

Nối vào Claude Cowork

python3.13 -m venv .venv && .venv/bin/pip install -e .
.venv/bin/python scripts/make_demo_data.py   # dữ liệu giả để thử
./scripts/serve.sh                           # server + URL công khai

Script in ra URL dạng https://…trycloudflare.com/mcp/<token> — dán vào Cowork → Customize → Connectors → + → Add custom connector.

Claude gọi từ đám mây của Anthropic chứ không phải từ máy bạn, nên bắt buộc phải có URL công khai; localhost không dùng được. Chi tiết và cách lên máy chủ thật: docs/DEPLOY.md.

Cây thư mục

lsth-mcp/
├── config/                  Cấu hình: vùng dữ liệu, quy ước tên, thiết lập chạy
├── data/
│   ├── raw/                 File gốc — CHỈ ĐỌC, máy không bao giờ ghi vào đây
│   ├── work/                Vùng làm việc, bản trung gian
│   ├── out/                 Bản nháp giao cho người soát
│   ├── templates/           F4 · kho khuôn đã duyệt
│   ├── identity/            F3 · bảng ánh xạ định danh
│   ├── eval/                F5 · bộ ca kiểm thử chất lượng
│   ├── state/               Trạng thái cổng quyền ghi
│   └── audit/               Nhật ký lệnh gọi, giữ 12 tháng
├── docker/                  MinIO — kho lưu trữ file (docker compose)
├── docs/                    Kiến trúc, hợp đồng tool, khoảng trống dữ liệu, lộ trình
├── scripts/                 serve.sh · status · write_gate · scan_drive · run_eval
├── src/lsth_mcp/
│   ├── core/                Lớp nền
│   │   ├── models.py            F2 · năm thực thể chuẩn
│   │   ├── provenance.py        Nguyên tắc 4 · mọi giá trị kèm nguồn
│   │   ├── envelope.py          Khung {ok, data, sources, warnings, error}
│   │   ├── errors.py            Nguyên tắc 5 · lỗi nói được phải làm gì
│   │   ├── permissions.py       Ma trận quyền + cổng "đọc trước, ghi sau"
│   │   ├── zones.py             Nguyên tắc 6 · bốn vùng dữ liệu
│   │   ├── erp.py               Bản đồ ERP rút từ 9 cẩm nang nội bộ
│   │   ├── audit.py             Nhật ký sáu trường
│   │   ├── paths.py             Ràng buộc đường dẫn + quy ước tên file
│   │   └── config.py
│   ├── io/                  ⬅ CÁC MODULE ĐỌC GHI
│   │   ├── base.py              ReadResult · WriteResult
│   │   ├── registry.py          read_any() · list_files() — điểm vào đọc
│   │   ├── readers/             excel · pdf · tabular · jsonio · text/docx
│   │   ├── writers/             safe · excel · structured
│   │   └── storage/             đĩa cục bộ hoặc MinIO — reader không cần biết
│   ├── domain/              F3 identity · F4 templates · F5 evalset
│   ├── servers/             12 server: S1–S7, M1–M5
│   └── server.py            F1 · cổng điều phối, điểm vào MCP
└── tests/

Lớp đọc/ghi

Tìm file và xem cây dữ liệu

Gateway có 16 tool, gồm file_search và file_tree dùng metadata để duyệt MinIO hoặc các thư mục dữ liệu cục bộ, không đọc nội dung file:

file_search(query="S2749189", root="raw")
file_search(query=".xlsx", root="s3://lsth-raw/orders/")
file_tree(root="raw", max_depth=4, limit=200)
file_tree(root="s3://lsth-raw/", query="S2749189 BOM")
file_tree(root="raw", query="cong viec")

file_search và file_tree(query=...) tìm theo mọi từ trong tên/đường dẫn tương đối, không phân biệt hoa thường và dấu tiếng Việt (ví dụ cong viec tìm được công việc). file_tree giữ các thư mục cha của file khớp, trả cả cây JSON và tree_text dễ đọc. Bỏ query hoặc truyền chuỗi rỗng để xem toàn cây. matched_count là số file khớp trong phần đã quét, trước khi áp limit; không phải tổng toàn kho nếu scan_truncated=true. Thư mục được suy ra từ file nên không hiển thị thư mục rỗng. Cả hai giữ đường dẫn nguồn s3:// khi dùng MinIO. limit giới hạn kết quả (tối đa 1.000 file); scan_limit giới hạn metadata được xét (mặc định 10.000, tối đa 100.000). truncated/scan_truncated báo kết quả chưa đầy đủ; depth_limited và collapsed báo cây đang thu gọn theo max_depth.

Sau khi cập nhật, cần nạp lại tiến trình server và danh sách tool ở MCP client. Thêm tool không tự khắc phục việc client chưa nạp kết nối MCP vào phiên chat.

Đọc — lsth_mcp.io.readers

Module

Định dạng

Dùng cho

excel.py

.xlsx .xlsm

BOM 30 cột, file khảo sát, file xuất ERP — tự dò dòng tiêu đề

pdf.py

.pdf

Tech pack 48–86 trang; báo rõ trang nào là ảnh scan

tabular.py

.csv .tsv

Bảng ánh xạ định danh, dữ liệu trao đổi

jsonio.py

.json .jsonl

Hợp đồng dữ liệu giữa server, bộ ca kiểm thử

text.py

.txt .md .docx

Tài liệu mô tả công việc

Mọi reader trả về ReadResult mang theo sources — file, sheet, dòng, trang. Điểm vào chung là read_any(path), tự chọn đúng reader theo đuôi file.

from lsth_mcp.io import read_any

result = read_any("BOM_66P866.xlsx", sheet="BOM")
result.rows[0]                  # {"Style": "66P866", "Material Code": ...}
result.sources[0].label()       # "BOM_66P866.xlsx · sheet BOM · dòng 5"

Ghi — lsth_mcp.io.writers

Mọi thao tác ghi đi qua SafeWriter, nơi bốn ràng buộc được áp cùng lúc:

  1. Cổng quyền ghi — nguyên tắc 2: server chỉ ghi được sau khi chạy đúng 5 mã hàng thật

  2. Vùng ghi — chỉ work/, out/, state/; không bao giờ đè lên raw/

  3. Ghi nguyên tử — file tạm rồi đổi tên, không để lại file nửa vời

  4. Sao lưu trước khi đè — nguyên tắc 8, luôn giữ được đường lùi

from lsth_mcp.io import SafeWriter, write_rows

writer = SafeWriter.for_server("s6_packing", role="merchandiser_owner",
                               resource="packing")
write_rows(writer, "data/out/66P866_US_TLDG_v1.xlsx", rows,
           needs_human={0: ["upc"]})   # ô máy không tra được nguồn -> tô vàng

Không hàm nào ở lớp ghi gửi mail, đặt hàng hay đẩy dữ liệu ra hệ thống khách — nguyên tắc 1, máy soạn nháp, người bấm nút.

Kho lưu trữ file

Mặc định đọc thư mục data/ trên đĩa. Bật MinIO thì thêm LSTH_STORAGE=minio vào .env — không sửa dòng code nào, reader và writer đều không biết file nằm ở đâu.

make minio-up      # bật MinIO, tạo 6 bucket kèm chính sách quyền
make minio-sync    # đẩy data/ lên kho

Sáu bucket, mỗi vùng một chính sách: lsth-raw, lsth-templates, lsth-identity là chỉ đọc ngay ở tầng MinIO — code sai cũng không ghi đè được file gốc. Chi tiết: docs/STORAGE.md.

Tám nguyên tắc, nằm ở đâu trong code

#

Nguyên tắc

Thực thi ở

1

Máy soạn nháp, người bấm nút

io/writers/ chỉ ghi xuống ổ nội bộ; dấu "BẢN NHÁP" trên mọi file sinh ra

2

Đọc trước, ghi sau

core/permissions.py · WriteGate — 5 mã hàng mới mở

3

Một nguồn sự thật

errors.ConflictError · domain/identity.py báo mâu thuẫn, không tự chọn

4

Trả lời kèm nguồn

core/provenance.py · sources[] bắt buộc trong mọi envelope

5

Hỏng thì im lặng, không đoán

core/errors.py · BomLine._to_float · net_consumption() trả None

6

Dữ liệu ở đâu, xử lý ở đó

core/zones.py · config/data_zones.yaml

7

Hai người biết vận hành

README từng server ghi người nghiệm thu; docs/RUNBOOK.md

8

Luôn giữ được đường làm tay

Sao lưu trước khi đè; raw/ bất khả xâm phạm ở cả hai tầng — Python và chính sách MinIO

Trạng thái hiện tại

Chạy được: F1 cổng điều phối · F2 mô hình dữ liệu · F3 ánh xạ định danh · F4 kho khuôn · F5 bộ đánh giá · toàn bộ lớp đọc/ghi · S1 bom_extract và diff_check.

Chờ lấp khoảng trống dữ liệu: 9 server còn lại. Xem docs/DATA_GAPS.md — và make status để biết cái nào đang chặn cái nào.

Đã đọc Use_guide/ (9 cẩm nang ERP nội bộ) — kết quả ở docs/ERP_MAP.md. Lấp được một phần G1: ERP là web app có app di động, nên phía sau gần như chắc chắn có API HTTP; và 19/25 module xuất được Excel nên đường dự phòng qua file chắc chắn dùng được. Quy tắc nối mã của F3 cũng đã có văn bản và đã được cài vào domain.identity.erp_style_number().

Không nên dựng thêm thành phần nào trước khi lấp xong G1, G4, G5 và ít nhất một nửa G6. Dựng trên dữ liệu chưa rõ nghĩa thì phải làm lại từ đầu, và làm lại lần hai sẽ mất niềm tin của người dùng.

Available Tools

16 tools
audit_tailC

Chương 11 — xem lệnh gọi gần nhất: ai gọi, lúc nào, đọc file nào, kết quả sao.

Inputs: limit. Returns: result

bom_diffA

S1 — so tech pack với BOM, báo mâu thuẫn chứ không tự chọn (nguyên tắc 3).

Inputs: bom_file (required), techpack_file (required), bom_sheet. Returns: result

bom_extractC

S1 — bóc BOM xlsx ra BomLine[] theo hợp đồng dữ liệu F2.

Inputs: file (required), limit, sheet. Returns: result

csv_writeB

Xuất CSV (utf-8-sig, mở bằng Excel không vỡ dấu tiếng Việt).

Inputs: path (required), rows (required), server, dry_run. Returns: result

excel_sheetsA

Liệt kê sheet của một file Excel trước khi quyết định đọc sheet nào.

Inputs: path (required). Returns: result

excel_writeC

Xuất bảng ra Excel. Mặc định đóng dấu 'BẢN NHÁP DO MÁY DỰNG' ở dòng đầu.

Inputs: path (required), rows (required), server, dry_run, +2 more. Returns: result

file_listD

Liệt kê file trong vùng dữ liệu cho phép.

Inputs: root, limit, pattern. Returns: result

file_readB

Đọc bất kỳ file nào được hỗ trợ: xlsx, pdf, csv, json, docx, txt.

Inputs: path (required), limit, pages, sheet. Returns: result

file_treeA

Tìm trong cây thư mục MinIO/S3 hoặc local; trả tree JSON và tree_text dễ đọc.

root: tên vùng, URI s3://lsth-raw/thư-mục/ hoặc thư mục local. query: mã hàng, tên file/thư mục hoặc đuôi file; khớp mọi từ, không phân biệt dấu tiếng Việt và hoa thường. Ví dụ query='S2749189 BOM', root='s3://lsth-raw/'. Giữ nhánh cha của file khớp; bỏ query để hiện toàn cây. Không gồm thư mục rỗng. limit giới hạn số file; max_depth tính từ root, thư mục sâu hơn có collapsed=true. matched_count là số file khớp trong phần đã quét; scan_truncated=true nghĩa là chưa quét hết.

Inputs: root, limit, query, max_depth, +1 more. Returns: result

file_writeC

Ghi file chữ vào data/work hoặc data/out. Đi qua cổng quyền ghi.

Inputs: path (required), content (required), server, dry_run. Returns: result

identity_resolveD

F3 — đổi mã giữa các hệ: LS-style ↔ style khách ↔ UPC ↔ mã vật tư.

Inputs: value (required), to_system (required), from_system (required), market, +1 more. Returns: result

json_writeD

Ghi JSON — định dạng trao đổi giữa các server theo hợp đồng F2.

Inputs: data (required), path (required), server, dry_run. Returns: result

program_statusD

Bức tranh 17 thành phần: cái nào đã dựng, cái nào đang chờ lấp khoảng trống.

Inputs: no named parameters. Returns: result

techpack_parseC

S1 — bóc tech pack PDF ra thực thể Style.

Inputs: file (required), max_pages. Returns: result

template_getB

F4 — lấy file khuôn đã duyệt cho một loại tài liệu.

Inputs: kind (required), market, customer. Returns: result

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    C2.5/5.0

    Scored across 16 tools

    Disambiguation3/5

    file_search and file_tree both accept queries and return file matches, and file_list overlaps with simple enumeration. The descriptions clarify flat list versus tree output, but an agent may still hesitate when choosing among the three discovery tools.

    Naming Consistency4/5

    Most tools follow a predictable resource-first snake_case pattern like file_read, csv_write, identity_resolve, and bom_extract. A few names such as excel_sheets, program_status, and audit_tail are noun phrases rather than command-style, but the overall convention is readable and consistent.

    Tool Count3/5

    16 tools sits in the borderline-heavy range, and the three file-discovery tools plus three format-specific writers add some redundancy. The domain-specific tools for identity, templates, techpack/BOM processing, status, and audit appear purposeful, so the count is not excessive for the intended workflow.

    Completeness3/5

    File discovery, read/write, format export, parsing, and audit coverage are present. Obvious gaps remain: no file delete/move/update, no template listing, and truncated file searches have no continuation mechanism, so agents may hit dead ends in larger scans.

    Maintenance

    ActivityStale
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      D
      maintenance
      MCP server for reading and writing .xls (Excel 97-2003) files, enabling data manipulation, sheet listing, and metadata retrieval.
      MIT
    • A
      license
      A
      quality
      C
      maintenance
      MCP server for reading and inspecting local Excel files (.xlsx, .xlsm, .xls, .xlsb, .ods) with tools for inspecting metadata, reading ranges, and profiling structure.
      3
      9 npm
      MIT
    • A
      license
      Not graded
      quality
      B
      maintenance
      A security-first, read-only MCP server that lets clients browse and read text, PDF, and XLSX files from an explicit allowlist of local folders, with strict path and secret protections.
      MIT