ohos-playwright-mcp 0.2.4 → 0.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -2
- package/server.mjs +18 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ohos-playwright-mcp",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.6",
|
|
4
4
|
"description": "MCP server for HarmonyOS / OpenHarmony ArkWeb — playwright-core over CDP. 61 tools: navigation, input, network, cookies, storage, snapshot, tracing. The ohos counterpart of @playwright/mcp.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"node": ">=24"
|
|
39
39
|
},
|
|
40
40
|
"peerDependencies": {
|
|
41
|
-
"ohos-playwright": ">=0.2.
|
|
41
|
+
"ohos-playwright": ">=0.2.5",
|
|
42
42
|
"playwright-core": ">=1.59.0"
|
|
43
43
|
},
|
|
44
44
|
"publishConfig": {
|
package/server.mjs
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
import { createRequire } from 'node:module'
|
|
9
9
|
import { existsSync, readFileSync, mkdirSync, writeFileSync } from 'node:fs'
|
|
10
|
-
import { dirname, join } from 'node:path'
|
|
10
|
+
import { dirname, join, resolve as resolvePath } from 'node:path'
|
|
11
11
|
import { tmpdir } from 'node:os'
|
|
12
12
|
|
|
13
13
|
const require = createRequire(import.meta.url)
|
|
@@ -30,6 +30,19 @@ const SETUP_PATH = resolveOrThrow('ohos-playwright/setup', 'ARKWEB_OHOS_PW
|
|
|
30
30
|
const PW_CORE_PATH = resolveOrThrow('playwright-core', 'ARKWEB_PW_CORE')
|
|
31
31
|
const INFO_PATH = process.env.OHOS_PW_INFO_PATH ?? `${tmpdir()}/ohos-playwright-cdp.json`
|
|
32
32
|
|
|
33
|
+
function safeOutputPath(inputPath) {
|
|
34
|
+
// 拒绝包含 .. 的路径,防止路径穿越
|
|
35
|
+
if (inputPath.includes('..')) {
|
|
36
|
+
throw new Error(`path traversal rejected: "${inputPath}" contains ".."`)
|
|
37
|
+
}
|
|
38
|
+
const resolved = resolvePath(inputPath)
|
|
39
|
+
const cwd = process.cwd()
|
|
40
|
+
if (!resolved.startsWith(tmpdir()) && !resolved.startsWith(cwd)) {
|
|
41
|
+
throw new Error(`output path must be within current directory or temp directory: ${resolved}`)
|
|
42
|
+
}
|
|
43
|
+
return resolved
|
|
44
|
+
}
|
|
45
|
+
|
|
33
46
|
let cdpEndpoint = null
|
|
34
47
|
|
|
35
48
|
await import(REGISTER_PATH)
|
|
@@ -47,7 +60,6 @@ let bootstrapPromise = null
|
|
|
47
60
|
const consoleBuffer = [] // { pageUrl, type, text, ts }
|
|
48
61
|
const networkRequests = [] // { id, url, method, status, requestHeaders, responseHeaders, postData, fromCache, durationMs }
|
|
49
62
|
const networkById = new Map()
|
|
50
|
-
const dialogQueue = [] // pending dialog handlers; auto-dismiss with default
|
|
51
63
|
let dialogPolicy = { action: 'dismiss', promptText: '' }
|
|
52
64
|
const routeHandlers = new Map() // pattern -> {handler, status: 'active', hits: 0}
|
|
53
65
|
|
|
@@ -269,7 +281,7 @@ tool('screenshot', 'Take a PNG screenshot. Default saves to a tmp path (ArkWeb r
|
|
|
269
281
|
if (inline) {
|
|
270
282
|
return { content: [{ type: 'image', data: buf.toString('base64'), mimeType: 'image/png' }] }
|
|
271
283
|
}
|
|
272
|
-
const outPath = path
|
|
284
|
+
const outPath = path ? safeOutputPath(path) : join(tmpdir(), `ohos-screenshot-${Date.now()}.png`)
|
|
273
285
|
mkdirSync(dirname(outPath), { recursive: true })
|
|
274
286
|
writeFileSync(outPath, buf)
|
|
275
287
|
return `saved ${buf.length} bytes to ${outPath}`
|
|
@@ -676,6 +688,7 @@ tool('pdf_save', 'Save the current page as PDF (headless-only in Chrome — may
|
|
|
676
688
|
sObj({ path: sStr() }, ['path']),
|
|
677
689
|
async ({ path }) => {
|
|
678
690
|
const page = await getPage()
|
|
691
|
+
path = safeOutputPath(path)
|
|
679
692
|
mkdirSync(dirname(path), { recursive: true })
|
|
680
693
|
await page.pdf({ path })
|
|
681
694
|
return `saved PDF to ${path}`
|
|
@@ -693,6 +706,7 @@ tool('stop_tracing', 'Stop tracing and save the .zip to `path`.',
|
|
|
693
706
|
sObj({ path: sStr() }, ['path']),
|
|
694
707
|
async ({ path }) => {
|
|
695
708
|
await getPage()
|
|
709
|
+
path = safeOutputPath(path)
|
|
696
710
|
mkdirSync(dirname(path), { recursive: true })
|
|
697
711
|
await context.tracing.stop({ path })
|
|
698
712
|
return `trace saved to ${path}`
|
|
@@ -708,7 +722,7 @@ async function handle(msg) {
|
|
|
708
722
|
try {
|
|
709
723
|
switch (msg.method) {
|
|
710
724
|
case 'initialize':
|
|
711
|
-
return { protocolVersion: '2024-11-05', capabilities: { tools: {} }, serverInfo: { name: 'ohos-playwright-mcp', version: '0.2.
|
|
725
|
+
return { protocolVersion: '2024-11-05', capabilities: { tools: {} }, serverInfo: { name: 'ohos-playwright-mcp', version: '0.2.5' } }
|
|
712
726
|
case 'notifications/initialized':
|
|
713
727
|
return null
|
|
714
728
|
case 'tools/list':
|