From 1d870520f07062ea7140c787f4a7be7fd955421b Mon Sep 17 00:00:00 2001 From: Aaron Elijah Mars Date: Wed, 25 Jun 2025 13:13:49 +0200 Subject: [PATCH] better interaction capabilities --- opendia-mcp/package-lock.json | 384 +--------------------------------- opendia-mcp/package.json | 3 +- opendia-mcp/server.js | 259 ++++++++++++----------- 3 files changed, 143 insertions(+), 503 deletions(-) diff --git a/opendia-mcp/package-lock.json b/opendia-mcp/package-lock.json index a22242a..cba5d08 100644 --- a/opendia-mcp/package-lock.json +++ b/opendia-mcp/package-lock.json @@ -1,18 +1,15 @@ { - "name": "browser-mcp-server", + "name": "opendia-server", "version": "1.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "browser-mcp-server", + "name": "opendia-server", "version": "1.0.0", "dependencies": { - "express": "^4.18.2", - "ws": "^8.16.0" - }, - "devDependencies": { - "nodemon": "^3.0.2" + "express": "^4.x.x", + "ws": "^8.x.x" } }, "node_modules/accepts": { @@ -28,46 +25,12 @@ "node": ">= 0.6" } }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, - "license": "ISC", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", "license": "MIT" }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true, - "license": "MIT" - }, - "node_modules/binary-extensions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", - "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/body-parser": { "version": "1.20.3", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", @@ -92,30 +55,6 @@ "npm": "1.2.8000 || >= 1.4.16" } }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dev": true, - "license": "MIT", - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", @@ -154,38 +93,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "dev": true, - "license": "MIT", - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true, - "license": "MIT" - }, "node_modules/content-disposition": { "version": "0.5.4", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", @@ -370,19 +277,6 @@ "url": "https://opencollective.com/express" } }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dev": true, - "license": "MIT", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/finalhandler": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", @@ -419,21 +313,6 @@ "node": ">= 0.6" } }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", @@ -480,19 +359,6 @@ "node": ">= 0.4" } }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/gopd": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", @@ -505,16 +371,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/has-symbols": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", @@ -567,13 +423,6 @@ "node": ">=0.10.0" } }, - "node_modules/ignore-by-default": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", - "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", - "dev": true, - "license": "ISC" - }, "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", @@ -589,52 +438,6 @@ "node": ">= 0.10" } }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "license": "MIT", - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.12.0" - } - }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", @@ -704,19 +507,6 @@ "node": ">= 0.6" } }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -732,70 +522,6 @@ "node": ">= 0.6" } }, - "node_modules/nodemon": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.10.tgz", - "integrity": "sha512-WDjw3pJ0/0jMFmyNDp3gvY2YizjLmmOUQo6DEBY+JgdvW/yQ9mEeSw6H5ythl5Ny2ytb7f9C2nIbjSxMNzbJXw==", - "dev": true, - "license": "MIT", - "dependencies": { - "chokidar": "^3.5.2", - "debug": "^4", - "ignore-by-default": "^1.0.1", - "minimatch": "^3.1.2", - "pstree.remy": "^1.1.8", - "semver": "^7.5.3", - "simple-update-notifier": "^2.0.0", - "supports-color": "^5.5.0", - "touch": "^3.1.0", - "undefsafe": "^2.0.5" - }, - "bin": { - "nodemon": "bin/nodemon.js" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/nodemon" - } - }, - "node_modules/nodemon/node_modules/debug": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", - "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/nodemon/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==", - "dev": true, - "license": "MIT" - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/object-inspect": { "version": "1.13.4", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", @@ -835,19 +561,6 @@ "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", "license": "MIT" }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -861,13 +574,6 @@ "node": ">= 0.10" } }, - "node_modules/pstree.remy": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", - "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", - "dev": true, - "license": "MIT" - }, "node_modules/qs": { "version": "6.13.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", @@ -907,19 +613,6 @@ "node": ">= 0.8" } }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "license": "MIT", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -946,19 +639,6 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "license": "MIT" }, - "node_modules/semver": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", - "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/send": { "version": "0.19.0", "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", @@ -1091,19 +771,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/simple-update-notifier": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", - "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "semver": "^7.5.3" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/statuses": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", @@ -1113,32 +780,6 @@ "node": ">= 0.8" } }, - "node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, "node_modules/toidentifier": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", @@ -1148,16 +789,6 @@ "node": ">=0.6" } }, - "node_modules/touch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.1.tgz", - "integrity": "sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==", - "dev": true, - "license": "ISC", - "bin": { - "nodetouch": "bin/nodetouch.js" - } - }, "node_modules/type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", @@ -1171,13 +802,6 @@ "node": ">= 0.6" } }, - "node_modules/undefsafe": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", - "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", - "dev": true, - "license": "MIT" - }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", diff --git a/opendia-mcp/package.json b/opendia-mcp/package.json index 2ffe4ee..d220862 100644 --- a/opendia-mcp/package.json +++ b/opendia-mcp/package.json @@ -7,6 +7,7 @@ "start": "node server.js" }, "dependencies": { - "ws": "^8.x.x" + "ws": "^8.x.x", + "express": "^4.x.x" } } \ No newline at end of file diff --git a/opendia-mcp/server.js b/opendia-mcp/server.js index 4c48d61..df14fc3 100644 --- a/opendia-mcp/server.js +++ b/opendia-mcp/server.js @@ -47,8 +47,12 @@ async function handleMCPRequest(request) { break; case "tools/list": - // Return tools even if extension not connected yet - if (availableTools.length > 0) { + // Debug logging + console.error(`Tools/list called. Extension connected: ${chromeExtensionSocket && chromeExtensionSocket.readyState === WebSocket.OPEN}, Available tools: ${availableTools.length}`); + + // Return tools from extension if available, otherwise fallback tools + if (chromeExtensionSocket && chromeExtensionSocket.readyState === WebSocket.OPEN && availableTools.length > 0) { + console.error(`Returning ${availableTools.length} tools from extension`); result = { tools: availableTools.map((tool) => ({ name: tool.name, @@ -57,12 +61,10 @@ async function handleMCPRequest(request) { })), }; } else { - // Return static tools with note that extension is connecting + // Return basic fallback tools + console.error("Extension not connected, returning fallback tools"); result = { - tools: getStaticTools().map(tool => ({ - ...tool, - description: tool.description + " (Extension connecting...)" - })) + tools: getFallbackTools() }; } break; @@ -86,11 +88,15 @@ async function handleMCPRequest(request) { params.name, params.arguments || {} ); + + // Format response based on tool type + const formattedResult = formatToolResult(params.name, toolResult); + result = { content: [ { type: "text", - text: JSON.stringify(toolResult, null, 2), + text: formattedResult, }, ], isError: false @@ -136,12 +142,112 @@ async function handleMCPRequest(request) { } } -// Static tool definitions for when extension isn't connected -function getStaticTools() { +// Remove static tools - they were causing duplicates +// All tools now come from the extension only + +// Format tool results for better MCP response +function formatToolResult(toolName, result) { + const metadata = { + tool: toolName, + execution_time: result.execution_time || 0, + timestamp: new Date().toISOString() + }; + + switch (toolName) { + case 'page_analyze': + if (result.elements && result.elements.length > 0) { + const summary = `Found ${result.elements.length} relevant elements using ${result.method}:\n\n` + + result.elements.map(el => + `• ${el.name} (${el.type}) - Confidence: ${Math.round(el.confidence * 100)}%\n Selector: ${el.selector}\n Element ID: ${el.id}` + ).join('\n\n'); + return `${summary}\n\n${JSON.stringify(metadata, null, 2)}`; + } else { + return `No relevant elements found for intent: "${result.intent_hint || 'unknown'}"\n\n${JSON.stringify(metadata, null, 2)}`; + } + + case 'page_extract_content': + const contentSummary = `Extracted ${result.content_type} content using ${result.method}:\n\n`; + if (result.content) { + const preview = typeof result.content === 'string' + ? result.content.substring(0, 500) + (result.content.length > 500 ? '...' : '') + : JSON.stringify(result.content, null, 2).substring(0, 500); + return `${contentSummary}${preview}\n\n${JSON.stringify(metadata, null, 2)}`; + } else { + return `${contentSummary}No content found\n\n${JSON.stringify(metadata, null, 2)}`; + } + + case 'element_click': + return `✅ Successfully clicked element: ${result.element_name || result.element_id}\n` + + `Click type: ${result.click_type || 'left'}\n\n${JSON.stringify(metadata, null, 2)}`; + + case 'element_fill': + return `✅ Successfully filled element: ${result.element_name || result.element_id}\n` + + `Value: "${result.value}"\n\n${JSON.stringify(metadata, null, 2)}`; + + case 'page_navigate': + return `✅ Successfully navigated to: ${result.url || 'unknown URL'}\n\n${JSON.stringify(metadata, null, 2)}`; + + case 'page_wait_for': + return `✅ Condition met: ${result.condition_type || 'unknown'}\n` + + `Wait time: ${result.wait_time || 0}ms\n\n${JSON.stringify(metadata, null, 2)}`; + + default: + // Legacy tools or unknown tools + return JSON.stringify(result, null, 2); + } +} + +// Fallback tools when extension is not connected +function getFallbackTools() { return [ { - name: "browser_navigate", - description: "Navigate to a URL in the active tab", + name: "page_analyze", + description: "Analyze current page structure (Extension required)", + inputSchema: { + type: "object", + properties: { + intent_hint: { type: "string", description: "What user wants to do" } + }, + required: ["intent_hint"] + } + }, + { + name: "page_extract_content", + description: "Extract structured content (Extension required)", + inputSchema: { + type: "object", + properties: { + content_type: { type: "string", enum: ["article", "search_results", "posts"] } + }, + required: ["content_type"] + } + }, + { + name: "element_click", + description: "Click page elements (Extension required)", + inputSchema: { + type: "object", + properties: { + element_id: { type: "string", description: "Element ID from page_analyze" } + }, + required: ["element_id"] + } + }, + { + name: "element_fill", + description: "Fill input fields (Extension required)", + inputSchema: { + type: "object", + properties: { + element_id: { type: "string", description: "Element ID" }, + value: { type: "string", description: "Text to input" } + }, + required: ["element_id", "value"] + } + }, + { + name: "page_navigate", + description: "Navigate to URLs (Extension required)", inputSchema: { type: "object", properties: { @@ -151,38 +257,30 @@ function getStaticTools() { } }, { - name: "browser_get_tabs", - description: "Get all open browser tabs", - inputSchema: { - type: "object", - properties: {} - } - }, - { - name: "browser_create_tab", - description: "Create a new browser tab", + name: "page_wait_for", + description: "Wait for elements (Extension required)", inputSchema: { type: "object", properties: { - url: { type: "string", description: "URL for new tab" }, - active: { type: "boolean", description: "Make tab active" } - } - } - }, - { - name: "browser_close_tab", - description: "Close a tab by ID", - inputSchema: { - type: "object", - properties: { - tabId: { type: "integer", description: "Tab ID to close" } + condition_type: { type: "string", enum: ["element_visible", "text_present"] } }, - required: ["tabId"] + required: ["condition_type"] + } + }, + { + name: "browser_navigate", + description: "Navigate to URLs - legacy (Extension required)", + inputSchema: { + type: "object", + properties: { + url: { type: "string", description: "URL to navigate to" } + }, + required: ["url"] } }, { name: "browser_execute_script", - description: "Execute JavaScript in active tab", + description: "Execute JavaScript (Extension required - limited by CSP)", inputSchema: { type: "object", properties: { @@ -190,91 +288,6 @@ function getStaticTools() { }, required: ["code"] } - }, - { - name: "browser_get_page_content", - description: "Get page text content", - inputSchema: { - type: "object", - properties: { - selector: { type: "string", description: "CSS selector (optional)" } - } - } - }, - { - name: "browser_take_screenshot", - description: "Take screenshot of active tab", - inputSchema: { - type: "object", - properties: { - format: { type: "string", enum: ["png", "jpeg"], description: "Image format" } - } - } - }, - { - name: "browser_get_bookmarks", - description: "Get browser bookmarks", - inputSchema: { - type: "object", - properties: { - query: { type: "string", description: "Search query" } - } - } - }, - { - name: "browser_add_bookmark", - description: "Add a bookmark", - inputSchema: { - type: "object", - properties: { - title: { type: "string", description: "Bookmark title" }, - url: { type: "string", description: "Bookmark URL" } - }, - required: ["title", "url"] - } - }, - { - name: "browser_get_history", - description: "Search browser history", - inputSchema: { - type: "object", - properties: { - query: { type: "string", description: "Search query" }, - maxResults: { type: "integer", description: "Max results" } - } - } - }, - { - name: "browser_get_cookies", - description: "Get cookies for domain", - inputSchema: { - type: "object", - properties: { - domain: { type: "string", description: "Domain name" } - } - } - }, - { - name: "browser_fill_form", - description: "Fill form on current page", - inputSchema: { - type: "object", - properties: { - formData: { type: "object", description: "Form field data" } - }, - required: ["formData"] - } - }, - { - name: "browser_click_element", - description: "Click element on page", - inputSchema: { - type: "object", - properties: { - selector: { type: "string", description: "CSS selector" } - }, - required: ["selector"] - } } ]; } @@ -344,7 +357,8 @@ wss.on("connection", (ws) => { if (message.type === "register") { availableTools = message.tools; - console.error(`Registered ${availableTools.length} browser tools`); + console.error(`✅ Registered ${availableTools.length} browser tools from extension`); + console.error(`Tools: ${availableTools.map(t => t.name).join(', ')}`); } else if (message.type === "ping") { // Respond to ping with pong ws.send(JSON.stringify({ type: "pong", timestamp: Date.now() })); @@ -360,6 +374,7 @@ wss.on("connection", (ws) => { ws.on("close", () => { console.error("Chrome Extension disconnected"); chromeExtensionSocket = null; + availableTools = []; // Clear tools when extension disconnects clearInterval(pingInterval); });