Biến một công cụ web thành một MCP server không phụ thuộc (zero-dependency)

Tôi vận hành DomainIntel. Đó là một ứng dụng web nhỏ. Tôi muốn biến nó thành một Model Context Protocol (MCP) server.

Tôi muốn người dùng chỉ cần chạy một câu lệnh duy nhất: npx -y @domainintel/mcp.

Điều này giúp loại bỏ mọi rào cản. Không cần clone repo. Không mất thời gian cài đặt lâu. Server phải hoạt động như một tệp duy nhất mà không có các phụ thuộc khi chạy (runtime dependencies).

Dưới đây là cách tôi đã xây dựng nó bằng esbuild.

Thách thức: Đóng gói

Tôi đã sử dụng esbuild để đóng gói mọi thứ. Tôi đã phải giải quyết một vài rào cản kỹ thuật:

• Static Imports: esbuild không thể theo dõi các lệnh require tại thời điểm runtime. Tôi đã chuyển từ createRequire sang các lệnh import ESM tiêu chuẩn. Điều này cho phép esbuild theo dõi được đồ thị phụ thuộc (dependency graph).

• CommonJS Compatibility: Một dependency đã sử dụng require('net') ở bên trong. Tôi đã thêm một banner vào cấu hình esbuild. Banner này sẽ inject createRequire để bản shim hoạt động được với các module tích hợp sẵn (built-in modules).

• Logger Conflicts: MCP sử dụng stdout để giao tiếp. Logger hiện tại của tôi cố gắng ghi vào một thư mục cục bộ. Điều này sẽ thất bại khi chạy trong một CLI toàn cục. Tôi đã sử dụng một plugin onResolve để stub lại logger.

• Double Shebangs: Cả tệp entry và banner của tôi đều có shebang. Điều này tạo ra một tệp không hợp lệ. Tôi đã loại bỏ shebang khỏi mã nguồn.

• Module Types: Tôi đã xóa "type": "module" khỏi package.json. Việc này ngăn esbuild xử lý các tệp CommonJS như là ESM. Tệp entry .mjs vẫn là ESM nhờ vào phần mở rộng.

• Version Pinning: Một dependency đã chuyển sang ESM và làm hỏng bản build của tôi. Tôi đã chốt (pin) phiên bản để đảm bảo bản bundle có thể tái lập (reproducible).

Kết quả

Tệp cuối cùng là mcp/dist/server.mjs. Nó nặng khoảng 1.7 MB và không có bất kỳ phụ thuộc runtime nào.

Bạn có thể thêm nó vào Claude bằng lệnh: claude mcp add domainintel -- npx -y @domainintel/mcp

Giờ đây, agent của bạn có thể chạy "give me a full report on stripe.com" và nhận được dữ liệu ngay lập tức.

Nếu bạn có một công cụ với logic cốt lõi, hãy đóng gói nó thành một MCP server. Điều này sẽ giúp công cụ của bạn trở nên hữu ích cho các AI agent.

Source: https://dev.to/chris_morris/turning-a-web-tool-into-a-zero-dependency-mcp-server-21ca

Optional learning community: https://t.me/GyaanSetuAi