ವೆಬ್ ಟೂಲ್ ಅನ್ನು ಶೂನ್ಯ-ಅವಲಂಬನೆಯ (zero-dependency) MCP ಸರ್ವರ್ ಆಗಿ ಪರಿವರ್ತಿಸುವುದು
ನಾನು DomainIntel ಅನ್ನು ನಡೆಸುತ್ತಿದ್ದೇನೆ. ಇದು ಒಂದು ಸಣ್ಣ ವೆಬ್ ಅಪ್ಲಿಕೇಶನ್. ನಾನು ಇದನ್ನು Model Context Protocol (MCP) ಸರ್ವರ್ ಆಗಿ ಪರಿವರ್ತಿಸಲು ಬಯಸಿದೆ.
ಬಳಕೆದಾರರು ಕೇವಲ ಒಂದು ಕಮಾಂಡ್ ಅನ್ನು ರನ್ ಮಾಡಬೇಕೆಂದು ನಾನು ಬಯಸಿದೆ: npx -y @domainintel/mcp.
ಇದರರ್ಥ ಯಾವುದೇ ಅಡೆತಡೆಗಳಿಲ್ಲ (zero friction). ರೆಪೊಸಿಟರಿಗಳನ್ನು ಕ್ಲೋನ್ ಮಾಡುವ ಅಗತ್ಯವಿಲ್ಲ. ದೀರ್ಘ ಇನ್ಸ್ಟಾಲೇಶನ್ ಸಮಯವಿಲ್ಲ. ಸರ್ವರ್ ಯಾವುದೇ ರನ್ಟೈಮ್ ಅವಲಂಬನೆಗಳಿಲ್ಲದೆ (runtime dependencies) ಏಕೈಕ ಫೈಲ್ ಆಗಿ ಕೆಲಸ ಮಾಡಬೇಕು.
ನಾನು ಇದನ್ನು esbuild ಬಳಸಿ ಹೇಗೆ ನಿರ್ಮಿಸಿದೆ ಎಂಬುದು ಇಲ್ಲಿದೆ.
The Challenge: Packaging
ನಾನು ಎಲ್ಲವನ್ನೂ ಬಂಡಲ್ ಮಾಡಲು esbuild ಅನ್ನು ಬಳಸಿದೆ. ನಾನು ಹಲವಾರು ತಾಂತ್ರಿಕ ಸವಾಲುಗಳನ್ನು ಪರಿಹರಿಸಬೇಕಾಯಿತು:
• Static Imports: esbuild ರನ್ಟೈಮ್ require ಕರೆಗಳನ್ನು ಅನುಸರಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ. ನಾನು createRequire ನಿಂದ ಸ್ಟ್ಯಾಂಡರ್ಡ್ ESM ಇಂಪೋರ್ಟ್ಗಳಿಗೆ ಬದಲಾಯಿಸಿದೆ. ಇದು esbuild ಗೆ ಡಿಪೆಂಡೆನ್ಸಿ ಗ್ರಾಫ್ ಅನ್ನು ಅನುಸರಿಸಲು ಅನುವು ಮಾಡಿಕೊಟ್ಟಿತು.
• CommonJS Compatibility: ಒಂದು ಡಿಪೆಂಡೆನ್ಸಿ ಆಂತರಿಕವಾಗಿ require('net') ಅನ್ನು ಬಳಸುತ್ತಿತ್ತು. ನಾನು esbuild ಕಾನ್ಫಿಗರೇಶನ್ನಲ್ಲಿ ಒಂದು ಬ್ಯಾನರ್ (banner) ಅನ್ನು ಸೇರಿಸಿದೆ. ಈ ಬ್ಯಾನರ್ createRequire ಅನ್ನು ಇಂಜೆಕ್ಟ್ ಮಾಡುತ್ತದೆ, ಇದರಿಂದ ಬಿಲ್ಟ್-ಇನ್ ಮಾಡ್ಯೂಲ್ಗಳಿಗೆ ಶಿಮ್ (shim) ಕೆಲಸ ಮಾಡುತ್ತದೆ.
• Logger Conflicts: MCP ಸಂವಹನಕ್ಕಾಗಿ stdout ಅನ್ನು ಬಳಸುತ್ತದೆ. ನನ್ನ ಅಸ್ತಿತ್ವದಲ್ಲಿರುವ ಲೋಗರ್ (logger) ಸ್ಥಳೀಯ ಡೈರೆಕ್ಟರಿಗೆ ಬರೆಯಲು ಪ್ರಯತ್ನಿಸುತ್ತಿತ್ತು. ಇದು ಗ್ಲೋಬಲ್ CLI ನಲ್ಲಿ ವಿಫಲವಾಗುತ್ತದೆ. ಲೋಗರ್ ಅನ್ನು ಸ್ಟಬ್ (stub) ಮಾಡಲು ನಾನು onResolve ಪ್ಲಗಿನ್ ಅನ್ನು ಬಳಸಿದೆ.
• Double Shebangs: ನನ್ನ ಎಂಟ್ರಿ ಫೈಲ್ ಮತ್ತು ಬ್ಯಾನರ್ ಎರಡರಲ್ಲೂ ಶೆಬಾಂಗ್ಗಳು (shebangs) ಇದ್ದವು. ಇದು ಅಮಾನ್ಯವಾದ ಫೈಲ್ ಅನ್ನು ಸೃಷ್ಟಿಸಿತು. ನಾನು ಸೋರ್ಸ್ ಕೋಡ್ನಿಂದ ಶೆಬಾಂಗ್ ಅನ್ನು ತೆಗೆದುಹಾಕಿದೆ.
• Module Types: ನಾನು package.json ನಿಂದ "type": "module" ಅನ್ನು ತೆಗೆದುಹಾಕಿದೆ. ಇದು CommonJS ಫೈಲ್ಗಳನ್ನು ESM ಎಂದು ಪರಿಗಣಿಸದಂತೆ esbuild ಅನ್ನು ತಡೆಯಿತು. .mjs ಎಂಟ್ರಿ ಫೈಲ್ ಎಕ್ಸ್ಟೆನ್ಶನ್ ಮೂಲಕ ESM ಆಗಿಯೇ ಉಳಿಯುತ್ತದೆ.
• Version Pinning: ಒಂದು ಡಿಪೆಂಡೆನ್ಸಿ ESM ಗೆ ಬದಲಾಯಿತು ಮತ್ತು ನನ್ನ ಬಿಲ್ಡ್ ಅನ್ನು ಹಾಳುಮಾಡಿತು. ಬಂಡಲ್ ಅನ್ನು ಪುನರಾವರ್ತಿತವಾಗಿ (reproducible) ಮಾಡಲು ನಾನು ಆ ವರ್ಷನ್ ಅನ್ನು ಪಿನ್ (pin) ಮಾಡಿದೆ.
The Result
ಅಂತಿಮ ಫೈಲ್ mcp/dist/server.mjs. ಇದು ಸುಮಾರು 1.7 MB ಇದೆ. ಇದು ಯಾವುದೇ ರನ್ಟೈಮ್ ಡಿಪೆಂಡೆನ್ಸಿಗಳಿಲ್ಲದೆ ಕೆಲಸ ಮಾಡುತ್ತದೆ.
ನೀವು ಇದನ್ನು Claude ಗೆ ಈ ಕೆಳಗಿನಂತೆ ಸೇರಿಸಬಹುದು:
claude mcp add domainintel -- npx -y @domainintel/mcp
ಈಗ ನಿಮ್ಮ ಏಜೆಂಟ್ "give me a full report on stripe.com" ಎಂದು ರನ್ ಮಾಡಿ ತಕ್ಷಣದ ಡೇಟಾವನ್ನು ಪಡೆಯಬಹುದು.
ನಿಮ್ಮ ಬಳಿ ಕೋರ್ ಲಾಜಿಕ್ ಹೊಂದಿರುವ ಟೂಲ್ ಇದ್ದರೆ, ಅದನ್ನು MCP ಸರ್ವರ್ ಆಗಿ ಎನ್ಕ್ಯಾಪ್ (wrap) ಮಾಡಿ. ಇದು ನಿಮ್ಮ ಟೂಲ್ ಅನ್ನು AI ಏಜೆಂಟ್ಗಳಿಗೆ ಉಪಯುಕ್ತವಾಗಿಸುತ್ತದೆ.
Source: https://dev.to/chris_morris/turning-a-web-tool-into-a-zero-dependency-mcp-server-21ca
Optional learning community: https://t.me/GyaanSetuAi
