autorunner-mcp 0.1.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.
Files changed (3) hide show
  1. package/README.md +24 -0
  2. package/index.js +147 -0
  3. package/package.json +21 -0
package/README.md ADDED
@@ -0,0 +1,24 @@
1
+ # autorunner-mcp
2
+
3
+ MCP server for [autoRunner](https://gitee.com/miaoooooooo/auto-runner) — control a browser via AI agents.
4
+
5
+ ## Usage
6
+
7
+ ```json
8
+ {
9
+ "mcpServers": {
10
+ "autorunner": {
11
+ "command": "npx",
12
+ "args": ["-y", "autorunner-mcp"]
13
+ }
14
+ }
15
+ }
16
+ ```
17
+
18
+ The binary is downloaded automatically on first run from Gitee Releases, cached at `~/.autorunner/bin/`.
19
+
20
+ ## Supported Platforms
21
+
22
+ - Windows x64
23
+ - macOS arm64 (Apple Silicon) & x64 (Intel)
24
+ - Linux x64
package/index.js ADDED
@@ -0,0 +1,147 @@
1
+ #!/usr/bin/env node
2
+
3
+ // autoRunner MCP — download the native binary and run it as an MCP server.
4
+ //
5
+ // No dependencies. Uses only Node.js built-ins (https, fs, path, child_process).
6
+ // Downloads the correct binary for the current platform from Gitee Releases.
7
+ // Caches the binary at ~/.autorunner/bin/ for reuse.
8
+
9
+ const https = require("https");
10
+ const fs = require("fs");
11
+ const path = require("path");
12
+ const { spawn } = require("child_process");
13
+
14
+ const GITEE_OWNER = "miaoooooooo";
15
+ const GITEE_REPO = "auto-runner";
16
+
17
+ const CACHE_DIR = path.join(
18
+ process.env.HOME || process.env.USERPROFILE || "~",
19
+ ".autorunner",
20
+ "bin"
21
+ );
22
+
23
+ // Map Node.js process.platform+arch → Gitee Release asset filename
24
+ function assetName() {
25
+ const plat = process.platform;
26
+ const arch = process.arch;
27
+ const ext = plat === "win32" ? ".exe" : "";
28
+
29
+ const map = {
30
+ "win32-x64": `autorunner-x86_64-pc-windows-msvc${ext}`,
31
+ "darwin-arm64": "autorunner-aarch64-apple-darwin",
32
+ "darwin-x64": "autorunner-x86_64-apple-darwin",
33
+ "linux-x64": "autorunner-x86_64-unknown-linux-gnu",
34
+ };
35
+ const key = `${plat}-${arch}`;
36
+ if (!map[key]) {
37
+ console.error(`Unsupported platform: ${plat} ${arch}`);
38
+ process.exit(1);
39
+ }
40
+ return map[key];
41
+ }
42
+
43
+ function binaryPath() {
44
+ return path.join(CACHE_DIR, assetName());
45
+ }
46
+
47
+ function httpsGet(url) {
48
+ return new Promise((resolve, reject) => {
49
+ https.get(url, { headers: { "User-Agent": "autorunner-mcp" } }, (res) => {
50
+ if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
51
+ httpsGet(res.headers.location).then(resolve).catch(reject);
52
+ return;
53
+ }
54
+ if (res.statusCode !== 200) {
55
+ reject(new Error(`HTTP ${res.statusCode} from ${url}`));
56
+ return;
57
+ }
58
+ resolve(res);
59
+ }).on("error", reject);
60
+ });
61
+ }
62
+
63
+ async function getLatestTag() {
64
+ // Gitee latest API requires auth; use releases list instead (public repos work)
65
+ const url = `https://gitee.com/api/v5/repos/${GITEE_OWNER}/${GITEE_REPO}/releases?per_page=1&page=1`;
66
+ const res = await httpsGet(url);
67
+ let body = "";
68
+ for await (const chunk of res) body += chunk;
69
+ const data = JSON.parse(body);
70
+ if (Array.isArray(data) && data.length > 0 && data[0].tag_name) return data[0].tag_name;
71
+ throw new Error(data.message || "no releases found");
72
+ }
73
+
74
+ async function listReleaseAssets(tag) {
75
+ const url = `https://api.gitee.com/repos/${GITEE_OWNER}/${GITEE_REPO}/releases/tags/${tag}`;
76
+ const res = await httpsGet(url);
77
+ let body = "";
78
+ for await (const chunk of res) body += chunk;
79
+ const data = JSON.parse(body);
80
+ return (data.assets || []).map((a) => a.name);
81
+ }
82
+
83
+ async function downloadBinary(tag, asset) {
84
+ const url = `https://gitee.com/${GITEE_OWNER}/${GITEE_REPO}/releases/download/${tag}/${asset}`;
85
+ console.error(`[autorunner-mcp] downloading ${asset}...`);
86
+
87
+ // Gitee returns 302 → follow it to the CDN
88
+ const res = await new Promise((resolve, reject) => {
89
+ const follow = (uri) => {
90
+ https.get(uri, { headers: { "User-Agent": "autorunner-mcp" } }, (r) => {
91
+ if (r.statusCode >= 300 && r.statusCode < 400 && r.headers.location) {
92
+ console.error(`[autorunner-mcp] -> ${r.headers.location}`);
93
+ follow(r.headers.location);
94
+ } else {
95
+ resolve(r);
96
+ }
97
+ }).on("error", reject);
98
+ };
99
+ follow(url);
100
+ });
101
+
102
+ if (res.statusCode !== 200) {
103
+ throw new Error(`HTTP ${res.statusCode} downloading ${asset}`);
104
+ }
105
+
106
+ fs.mkdirSync(CACHE_DIR, { recursive: true });
107
+ const tmp = binaryPath() + ".tmp";
108
+ const file = fs.createWriteStream(tmp);
109
+ res.pipe(file);
110
+ await new Promise((resolve, reject) => {
111
+ file.on("finish", resolve);
112
+ file.on("error", reject);
113
+ });
114
+ fs.chmodSync(tmp, 0o755);
115
+ fs.renameSync(tmp, binaryPath());
116
+ console.error(`[autorunner-mcp] saved to ${binaryPath()}`);
117
+ }
118
+
119
+ async function ensureBinary() {
120
+ const bin = binaryPath();
121
+ if (fs.existsSync(bin)) return;
122
+
123
+ console.error(`[autorunner-mcp] binary not found, downloading from Gitee...`);
124
+ const tag = await getLatestTag();
125
+ await downloadBinary(tag, assetName());
126
+ }
127
+
128
+ async function main() {
129
+ await ensureBinary();
130
+ const bin = binaryPath();
131
+
132
+ const child = spawn(bin, ["mcp"], {
133
+ stdio: ["inherit", "inherit", "inherit"],
134
+ env: { ...process.env },
135
+ });
136
+
137
+ child.on("exit", (code) => process.exit(code !== null ? code : 1));
138
+ child.on("error", (err) => {
139
+ console.error(`[autorunner-mcp] failed to spawn: ${err.message}`);
140
+ process.exit(1);
141
+ });
142
+ }
143
+
144
+ main().catch((err) => {
145
+ console.error(`[autorunner-mcp] error: ${err.message}`);
146
+ process.exit(1);
147
+ });
package/package.json ADDED
@@ -0,0 +1,21 @@
1
+ {
2
+ "name": "autorunner-mcp",
3
+ "version": "0.1.0",
4
+ "description": "MCP server for autoRunner browser automation — control a browser via AI agents",
5
+ "bin": {
6
+ "autorunner-mcp": "index.js"
7
+ },
8
+ "files": [
9
+ "index.js",
10
+ "README.md"
11
+ ],
12
+ "engines": {
13
+ "node": ">=18"
14
+ },
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "https://gitee.com/miaoooooooo/auto-runner"
18
+ },
19
+ "keywords": ["mcp", "browser", "automation", "autorunner"],
20
+ "license": "MIT"
21
+ }