diff --git a/package-lock.json b/package-lock.json index 3614fa909c8..e7081e78882 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12528,6 +12528,334 @@ "dev": true, "license": "MIT" }, + "node_modules/@modelcontextprotocol/sdk": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.9.0.tgz", + "integrity": "sha512-Jq2EUCQpe0iyO5FGpzVYDNFR6oR53AIrwph9yWl7uSc7IWUMsrmpmSaTGra5hQNunXpM+9oit85p924jWuHzUA==", + "license": "MIT", + "dependencies": { + "content-type": "^1.0.5", + "cors": "^2.8.5", + "cross-spawn": "^7.0.3", + "eventsource": "^3.0.2", + "express": "^5.0.1", + "express-rate-limit": "^7.5.0", + "pkce-challenge": "^5.0.0", + "raw-body": "^3.0.0", + "zod": "^3.23.8", + "zod-to-json-schema": "^3.24.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/accepts": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", + "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", + "license": "MIT", + "dependencies": { + "mime-types": "^3.0.0", + "negotiator": "^1.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/body-parser": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.0.tgz", + "integrity": "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==", + "license": "MIT", + "dependencies": { + "bytes": "^3.1.2", + "content-type": "^1.0.5", + "debug": "^4.4.0", + "http-errors": "^2.0.0", + "iconv-lite": "^0.6.3", + "on-finished": "^2.4.1", + "qs": "^6.14.0", + "raw-body": "^3.0.0", + "type-is": "^2.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/content-disposition": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.0.tgz", + "integrity": "sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==", + "license": "MIT", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/cookie-signature": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", + "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", + "license": "MIT", + "engines": { + "node": ">=6.6.0" + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/express": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/express/-/express-5.1.0.tgz", + "integrity": "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==", + "license": "MIT", + "dependencies": { + "accepts": "^2.0.0", + "body-parser": "^2.2.0", + "content-disposition": "^1.0.0", + "content-type": "^1.0.5", + "cookie": "^0.7.1", + "cookie-signature": "^1.2.1", + "debug": "^4.4.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "finalhandler": "^2.1.0", + "fresh": "^2.0.0", + "http-errors": "^2.0.0", + "merge-descriptors": "^2.0.0", + "mime-types": "^3.0.0", + "on-finished": "^2.4.1", + "once": "^1.4.0", + "parseurl": "^1.3.3", + "proxy-addr": "^2.0.7", + "qs": "^6.14.0", + "range-parser": "^1.2.1", + "router": "^2.2.0", + "send": "^1.1.0", + "serve-static": "^2.2.0", + "statuses": "^2.0.1", + "type-is": "^2.0.1", + "vary": "^1.1.2" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/finalhandler": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.0.tgz", + "integrity": "sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "on-finished": "^2.4.1", + "parseurl": "^1.3.3", + "statuses": "^2.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", + "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/media-typer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", + "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/merge-descriptors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", + "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/mime-types": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz", + "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==", + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/negotiator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", + "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/qs": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", + "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/raw-body": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz", + "integrity": "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==", + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.6.3", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/send": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/send/-/send-1.2.0.tgz", + "integrity": "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==", + "license": "MIT", + "dependencies": { + "debug": "^4.3.5", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "fresh": "^2.0.0", + "http-errors": "^2.0.0", + "mime-types": "^3.0.1", + "ms": "^2.1.3", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "statuses": "^2.0.1" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/serve-static": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.0.tgz", + "integrity": "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==", + "license": "MIT", + "dependencies": { + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "parseurl": "^1.3.3", + "send": "^1.2.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/type-is": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", + "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", + "license": "MIT", + "dependencies": { + "content-type": "^1.0.5", + "media-typer": "^1.1.0", + "mime-types": "^3.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "dev": true, @@ -15673,7 +16001,6 @@ }, "node_modules/accepts": { "version": "1.3.8", - "dev": true, "license": "MIT", "dependencies": { "mime-types": "~2.1.34", @@ -16312,7 +16639,6 @@ }, "node_modules/body-parser": { "version": "1.20.3", - "dev": true, "license": "MIT", "dependencies": { "bytes": "3.1.2", @@ -16335,7 +16661,6 @@ }, "node_modules/body-parser/node_modules/debug": { "version": "2.6.9", - "dev": true, "license": "MIT", "dependencies": { "ms": "2.0.0" @@ -16343,7 +16668,6 @@ }, "node_modules/body-parser/node_modules/depd": { "version": "2.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" @@ -16351,7 +16675,6 @@ }, "node_modules/body-parser/node_modules/ms": { "version": "2.0.0", - "dev": true, "license": "MIT" }, "node_modules/bonjour-service": { @@ -16631,6 +16954,35 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/call-me-maybe": { "version": "1.0.2", "dev": true, @@ -17171,7 +17523,6 @@ }, "node_modules/content-disposition": { "version": "0.5.4", - "dev": true, "license": "MIT", "dependencies": { "safe-buffer": "5.2.1" @@ -17182,7 +17533,6 @@ }, "node_modules/content-type": { "version": "1.0.5", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -17195,7 +17545,6 @@ }, "node_modules/cookie": { "version": "0.7.1", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -17203,7 +17552,6 @@ }, "node_modules/cookie-signature": { "version": "1.0.6", - "dev": true, "license": "MIT" }, "node_modules/cookies": { @@ -17242,6 +17590,19 @@ "version": "1.0.3", "license": "MIT" }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "license": "MIT", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, "node_modules/cosmiconfig": { "version": "5.2.1", "dev": true, @@ -17701,7 +18062,6 @@ }, "node_modules/destroy": { "version": "1.2.0", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.8", @@ -17827,6 +18187,20 @@ "url": "https://github.com/fb55/domutils?sponsor=1" } }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/duplexer": { "version": "0.1.2", "license": "MIT" @@ -17875,7 +18249,6 @@ }, "node_modules/ee-first": { "version": "1.1.1", - "dev": true, "license": "MIT" }, "node_modules/electron-to-chromium": { @@ -17918,7 +18291,6 @@ }, "node_modules/encodeurl": { "version": "1.0.2", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" @@ -18013,11 +18385,10 @@ } }, "node_modules/es-define-property": { - "version": "1.0.0", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.2.4" - }, "engines": { "node": ">= 0.4" } @@ -18034,6 +18405,18 @@ "dev": true, "license": "MIT" }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/es-to-primitive": { "version": "1.2.1", "license": "MIT", @@ -18587,7 +18970,6 @@ }, "node_modules/etag": { "version": "1.8.1", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -18627,6 +19009,27 @@ "node": ">=0.4.x" } }, + "node_modules/eventsource": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.6.tgz", + "integrity": "sha512-l19WpE2m9hSuyP06+FbuUUf1G+R0SFLrtQfbRb9PRr+oimOfxQhgGCbVaXg5IvZyyTThJsxh6L/srkMiCeBPDA==", + "license": "MIT", + "dependencies": { + "eventsource-parser": "^3.0.1" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/eventsource-parser": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.1.tgz", + "integrity": "sha512-VARTJ9CYeuQYb0pZEPbzi740OWFgpHe7AYJ2WFZVnUDUQp5Dk2yJUgF36YsZ81cOyxT0QxmXD2EQpapAouzWVA==", + "license": "MIT", + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/evp_bytestokey": { "version": "1.0.3", "license": "MIT", @@ -18679,7 +19082,6 @@ }, "node_modules/express": { "version": "4.21.2", - "dev": true, "license": "MIT", "dependencies": { "accepts": "~1.3.8", @@ -18722,14 +19124,27 @@ "url": "https://opencollective.com/express" } }, + "node_modules/express-rate-limit": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-7.5.0.tgz", + "integrity": "sha512-eB5zbQh5h+VenMPM3fh+nw1YExi5nMr6HUCR62ELSP11huvxm/Uir1H1QEyTkk5QX6A58pX6NmaTMceKZ0Eodg==", + "license": "MIT", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/express-rate-limit" + }, + "peerDependencies": { + "express": "^4.11 || 5 || ^5.0.0-beta.1" + } + }, "node_modules/express/node_modules/array-flatten": { "version": "1.1.1", - "dev": true, "license": "MIT" }, "node_modules/express/node_modules/debug": { "version": "2.6.9", - "dev": true, "license": "MIT", "dependencies": { "ms": "2.0.0" @@ -18737,7 +19152,6 @@ }, "node_modules/express/node_modules/depd": { "version": "2.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" @@ -18745,7 +19159,6 @@ }, "node_modules/express/node_modules/encodeurl": { "version": "2.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" @@ -18753,17 +19166,14 @@ }, "node_modules/express/node_modules/ms": { "version": "2.0.0", - "dev": true, "license": "MIT" }, "node_modules/express/node_modules/path-to-regexp": { "version": "0.1.12", - "dev": true, "license": "MIT" }, "node_modules/express/node_modules/statuses": { "version": "2.0.1", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" @@ -18955,7 +19365,6 @@ }, "node_modules/finalhandler": { "version": "1.3.1", - "dev": true, "license": "MIT", "dependencies": { "debug": "2.6.9", @@ -18972,7 +19381,6 @@ }, "node_modules/finalhandler/node_modules/debug": { "version": "2.6.9", - "dev": true, "license": "MIT", "dependencies": { "ms": "2.0.0" @@ -18980,7 +19388,6 @@ }, "node_modules/finalhandler/node_modules/encodeurl": { "version": "2.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" @@ -18988,12 +19395,10 @@ }, "node_modules/finalhandler/node_modules/ms": { "version": "2.0.0", - "dev": true, "license": "MIT" }, "node_modules/finalhandler/node_modules/statuses": { "version": "2.0.1", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" @@ -19108,7 +19513,6 @@ }, "node_modules/forwarded": { "version": "0.2.0", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -19116,7 +19520,6 @@ }, "node_modules/fresh": { "version": "0.5.2", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -19209,14 +19612,21 @@ } }, "node_modules/get-intrinsic": { - "version": "1.2.4", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", "license": "MIT", "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -19225,6 +19635,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/get-stdin": { "version": "8.0.0", "dev": true, @@ -19370,10 +19793,12 @@ } }, "node_modules/gopd": { - "version": "1.0.1", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.1.3" + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -19476,18 +19901,10 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/has-proto": { - "version": "1.0.3", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/has-symbols": { - "version": "1.0.3", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -19703,7 +20120,6 @@ }, "node_modules/http-errors": { "version": "2.0.0", - "dev": true, "license": "MIT", "dependencies": { "depd": "2.0.0", @@ -19718,7 +20134,6 @@ }, "node_modules/http-errors/node_modules/depd": { "version": "2.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" @@ -19726,7 +20141,6 @@ }, "node_modules/http-errors/node_modules/statuses": { "version": "2.0.1", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" @@ -19855,7 +20269,6 @@ }, "node_modules/iconv-lite": { "version": "0.4.24", - "dev": true, "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3" @@ -21280,6 +21693,15 @@ "node": ">= 18" } }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/md5": { "version": "2.3.0", "dev": true, @@ -21305,7 +21727,6 @@ }, "node_modules/media-typer": { "version": "0.3.0", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -21383,7 +21804,6 @@ }, "node_modules/merge-descriptors": { "version": "1.0.3", - "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -21404,7 +21824,6 @@ }, "node_modules/methods": { "version": "1.1.2", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -21444,7 +21863,6 @@ }, "node_modules/mime": { "version": "1.6.0", - "dev": true, "license": "MIT", "bin": { "mime": "cli.js" @@ -21904,7 +22322,6 @@ }, "node_modules/negotiator": { "version": "0.6.3", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -22090,14 +22507,15 @@ }, "node_modules/object-assign": { "version": "4.1.1", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/object-inspect": { - "version": "1.13.2", + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -22151,7 +22569,6 @@ }, "node_modules/on-finished": { "version": "2.4.1", - "dev": true, "license": "MIT", "dependencies": { "ee-first": "1.1.1" @@ -22392,7 +22809,6 @@ }, "node_modules/parseurl": { "version": "1.3.3", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" @@ -22537,6 +22953,15 @@ "node": ">=4" } }, + "node_modules/pkce-challenge": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-5.0.0.tgz", + "integrity": "sha512-ueGLflrrnvwB3xuo/uGob5pd5FN7l0MsLf0Z87o/UQmRtwjvfylfc9MurIxRAWywCYTgrvpXBcqjV4OfCYGCIQ==", + "license": "MIT", + "engines": { + "node": ">=16.20.0" + } + }, "node_modules/pkg-dir": { "version": "4.2.0", "dev": true, @@ -22943,7 +23368,6 @@ }, "node_modules/proxy-addr": { "version": "2.0.7", - "dev": true, "license": "MIT", "dependencies": { "forwarded": "0.2.0", @@ -22955,7 +23379,6 @@ }, "node_modules/proxy-addr/node_modules/ipaddr.js": { "version": "1.9.1", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.10" @@ -23025,7 +23448,6 @@ }, "node_modules/qs": { "version": "6.13.0", - "dev": true, "license": "BSD-3-Clause", "dependencies": { "side-channel": "^1.0.6" @@ -23099,7 +23521,6 @@ }, "node_modules/range-parser": { "version": "1.2.1", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -23107,7 +23528,6 @@ }, "node_modules/raw-body": { "version": "2.5.2", - "dev": true, "license": "MIT", "dependencies": { "bytes": "3.1.2", @@ -23681,6 +24101,69 @@ "inherits": "^2.0.1" } }, + "node_modules/router": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", + "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "depd": "^2.0.0", + "is-promise": "^4.0.0", + "parseurl": "^1.3.3", + "path-to-regexp": "^8.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/router/node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/router/node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/router/node_modules/is-promise": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", + "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", + "license": "MIT" + }, + "node_modules/router/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/router/node_modules/path-to-regexp": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.2.0.tgz", + "integrity": "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==", + "license": "MIT", + "engines": { + "node": ">=16" + } + }, "node_modules/rrweb-cssom": { "version": "0.6.0", "dev": true, @@ -23881,7 +24364,6 @@ }, "node_modules/send": { "version": "0.19.0", - "dev": true, "license": "MIT", "dependencies": { "debug": "2.6.9", @@ -23904,7 +24386,6 @@ }, "node_modules/send/node_modules/debug": { "version": "2.6.9", - "dev": true, "license": "MIT", "dependencies": { "ms": "2.0.0" @@ -23912,12 +24393,10 @@ }, "node_modules/send/node_modules/debug/node_modules/ms": { "version": "2.0.0", - "dev": true, "license": "MIT" }, "node_modules/send/node_modules/depd": { "version": "2.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" @@ -23925,12 +24404,10 @@ }, "node_modules/send/node_modules/ms": { "version": "2.1.3", - "dev": true, "license": "MIT" }, "node_modules/send/node_modules/statuses": { "version": "2.0.1", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" @@ -24000,7 +24477,6 @@ }, "node_modules/serve-static": { "version": "1.16.2", - "dev": true, "license": "MIT", "dependencies": { "encodeurl": "~2.0.0", @@ -24014,7 +24490,6 @@ }, "node_modules/serve-static/node_modules/encodeurl": { "version": "2.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" @@ -24042,7 +24517,6 @@ }, "node_modules/setprototypeof": { "version": "1.2.0", - "dev": true, "license": "ISC" }, "node_modules/sh-syntax": { @@ -24121,13 +24595,69 @@ "license": "MIT" }, "node_modules/side-channel": { - "version": "1.0.6", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "object-inspect": "^1.13.1" + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" }, "engines": { "node": ">= 0.4" @@ -24961,7 +25491,6 @@ }, "node_modules/toidentifier": { "version": "1.0.1", - "dev": true, "license": "MIT", "engines": { "node": ">=0.6" @@ -25191,7 +25720,6 @@ }, "node_modules/type-is": { "version": "1.6.18", - "dev": true, "license": "MIT", "dependencies": { "media-typer": "0.3.0", @@ -25309,7 +25837,6 @@ }, "node_modules/unpipe": { "version": "1.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" @@ -25395,7 +25922,6 @@ }, "node_modules/utils-merge": { "version": "1.0.1", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4.0" @@ -25476,7 +26002,6 @@ }, "node_modules/vary": { "version": "1.1.2", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" @@ -26732,6 +27257,24 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/zod": { + "version": "3.24.2", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.2.tgz", + "integrity": "sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/zod-to-json-schema": { + "version": "3.24.5", + "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.24.5.tgz", + "integrity": "sha512-/AuWwMP+YqiPbsJx5D6TfgRTc4kTLjsh5SOcd4bLsfUg2RcEXrFMJl1DGgdHy2aCfsIA/cr/1JM0xcB2GZji8g==", + "license": "ISC", + "peerDependencies": { + "zod": "^3.24.1" + } + }, "packages/amazonq": { "name": "amazon-q-vscode", "version": "1.60.0-SNAPSHOT", @@ -26780,6 +27323,7 @@ "@aws/mynah-ui": "^4.31.0-beta.6", "@gerhobbelt/gitignore-parser": "^0.2.0-9", "@iarna/toml": "^2.2.5", + "@modelcontextprotocol/sdk": "^1.9.0", "@smithy/fetch-http-handler": "^5.0.1", "@smithy/middleware-retry": "^4.0.3", "@smithy/node-http-handler": "^4.0.2", diff --git a/packages/amazonq/.vscode/launch.json b/packages/amazonq/.vscode/launch.json index 47a87b7d6f9..77e3160d7ef 100644 --- a/packages/amazonq/.vscode/launch.json +++ b/packages/amazonq/.vscode/launch.json @@ -13,7 +13,8 @@ "args": ["--extensionDevelopmentPath=${workspaceFolder}"], "env": { "SSMDOCUMENT_LANGUAGESERVER_PORT": "6010", - "WEBPACK_DEVELOPER_SERVER": "http://localhost:8080" + "WEBPACK_DEVELOPER_SERVER": "http://localhost:8080", + "PATH": "/Users/bywang/.toolbox/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin" // "__AMAZONQLSP_PATH": "${workspaceFolder}/../../../language-servers/app/aws-lsp-codewhisperer-runtimes/out/token-standalone.js", // "__AMAZONQLSP_UI": "${workspaceFolder}/../../../language-servers/chat-client/build/amazonq-ui.js" }, diff --git a/packages/core/package.json b/packages/core/package.json index 2501aae0fd0..eaeee58ad9f 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -576,7 +576,8 @@ "winston": "^3.11.0", "winston-transport": "^4.6.0", "xml2js": "^0.6.1", - "yaml-cfn": "^0.3.2" + "yaml-cfn": "^0.3.2", + "@modelcontextprotocol/sdk": "^1.9.0" }, "overrides": { "webfont": { diff --git a/packages/core/src/amazonq/webview/ui/main.ts b/packages/core/src/amazonq/webview/ui/main.ts index 9d0507b846e..f1b1036921f 100644 --- a/packages/core/src/amazonq/webview/ui/main.ts +++ b/packages/core/src/amazonq/webview/ui/main.ts @@ -1023,6 +1023,11 @@ export const createMynahUI = ( feedbackOptions: feedbackOptions, texts: uiComponentsTexts, tabBarButtons: [ + { + id: 'mcp_configuration', + icon: MynahIcons.MAGIC, + description: 'MCP configuration', + }, { id: 'history_sheet', icon: MynahIcons.HISTORY, diff --git a/packages/core/src/codewhisperer/activation.ts b/packages/core/src/codewhisperer/activation.ts index 70a7417f263..215e8faeabf 100644 --- a/packages/core/src/codewhisperer/activation.ts +++ b/packages/core/src/codewhisperer/activation.ts @@ -90,6 +90,8 @@ import { SecurityIssueTreeViewProvider } from './service/securityIssueTreeViewPr import { setContext } from '../shared/vscode/setContext' import { syncSecurityIssueWebview } from './views/securityIssue/securityIssueWebview' import { detectCommentAboveLine } from '../shared/utilities/commentUtils' +import { globalMcpConfigPath } from '../codewhispererChat/constants' +import { McpManager } from '../codewhispererChat/tools/mcp/mcpManager' let localize: nls.LocalizeFunc @@ -373,6 +375,12 @@ export async function activate(context: ExtContext): Promise { setSubscriptionsForCodeIssues() + /** + * MCP client initialization + */ + await McpManager.initMcpManager(globalMcpConfigPath) + setSubscriptionsForMcp() + function shouldRunAutoScan(editor: vscode.TextEditor | undefined, isScansEnabled?: boolean) { return ( (isScansEnabled ?? CodeScansState.instance.isScansEnabled()) && @@ -499,6 +507,29 @@ export async function activate(context: ExtContext): Promise { }) ) } + + function setSubscriptionsForMcp() { + let lastMcpContent: string | undefined + const updateLastContent = (document: vscode.TextDocument) => { + lastMcpContent = document.getText() + } + const mcpOpenListener = vscode.workspace.onDidOpenTextDocument((document: vscode.TextDocument) => { + if (document.uri.fsPath === globalMcpConfigPath) { + updateLastContent(document) + } + }) + context.extensionContext.subscriptions.push(mcpOpenListener) + const mcpSaveListener = vscode.workspace.onDidSaveTextDocument(async (doc) => { + if (doc.uri.fsPath === globalMcpConfigPath) { + const newContent = doc.getText() + if (lastMcpContent === undefined || newContent !== lastMcpContent) { + await McpManager.initMcpManager(globalMcpConfigPath) + lastMcpContent = newContent + } + } + }) + context.extensionContext.subscriptions.push(mcpSaveListener) + } } export async function shutdown() { diff --git a/packages/core/src/codewhispererChat/constants.ts b/packages/core/src/codewhispererChat/constants.ts index 093b7e1a1d2..60db006a598 100644 --- a/packages/core/src/codewhispererChat/constants.ts +++ b/packages/core/src/codewhispererChat/constants.ts @@ -66,3 +66,5 @@ export const ignoredDirectoriesAndFiles = [ // OS specific files '.DS_Store', ] + +export const globalMcpConfigPath = path.join(process.env.HOME ?? '', '.aws', 'amazonq', 'mcp.json') diff --git a/packages/core/src/codewhispererChat/controllers/chat/tabBarController.ts b/packages/core/src/codewhispererChat/controllers/chat/tabBarController.ts index 0ab29393ce7..6f9ba2ea4ca 100644 --- a/packages/core/src/codewhispererChat/controllers/chat/tabBarController.ts +++ b/packages/core/src/codewhispererChat/controllers/chat/tabBarController.ts @@ -15,6 +15,7 @@ import { Database } from '../../../shared/db/chatDb/chatDb' import { TabBarButtonClick, SaveChatMessage } from './model' import { Conversation, messageToChatItem, Tab } from '../../../shared/db/chatDb/util' import { DetailedListItemGroup, MynahIconsType } from '@aws/mynah-ui' +import { globalMcpConfigPath } from '../../constants' export class TabBarController { private readonly messenger: Messenger @@ -146,11 +147,29 @@ export class TabBarController { case 'history_sheet': await this.historyButtonClicked(message) break + case 'mcp_configuration': + await this.mcpButtonClicked(message) + break case 'export_chat': await this.exportChatButtonClicked(message) break } } + private async mcpButtonClicked(message: TabBarButtonClick) { + let fileExists = false + try { + await fs.stat(globalMcpConfigPath) + fileExists = true + } catch (error) { + fileExists = false + } + if (!fileExists) { + const defaultContent = JSON.stringify({ mcpServers: {} }, undefined, 2) + await fs.writeFile(globalMcpConfigPath, defaultContent, { encoding: 'utf8' }) + } + const document = await vscode.workspace.openTextDocument(globalMcpConfigPath) + await vscode.window.showTextDocument(document, { preview: false }) + } private async exportChatButtonClicked(message: TabBarButtonClick) { const defaultFileName = `q-dev-chat-${new Date().toISOString().split('T')[0]}.md` diff --git a/packages/core/src/codewhispererChat/tools/mcp/mcpManager.ts b/packages/core/src/codewhispererChat/tools/mcp/mcpManager.ts new file mode 100644 index 00000000000..635cbcb61e5 --- /dev/null +++ b/packages/core/src/codewhispererChat/tools/mcp/mcpManager.ts @@ -0,0 +1,162 @@ +/*! + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +import { ListToolsResponse, MCPConfig, MCPServerConfig } from './mcpTypes' +import { Client } from '@modelcontextprotocol/sdk/client/index.js' +import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js' +import fs from '../../../shared/fs/fs' +import { getLogger } from '../../../shared/logger/logger' +import { tools } from '../../constants' + +export interface McpToolDefinition { + serverName: string + toolName: string + description: string + inputSchema: any // schema from the server +} + +export class McpManager { + static #instance: McpManager | undefined + private mcpServers: Record = {} + private clients: Map = new Map() // key: serverName, val: MCP client + private mcpTools: McpToolDefinition[] = [] + + private constructor(private readonly configPath: string) {} + + public static get instance(): McpManager { + if (!McpManager.#instance) { + throw new Error('McpManager not initialized—call initMcpManager() first') + } + return McpManager.#instance + } + + public async loadConfig(): Promise { + if (!(await fs.exists(this.configPath))) { + throw new Error(`Could not load the MCP config at ${this.configPath}`) + } + const raw = await fs.readFileText(this.configPath) + const json = JSON.parse(raw) as MCPConfig + if (!json.mcpServers) { + throw new Error(`No "mcpServers" field found in config: ${this.configPath}`) + } + this.mcpServers = json.mcpServers + } + + public async initAllServers(): Promise { + this.mcpTools = [] + for (const [serverName, serverConfig] of Object.entries(this.mcpServers)) { + if (serverConfig.disabled) { + getLogger().info(`MCP server [${serverName}] is disabled, skipping.`) + continue + } + await this.initOneServer(serverName, serverConfig) + } + } + + private async initOneServer(serverName: string, serverConfig: MCPServerConfig): Promise { + try { + getLogger().debug(`Initializing MCP server [${serverName}] with command: ${serverConfig.command}`) + const transport = new StdioClientTransport({ + command: serverConfig.command, + args: serverConfig.args ?? [], + env: process.env as Record, + }) + const client = new Client({ + name: `q-agentic-chat-mcp-client-${serverName}`, + version: '1.0.0', + }) + await client.connect(transport) + this.clients.set(serverName, client) + + const toolsResult = (await client.listTools()) as ListToolsResponse + for (const toolInfo of toolsResult.tools) { + const toolDef: McpToolDefinition = { + serverName, + toolName: toolInfo.name ?? 'unknown', + description: toolInfo.description ?? '', + inputSchema: toolInfo.inputSchema ?? {}, + } + this.mcpTools.push(toolDef) + getLogger().info(`Found MCP tool [${toolDef.toolName}] from server [${serverName}]`) + } + } catch (err) { + // Log the error for this server but allow the initialization of others to continue. + getLogger().error(`Failed to init server [${serverName}]: ${(err as Error).message}`) + } + } + + public getAllMcpTools(): McpToolDefinition[] { + return [...this.mcpTools] + } + + public async callTool(serverName: string, toolName: string, args: any): Promise { + const client = this.clients.get(serverName) + if (!client) { + throw new Error(`MCP server [${serverName}] not connected or not found in clients.`) + } + return await client.callTool({ + name: toolName, + arguments: args, + }) + } + + public findTool(toolName: string): McpToolDefinition | undefined { + return this.mcpTools.find((t) => t.toolName === toolName) + } + + public static async initMcpManager(configPath: string): Promise { + try { + if (!McpManager.#instance) { + const mgr = new McpManager(configPath) + McpManager.#instance = mgr + } + await McpManager.#instance.loadConfig() + await McpManager.#instance.initAllServers() + const discovered = McpManager.#instance.getAllMcpTools() + const builtInToolNames = new Set(['fsRead', 'fsWrite', 'executeBash', 'listDirectory']) + const discoveredNames = new Set(discovered.map((d) => d.toolName)) + + for (const def of discovered) { + const spec = { + toolSpecification: { + name: def.toolName, + description: def.description, + inputSchema: { json: def.inputSchema }, + }, + } + const idx = tools.findIndex((t) => t.toolSpecification!.name === def.toolName) + if (idx >= 0) { + // replace existing entry + tools[idx] = spec + } else { + // append new entry + tools.push(spec) + } + } + + // Prune stale _dynamic_ tools (leave built‑ins intact) + for (let i = tools.length - 1; i >= 0; --i) { + const name = tools[i].toolSpecification!.name + if (!name || builtInToolNames.has(name)) { + continue + } + // if it wasn’t rediscovered in new MCP config, remove it + if (!discoveredNames.has(name)) { + tools.splice(i, 1) + } + } + getLogger().info(`MCP: successfully discovered ${discovered.length} new tools.`) + return McpManager.instance + } catch (err) { + getLogger().error(`Failed to init MCP manager: ${(err as Error).message}`) + return undefined + } + } + + // public async dispose(): Promise { + // this.clients.clear() + // this.mcpTools = [] + // } +} diff --git a/packages/core/src/codewhispererChat/tools/mcp/mcpTool.ts b/packages/core/src/codewhispererChat/tools/mcp/mcpTool.ts new file mode 100644 index 00000000000..112deee5e04 --- /dev/null +++ b/packages/core/src/codewhispererChat/tools/mcp/mcpTool.ts @@ -0,0 +1,55 @@ +/*! + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ +import { Writable } from 'stream' +import { getLogger } from '../../../shared/logger/logger' +import { CommandValidation, InvokeOutput, OutputKind } from '../toolShared' +import { McpManager } from './mcpManager' + +export interface McpToolParams { + serverName: string + toolName: string + input?: any +} + +export class McpTool { + private readonly logger = getLogger('mcp') + private serverName: string + private toolName: string + private input: any + + public constructor(params: McpToolParams) { + this.serverName = params.serverName + this.toolName = params.toolName + this.input = params.input + } + + public async validate(): Promise {} + + public queueDescription(updates: Writable): void { + updates.write(`Invoking remote MCP tool: ${this.toolName} on server ${this.serverName}`) + updates.end() + } + + public requiresAcceptance(): CommandValidation { + return { requiresAcceptance: true } + } + + public async invoke(updates?: Writable): Promise { + try { + const result = await McpManager.instance.callTool(this.serverName, this.toolName, this.input) + const content = typeof result === 'object' ? JSON.stringify(result) : String(result) + + return { + output: { + kind: OutputKind.Text, + content, + }, + } + } catch (error: any) { + this.logger.error(`Failed to invoke MCP tool: ${error.message ?? error}`) + throw new Error(`Failed to invoke MCP tool: ${error.message ?? error}`) + } + } +} diff --git a/packages/core/src/codewhispererChat/tools/mcp/mcpTypes.ts b/packages/core/src/codewhispererChat/tools/mcp/mcpTypes.ts new file mode 100644 index 00000000000..8fbcb6bbdc1 --- /dev/null +++ b/packages/core/src/codewhispererChat/tools/mcp/mcpTypes.ts @@ -0,0 +1,25 @@ +/*! + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +export interface MCPServerConfig { + command: string + args?: string[] + env?: Record + disabled?: boolean + autoApprove?: string[] +} + +export interface MCPConfig { + mcpServers: Record +} + +export interface ListToolsResponse { + tools: { + name?: string + description?: string + inputSchema?: object + [key: string]: any + }[] +} diff --git a/packages/core/src/codewhispererChat/tools/toolUtils.ts b/packages/core/src/codewhispererChat/tools/toolUtils.ts index 1a286b74777..1c492717ff6 100644 --- a/packages/core/src/codewhispererChat/tools/toolUtils.ts +++ b/packages/core/src/codewhispererChat/tools/toolUtils.ts @@ -14,12 +14,14 @@ import { fsReadToolResponseSize, } from './toolShared' import { ListDirectory, ListDirectoryParams } from './listDirectory' +import type { McpTool } from './mcp/mcpTool' export enum ToolType { FsRead = 'fsRead', FsWrite = 'fsWrite', ExecuteBash = 'executeBash', ListDirectory = 'listDirectory', + Mcp = 'mcp', } export type Tool = @@ -27,6 +29,7 @@ export type Tool = | { type: ToolType.FsWrite; tool: FsWrite } | { type: ToolType.ExecuteBash; tool: ExecuteBash } | { type: ToolType.ListDirectory; tool: ListDirectory } + | { type: ToolType.Mcp; tool: McpTool } export class ToolUtils { static displayName(tool: Tool): string { @@ -39,6 +42,8 @@ export class ToolUtils { return 'Execute shell command' case ToolType.ListDirectory: return 'List directory from filesystem' + case ToolType.Mcp: + return 'Execute MCP tool' } } @@ -52,6 +57,8 @@ export class ToolUtils { return tool.tool.requiresAcceptance() case ToolType.ListDirectory: return tool.tool.requiresAcceptance() + case ToolType.Mcp: + return { requiresAcceptance: false } } } @@ -69,6 +76,8 @@ export class ToolUtils { return tool.tool.invoke(updates) case ToolType.ListDirectory: return tool.tool.invoke(updates) + case ToolType.Mcp: + return tool.tool.invoke(updates) } } @@ -153,7 +162,20 @@ export class ToolUtils { type: ToolType.ListDirectory, tool: new ListDirectory(value.input as unknown as ListDirectoryParams), } - default: + default: { + const { McpManager } = require('./mcp/mcpManager') + const { McpTool } = require('./mcp/mcpTool') + const mcpToolDef = McpManager.instance.findTool(value.name as string) + if (mcpToolDef) { + return { + type: ToolType.Mcp, + tool: new McpTool({ + serverName: mcpToolDef.serverName, + toolName: mcpToolDef.toolName, + input: value.input, // pass LLM's JSON input + }), + } + } return { toolUseId: value.toolUseId, content: [ @@ -163,6 +185,7 @@ export class ToolUtils { } as ToolResultContentBlock, ], } + } } } catch (error) { return mapErr(error) diff --git a/packages/core/src/shared/logger/logger.ts b/packages/core/src/shared/logger/logger.ts index 5786799ae99..c842bc68a73 100644 --- a/packages/core/src/shared/logger/logger.ts +++ b/packages/core/src/shared/logger/logger.ts @@ -22,6 +22,7 @@ export type LogTopic = | 'listDirectory' | 'chatStream' | 'chatHistoryDb' + | 'mcp' | 'unknown' class ErrorLog {