@magentaesolutions/device-screenshot-mcp 1.0.0

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.
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,59 @@
1
+ #!/usr/bin/env node
2
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
3
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
4
+ import { execFile } from 'node:child_process';
5
+ import { readFile, unlink } from 'node:fs/promises';
6
+ import { tmpdir } from 'node:os';
7
+ import { join } from 'node:path';
8
+ const PMD3 = process.env.PYMOBILEDEVICE3_PATH || 'pymobiledevice3';
9
+ const server = new McpServer({
10
+ name: 'device-screenshot',
11
+ version: '1.0.0',
12
+ });
13
+ function exec(cmd, args, timeout = 15000) {
14
+ return new Promise((resolve, reject) => {
15
+ execFile(cmd, args, { timeout }, (err, stdout, stderr) => {
16
+ if (err)
17
+ reject(new Error(stderr || err.message));
18
+ else
19
+ resolve({ stdout, stderr });
20
+ });
21
+ });
22
+ }
23
+ server.tool('take_screenshot', 'Take a screenshot from a connected physical iOS device via USB. Returns the image as a PNG. Requires pymobiledevice3 tunneld to be running (sudo pymobiledevice3 remote tunneld).', {}, async () => {
24
+ const outPath = join(tmpdir(), `device-screenshot-${Date.now()}.png`);
25
+ try {
26
+ await exec(PMD3, ['developer', 'dvt', 'screenshot', outPath, '--tunnel', '']);
27
+ const data = await readFile(outPath);
28
+ await unlink(outPath).catch(() => { });
29
+ return {
30
+ content: [
31
+ {
32
+ type: 'image',
33
+ data: data.toString('base64'),
34
+ mimeType: 'image/png',
35
+ },
36
+ ],
37
+ };
38
+ }
39
+ catch (e) {
40
+ const msg = e instanceof Error ? e.message : String(e);
41
+ if (msg.includes('tunneld') || msg.includes('tunnel')) {
42
+ return {
43
+ content: [
44
+ {
45
+ type: 'text',
46
+ text: 'Tunneld is not running. Start it with:\n sudo pymobiledevice3 remote tunneld',
47
+ },
48
+ ],
49
+ isError: true,
50
+ };
51
+ }
52
+ return {
53
+ content: [{ type: 'text', text: `Screenshot failed: ${msg}` }],
54
+ isError: true,
55
+ };
56
+ }
57
+ });
58
+ const transport = new StdioServerTransport();
59
+ await server.connect(transport);
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "@magentaesolutions/device-screenshot-mcp",
3
+ "version": "1.0.0",
4
+ "description": "MCP server for taking screenshots from physical iOS devices via USB",
5
+ "type": "module",
6
+ "bin": {
7
+ "device-screenshot-mcp": "dist/index.js"
8
+ },
9
+ "files": [
10
+ "dist"
11
+ ],
12
+ "scripts": {
13
+ "build": "tsc",
14
+ "prepublishOnly": "npm run build"
15
+ },
16
+ "keywords": [
17
+ "mcp",
18
+ "ios",
19
+ "screenshot",
20
+ "claude",
21
+ "pymobiledevice3"
22
+ ],
23
+ "license": "MIT",
24
+ "engines": {
25
+ "node": ">=18"
26
+ },
27
+ "dependencies": {
28
+ "@modelcontextprotocol/sdk": "^1.12.1",
29
+ "zod": "^3.24.0"
30
+ },
31
+ "devDependencies": {
32
+ "@types/node": "^25.5.0",
33
+ "typescript": "^5.9.3"
34
+ }
35
+ }