{"title":"Claude Artifacts","description":"\u003cp\u003eTạo dashboard, app, biểu đồ và tài liệu tương tác với Claude Artifacts — không cần code.\u003c\/p\u003e","products":[{"product_id":"mcp-model-context-protocol-giải-thich-dơn-giản","title":"MCP (Model Context Protocol) — Giải thích đơn giản","description":"\u003ch2\u003eMCP là gì?\u003c\/h2\u003e\n\u003cp\u003eModel Context Protocol (MCP) là một open standard do Anthropic phát triển, được thiết kế để giải quyết một vấn đề căn bản: làm thế nào để AI models kết nối một cách nhất quán với external tools, data sources, và services.\u003c\/p\u003e\n\n\u003cp\u003eTrước khi có MCP, mỗi AI application phải tự xây dựng integration riêng với từng tool — một codebase phức tạp, không tái sử dụng được, và khó maintain. MCP tạo ra một \"ngôn ngữ chung\" để mọi AI client có thể nói chuyện với mọi tool server theo cùng một cách.\u003c\/p\u003e\n\n\u003cblockquote\u003eMCP giống như USB-C trong thế giới AI integration: thay vì mỗi thiết bị cần một loại cáp riêng, tất cả dùng chung một chuẩn kết nối.\u003c\/blockquote\u003e\n\n\u003ch2\u003eTại sao MCP quan trọng?\u003c\/h2\u003e\n\n\u003ch3\u003eVấn đề trước MCP\u003c\/h3\u003e\n\u003cp\u003eHãy tưởng tượng bạn muốn xây dựng một AI assistant có thể:\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003eĐọc file từ máy tính local\u003c\/li\u003e\n\u003cli\u003eQuery database\u003c\/li\u003e\n\u003cli\u003eGọi GitHub API\u003c\/li\u003e\n\u003cli\u003eGửi message Slack\u003c\/li\u003e\n\u003c\/ul\u003e\n\n\u003cp\u003eTrước MCP, bạn phải viết custom integration code cho từng usecase, với từng AI model. Khi đổi từ Claude sang model khác, toàn bộ integration phải viết lại.\u003c\/p\u003e\n\n\u003ch3\u003eVới MCP\u003c\/h3\u003e\n\u003cp\u003eMỗi service (GitHub, Slack, filesystem...) xây dựng một \u003cstrong\u003eMCP Server\u003c\/strong\u003e theo chuẩn chung. Mọi AI client hỗ trợ MCP (Claude Code, Claude Desktop, và các tools khác) có thể kết nối với bất kỳ MCP Server nào — không cần custom code thêm.\u003c\/p\u003e\n\n\u003cp\u003eĐây là \u003cstrong\u003einteroperability\u003c\/strong\u003e thực sự: build once, work everywhere trong hệ sinh thái MCP.\u003c\/p\u003e\n\n\u003ch2\u003eKiến trúc MCP — Client-Server Model\u003c\/h2\u003e\n\n\u003ch3\u003eCác thành phần chính\u003c\/h3\u003e\n\u003cp\u003eMCP hoạt động theo mô hình client-server với ba loại thành phần:\u003c\/p\u003e\n\n\u003cul\u003e\n\u003cli\u003e\n\u003cstrong\u003eMCP Host:\u003c\/strong\u003e Ứng dụng AI bạn đang dùng (Claude Desktop, Claude Code, IDE plugins...)\u003c\/li\u003e\n\u003cli\u003e\n\u003cstrong\u003eMCP Client:\u003c\/strong\u003e Component bên trong Host, quản lý kết nối với servers\u003c\/li\u003e\n\u003cli\u003e\n\u003cstrong\u003eMCP Server:\u003c\/strong\u003e Process độc lập cung cấp capabilities (tools, resources, prompts)\u003c\/li\u003e\n\u003c\/ul\u003e\n\n\u003cp\u003eLuồng hoạt động điển hình:\u003c\/p\u003e\n\u003col\u003e\n\u003cli\u003eUser yêu cầu Claude làm gì đó liên quan đến external data\u003c\/li\u003e\n\u003cli\u003eClaude (qua MCP Client) gọi MCP Server tương ứng\u003c\/li\u003e\n\u003cli\u003eMCP Server thực hiện action\/query và trả kết quả\u003c\/li\u003e\n\u003cli\u003eClaude nhận kết quả và đưa vào context để trả lời user\u003c\/li\u003e\n\u003c\/ol\u003e\n\n\u003ch3\u003eBa khái niệm cốt lõi của MCP\u003c\/h3\u003e\n\n\u003ch4\u003e1. Resources\u003c\/h4\u003e\n\u003cp\u003eResources là dữ liệu mà server expose để AI có thể đọc — giống như file system hoặc database records. Resources có URI dạng \u003ccode\u003eprotocol:\/\/path\/to\/resource\u003c\/code\u003e và có thể là text hoặc binary.\u003c\/p\u003e\n\n\u003cp\u003eVí dụ:\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003ccode\u003efile:\/\/\/home\/user\/project\/README.md\u003c\/code\u003e — một file cụ thể\u003c\/li\u003e\n\u003cli\u003e\n\u003ccode\u003egithub:\/\/repos\/anthropic\/mcp\/issues\u003c\/code\u003e — list GitHub issues\u003c\/li\u003e\n\u003cli\u003e\n\u003ccode\u003epostgres:\/\/db\/customers\/recent\u003c\/code\u003e — query database\u003c\/li\u003e\n\u003c\/ul\u003e\n\n\u003ch4\u003e2. Tools\u003c\/h4\u003e\n\u003cp\u003eTools là các hàm mà AI có thể gọi để thực hiện actions — tạo file, gửi message, search web, chạy query. Mỗi tool có schema định nghĩa input parameters và output format.\u003c\/p\u003e\n\n\u003cp\u003eVí dụ tool schema:\u003c\/p\u003e\n\u003cpre\u003e\u003ccode\u003e{\n  \"name\": \"create_github_issue\",\n  \"description\": \"Tạo một issue mới trên GitHub repository\",\n  \"inputSchema\": {\n    \"type\": \"object\",\n    \"properties\": {\n      \"repo\": {\n        \"type\": \"string\",\n        \"description\": \"Repository name (owner\/repo)\"\n      },\n      \"title\": {\n        \"type\": \"string\",\n        \"description\": \"Tiêu đề issue\"\n      },\n      \"body\": {\n        \"type\": \"string\",\n        \"description\": \"Nội dung issue\"\n      }\n    },\n    \"required\": [\"repo\", \"title\"]\n  }\n}\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch4\u003e3. Prompts\u003c\/h4\u003e\n\u003cp\u003ePrompts là các template prompt được pre-defined trong server — reusable workflows mà user có thể invoke. Ví dụ: \"Analyze this codebase for security issues\" là một prompt template mà filesystem server có thể cung cấp.\u003c\/p\u003e\n\n\u003ch2\u003eMCP với Claude Code\u003c\/h2\u003e\n\n\u003ch3\u003eClaude Code là MCP Client\u003c\/h3\u003e\n\u003cp\u003eClaude Code có built-in MCP support. Khi bạn install một MCP server, Claude Code có thể sử dụng tất cả tools và resources mà server đó cung cấp.\u003c\/p\u003e\n\n\u003cp\u003eCài đặt MCP server trong Claude Code:\u003c\/p\u003e\n\u003cpre\u003e\u003ccode\u003e# Thêm MCP server (ví dụ: filesystem server)\nclaude mcp add filesystem npx @modelcontextprotocol\/server-filesystem \/path\/to\/allowed\/dir\n\n# Xem danh sách servers đã cài\nclaude mcp list\n\n# Xóa server\nclaude mcp remove filesystem\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003cp\u003eSau khi add server, Claude Code có thể trực tiếp đọc file, tạo file, hay search trong thư mục được cho phép — không cần bạn copy-paste nội dung thủ công.\u003c\/p\u003e\n\n\u003ch3\u003eCLAUDE.md và MCP context\u003c\/h3\u003e\n\u003cp\u003eTrong file \u003ccode\u003eCLAUDE.md\u003c\/code\u003e của project, bạn có thể định nghĩa MCP servers nào nên được active và cách Claude nên sử dụng chúng, tạo ra workflow nhất quán cho toàn team.\u003c\/p\u003e\n\n\u003ch2\u003eMCP với Claude Desktop\u003c\/h2\u003e\n\n\u003ch3\u003eCấu hình claude_desktop_config.json\u003c\/h3\u003e\n\u003cp\u003eClaude Desktop đọc MCP server configuration từ file:\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cstrong\u003emacOS:\u003c\/strong\u003e \u003ccode\u003e~\/Library\/Application Support\/Claude\/claude_desktop_config.json\u003c\/code\u003e\n\u003c\/li\u003e\n\u003cli\u003e\n\u003cstrong\u003eWindows:\u003c\/strong\u003e \u003ccode\u003e%APPDATA%Claudeclaude_desktop_config.json\u003c\/code\u003e\n\u003c\/li\u003e\n\u003c\/ul\u003e\n\n\u003cp\u003eFormat cấu hình:\u003c\/p\u003e\n\u003cpre\u003e\u003ccode\u003e{\n  \"mcpServers\": {\n    \"filesystem\": {\n      \"command\": \"npx\",\n      \"args\": [\n        \"-y\",\n        \"@modelcontextprotocol\/server-filesystem\",\n        \"\/Users\/username\/Documents\",\n        \"\/Users\/username\/Projects\"\n      ]\n    },\n    \"github\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@modelcontextprotocol\/server-github\"],\n      \"env\": {\n        \"GITHUB_PERSONAL_ACCESS_TOKEN\": \"ghp_your_token_here\"\n      }\n    },\n    \"slack\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@modelcontextprotocol\/server-slack\"],\n      \"env\": {\n        \"SLACK_BOT_TOKEN\": \"xoxb-your-token\"\n      }\n    }\n  }\n}\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003cp\u003eSau khi lưu file và restart Claude Desktop, bạn sẽ thấy biểu tượng hammer trong chat interface — nhấn vào để xem danh sách tools khả dụng.\u003c\/p\u003e\n\n\u003ch2\u003ePopular MCP Servers\u003c\/h2\u003e\n\n\u003ch3\u003eEcosystem hiện tại\u003c\/h3\u003e\n\u003cp\u003eCộng đồng đã xây dựng nhiều MCP servers cho các use cases phổ biến:\u003c\/p\u003e\n\n\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003eServer\u003c\/th\u003e\n\u003cth\u003ePackage\u003c\/th\u003e\n\u003cth\u003eChức năng\u003c\/th\u003e\n\u003c\/tr\u003e\n\u003c\/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd\u003eFilesystem\u003c\/td\u003e\n\u003ctd\u003e\u003ccode\u003e@modelcontextprotocol\/server-filesystem\u003c\/code\u003e\u003c\/td\u003e\n\u003ctd\u003eĐọc\/ghi file local\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eGitHub\u003c\/td\u003e\n\u003ctd\u003e\u003ccode\u003e@modelcontextprotocol\/server-github\u003c\/code\u003e\u003c\/td\u003e\n\u003ctd\u003eIssues, PRs, repos\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eSlack\u003c\/td\u003e\n\u003ctd\u003e\u003ccode\u003e@modelcontextprotocol\/server-slack\u003c\/code\u003e\u003c\/td\u003e\n\u003ctd\u003eChannels, messages\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003ePostgreSQL\u003c\/td\u003e\n\u003ctd\u003e\u003ccode\u003e@modelcontextprotocol\/server-postgres\u003c\/code\u003e\u003c\/td\u003e\n\u003ctd\u003eQuery database\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eSQLite\u003c\/td\u003e\n\u003ctd\u003e\u003ccode\u003e@modelcontextprotocol\/server-sqlite\u003c\/code\u003e\u003c\/td\u003e\n\u003ctd\u003eLocal SQLite DB\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eBrave Search\u003c\/td\u003e\n\u003ctd\u003e\u003ccode\u003e@modelcontextprotocol\/server-brave-search\u003c\/code\u003e\u003c\/td\u003e\n\u003ctd\u003eWeb search\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eGoogle Maps\u003c\/td\u003e\n\u003ctd\u003e\u003ccode\u003e@modelcontextprotocol\/server-google-maps\u003c\/code\u003e\u003c\/td\u003e\n\u003ctd\u003eMaps, geocoding\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003ePuppeteer\u003c\/td\u003e\n\u003ctd\u003e\u003ccode\u003e@modelcontextprotocol\/server-puppeteer\u003c\/code\u003e\u003c\/td\u003e\n\u003ctd\u003eBrowser automation\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003c\/tbody\u003e\n\u003c\/table\u003e\n\n\u003cp\u003eToàn bộ danh sách servers tham khảo tại: github.com\/modelcontextprotocol\/servers\u003c\/p\u003e\n\n\u003ch3\u003eCommunity servers\u003c\/h3\u003e\n\u003cp\u003eNgoài các server chính thức, cộng đồng đã tạo ra hàng trăm MCP servers cho các services khác: Notion, Jira, Figma, AWS, Google Workspace, Shopify, và nhiều hơn nữa. Tìm kiếm trên npm với keyword \"mcp-server\" để khám phá.\u003c\/p\u003e\n\n\u003ch2\u003eMCP vs Traditional API Integration\u003c\/h2\u003e\n\n\u003ch3\u003eSo sánh hai cách tiếp cận\u003c\/h3\u003e\n\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003eTiêu chí\u003c\/th\u003e\n\u003cth\u003eTraditional API\u003c\/th\u003e\n\u003cth\u003eMCP\u003c\/th\u003e\n\u003c\/tr\u003e\n\u003c\/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd\u003eReusability\u003c\/td\u003e\n\u003ctd\u003eMỗi app tự build\u003c\/td\u003e\n\u003ctd\u003eBuild once, dùng nhiều nơi\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eAI model switching\u003c\/td\u003e\n\u003ctd\u003ePhải rewrite integration\u003c\/td\u003e\n\u003ctd\u003eServer tương thích mọi MCP client\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eDiscovery\u003c\/td\u003e\n\u003ctd\u003eHardcoded trong app\u003c\/td\u003e\n\u003ctd\u003eDynamic — AI thấy tools qua schema\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eSecurity\u003c\/td\u003e\n\u003ctd\u003eTùy app implement\u003c\/td\u003e\n\u003ctd\u003eChuẩn hóa qua protocol\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eComplexity\u003c\/td\u003e\n\u003ctd\u003eCao khi nhiều integrations\u003c\/td\u003e\n\u003ctd\u003eGiảm nhờ chuẩn hóa\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003c\/tbody\u003e\n\u003c\/table\u003e\n\n\u003ch3\u003eKhi nào dùng MCP, khi nào dùng traditional API?\u003c\/h3\u003e\n\u003cp\u003eDùng MCP khi:\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003eMuốn Claude trực tiếp access và thao tác với external services\u003c\/li\u003e\n\u003cli\u003eXây dựng agent workflows cần nhiều tools\u003c\/li\u003e\n\u003cli\u003eMuốn reuse integration cho nhiều AI clients\u003c\/li\u003e\n\u003c\/ul\u003e\n\n\u003cp\u003eDùng traditional API call khi:\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003eỨng dụng của bạn gọi API và truyền kết quả vào Claude (không cần Claude chủ động gọi)\u003c\/li\u003e\n\u003cli\u003eIntegration đơn giản, một chiều\u003c\/li\u003e\n\u003cli\u003eKhông cần AI model chủ động quyết định khi nào gọi tool\u003c\/li\u003e\n\u003c\/ul\u003e\n\n\u003ch2\u003eSecurity và Permissions\u003c\/h2\u003e\n\n\u003ch3\u003eNguyên tắc least privilege\u003c\/h3\u003e\n\u003cp\u003eKhi cấu hình MCP servers, chỉ cấp quyền tối thiểu cần thiết:\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003eFilesystem server: chỉ expose những thư mục cần thiết, không expose \u003ccode\u003e\/\u003c\/code\u003e hay \u003ccode\u003e~\u003c\/code\u003e\n\u003c\/li\u003e\n\u003cli\u003eGitHub server: dùng fine-grained tokens với chỉ những repo permissions cần thiết\u003c\/li\u003e\n\u003cli\u003eDatabase servers: dùng read-only user nếu Claude chỉ cần đọc data\u003c\/li\u003e\n\u003c\/ul\u003e\n\n\u003ch3\u003eUser consent\u003c\/h3\u003e\n\u003cp\u003eMCP được thiết kế để user luôn biết Claude đang làm gì. Trong Claude Desktop và Claude Code, bạn có thể thấy và approve các tool calls trước khi chúng được thực thi (tùy cấu hình).\u003c\/p\u003e\n\n\u003ch2\u003eDebugging và Troubleshooting MCP\u003c\/h2\u003e\n\n\u003ch3\u003eMCP server không hiện trong Claude Desktop\u003c\/h3\u003e\n\u003cp\u003eCác nguyên nhân phổ biến:\u003c\/p\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cstrong\u003eJSON syntax error:\u003c\/strong\u003e Dùng jsonlint.com để validate \u003ccode\u003eclaude_desktop_config.json\u003c\/code\u003e\n\u003c\/li\u003e\n\u003cli\u003e\n\u003cstrong\u003eNode.js chưa install:\u003c\/strong\u003e Kiểm tra bằng \u003ccode\u003enode --version\u003c\/code\u003e trong terminal\u003c\/li\u003e\n\u003cli\u003e\n\u003cstrong\u003eChưa restart app:\u003c\/strong\u003e Quit hoàn toàn (không chỉ đóng cửa sổ) và mở lại\u003c\/li\u003e\n\u003cli\u003e\n\u003cstrong\u003ePermission denied:\u003c\/strong\u003e npx cần quyền download package lần đầu\u003c\/li\u003e\n\u003c\/ol\u003e\n\n\u003ch3\u003eXem MCP logs\u003c\/h3\u003e\n\u003cp\u003eClaude Desktop ghi logs của MCP servers tại:\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cstrong\u003emacOS:\u003c\/strong\u003e \u003ccode\u003e~\/Library\/Logs\/Claude\/mcp-server-[name].log\u003c\/code\u003e\n\u003c\/li\u003e\n\u003cli\u003e\n\u003cstrong\u003eWindows:\u003c\/strong\u003e \u003ccode\u003e%APPDATA%Claudelogsmcp-server-[name].log\u003c\/code\u003e\n\u003c\/li\u003e\n\u003c\/ul\u003e\n\n\u003cp\u003eXem logs để debug lỗi kết nối hoặc error trong server code.\u003c\/p\u003e\n\n\u003ch2\u003eMCP Protocol — Cơ chế hoạt động kỹ thuật\u003c\/h2\u003e\n\n\u003ch3\u003eTransport layer\u003c\/h3\u003e\n\u003cp\u003eMCP hỗ trợ hai transport mechanisms:\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cstrong\u003estdio (Standard I\/O):\u003c\/strong\u003e Dùng cho local servers — Claude Desktop fork server process và giao tiếp qua stdin\/stdout. Đây là transport mặc định và đơn giản nhất.\u003c\/li\u003e\n\u003cli\u003e\n\u003cstrong\u003eHTTP with SSE:\u003c\/strong\u003e Dùng cho remote servers — server chạy tại một URL, Claude connect qua HTTP. Phù hợp khi server cần chạy ở xa (cloud, team server).\u003c\/li\u003e\n\u003c\/ul\u003e\n\n\u003ch3\u003eMessage format\u003c\/h3\u003e\n\u003cp\u003eMCP dùng JSON-RPC 2.0 format cho tất cả communication:\u003c\/p\u003e\n\u003cpre\u003e\u003ccode\u003e\/\/ Request từ client đến server\n{\n  \"jsonrpc\": \"2.0\",\n  \"id\": 1,\n  \"method\": \"tools\/call\",\n  \"params\": {\n    \"name\": \"read_file\",\n    \"arguments\": { \"path\": \"\/home\/user\/notes.txt\" }\n  }\n}\n\n\/\/ Response từ server\n{\n  \"jsonrpc\": \"2.0\",\n  \"id\": 1,\n  \"result\": {\n    \"content\": [{ \"type\": \"text\", \"text\": \"Nội dung file...\" }]\n  }\n}\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch3\u003eLifecycle của một MCP session\u003c\/h3\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cstrong\u003eInitialize:\u003c\/strong\u003e Client gửi capabilities của mình, server trả về capabilities của server\u003c\/li\u003e\n\u003cli\u003e\n\u003cstrong\u003eDiscovery:\u003c\/strong\u003e Client hỏi list tools, resources, prompts server cung cấp\u003c\/li\u003e\n\u003cli\u003e\n\u003cstrong\u003eOperation:\u003c\/strong\u003e Client gọi tools, đọc resources theo nhu cầu\u003c\/li\u003e\n\u003cli\u003e\n\u003cstrong\u003eShutdown:\u003c\/strong\u003e Session kết thúc khi app close hoặc server disconnect\u003c\/li\u003e\n\u003c\/ol\u003e\n\n\u003ch2\u003eMCP trong Claude Code — Workflow developer\u003c\/h2\u003e\n\n\u003ch3\u003eCLAUDE.md và MCP\u003c\/h3\u003e\n\u003cp\u003eTrong project có file \u003ccode\u003eCLAUDE.md\u003c\/code\u003e, bạn có thể định nghĩa MCP context guidelines:\u003c\/p\u003e\n\n\u003cpre\u003e\u003ccode\u003e# CLAUDE.md\n\n## MCP Tools Available\n- filesystem: có thể đọc\/ghi toàn bộ thư mục project\n- github: access repo anthropic\/myproject\n\n## MCP Usage Guidelines\n- Trước khi sửa file, đọc file đó trước để hiểu context\n- Khi tạo file mới, kiểm tra naming conventions từ file hiện có\n- Commit message format: \"type(scope): description\"\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch3\u003eAgentic workflows với MCP\u003c\/h3\u003e\n\u003cp\u003eMCP là foundation cho các agentic tasks trong Claude Code. Ví dụ workflow \"Refactor module X\":\u003c\/p\u003e\n\u003col\u003e\n\u003cli\u003eClaude đọc tất cả file trong module (filesystem tool)\u003c\/li\u003e\n\u003cli\u003ePhân tích dependencies (đọc import statements)\u003c\/li\u003e\n\u003cli\u003eThực hiện refactoring theo plan\u003c\/li\u003e\n\u003cli\u003eCheck GitHub issues để xem có liên quan không (GitHub tool)\u003c\/li\u003e\n\u003cli\u003eTạo summary commit message\u003c\/li\u003e\n\u003c\/ol\u003e\n\n\u003cp\u003eTất cả các bước trên xảy ra tự động khi bạn chỉ cần ra lệnh một lần — MCP là cơ sở hạ tầng cho phép điều này.\u003c\/p\u003e\n\n\u003ch2\u003eRoadmap và tương lai\u003c\/h2\u003e\n\u003cp\u003eMCP được phát hành open source và đang được cộng đồng phát triển mạnh mẽ. Anthropic đã công bố MCP như là foundation cho agentic AI — tức là các AI agents có thể tự chủ thực hiện complex tasks bằng cách kết hợp nhiều MCP tools.\u003c\/p\u003e\n\n\u003cp\u003eNhiều IDE, code editors, và productivity tools đang thêm MCP support. Đây đang trở thành \"USB standard\" thực sự của AI tool integration.\u003c\/p\u003e\n\n\u003ch2\u003eXây dựng MCP Server của riêng bạn\u003c\/h2\u003e\n\n\u003ch3\u003eKhi nào nên build custom server\u003c\/h3\u003e\n\u003cp\u003eBạn nên build MCP server riêng khi:\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003eCần tích hợp với internal tools hoặc proprietary systems (CRM nội bộ, database riêng)\u003c\/li\u003e\n\u003cli\u003eMuốn expose business logic cụ thể của công ty dưới dạng Claude tools\u003c\/li\u003e\n\u003cli\u003eCommunity server chưa tồn tại cho service bạn dùng\u003c\/li\u003e\n\u003cli\u003eCần customization mà ready-made server không hỗ trợ\u003c\/li\u003e\n\u003c\/ul\u003e\n\n\u003ch3\u003eStack để build MCP Server\u003c\/h3\u003e\n\u003cp\u003eMCP SDK hiện có official support cho:\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cstrong\u003eTypeScript\/Node.js:\u003c\/strong\u003e \u003ccode\u003e@modelcontextprotocol\/sdk\u003c\/code\u003e — stable, đầy đủ examples\u003c\/li\u003e\n\u003cli\u003e\n\u003cstrong\u003ePython:\u003c\/strong\u003e \u003ccode\u003emcp\u003c\/code\u003e package — cũng stable, tốt cho data science workflows\u003c\/li\u003e\n\u003c\/ul\u003e\n\n\u003cp\u003eCommunity đã xây dựng thêm SDK cho Go, Rust, Java, và nhiều ngôn ngữ khác.\u003c\/p\u003e\n\n\u003ch3\u003ePattern cơ bản của một MCP Server\u003c\/h3\u003e\n\u003cpre\u003e\u003ccode\u003e\/\/ TypeScript — cấu trúc tối giản của một MCP Server\nimport { Server } from \"@modelcontextprotocol\/sdk\/server\/index.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol\/sdk\/server\/stdio.js\";\nimport { ListToolsRequestSchema, CallToolRequestSchema } from \"@modelcontextprotocol\/sdk\/types.js\";\n\nconst server = new Server(\n  { name: \"my-server\", version: \"1.0.0\" },\n  { capabilities: { tools: {} } }\n);\n\n\/\/ 1. Khai báo tools\nserver.setRequestHandler(ListToolsRequestSchema, async () =\u0026gt; ({\n  tools: [{ name: \"my_tool\", description: \"...\", inputSchema: { type: \"object\", properties: {} } }]\n}));\n\n\/\/ 2. Xử lý tool calls\nserver.setRequestHandler(CallToolRequestSchema, async (request) =\u0026gt; {\n  if (request.params.name === \"my_tool\") {\n    \/\/ Thực hiện logic\n    return { content: [{ type: \"text\", text: \"Kết quả\" }] };\n  }\n  throw new Error(\"Tool không tồn tại\");\n});\n\n\/\/ 3. Kết nối transport và start\nconst transport = new StdioServerTransport();\nawait server.connect(transport);\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch2\u003eMCP trong tương lai của Agentic AI\u003c\/h2\u003e\n\n\u003ch3\u003eMCP và multi-agent systems\u003c\/h3\u003e\n\u003cp\u003eMột trong những ứng dụng quan trọng nhất của MCP là trong multi-agent architectures. Khi nhiều AI agents cần collaborate — một agent orchestrate, một agent execute code, một agent search web — MCP cung cấp standard interface để chúng communicate và chia sẻ tools.\u003c\/p\u003e\n\n\u003cp\u003eThay vì hardcode \"agent A gọi agent B theo cách X\", MCP cho phép dynamic discovery: agent có thể hỏi \"tools nào đang khả dụng?\" và quyết định theo context.\u003c\/p\u003e\n\n\u003ch3\u003eLong-running tools\u003c\/h3\u003e\n\u003cp\u003eMCP đang phát triển support cho long-running tools — những operations mất nhiều phút thay vì giây. Điều này mở ra khả năng cho các workflows phức tạp như:\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003eRunning CI\/CD pipeline và chờ kết quả\u003c\/li\u003e\n\u003cli\u003eExecuting large data processing jobs\u003c\/li\u003e\n\u003cli\u003eMulti-step automation với human-in-the-loop checkpoints\u003c\/li\u003e\n\u003c\/ul\u003e\n\n\u003ch2\u003eKết luận\u003c\/h2\u003e\n\u003cp\u003eMCP giải quyết một vấn đề thực sự trong AI development: fragmentation của integrations. Thay vì mỗi team, mỗi app phải reinvent the wheel, MCP tạo ra ecosystem nơi servers được build một lần và work với mọi MCP-compatible client.\u003c\/p\u003e\n\n\u003cp\u003eNếu bạn đang dùng Claude Code hoặc Claude Desktop, hãy bắt đầu với filesystem MCP server — nó ngay lập tức giúp Claude làm việc với codebase local của bạn mà không cần copy-paste file. Đó là điểm khởi đầu tốt nhất để hiểu MCP trong thực tế.\u003c\/p\u003e","brand":"Minh Tuấn","offers":[{"title":"Default Title","offer_id":47721068396756,"sku":null,"price":0.0,"currency_code":"VND","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0821\/0264\/9044\/files\/mcp-model-context-protocol-gi_i-thich-d_n-gi_n.jpg?v=1774513832"},{"product_id":"xay-dựng-mcp-server-dầu-tien-hướng-dẫn-step-by-step","title":"Xây dựng MCP Server đầu tiên — Hướng dẫn step-by-step","description":"\u003ch2\u003eGiới thiệu\u003c\/h2\u003e\n\u003cp\u003eSau khi đã hiểu MCP là gì, bước tiếp theo tự nhiên là xây dựng MCP Server riêng. Đây là cách bạn tạo custom tools cho Claude Code và Claude Desktop — biến Claude thành một AI agent có thể thao tác trực tiếp với systems của bạn.\u003c\/p\u003e\n\n\u003cp\u003eTrong bài này, chúng ta sẽ xây dựng một MCP Server thực tế bằng TypeScript: bắt đầu từ server đọc file đơn giản, sau đó mở rộng thành một weather API server hoàn chỉnh.\u003c\/p\u003e\n\n\u003ch2\u003ePrerequisites\u003c\/h2\u003e\n\n\u003ch3\u003eYêu cầu môi trường\u003c\/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cstrong\u003eNode.js 18+\u003c\/strong\u003e — kiểm tra: \u003ccode\u003enode --version\u003c\/code\u003e\n\u003c\/li\u003e\n\u003cli\u003e\u003cstrong\u003enpm hoặc pnpm\u003c\/strong\u003e\u003c\/li\u003e\n\u003cli\u003e\n\u003cstrong\u003eTypeScript 5+\u003c\/strong\u003e — install global: \u003ccode\u003enpm install -g typescript\u003c\/code\u003e\n\u003c\/li\u003e\n\u003cli\u003e\n\u003cstrong\u003eClaude Desktop hoặc Claude Code\u003c\/strong\u003e để test\u003c\/li\u003e\n\u003c\/ul\u003e\n\n\u003ch3\u003eHiểu cơ bản về TypeScript và async\/await\u003c\/h3\u003e\n\u003cp\u003eBài hướng dẫn này giả định bạn đã quen với TypeScript cơ bản và async programming. Nếu chưa, hãy xem qua TypeScript handbook trước.\u003c\/p\u003e\n\n\u003ch2\u003eSetup project\u003c\/h2\u003e\n\n\u003ch3\u003eKhởi tạo project\u003c\/h3\u003e\n\u003cpre\u003e\u003ccode\u003e# Tạo thư mục project\nmkdir my-mcp-server\ncd my-mcp-server\n\n# Khởi tạo npm project\nnpm init -y\n\n# Cài MCP SDK và dependencies\nnpm install @modelcontextprotocol\/sdk zod\n\n# Cài dev dependencies\nnpm install -D typescript @types\/node tsx\n\n# Tạo tsconfig\nnpx tsc --init\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003cp\u003eCập nhật \u003ccode\u003etsconfig.json\u003c\/code\u003e:\u003c\/p\u003e\n\u003cpre\u003e\u003ccode\u003e{\n  \"compilerOptions\": {\n    \"target\": \"ES2022\",\n    \"module\": \"Node16\",\n    \"moduleResolution\": \"Node16\",\n    \"outDir\": \".\/dist\",\n    \"rootDir\": \".\/src\",\n    \"strict\": true,\n    \"esModuleInterop\": true,\n    \"skipLibCheck\": true\n  },\n  \"include\": [\"src\/**\/*\"],\n  \"exclude\": [\"node_modules\", \"dist\"]\n}\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003cp\u003eCập nhật \u003ccode\u003epackage.json\u003c\/code\u003e:\u003c\/p\u003e\n\u003cpre\u003e\u003ccode\u003e{\n  \"name\": \"my-mcp-server\",\n  \"version\": \"1.0.0\",\n  \"type\": \"module\",\n  \"main\": \"dist\/index.js\",\n  \"scripts\": {\n    \"build\": \"tsc\",\n    \"dev\": \"tsx src\/index.ts\",\n    \"start\": \"node dist\/index.js\"\n  }\n}\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch2\u003eMCP Server đầu tiên — Đọc file\u003c\/h2\u003e\n\n\u003ch3\u003eTạo server cơ bản\u003c\/h3\u003e\n\u003cp\u003eTạo file \u003ccode\u003esrc\/index.ts\u003c\/code\u003e:\u003c\/p\u003e\n\n\u003cpre\u003e\u003ccode\u003eimport { Server } from \"@modelcontextprotocol\/sdk\/server\/index.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol\/sdk\/server\/stdio.js\";\nimport {\n  CallToolRequestSchema,\n  ListToolsRequestSchema,\n} from \"@modelcontextprotocol\/sdk\/types.js\";\nimport { z } from \"zod\";\nimport { readFileSync, existsSync } from \"fs\";\nimport { resolve } from \"path\";\n\n\/\/ Khởi tạo server với metadata\nconst server = new Server(\n  {\n    name: \"my-file-server\",\n    version: \"1.0.0\",\n  },\n  {\n    capabilities: {\n      tools: {}, \/\/ Server này cung cấp tools\n    },\n  }\n);\n\n\/\/ Định nghĩa danh sách tools\nserver.setRequestHandler(ListToolsRequestSchema, async () =\u0026gt; {\n  return {\n    tools: [\n      {\n        name: \"read_file\",\n        description: \"Đọc nội dung của một file text\",\n        inputSchema: {\n          type: \"object\",\n          properties: {\n            path: {\n              type: \"string\",\n              description: \"Đường dẫn tuyệt đối đến file cần đọc\",\n            },\n          },\n          required: [\"path\"],\n        },\n      },\n      {\n        name: \"check_file_exists\",\n        description: \"Kiểm tra file có tồn tại hay không\",\n        inputSchema: {\n          type: \"object\",\n          properties: {\n            path: {\n              type: \"string\",\n              description: \"Đường dẫn đến file cần kiểm tra\",\n            },\n          },\n          required: [\"path\"],\n        },\n      },\n    ],\n  };\n});\n\n\/\/ Xử lý tool calls\nserver.setRequestHandler(CallToolRequestSchema, async (request) =\u0026gt; {\n  const { name, arguments: args } = request.params;\n\n  if (name === \"read_file\") {\n    const { path } = z.object({ path: z.string() }).parse(args);\n    const absolutePath = resolve(path);\n\n    if (!existsSync(absolutePath)) {\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: `Lỗi: File không tồn tại: ${absolutePath}`,\n          },\n        ],\n        isError: true,\n      };\n    }\n\n    try {\n      const content = readFileSync(absolutePath, \"utf-8\");\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: content,\n          },\n        ],\n      };\n    } catch (error) {\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: `Lỗi đọc file: ${error instanceof Error ? error.message : String(error)}`,\n          },\n        ],\n        isError: true,\n      };\n    }\n  }\n\n  if (name === \"check_file_exists\") {\n    const { path } = z.object({ path: z.string() }).parse(args);\n    const absolutePath = resolve(path);\n    const exists = existsSync(absolutePath);\n\n    return {\n      content: [\n        {\n          type: \"text\",\n          text: exists\n            ? `File tồn tại: ${absolutePath}`\n            : `File không tồn tại: ${absolutePath}`,\n        },\n      ],\n    };\n  }\n\n  return {\n    content: [{ type: \"text\", text: `Tool không tồn tại: ${name}` }],\n    isError: true,\n  };\n});\n\n\/\/ Khởi động server với stdio transport\nasync function main() {\n  const transport = new StdioServerTransport();\n  await server.connect(transport);\n  console.error(\"MCP File Server đã khởi động\"); \/\/ Log ra stderr\n}\n\nmain().catch(console.error);\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch3\u003eBuild và test\u003c\/h3\u003e\n\u003cpre\u003e\u003ccode\u003e# Build TypeScript\nnpm run build\n\n# Test thủ công\necho '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"tools\/list\",\"params\":{}}' | node dist\/index.js\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch2\u003eĐăng ký server với Claude Code\u003c\/h2\u003e\n\n\u003cpre\u003e\u003ccode\u003e# Thêm server vào Claude Code\nclaude mcp add my-file-server node \/absolute\/path\/to\/my-mcp-server\/dist\/index.js\n\n# Kiểm tra server đã được thêm\nclaude mcp list\n\n# Test trong Claude Code\nclaude \"Đọc file \/etc\/hosts và tóm tắt nội dung\"\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch2\u003eĐăng ký server với Claude Desktop\u003c\/h2\u003e\n\n\u003cp\u003eThêm vào \u003ccode\u003eclaude_desktop_config.json\u003c\/code\u003e:\u003c\/p\u003e\n\u003cpre\u003e\u003ccode\u003e{\n  \"mcpServers\": {\n    \"my-file-server\": {\n      \"command\": \"node\",\n      \"args\": [\"\/absolute\/path\/to\/my-mcp-server\/dist\/index.js\"]\n    }\n  }\n}\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003cp\u003eRestart Claude Desktop. Bạn sẽ thấy tools \u003ccode\u003eread_file\u003c\/code\u003e và \u003ccode\u003echeck_file_exists\u003c\/code\u003e xuất hiện trong danh sách available tools.\u003c\/p\u003e\n\n\u003ch2\u003eThêm Resources\u003c\/h2\u003e\n\n\u003cp\u003eNgoài Tools, MCP Server có thể expose Resources — dữ liệu mà Claude có thể đọc. Thêm resource support vào server:\u003c\/p\u003e\n\n\u003cpre\u003e\u003ccode\u003eimport {\n  ListResourcesRequestSchema,\n  ReadResourceRequestSchema,\n} from \"@modelcontextprotocol\/sdk\/types.js\";\n\n\/\/ Khai báo capabilities bao gồm resources\nconst server = new Server(\n  { name: \"my-file-server\", version: \"1.0.0\" },\n  {\n    capabilities: {\n      tools: {},\n      resources: {}, \/\/ Thêm resources capability\n    },\n  }\n);\n\n\/\/ Handler cho list resources\nserver.setRequestHandler(ListResourcesRequestSchema, async () =\u0026gt; {\n  return {\n    resources: [\n      {\n        uri: \"file:\/\/\/var\/log\/app.log\",\n        name: \"Application Log\",\n        description: \"Log file của ứng dụng\",\n        mimeType: \"text\/plain\",\n      },\n    ],\n  };\n});\n\n\/\/ Handler cho read resource\nserver.setRequestHandler(ReadResourceRequestSchema, async (request) =\u0026gt; {\n  const { uri } = request.params;\n\n  if (uri === \"file:\/\/\/var\/log\/app.log\") {\n    const content = readFileSync(\"\/var\/log\/app.log\", \"utf-8\");\n    return {\n      contents: [\n        {\n          uri,\n          mimeType: \"text\/plain\",\n          text: content,\n        },\n      ],\n    };\n  }\n\n  throw new Error(`Resource không tồn tại: ${uri}`);\n});\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch2\u003eVí dụ thực tế — Weather API Server\u003c\/h2\u003e\n\n\u003cp\u003eBây giờ hãy build một server thực tế hơn: gọi weather API và trả kết quả cho Claude.\u003c\/p\u003e\n\n\u003cpre\u003e\u003ccode\u003eimport { Server } from \"@modelcontextprotocol\/sdk\/server\/index.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol\/sdk\/server\/stdio.js\";\nimport {\n  CallToolRequestSchema,\n  ListToolsRequestSchema,\n} from \"@modelcontextprotocol\/sdk\/types.js\";\nimport { z } from \"zod\";\n\nconst server = new Server(\n  { name: \"weather-server\", version: \"1.0.0\" },\n  { capabilities: { tools: {} } }\n);\n\nserver.setRequestHandler(ListToolsRequestSchema, async () =\u0026gt; ({\n  tools: [\n    {\n      name: \"get_weather\",\n      description: \"Lấy thông tin thời tiết hiện tại cho một thành phố\",\n      inputSchema: {\n        type: \"object\",\n        properties: {\n          city: {\n            type: \"string\",\n            description: \"Tên thành phố (tiếng Anh), ví dụ: Hanoi, Ho Chi Minh City\",\n          },\n          units: {\n            type: \"string\",\n            enum: [\"metric\", \"imperial\"],\n            description: \"Đơn vị nhiệt độ: metric (Celsius) hoặc imperial (Fahrenheit)\",\n            default: \"metric\",\n          },\n        },\n        required: [\"city\"],\n      },\n    },\n  ],\n}));\n\nserver.setRequestHandler(CallToolRequestSchema, async (request) =\u0026gt; {\n  const { name, arguments: args } = request.params;\n\n  if (name === \"get_weather\") {\n    const { city, units = \"metric\" } = z\n      .object({\n        city: z.string(),\n        units: z.enum([\"metric\", \"imperial\"]).optional().default(\"metric\"),\n      })\n      .parse(args);\n\n    const apiKey = process.env.OPENWEATHER_API_KEY;\n    if (!apiKey) {\n      return {\n        content: [\n          { type: \"text\", text: \"Lỗi: OPENWEATHER_API_KEY chưa được cấu hình\" },\n        ],\n        isError: true,\n      };\n    }\n\n    try {\n      const url = `https:\/\/api.openweathermap.org\/data\/2.5\/weather?q=${encodeURIComponent(city)}\u0026amp;units=${units}\u0026amp;appid=${apiKey}`;\n      const response = await fetch(url);\n\n      if (!response.ok) {\n        const error = await response.json() as { message?: string };\n        return {\n          content: [\n            {\n              type: \"text\",\n              text: `Lỗi từ API: ${error.message || response.statusText}`,\n            },\n          ],\n          isError: true,\n        };\n      }\n\n      const data = await response.json() as {\n        name: string;\n        sys: { country: string };\n        main: { temp: number; feels_like: number; humidity: number };\n        weather: Array\u0026lt;{ description: string }\u0026gt;;\n        wind: { speed: number };\n      };\n\n      const tempUnit = units === \"metric\" ? \"°C\" : \"°F\";\n      const windUnit = units === \"metric\" ? \"m\/s\" : \"mph\";\n\n      const summary = [\n        `Thời tiết tại ${data.name}, ${data.sys.country}:`,\n        `- Nhiệt độ: ${data.main.temp}${tempUnit} (cảm giác như ${data.main.feels_like}${tempUnit})`,\n        `- Điều kiện: ${data.weather[0].description}`,\n        `- Độ ẩm: ${data.main.humidity}%`,\n        `- Gió: ${data.wind.speed} ${windUnit}`,\n      ].join(\"\\n\");\n\n      return {\n        content: [{ type: \"text\", text: summary }],\n      };\n    } catch (error) {\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: `Lỗi kết nối: ${error instanceof Error ? error.message : String(error)}`,\n          },\n        ],\n        isError: true,\n      };\n    }\n  }\n\n  return {\n    content: [{ type: \"text\", text: `Tool không tồn tại: ${name}` }],\n    isError: true,\n  };\n});\n\nasync function main() {\n  const transport = new StdioServerTransport();\n  await server.connect(transport);\n  console.error(\"Weather MCP Server đã khởi động\");\n}\n\nmain().catch(console.error);\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003cp\u003eĐăng ký với Claude Desktop:\u003c\/p\u003e\n\u003cpre\u003e\u003ccode\u003e{\n  \"mcpServers\": {\n    \"weather\": {\n      \"command\": \"node\",\n      \"args\": [\"\/path\/to\/weather-server\/dist\/index.js\"],\n      \"env\": {\n        \"OPENWEATHER_API_KEY\": \"your_api_key_here\"\n      }\n    }\n  }\n}\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003cp\u003eSau khi cấu hình, bạn có thể hỏi Claude: \"Thời tiết Hà Nội hôm nay thế nào?\" và Claude sẽ gọi tool để lấy dữ liệu thực.\u003c\/p\u003e\n\n\u003ch2\u003eTesting MCP Server\u003c\/h2\u003e\n\n\u003ch3\u003eUnit testing handlers\u003c\/h3\u003e\n\u003cp\u003eTest handlers riêng biệt mà không cần khởi động full server:\u003c\/p\u003e\n\n\u003cpre\u003e\u003ccode\u003e\/\/ tests\/handlers.test.ts\nimport { describe, it, expect } from \"vitest\";\nimport { readFileSync, writeFileSync, unlinkSync } from \"fs\";\nimport { tmpdir } from \"os\";\nimport { join } from \"path\";\n\ndescribe(\"read_file tool\", () =\u0026gt; {\n  it(\"đọc file thành công\", async () =\u0026gt; {\n    \/\/ Tạo temp file\n    const tmpPath = join(tmpdir(), \"test-mcp.txt\");\n    writeFileSync(tmpPath, \"Hello MCP World\");\n\n    \/\/ Import và test handler function trực tiếp\n    const content = readFileSync(tmpPath, \"utf-8\");\n    expect(content).toBe(\"Hello MCP World\");\n\n    \/\/ Cleanup\n    unlinkSync(tmpPath);\n  });\n\n  it(\"trả về lỗi khi file không tồn tại\", () =\u0026gt; {\n    const fakePath = \"\/nonexistent\/path\/file.txt\";\n    const { existsSync } = require(\"fs\");\n    expect(existsSync(fakePath)).toBe(false);\n  });\n});\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch3\u003eIntegration testing với MCP Inspector\u003c\/h3\u003e\n\u003cp\u003eAnthropic cung cấp MCP Inspector — tool để test MCP servers interactively:\u003c\/p\u003e\n\n\u003cpre\u003e\u003ccode\u003e# Cài MCP Inspector\nnpm install -g @modelcontextprotocol\/inspector\n\n# Chạy inspector với server của bạn\nnpx @modelcontextprotocol\/inspector node dist\/index.js\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003cp\u003eInspector mở giao diện web tại localhost:5173, cho phép:\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003eXem danh sách tools, resources, prompts server expose\u003c\/li\u003e\n\u003cli\u003eGọi tool với custom input và xem response\u003c\/li\u003e\n\u003cli\u003eDebug message exchange giữa client và server\u003c\/li\u003e\n\u003c\/ul\u003e\n\n\u003ch3\u003eTesting với Claude Code trực tiếp\u003c\/h3\u003e\n\u003cp\u003eCách test nhanh nhất là thêm server vào Claude Code và test bằng ngôn ngữ tự nhiên:\u003c\/p\u003e\n\n\u003cpre\u003e\u003ccode\u003e# Thêm server đang develop (dùng tsx để không cần build)\nclaude mcp add my-server tsx \/path\/to\/server\/src\/index.ts\n\n# Test\nclaude \"Dùng tool read_file để đọc \/etc\/hostname\"\nclaude \"Check xem file \/tmp\/test.txt có tồn tại không\"\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch2\u003eThêm Prompts vào MCP Server\u003c\/h2\u003e\n\n\u003ch3\u003ePrompts là gì và khi nào dùng\u003c\/h3\u003e\n\u003cp\u003eNgoài Tools và Resources, MCP Server có thể cung cấp Prompts — template workflows được định nghĩa sẵn. User có thể invoke prompt bằng slash commands trong supported clients.\u003c\/p\u003e\n\n\u003cpre\u003e\u003ccode\u003eimport {\n  ListPromptsRequestSchema,\n  GetPromptRequestSchema,\n} from \"@modelcontextprotocol\/sdk\/types.js\";\n\nserver.setRequestHandler(ListPromptsRequestSchema, async () =\u0026gt; ({\n  prompts: [\n    {\n      name: \"analyze_file\",\n      description: \"Phân tích một file và đưa ra nhận xét\",\n      arguments: [\n        {\n          name: \"filepath\",\n          description: \"Đường dẫn đến file cần phân tích\",\n          required: true,\n        },\n      ],\n    },\n  ],\n}));\n\nserver.setRequestHandler(GetPromptRequestSchema, async (request) =\u0026gt; {\n  const { name, arguments: args } = request.params;\n\n  if (name === \"analyze_file\") {\n    const filepath = args?.filepath as string;\n    return {\n      description: \"Phân tích file\",\n      messages: [\n        {\n          role: \"user\",\n          content: {\n            type: \"text\",\n            text: `Hãy đọc file ${filepath} và phân tích:\n1. Mục đích của file\n2. Cấu trúc và tổ chức\n3. Điểm mạnh trong code\/content\n4. Điểm cần cải thiện\n5. Đề xuất cụ thể`,\n          },\n        },\n      ],\n    };\n  }\n\n  throw new Error(`Prompt không tồn tại: ${name}`);\n});\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch2\u003eError Handling tốt trong MCP Server\u003c\/h2\u003e\n\n\u003cp\u003eMột MCP Server production-ready cần handle errors rõ ràng:\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cstrong\u003eValidation errors:\u003c\/strong\u003e Dùng zod để validate input, throw với message rõ ràng\u003c\/li\u003e\n\u003cli\u003e\n\u003cstrong\u003eExternal API errors:\u003c\/strong\u003e Catch và wrap với context hữu ích\u003c\/li\u003e\n\u003cli\u003e\n\u003cstrong\u003eisError flag:\u003c\/strong\u003e Set \u003ccode\u003eisError: true\u003c\/code\u003e trong response khi có lỗi để Claude biết\u003c\/li\u003e\n\u003cli\u003e\n\u003cstrong\u003eLogging:\u003c\/strong\u003e Log ra \u003ccode\u003estderr\u003c\/code\u003e (không phải stdout) vì stdout dùng cho MCP protocol\u003c\/li\u003e\n\u003c\/ul\u003e\n\n\u003ch2\u003ePublishing MCP Server\u003c\/h2\u003e\n\n\u003cp\u003eĐể share server với cộng đồng:\u003c\/p\u003e\n\u003col\u003e\n\u003cli\u003ePublish lên npm: \u003ccode\u003enpm publish\u003c\/code\u003e\n\u003c\/li\u003e\n\u003cli\u003eĐặt tên convention: \u003ccode\u003emcp-server-[tên]\u003c\/code\u003e hoặc \u003ccode\u003e@scope\/mcp-server-[tên]\u003c\/code\u003e\n\u003c\/li\u003e\n\u003cli\u003eThêm README với hướng dẫn cài đặt rõ ràng\u003c\/li\u003e\n\u003cli\u003eSubmit lên awesome-mcp-servers repository trên GitHub\u003c\/li\u003e\n\u003c\/ol\u003e\n\n\u003ch2\u003eBest Practices khi build MCP Server\u003c\/h2\u003e\n\n\u003ch3\u003eIdempotency và side effects\u003c\/h3\u003e\n\u003cp\u003eThiết kế tools với tư duy rõ ràng về side effects:\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cstrong\u003eRead-only tools:\u003c\/strong\u003e Không có side effects, safe to call nhiều lần. Ví dụ: \u003ccode\u003eread_file\u003c\/code\u003e, \u003ccode\u003esearch_database\u003c\/code\u003e, \u003ccode\u003eget_weather\u003c\/code\u003e\n\u003c\/li\u003e\n\u003cli\u003e\n\u003cstrong\u003eMutating tools:\u003c\/strong\u003e Có side effects, nên có confirmation step hoặc dry-run mode. Ví dụ: \u003ccode\u003ewrite_file\u003c\/code\u003e, \u003ccode\u003esend_email\u003c\/code\u003e, \u003ccode\u003edelete_record\u003c\/code\u003e\n\u003c\/li\u003e\n\u003c\/ul\u003e\n\n\u003cp\u003eĐặt tên tools phản ánh rõ ràng liệu chúng có destructive hay không:\u003c\/p\u003e\n\u003cpre\u003e\u003ccode\u003e\/\/ Rõ ràng\nread_file       \/\/ Read-only, safe\ncreate_file     \/\/ Creates new file\noverwrite_file  \/\/ Destructive, cần cẩn thận\ndelete_file     \/\/ Destructive, cần confirm\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch3\u003eTool descriptions chất lượng cao\u003c\/h3\u003e\n\u003cp\u003eClaude quyết định khi nào gọi tool dựa trên description. Description tốt dẫn đến usage đúng; description kém dẫn đến wrong tool calls:\u003c\/p\u003e\n\n\u003cpre\u003e\u003ccode\u003e\/\/ BAD - quá chung chung\n{\n  name: \"process\",\n  description: \"Xử lý data\",\n}\n\n\/\/ GOOD - cụ thể và có context\n{\n  name: \"analyze_csv_file\",\n  description: \"Đọc và phân tích file CSV. Trả về: số rows, column names, sample data (5 rows đầu), và basic statistics (min\/max\/mean cho numeric columns). Dùng khi user muốn hiểu cấu trúc hoặc nội dung của file CSV.\",\n}\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch3\u003eInput validation chặt chẽ\u003c\/h3\u003e\n\u003cp\u003eDùng zod hoặc JSON Schema validation cho mọi input. Đừng trust input từ AI model:\u003c\/p\u003e\n\n\u003cpre\u003e\u003ccode\u003eimport { z } from \"zod\";\n\nconst ReadFileInput = z.object({\n  path: z\n    .string()\n    .min(1)\n    .refine((p) =\u0026gt; !p.includes(\"..\"), \"Path traversal không được phép\")\n    .refine((p) =\u0026gt; p.startsWith(\"\/allowed\/\"), \"Chỉ đọc trong thư mục được phép\"),\n});\n\n\/\/ Trong handler\ntry {\n  const { path } = ReadFileInput.parse(args);\n  \/\/ safe to proceed\n} catch (error) {\n  if (error instanceof z.ZodError) {\n    return {\n      content: [{ type: \"text\", text: `Input không hợp lệ: ${error.errors.map(e =\u0026gt; e.message).join(\", \")}` }],\n      isError: true,\n    };\n  }\n  throw error;\n}\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch3\u003eRate limiting cho external APIs\u003c\/h3\u003e\n\u003cp\u003eNếu tools của bạn gọi external APIs, implement rate limiting trong server để tránh bị block:\u003c\/p\u003e\n\n\u003cpre\u003e\u003ccode\u003eimport Bottleneck from \"bottleneck\";\n\n\/\/ Giới hạn 10 requests\/giây cho external API\nconst limiter = new Bottleneck({\n  maxConcurrent: 1,\n  minTime: 100, \/\/ 100ms giữa các requests\n});\n\nasync function callExternalAPI(params: any) {\n  return limiter.schedule(() =\u0026gt; fetch(\"https:\/\/api.example.com\/...\", params));\n}\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch2\u003eDeploying MCP Server\u003c\/h2\u003e\n\n\u003ch3\u003eLocal development server\u003c\/h3\u003e\n\u003cp\u003eTrong quá trình development, dùng \u003ccode\u003etsx\u003c\/code\u003e để không cần rebuild mỗi lần thay đổi:\u003c\/p\u003e\n\n\u003cpre\u003e\u003ccode\u003e# Thêm vào Claude Code với tsx (auto-reload khi file thay đổi)\nclaude mcp add my-server tsx \/path\/to\/server\/src\/index.ts\n\n# Sau khi build production\nclaude mcp add my-server node \/path\/to\/server\/dist\/index.js\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch3\u003ePackaging và distribution\u003c\/h3\u003e\n\u003cp\u003eĐể share server với team hoặc cộng đồng:\u003c\/p\u003e\n\n\u003cpre\u003e\u003ccode\u003e\/\/ package.json — setup để chạy trực tiếp qua npx\n{\n  \"name\": \"@yourorg\/mcp-server-myapp\",\n  \"version\": \"1.0.0\",\n  \"bin\": {\n    \"mcp-server-myapp\": \".\/dist\/index.js\"\n  },\n  \"files\": [\"dist\/\"],\n  \"scripts\": {\n    \"build\": \"tsc\",\n    \"prepublishOnly\": \"npm run build\"\n  }\n}\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003cp\u003eSau khi publish, users chỉ cần:\u003c\/p\u003e\n\u003cpre\u003e\u003ccode\u003e{\n  \"mcpServers\": {\n    \"myapp\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@yourorg\/mcp-server-myapp\"]\n    }\n  }\n}\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch2\u003eKết luận\u003c\/h2\u003e\n\u003cp\u003eXây dựng MCP Server không phức tạp như bạn nghĩ. Với MCP SDK, bạn chỉ cần định nghĩa tools và handlers — SDK lo phần còn lại (protocol, transport, serialization).\u003c\/p\u003e\n\n\u003cp\u003eBắt đầu với server đọc file đơn giản, test với Claude Code, rồi mở rộng dần. Khi đã hiểu pattern cơ bản, việc thêm tools mới chỉ là thêm entry vào \u003ccode\u003etools\u003c\/code\u003e array và thêm case vào handler.\u003c\/p\u003e\n\n\u003cp\u003eCustom MCP Server là cách mạnh nhất để tích hợp Claude vào existing workflow của bạn — biến Claude từ chat tool thành một agent thực sự làm việc với systems của bạn.\u003c\/p\u003e","brand":"Minh Tuấn","offers":[{"title":"Default Title","offer_id":47721068429524,"sku":null,"price":0.0,"currency_code":"VND","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0821\/0264\/9044\/files\/xay-d_ng-mcp-server-d_u-tien-h_ng-d_n-step-by-step.jpg?v=1774504050"},{"product_id":"claude-code-co-skills-marketplace-rồi-hướng-dẫn-bắt-dầu-cho-người-mới-hoan-toan","title":"Claude Code Có Skills Marketplace Rồi: Hướng Dẫn Bắt Đầu Cho Người Mới Hoàn Toàn","description":"\n\u003ch2\u003eTrước Khi Có Marketplace: Vấn Đề Của \"Works On My Machine\"\u003c\/h2\u003e\n\n\u003cp\u003eTrước tháng 10\/2025, skills trong Claude Code tồn tại nhưng khó chia sẻ. Nếu bạn xây dựng được một skill hữu ích cho workflow của mình, để đồng nghiệp dùng được, bạn phải:\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003eCopy file markdown thủ công\u003c\/li\u003e\n\u003cli\u003eGiải thích cách cài đặt từng bước\u003c\/li\u003e\n\u003cli\u003eSửa lại khi có thay đổi\u003c\/li\u003e\n\u003cli\u003eKhông có cách nào tự động update\u003c\/li\u003e\n\u003c\/ul\u003e\n\n\u003cp\u003eMark Chen, trong bài viết tháng 1\/2026 trên Medium, mô tả insight quan trọng từ sự thay đổi này: \u003cem\u003e\"Discovery becomes browsing, not searching the web. Installation becomes a command, not manual copying. Updates become managed.\"\u003c\/em\u003e\u003c\/p\u003e\n\n\u003cp\u003eVới Skills Marketplace, toàn bộ quy trình trên được giải quyết. Đây không chỉ là tính năng mới — đây là thay đổi ecosystem.\u003c\/p\u003e\n\n\u003ch2\u003eSkills Là Gì? Giải Thích Đơn Giản Nhất\u003c\/h2\u003e\n\n\u003cp\u003eHãy nghĩ skills như \"macro\" hoặc \"template thông minh\" cho Claude Code. Thay vì gõ lại một chuỗi instructions phức tạp mỗi lần, bạn lưu nó thành một file và gọi bằng slash command.\u003c\/p\u003e\n\n\u003cp\u003e\u003cstrong\u003eVí dụ đơn giản:\u003c\/strong\u003e\u003c\/p\u003e\n\u003cp\u003eKhông có skill:\u003c\/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e\"Review this code for security vulnerabilities, check for SQL injection, XSS, CSRF, authentication issues, and insecure direct object references. Format findings as: severity, location, description, recommended fix.\"\u003c\/p\u003e\n\u003c\/blockquote\u003e\n\n\u003cp\u003eVới skill \u003ccode\u003e\/security-review\u003c\/code\u003e:\u003c\/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e\/security-review [paste code here]\u003c\/p\u003e\n\u003c\/blockquote\u003e\n\n\u003cp\u003eKết quả như nhau. Nhưng bạn tiết kiệm thời gian gõ prompt mỗi lần, đảm bảo consistency, và có thể cải tiến skill một lần — áp dụng cho mọi lần dùng sau đó.\u003c\/p\u003e\n\n\u003ch2\u003eCấu Trúc Của Một Skill File\u003c\/h2\u003e\n\n\u003cp\u003eMột skill là file Markdown đơn giản với YAML frontmatter:\u003c\/p\u003e\n\n\u003cpre\u003e\u003ccode\u003e---\nname: security-review\ndescription: Comprehensive security vulnerability scan for code\n---\n\nReview the provided code for security vulnerabilities including:\n1. SQL injection risks\n2. XSS vulnerabilities\n3. Authentication issues\n4. Insecure direct object references\n5. CSRF vulnerabilities\n\nFormat output as: **Severity** | **Location** | **Issue** | **Fix**\n\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003cp\u003eFile này đặt trong \u003ccode\u003e~\/.claude\/skills\/\u003c\/code\u003e (global) hoặc \u003ccode\u003e.claude\/skills\/\u003c\/code\u003e trong project (local). Claude Code tự detect và available ngay.\u003c\/p\u003e\n\n\u003cp\u003eTìm hiểu thêm về cách xây dựng skills từ đầu trong bài \u003ca href=\"\/products\/claude-code-skills-huong-d%E1%BA%ABn-t%E1%BA%A1o-va-qu%E1%BA%A3n-ly\"\u003eClaude Code Skills: Hướng dẫn tạo và quản lý\u003c\/a\u003e.\u003c\/p\u003e\n\n\u003ch2\u003eSkills Marketplace Là Gì Và Nó Hoạt Động Thế Nào\u003c\/h2\u003e\n\n\u003cp\u003eMarketplace là repository tập trung các skills đã được cộng đồng xây dựng và kiểm tra. Theo Chen, đây là điểm thay đổi quan trọng nhất:\u003c\/p\u003e\n\n\u003cblockquote\u003e\n\u003cp\u003e\"The underlying shift is bigger than the UI — skills are becoming a normal part of how you use AI.\"\u003c\/p\u003e\n\u003c\/blockquote\u003e\n\n\u003cp\u003eThay vì mỗi người tự reinvent the wheel, cộng đồng chia sẻ skills đã được kiểm tra kỹ. Bạn browse, tìm skill phù hợp, cài bằng một lệnh.\u003c\/p\u003e\n\n\u003ch3\u003eCác Danh Mục Skills Phổ Biến Trong Marketplace\u003c\/h3\u003e\n\n\u003cp\u003e\u003cstrong\u003eDevelopment Skills:\u003c\/strong\u003e\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003eCode review với focus cụ thể (security, performance, accessibility)\u003c\/li\u003e\n\u003cli\u003eRefactoring patterns (clean code, SOLID principles)\u003c\/li\u003e\n\u003cli\u003eDocumentation generation (JSDoc, docstrings, README)\u003c\/li\u003e\n\u003cli\u003eTest generation (unit tests, integration tests)\u003c\/li\u003e\n\u003c\/ul\u003e\n\n\u003cp\u003e\u003cstrong\u003eContent Skills:\u003c\/strong\u003e\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003eTechnical writing templates\u003c\/li\u003e\n\u003cli\u003eBlog post frameworks\u003c\/li\u003e\n\u003cli\u003eEmail templates cho developer workflows\u003c\/li\u003e\n\u003c\/ul\u003e\n\n\u003cp\u003e\u003cstrong\u003eData Analysis Skills:\u003c\/strong\u003e\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003eSQL query optimization\u003c\/li\u003e\n\u003cli\u003eData cleaning workflows\u003c\/li\u003e\n\u003cli\u003eVisualization recommendations\u003c\/li\u003e\n\u003c\/ul\u003e\n\n\u003cp\u003e\u003cstrong\u003eDevOps Skills:\u003c\/strong\u003e\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003eDockerfile generation\u003c\/li\u003e\n\u003cli\u003eCI\/CD pipeline review\u003c\/li\u003e\n\u003cli\u003eInfrastructure as code templates\u003c\/li\u003e\n\u003c\/ul\u003e\n\n\u003ch2\u003eBước 1: Cài Đặt Skill Đầu Tiên\u003c\/h2\u003e\n\n\u003cp\u003eQuy trình cơ bản để cài một skill từ marketplace:\u003c\/p\u003e\n\n\u003ch3\u003eOption A: Từ GitHub (Phổ Biến Nhất)\u003c\/h3\u003e\n\u003cpre\u003e\u003ccode\u003e# Vào thư mục skills\ncd ~\/.claude\/skills\/\n\n# Clone một skill repo\ngit clone https:\/\/github.com\/username\/claude-skill-name\n\n# Hoặc chỉ download file skill đơn lẻ\ncurl -O https:\/\/raw.githubusercontent.com\/username\/repo\/main\/skill-name.md\n\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch3\u003eOption B: Từ Plugin Package\u003c\/h3\u003e\n\u003cpre\u003e\u003ccode\u003e# Cài plugin (bundle bao gồm nhiều skills)\nclaude plugin install claude-code-toolkit\n\n# List skills đã cài\nclaude skills list\n\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch3\u003eOption C: Tự Tạo\u003c\/h3\u003e\n\u003cpre\u003e\u003ccode\u003e# Tạo file skill mới\ntouch ~\/.claude\/skills\/my-skill.md\n# Mở và edit với text editor yêu thích\n\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch2\u003eBước 2: Kiểm Tra Skill Đã Hoạt Động\u003c\/h2\u003e\n\n\u003cp\u003eSau khi cài, verify bằng cách gõ trong Claude Code:\u003c\/p\u003e\n\u003cpre\u003e\u003ccode\u003e\/skills\n\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003cp\u003eClaude sẽ list tất cả skills đang active. Nếu skill bạn vừa cài xuất hiện, nó đã sẵn sàng.\u003c\/p\u003e\n\n\u003cp\u003e\u003cstrong\u003eLưu ý quan trọng từ nghiên cứu của Claude.vn:\u003c\/strong\u003e Skills chỉ activate khoảng 20% thời gian nếu không có forced-eval hook. Với hook này, tỷ lệ kích hoạt tăng lên 84%. Đây là kỹ thuật nâng cao được giải thích chi tiết trong bài về \u003ca href=\"\/products\/claude-code-skills-plugin-marketplace-scott-spence\"\u003eScott Spence và Plugin Marketplace\u003c\/a\u003e.\u003c\/p\u003e\n\n\u003ch2\u003eBước 3: Sử Dụng Skill Trong Practice\u003c\/h2\u003e\n\n\u003cp\u003eSyntax cơ bản:\u003c\/p\u003e\n\u003cpre\u003e\u003ccode\u003e\/skill-name [optional arguments]\n\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003cp\u003eVí dụ thực tế:\u003c\/p\u003e\n\u003cpre\u003e\u003ccode\u003e# Review code security\n\/security-review\n[paste your code here]\n\n# Generate documentation\n\/generate-docs\n[paste function here]\n\n# Refactor theo clean code\n\/refactor-clean\n[paste messy code here]\n\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003cp\u003eSkills cũng hỗ trợ argument placeholders. Ví dụ skill \u003ccode\u003e\/translate\u003c\/code\u003e có thể nhận argument ngôn ngữ:\u003c\/p\u003e\n\u003cpre\u003e\u003ccode\u003e\/translate --lang=vi\n[paste English text here]\n\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch2\u003ePlugins: Skills On Steroids\u003c\/h2\u003e\n\n\u003cp\u003ePlugin là bước tiếp theo của skills — một bundle đóng gói skills, hooks, và MCP configurations thành một unit cài đặt duy nhất.\u003c\/p\u003e\n\n\u003cp\u003eKhác biệt chính:\u003c\/p\u003e\n\n\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003eSkills\u003c\/th\u003e\n\u003cth\u003ePlugins\u003c\/th\u003e\n\u003c\/tr\u003e\n\u003c\/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd\u003eFile Markdown đơn lẻ\u003c\/td\u003e\n\u003ctd\u003eBundle nhiều skills + hooks + configs\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eManual copy\u003c\/td\u003e\n\u003ctd\u003eSingle install command\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eNo versioning\u003c\/td\u003e\n\u003ctd\u003eBuilt-in version management\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003ePersonal use\u003c\/td\u003e\n\u003ctd\u003eTeam distribution\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003c\/tbody\u003e\n\u003c\/table\u003e\n\n\u003cp\u003ePlugin được cài với:\u003c\/p\u003e\n\u003cpre\u003e\u003ccode\u003eclaude plugin install plugin-name\n\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003cp\u003eVà gọi skills trong plugin với namespace:\u003c\/p\u003e\n\u003cpre\u003e\u003ccode\u003e\/pluginName:skillName [arguments]\n\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch2\u003eAuto-Activation: Skill Tự Kích Hoạt Khi Cần\u003c\/h2\u003e\n\n\u003cp\u003eMột tính năng mạnh mẽ ít được biết đến: skills có thể tự động activate khi context phù hợp — không cần bạn gọi bằng slash command.\u003c\/p\u003e\n\n\u003cp\u003eVí dụ: Bạn có skill \"security-review\" với keyword \"vulnerability\" trong description. Khi bạn paste code có vẻ nhạy cảm và hỏi \"Is this safe?\", Claude có thể tự động trigger skill này.\u003c\/p\u003e\n\n\u003cp\u003eĐể enable auto-activation, thêm vào YAML frontmatter:\u003c\/p\u003e\n\u003cpre\u003e\u003ccode\u003e---\nname: security-review\ndescription: Security vulnerability scan\nauto_activate: true\ntriggers: [\"security\", \"vulnerability\", \"authentication\", \"password\"]\n---\n\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch2\u003eXây Dựng Skills Marketplace Riêng Cho Team\u003c\/h2\u003e\n\n\u003cp\u003eChen đề cập đến một use case doanh nghiệp quan trọng: xây dựng \u003cem\u003eprivate skills marketplace\u003c\/em\u003e cho team.\u003c\/p\u003e\n\n\u003cp\u003eThay vì mỗi developer tự build skills riêng, team lead tạo một shared repo gồm:\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003eCompany coding standards skill\u003c\/li\u003e\n\u003cli\u003eInternal API documentation skill\u003c\/li\u003e\n\u003cli\u003eOnboarding checklist skill\u003c\/li\u003e\n\u003cli\u003eCode review theo internal guidelines\u003c\/li\u003e\n\u003c\/ul\u003e\n\n\u003cp\u003eKhi developer mới join, họ chỉ cần:\u003c\/p\u003e\n\u003cpre\u003e\u003ccode\u003eclaude plugin install company\/internal-toolkit\n\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003cp\u003eVà ngay lập tức có đầy đủ tooling theo chuẩn team.\u003c\/p\u003e\n\n\u003cp\u003eĐây là một trong những cách Claude Code đang thay đổi developer experience theo hướng \"dễ onboard hơn\" — chi tiết được phân tích trong bài \u003ca href=\"\/products\/claude-code-cho-team-qu%E1%BA%A3n-ly-va-chia-s%E1%BA%BB\"\u003eClaude Code cho Team: Quản lý và chia sẻ workflow\u003c\/a\u003e.\u003c\/p\u003e\n\n\u003ch2\u003eNhìn Về Tương Lai: Skills Ecosystem Đang Phát Triển\u003c\/h2\u003e\n\n\u003cp\u003eNhư Chen kết luận: skills marketplace không chỉ là tính năng — nó là foundation cho một ecosystem mới. Tương tự như npm cho Node.js hay pip cho Python, skills marketplace đang tạo ra một layer of reusable AI workflows mà cộng đồng có thể build và share.\u003c\/p\u003e\n\n\u003cp\u003eDự đoán cho năm 2026-2027:\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003eSpecialized skills marketplace cho từng ngành (legal, medical, finance)\u003c\/li\u003e\n\u003cli\u003ePaid skills marketplace với premium tools\u003c\/li\u003e\n\u003cli\u003eSkills có thể test và verify trước khi install\u003c\/li\u003e\n\u003cli\u003eIntegration với version control workflows\u003c\/li\u003e\n\u003c\/ul\u003e\n\n\u003cp\u003eBây giờ là thời điểm tốt nhất để bắt đầu xây dựng skills của riêng bạn và contribute vào cộng đồng.\u003c\/p\u003e\n\n\u003chr\u003e\n\u003ch2\u003eNguồn tham khảo\u003c\/h2\u003e\n\u003cul\u003e\n\u003cli\u003eMark Chen, \"Claude Code Has a Skills Marketplace Now: A Beginner-Friendly Walkthrough,\" Medium, 22\/01\/2026. \u003ca href=\"https:\/\/medium.com\/@markchen69\/claude-code-has-a-skills-marketplace-now-a-beginner-friendly-walkthrough-8adeb67cdc89\" target=\"_blank\"\u003eĐọc bài gốc\u003c\/a\u003e\n\u003c\/li\u003e\n\u003cli\u003eMuneeb Ahmad, \"Claude Code Extensions Explained,\" Medium, 05\/03\/2026. \u003ca href=\"https:\/\/muneebsa.medium.com\/claude-code-extensions-explained-skills-mcp-hooks-subagents-agent-teams-plugins-9294907e84ff\" target=\"_blank\"\u003eBài liên quan\u003c\/a\u003e\n\u003c\/li\u003e\n\u003cli\u003eAnthropic, Claude Code Documentation, 2026. \u003ca href=\"https:\/\/code.claude.com\/docs\" target=\"_blank\"\u003eTài liệu chính thức\u003c\/a\u003e\n\u003c\/li\u003e\n\u003c\/ul\u003e\n","brand":"Minh Tuấn","offers":[{"title":"Default Title","offer_id":47725822705876,"sku":null,"price":0.0,"currency_code":"VND","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0821\/0264\/9044\/files\/claude-code-co-skills-marketplace-r_i-h_ng-d_n-b_t-d_u-cho-ng_i-m_i-hoan-toan.jpg?v=1774574289"}],"url":"https:\/\/claude.vn\/collections\/claude-artifacts.oembed","provider":"CLAUDE.VN","version":"1.0","type":"link"}