Khám phá Learn Học nhanh Stream About Jokes
SHIP WITH CLAUDE Build App nội bộ cho công ty. Ship app của riêng bạn với Claude Code Đăng ký →
Bài viết

Giao skill qua MCP khi Claude chưa hỗ trợ skills/list

Spec MCP Skills đã Final nhưng Claude chưa gọi skills/list. Figma MCP vẫn làm Claude Code đọc được skill bằng resource thường, nên mình dựng server theo cách đó trước và chờ Claude hỗ trợ bản native.

Công cụ & Stack

Giao skill qua MCP khi Claude chưa hỗ trợ skills/list

Mình đang build một MCP server cho học viên. Mỗi bạn kết nối Claude qua OAuth, rồi Claude gọi vào platform bằng code mode: chỉ có search và execute. Vì sao chọn kiểu này thì mình có viết trong bài Code mode đừng bắt AI gọi tool mãi: Claude tự tìm route rồi gọi qua execute, thay vì phải học một danh sách tool dài.

Nhưng API chỉ trả lời được câu Claude đã biết hỏi. Một bạn hỏi khóa học nào đang có, membership hoạt động ra sao, tại sao bài học bị khóa, hoặc mua thế nào cho đúng, thì Claude cần biết platform này vận hành theo logic nào trước đã. Nếu không, nó gọi được route nhưng vẫn nói chuyện như một người mới vô website lần đầu.

Claude cần một cuốn sổ tay

Mình muốn ship cùng server một skill. Agent Skills, ở dạng đơn giản nhất, là file SKILL.md: đầu file ghi tên và mô tả, bên dưới là hướng dẫn cho Claude. Phần dài nằm trong references/; Claude chỉ mở khi cần, nên không nhét toàn bộ kiến thức vô context.

Ban đầu mình chia nó theo task: mua course một skill, kiểm tra account một skill, tìm lesson một skill. Viết một hồi thì thấy sai. Học viên đâu có đi qua platform như một loạt task rời nhau; họ cần Claude hiểu một site từ góc nhìn người đang học: cái gì là course, cái gì là membership, quyền xem nằm ở đâu, khi nào cần hỏi lại. Mình đổi thành một platform skill cho mỗi site. Task skill có thể xuất hiện sau, nếu một việc đủ riêng và lặp lại đủ nhiều.

MCP đã có cách chính thức cho chuyện này. Extension MCP Skills, SEP-2640, ở trạng thái Final: server trả skills/list với skill, danh sách file, sha256 và kích thước; client gọi skills/get, rồi đọc bằng resources/read tại URI như skill://ard/SKILL.md. Mỗi skill tối đa 512 file và 16 MiB. Tên không có trả lỗi -32602.

Phần quan trọng nằm ở host, tức Claude app chứ không phải server. Host phải đối chiếu hash và size, hỏi lại người dùng khi nội dung đổi, và không được tự load skill chỉ vì vừa kết nối server. Nghĩa là người dùng biết Claude đang nhận thêm chỉ dẫn gì, còn server không lén thay nội dung sau khi đã được đồng ý.

Spec đã có, Claude thì chưa

Lúc viết bài này, client hỗ trợ chính thức có ChatGPT, fast-agent, MCP Inspector và MCPJam ở mức partial. Claude web, Desktop, Code chưa có; TypeScript SDK cũng còn pull request mở. Nếu server chỉ trả skills/list và skills/get, học viên dùng Claude không nhận được gì.

Mình đang dùng MCP server của Figma trong Claude Code, và Claude Code vẫn tự load rồi làm theo skill của Figma. Nên mình xem Figma đang đưa gì cho client. Server đó không có skills/list.

Figma đăng từng skill như một MCP resource bình thường, chẳng hạn skill://figma/figma-use/SKILL.md. Resource có title Skill: figma-use, type text/markdown, size; Figma viết description để bảo Claude load skill này trước mỗi lần gọi use_figma. Figma đăng các file tham khảo thành resource riêng và bảo Claude đọc SKILL.md trước. Server còn có skill://index.json, liệt kê toàn bộ skill theo discovery format của agentskills.io, dùng schema https://schemas.agentskills.io/discovery/0.2.0/schema.json.

Figma cũng ghi tên từng skill và URI trong instructions của server. Claude Code đưa phần này vô system prompt, rồi đọc resource khi cần. Claude chỉ cần thấy chỉ dẫn và mở đúng file.

Một bộ file, hai đường phục vụ

Mình giữ skill files ở một chỗ, rồi phục vụ đúng các byte đó theo hai đường. Trước mắt mình dùng đúng dạng Figma: MCP resources, skill://index.json, và instructions. Với client không đưa resource cho model, code mode có thêm hai route: GET /skills trả catalog, còn GET /skills/{name} trả danh sách file cùng hash.

Mình để đường thứ hai cho sau này. Khi Claude hỗ trợ MCP Skills, server trả skills/list và skills/get từ chính bộ file ấy, dùng lại URI và byte cũ. Mình không cần viết lại nội dung skill chỉ vì client đã kịp hiểu spec.

Có một chỗ chưa xong. Library code mode mình đang dùng dựng MCP server mà không có instructions; mình đang thêm phần đó vào. Nếu library không nhận, mình sẽ đặt dòng read skill://ard/SKILL.md first trong description của tool execute, vì mọi client đều đọc description của tool này.

Mình cũng buộc quyền xem đi cùng cách phục vụ. Server chỉ đăng ký resource của những skill học viên đang sở hữu. Skill chưa sở hữu không có trong resource list, không có trong index.json, và ai đọc thẳng URI của nó sẽ nhận -32602 như một skill không tồn tại. Nếu server trả hai loại lỗi khác nhau, người ta chỉ cần đoán tên skill để biết mình đang bán hay đang chuẩn bị cái gì.

Với skill trả phí hoặc đang khóa, server chỉ hiện teaser trong GET /skills: tên, mô tả, offer giá. Mình không đăng chúng thành resource. Claude mà thấy file trong danh sách rồi đọc bị từ chối thì phần kiểm tra của host không còn đúng nữa.

Đổi một byte thì phải hỏi lại

Khi server build store, server tính sha256 từng file và tạo version id từ danh sách file. Server phục vụ đúng bytes đã hash. Đổi một byte thì version đổi; Claude app hỏi người dùng lại. Skill bán cũng không kèm allowed-tools, vì quyền chạy lệnh phải nằm ở server và OAuth chứ không nằm trong một file hướng dẫn.

Mình cũng không muốn tài liệu API và skill mỗi bên nói một kiểu. Khi server khởi động, server đọc OpenAPI document của chính nó rồi sinh phần API trong skill: từng route dùng để làm gì, gọi lúc nào, theo đúng thứ tự một cuộc trò chuyện thật. Mình viết test để nó fail nếu route đổi mà skill không đổi theo. Mình đặt phần do người viết, như platform là gì, quyền truy cập vận hành ra sao, account gặp vấn đề gì, trong config của platform.

Trong skill, phần mua hàng viết khá chặt: Claude báo giá trước, đưa bản tóm tắt, chờ một câu đồng ý rõ ràng, gọi một lần xác nhận riêng, rồi chỉ thanh toán qua payment link. Claude không được tự suy ra người dùng “chắc muốn mua”. Khi tiền và quyền truy cập đi qua cùng một cuộc chat, một phỏng đoán sai là đủ tạo ra một đơn sai.

Skill không giữ được bí mật

Có một giới hạn khá thẳng: Claude đã load skill thì nội dung đó có thể bị copy. Text trong context không có DRM. Mình thấy giá trị nằm ở chuyện chọn đúng cái cần viết, cập nhật nó khi platform đổi, rồi đóng gói cùng course; secret thiệt sự không được đặt trong skill.

Claude chưa hỗ trợ cách native, nên mình đang build server theo đường resources trước. Mình cũng chưa biết về lâu dài skill sẽ thành chỗ mặc định để product truyền kiến thức cho agent, hay prompt và tool description vẫn đủ cho những site nhỏ. Khi bạn đưa AI agent của khách kiến thức về sản phẩm mình làm, bạn sẽ đặt nó ở prompt, description của tool, hay trong một skill đi theo client qua từng version?


Cheatsheet cho agent của bạn

Dán phần này cho AI agent của bạn khi nó cần dựng server giao skill qua MCP.

Resources (resources/list) theo hình Figma, ví dụ skill tên ard:

[
  {
    "uri": "skill://index.json",
    "name": "skill-index",
    "mimeType": "application/json"
  },
  {
    "uri": "skill://ard/SKILL.md",
    "name": "ard",
    "title": "Skill: ard",
    "description": "Load BEFORE the first search/execute call about this platform's courses, membership, orders or workshops.",
    "mimeType": "text/markdown",
    "size": 4096,
    "_meta": { "size": 4096 }
  },
  {
    "uri": "skill://ard/references/buying.md",
    "name": "ard/references/buying.md",
    "title": "ard reference: references/buying.md",
    "description": "Reference for ard. You must read skill://ard/SKILL.md first before using this reference.",
    "mimeType": "text/markdown"
  }
]

Nội dung skill://index.json:

{
  "$schema": "https://schemas.agentskills.io/discovery/0.2.0/schema.json",
  "skills": [
    { "name": "ard", "type": "skill-md", "description": "…", "url": "skill://ard/SKILL.md" }
  ]
}

Server instructions (fallback: đặt cùng câu này trong description của tool chính):

Load skill://ard/SKILL.md BEFORE calling search or execute.

Quy tắc:

  • Chỉ đăng ký và list những skill học viên đang sở hữu; index.json cũng vậy.
  • Không tồn tại và không sở hữu đều trả JSON-RPC error -32602.
  • Skill bị khóa chỉ hiện teaser (tên, mô tả, offer) trong GET /skills, không bao giờ là resource.
  • sha256 từng file, version = hash trên danh sách file, luôn trả đúng bytes đã hash.
  • Không đặt allowed-tools trong skill bán hoặc skill có gate.
  • Sinh phần API của skill từ OpenAPI lúc khởi động; test fail khi route đổi mà skill không đổi.
  • Khi client hỗ trợ SEP-2640: thêm skills/list + skills/get đọc từ cùng store, giữ nguyên URI và bytes.
#mcp #agent-skills #claude-code #code-mode

Bài viết liên quan

Tự động hoá hậu kỳ cho screen recording — tới đâu là hết

idea

Dựng một screen recording tốn thời gian nhất ở khâu ít cần suy nghĩ nhất: cắt khoảng lặng, tua đoạn ngồi chờ, thêm zoom. Để máy làm hết phần đó, mình còn nguyên sức cho phần thật sự quyết định video hay hay dở.

Cho agent thảo luận để ra kết quả, đừng cho chúng nói chuyện tự do

idea

Nhiều người thích "cho mấy con agent nói chuyện với nhau". Nghe cũng hợp lý: một agent làm được việc, thì vài con ngồi trao đổi chắc sẽ làm tốt hơn. Nhưng nói chuyện tự do thường ra kết quả ba phải và thành một cái chợ.

—
0:00

Chia sẻ ảnh

Bắt đầu gõ để tìm kiếm...