feat(mcp): make mcp navigated faster (#672)

* Revert "feat(mcp): make mcp navigated faster (#671)"

This reverts commit 81bcc5ec1a6338123ee87dfee76f41bdc97d578d.

* chore: use fkill replace kill-port
This commit is contained in:
2025-04-29 13:51:04 +08:00 committed by GitHub
parent 4718066bb1
commit 2e738f71cd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 132 additions and 56 deletions

View File

@ -33,9 +33,7 @@
"@midscene/core": "workspace:*",
"@midscene/shared": "workspace:*",
"@modelcontextprotocol/sdk": "1.10.1",
"zod": "3.24.3",
"kill-port": "2.0.1",
"@types/kill-port": "2.0.3"
"zod": "3.24.3"
},
"dependencies": {
"puppeteer": "24.2.0"

View File

@ -5,7 +5,6 @@ import {
} from '@midscene/shared/env';
import {
AgentOverChromeBridge,
DefaultBridgeServerPort,
allConfigFromEnv,
overrideAIConfig,
} from '@midscene/web/bridge-mode';
@ -16,7 +15,6 @@ import type {
ImageContent,
TextContent,
} from '@modelcontextprotocol/sdk/types.js';
import killPort from 'kill-port';
import { z } from 'zod';
import { PuppeteerBrowserAgent, ensureBrowser } from './puppeteer';
@ -35,12 +33,10 @@ export class MidsceneManager {
private mcpServer: McpServer; // Add server instance
private agent?: AgentOverChromeBridge | PuppeteerBrowserAgent;
private puppeteerMode = getAIConfigInBoolean(MIDSCENE_MCP_USE_PUPPETEER_MODE);
private initKillPort: Promise<void>;
constructor(server: McpServer) {
this.mcpServer = server;
this.initEnv();
this.registerTools();
this.initKillPort = this.killPort();
}
private initEnv() {
@ -55,14 +51,6 @@ export class MidsceneManager {
overrideAIConfig(envOverrides);
}
private async killPort() {
// Avoid existing bridge-mode servers that haven't exited occupying ports, which would cause new mcp server connections to take a long time
// And the killPort operation may take a long time
try {
await killPort(DefaultBridgeServerPort, 'tcp');
} catch (e) {}
}
// Asynchronously initializes or re-initializes the browser agent.
// Accepts an optional 'reInit' flag (default: false). If true, forces re-creation of the agent.
private async initAgent(openNewTabWithUrl?: string) {
@ -92,7 +80,6 @@ export class MidsceneManager {
private async initAgentByBridgeMode(
openNewTabWithUrl?: string,
): Promise<AgentOverChromeBridge> {
await this.initKillPort;
let agent: AgentOverChromeBridge;
try {
// Create a new agent instance designed for bridge mode.

View File

@ -135,6 +135,7 @@
"inquirer": "10.1.5",
"js-sha256": "0.11.0",
"js-yaml": "4.1.0",
"fkill": "7.2.1",
"openai": "4.81.0",
"socket.io": "^4.8.1",
"socket.io-client": "4.8.1"

View File

@ -20,11 +20,13 @@ const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
// actually, this is a proxy to the page in browser side
export const getBridgePageInCliSide = (
forceCloseServer?: boolean,
timeout?: number | false,
): ChromeExtensionPageCliSide => {
const server = new BridgeServer(DefaultBridgeServerPort);
server.listen({
timeout,
forceCloseServer,
});
const bridgeCaller = (method: string) => {
return async (...args: any[]) => {
@ -107,7 +109,10 @@ export class AgentOverChromeBridge extends PageAgent<ChromeExtensionPageCliSide>
serverListeningTimeout?: number | false;
},
) {
const page = getBridgePageInCliSide(opts?.serverListeningTimeout);
const page = getBridgePageInCliSide(
opts?.forceCloseServer,
opts?.serverListeningTimeout,
);
super(
page,
Object.assign(opts || {}, {

View File

@ -3,5 +3,3 @@ import { AgentOverChromeBridge } from './agent-cli-side';
export { AgentOverChromeBridge };
export { overrideAIConfig, allConfigFromEnv } from '@midscene/shared/env';
export { DefaultBridgeServerPort } from './common';

View File

@ -1,4 +1,5 @@
import { logMsg } from '@midscene/shared/utils';
import fkill from 'fkill';
import { Server, type Socket as ServerSocket } from 'socket.io';
import {
type BridgeCall,
@ -33,9 +34,13 @@ export class BridgeServer {
async listen(
opts: {
timeout?: number | false;
forceCloseServer?: boolean;
} = {},
): Promise<void> {
const { timeout = 30000 } = opts;
const { timeout = 30000, forceCloseServer = false } = opts;
if (forceCloseServer) {
await this.killPort();
}
return new Promise((resolve, reject) => {
if (this.listeningTimerFlag) {
@ -161,6 +166,15 @@ export class BridgeServer {
});
}
async killPort() {
if (!this.listeningTimerFlag) {
// kill the port if it is already occupied
try {
await fkill(this.port);
} catch (e) {}
}
}
private connectionLostErrorMsg = () => {
return `Connection lost, reason: ${this.connectionLostReason}`;
};

145
pnpm-lock.yaml generated
View File

@ -555,18 +555,12 @@ importers:
'@rslib/core':
specifier: ^0.6.2
version: 0.6.3(typescript@5.8.3)
'@types/kill-port':
specifier: 2.0.3
version: 2.0.3
'@types/node':
specifier: ^18.0.0
version: 18.19.62
dotenv:
specifier: 16.4.5
version: 16.4.5
kill-port:
specifier: 2.0.1
version: 2.0.1
typescript:
specifier: ^5.8.2
version: 5.8.3
@ -731,6 +725,9 @@ importers:
express:
specifier: ^4.21.2
version: 4.21.2
fkill:
specifier: 7.2.1
version: 7.2.1
fs-extra:
specifier: 11.2.0
version: 11.2.0
@ -5051,9 +5048,6 @@ packages:
'@types/jsonfile@6.1.4':
resolution: {integrity: sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==}
'@types/kill-port@2.0.3':
resolution: {integrity: sha512-ZHs59e5FBjDLQLOxM48+814LSyNf5sgpi0odtJ0FH6xrIAZXb4yksYG+4mZCbidX3fBOfHytAKAVMgkWvv/Piw==}
'@types/loadable__component@5.13.9':
resolution: {integrity: sha512-QWOtIkwZqHNdQj3nixQ8oyihQiTMKZLk/DNuvNxMSbTfxf47w+kqcbnxlUeBgAxdOtW0Dh48dTAIp83iJKtnrQ==}
@ -5090,6 +5084,9 @@ packages:
'@types/node@18.19.62':
resolution: {integrity: sha512-UOGhw+yZV/icyM0qohQVh3ktpY40Sp7tdTW7HxG3pTd7AiMrlFlAJNUrGK9t5mdW0+ViQcFV74zCSIx9ZJpncA==}
'@types/node@18.19.86':
resolution: {integrity: sha512-fifKayi175wLyKyc5qUfyENhQ1dCNI1UNjp653d8kuYcPQN5JhX3dGuP/XmvPTg/xRBn1VTLpbmi+H/Mr7tLfQ==}
'@types/node@18.19.87':
resolution: {integrity: sha512-OIAAu6ypnVZHmsHCeJ+7CCSub38QNBS9uceMQeg7K5Ur0Jr+wG9wEOEvvMbhp09pxD5czIUy/jND7s7Tb6Nw7A==}
@ -7115,10 +7112,18 @@ packages:
evp_bytestokey@1.0.3:
resolution: {integrity: sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==}
execa@3.4.0:
resolution: {integrity: sha512-r9vdGQk4bmCuK1yKQu1KTwcT2zwfWdbdaXfCtAh+5nU/4fSX+JAb7vZGvI5naJrQlvONrEB20jeruESI69530g==}
engines: {node: ^8.12.0 || >=9.7.0}
execa@4.1.0:
resolution: {integrity: sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==}
engines: {node: '>=10'}
execa@5.1.1:
resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==}
engines: {node: '>=10'}
execa@9.3.0:
resolution: {integrity: sha512-l6JFbqnHEadBoVAVpN5dl2yCyfX28WoBAGaoQcNmLLSedOxTxcn2Qa83s8I/PA5i56vWru2OHOtrwF7Om2vqlg==}
engines: {node: ^18.19.0 || >=20.5.0}
@ -7308,6 +7313,10 @@ packages:
resolution: {integrity: sha512-6jvvn/12IC4quLBL1KNokxC7wWTvYncaVUYSoxWw7YykPLuRrnv4qdHcSOywOI5RpkOVGeQRtWM8/q+G6W6qfQ==}
engines: {node: '>= 8'}
fkill@7.2.1:
resolution: {integrity: sha512-eN9cmsIlRdq06wu3m01OOEgQf5Xh/M7REm0jfZ4eL3V3XisjXzfRq3iyqtKS+FhO6wB36FvWRiRGdeSx5KpLAQ==}
engines: {node: '>=10'}
flat@5.0.2:
resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==}
hasBin: true
@ -7498,9 +7507,6 @@ packages:
resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==}
engines: {node: '>= 0.4'}
get-them-args@1.3.2:
resolution: {integrity: sha512-LRn8Jlk+DwZE4GTlDbT3Hikd1wSHgLMme/+7ddlqKd7ldwR6LjJgTVWzBnR01wnYGe4KgrXjg287RaI22UHmAw==}
get-tsconfig@4.8.1:
resolution: {integrity: sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==}
@ -7882,6 +7888,10 @@ packages:
resolution: {integrity: sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==}
engines: {node: '>=8.12.0'}
human-signals@2.1.0:
resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==}
engines: {node: '>=10.17.0'}
human-signals@7.0.0:
resolution: {integrity: sha512-74kytxOUSvNbjrT9KisAbaTZ/eJwD/LrbM/kh5j0IhPuJzwuA19dWvniFGwBzN9rVjg+O/e+F310PjObDXS+9Q==}
engines: {node: '>=18.18.0'}
@ -8490,10 +8500,6 @@ packages:
keyv@4.5.4:
resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==}
kill-port@2.0.1:
resolution: {integrity: sha512-e0SVOV5jFo0mx8r7bS29maVWp17qGqLBZ5ricNSajON6//kmb7qqqNnml4twNE8Dtj97UQD+gNFOaipS/q1zzQ==}
hasBin: true
kind-of@2.0.1:
resolution: {integrity: sha512-0u8i1NZ/mg0b+W3MGGw5I7+6Eib2nx72S/QvXa0hYjEkjTknYmEYQJwGu3mLC0BrhtJjtQafTkyRUQ75Kx0LVg==}
engines: {node: '>=0.10.0'}
@ -9438,6 +9444,10 @@ packages:
resolution: {integrity: sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==}
engines: {node: '>=4'}
p-finally@2.0.1:
resolution: {integrity: sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==}
engines: {node: '>=8'}
p-limit@2.3.0:
resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==}
engines: {node: '>=6'}
@ -9704,6 +9714,10 @@ packages:
resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==}
engines: {node: '>=12'}
pid-port@0.1.1:
resolution: {integrity: sha512-boqPJtSgZC6KOgXKNPC+/XR3xwVtpOtaLa7JLcdf8jfVe0ZM2TwllBXxxLUO8GQbOLJ4/hEtf2+L1QCKbaoHUg==}
engines: {node: '>=10'}
pify@2.3.0:
resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==}
engines: {node: '>=0.10.0'}
@ -10079,6 +10093,10 @@ packages:
resolution: {integrity: sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==}
engines: {node: '>=6'}
process-exists@4.1.0:
resolution: {integrity: sha512-BBJoiorUKoP2AuM5q/yKwIfT1YWRHsaxjW+Ayu9erLhqKOfnXzzVVML0XTYoQZuI1YvcWKmc1dh06DEy4+KzfA==}
engines: {node: '>=10'}
process-nextick-args@2.0.1:
resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==}
@ -10116,6 +10134,14 @@ packages:
prr@1.0.1:
resolution: {integrity: sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==}
ps-list@6.3.0:
resolution: {integrity: sha512-qau0czUSB0fzSlBOQt0bo+I2v6R+xiQdj78e1BR/Qjfl5OHWJ/urXi8+ilw1eHe+5hSeDI1wrwVTgDp2wst4oA==}
engines: {node: '>=8'}
ps-list@7.2.0:
resolution: {integrity: sha512-v4Bl6I3f2kJfr5o80ShABNHAokIgY+wFDTQfE+X3zWYgSGQOCBeYptLZUpoOALBqO5EawmDN/tjTldJesd0ujQ==}
engines: {node: '>=10'}
pseudomap@1.0.2:
resolution: {integrity: sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==}
@ -11343,9 +11369,6 @@ packages:
resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
engines: {node: '>=8'}
shell-exec@1.0.2:
resolution: {integrity: sha512-jyVd+kU2X+mWKMmGhx4fpWbPsjvD53k9ivqetutVW/BQ+WIZoDoP4d8vUMGezV6saZsiNoW2f9GIhg9Dondohg==}
shell-quote@1.8.2:
resolution: {integrity: sha512-AzqKpGKjrj7EM6rKVQEPpB288oCfnrEIuyoT9cyF4nmGa7V8Zk6f7RRqYisX8X9m+Q7bd632aZW4ky7EhbQztA==}
engines: {node: '>= 0.4'}
@ -11769,6 +11792,10 @@ packages:
tar-stream@3.1.7:
resolution: {integrity: sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==}
taskkill@3.1.0:
resolution: {integrity: sha512-5KcOFzPvd1nGFVrmB7H4+QAWVjYOf//+QTbOj0GpXbqtqbKGWVczG+rq6VhXAtdtlKLTs16NAmHRyF5vbggQ2w==}
engines: {node: '>=8'}
teen_process@2.3.1:
resolution: {integrity: sha512-duT4gPj7HxEYy+AR4bJ9MNwf8GMLpJd+sNRAK2PTx53FpCcaiXVft3ePZh3hO6PY8NFWZMxTC3ZAtxyztScEsw==}
engines: {node: ^16.13.0 || >=18.0.0, npm: '>=8'}
@ -18943,7 +18970,7 @@ snapshots:
'@types/connect@3.4.38':
dependencies:
'@types/node': 18.19.87
'@types/node': 18.19.86
'@types/conventional-commits-parser@5.0.1':
dependencies:
@ -19058,11 +19085,6 @@ snapshots:
dependencies:
'@types/node': 18.19.62
'@types/kill-port@2.0.3':
dependencies:
'@types/node': 18.19.87
shell-exec: 1.0.2
'@types/loadable__component@5.13.9':
dependencies:
'@types/react': 18.3.18
@ -19083,7 +19105,7 @@ snapshots:
'@types/mute-stream@0.0.4':
dependencies:
'@types/node': 18.19.87
'@types/node': 18.19.62
'@types/node-fetch@2.6.11':
dependencies:
@ -19098,6 +19120,10 @@ snapshots:
dependencies:
undici-types: 5.26.5
'@types/node@18.19.86':
dependencies:
undici-types: 5.26.5
'@types/node@18.19.87':
dependencies:
undici-types: 5.26.5
@ -19147,7 +19173,7 @@ snapshots:
'@types/send@0.17.4':
dependencies:
'@types/mime': 1.3.5
'@types/node': 18.19.87
'@types/node': 18.19.62
'@types/serve-static@1.15.7':
dependencies:
@ -21678,6 +21704,19 @@ snapshots:
md5.js: 1.3.5
safe-buffer: 5.2.1
execa@3.4.0:
dependencies:
cross-spawn: 7.0.6
get-stream: 5.2.0
human-signals: 1.1.1
is-stream: 2.0.1
merge-stream: 2.0.0
npm-run-path: 4.0.1
onetime: 5.1.2
p-finally: 2.0.1
signal-exit: 3.0.7
strip-final-newline: 2.0.0
execa@4.1.0:
dependencies:
cross-spawn: 7.0.6
@ -21690,6 +21729,18 @@ snapshots:
signal-exit: 3.0.7
strip-final-newline: 2.0.0
execa@5.1.1:
dependencies:
cross-spawn: 7.0.6
get-stream: 6.0.1
human-signals: 2.1.0
is-stream: 2.0.1
merge-stream: 2.0.0
npm-run-path: 4.0.1
onetime: 5.1.2
signal-exit: 3.0.7
strip-final-newline: 2.0.0
execa@9.3.0:
dependencies:
'@sindresorhus/merge-streams': 4.0.0
@ -21978,6 +22029,16 @@ snapshots:
micromatch: 4.0.8
resolve-dir: 1.0.1
fkill@7.2.1:
dependencies:
aggregate-error: 3.1.0
arrify: 2.0.1
execa: 5.1.1
pid-port: 0.1.1
process-exists: 4.1.0
ps-list: 7.2.0
taskkill: 3.1.0
flat@5.0.2: {}
flexsearch@0.6.32: {}
@ -22190,8 +22251,6 @@ snapshots:
es-errors: 1.3.0
get-intrinsic: 1.3.0
get-them-args@1.3.2: {}
get-tsconfig@4.8.1:
dependencies:
resolve-pkg-maps: 1.0.0
@ -22772,6 +22831,8 @@ snapshots:
human-signals@1.1.1: {}
human-signals@2.1.0: {}
human-signals@7.0.0: {}
humanize-ms@1.2.1:
@ -23403,11 +23464,6 @@ snapshots:
dependencies:
json-buffer: 3.0.1
kill-port@2.0.1:
dependencies:
get-them-args: 1.3.2
shell-exec: 1.0.2
kind-of@2.0.1:
dependencies:
is-buffer: 1.1.6
@ -24624,6 +24680,8 @@ snapshots:
p-finally@1.0.0: {}
p-finally@2.0.1: {}
p-limit@2.3.0:
dependencies:
p-try: 2.2.0
@ -24889,6 +24947,10 @@ snapshots:
picomatch@4.0.2: {}
pid-port@0.1.1:
dependencies:
execa: 5.1.1
pify@2.3.0: {}
pify@4.0.1: {}
@ -25236,6 +25298,10 @@ snapshots:
prismjs@1.30.0: {}
process-exists@4.1.0:
dependencies:
ps-list: 6.3.0
process-nextick-args@2.0.1: {}
process@0.11.10: {}
@ -25279,6 +25345,10 @@ snapshots:
prr@1.0.1:
optional: true
ps-list@6.3.0: {}
ps-list@7.2.0: {}
pseudomap@1.0.2: {}
psl@1.9.0: {}
@ -26785,8 +26855,6 @@ snapshots:
shebang-regex@3.0.0: {}
shell-exec@1.0.2: {}
shell-quote@1.8.2: {}
side-channel-list@1.0.0:
@ -27301,6 +27369,11 @@ snapshots:
fast-fifo: 1.3.2
streamx: 2.20.1
taskkill@3.1.0:
dependencies:
arrify: 2.0.1
execa: 3.4.0
teen_process@2.3.1:
dependencies:
bluebird: 3.7.2