@anythink-cloud/mcp 0.2.6 → 0.2.12
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/bin/anythink-mcp.js +13 -4
- package/install.js +54 -52
- package/package.json +1 -1
package/bin/anythink-mcp.js
CHANGED
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
// Thin launcher: exec the native
|
|
2
|
+
// Thin launcher: exec the native MCP server that postinstall placed next to this
|
|
3
3
|
// shim, forwarding argv and stdio (stdio is how MCP clients talk to the server).
|
|
4
|
+
//
|
|
5
|
+
// We prepend the bin dir to PATH so the server can find the bundled `anythink`
|
|
6
|
+
// CLI — in stdio mode the MCP's `cli` tool shells out to `anythink`.
|
|
4
7
|
const { spawnSync } = require("child_process");
|
|
5
8
|
const path = require("path");
|
|
6
9
|
const fs = require("fs");
|
|
7
10
|
|
|
8
11
|
const isWin = process.platform === "win32";
|
|
9
|
-
const
|
|
12
|
+
const binDir = __dirname;
|
|
13
|
+
const server = path.join(binDir, isWin ? "anythink-mcp.exe" : "anythink-mcp");
|
|
10
14
|
|
|
11
|
-
if (!fs.existsSync(
|
|
15
|
+
if (!fs.existsSync(server)) {
|
|
12
16
|
console.error(
|
|
13
17
|
"[anythink-mcp] native binary missing — postinstall may have failed. " +
|
|
14
18
|
"Reinstall, or grab a binary from " +
|
|
@@ -17,7 +21,12 @@ if (!fs.existsSync(bin)) {
|
|
|
17
21
|
process.exit(1);
|
|
18
22
|
}
|
|
19
23
|
|
|
20
|
-
const
|
|
24
|
+
const env = {
|
|
25
|
+
...process.env,
|
|
26
|
+
PATH: binDir + path.delimiter + (process.env.PATH || ""),
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const result = spawnSync(server, process.argv.slice(2), { stdio: "inherit", env });
|
|
21
30
|
if (result.error) {
|
|
22
31
|
console.error(`[anythink-mcp] failed to launch: ${result.error.message}`);
|
|
23
32
|
process.exit(1);
|
package/install.js
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
|
-
// Postinstall: download the matching
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
1
|
+
// Postinstall: download the matching native binaries for this platform from the
|
|
2
|
+
// GitHub release that corresponds to this package version, verify checksums, and
|
|
3
|
+
// place them next to the bin shim. No .NET required — the binaries are
|
|
4
|
+
// self-contained.
|
|
5
|
+
//
|
|
6
|
+
// We download BOTH `anythink-mcp` (the server) and `anythink` (the CLI): in
|
|
7
|
+
// stdio mode the MCP's generic `cli` tool shells out to `anythink` on PATH, so
|
|
8
|
+
// shipping only the server would leave that tool broken.
|
|
5
9
|
const fs = require("fs");
|
|
6
10
|
const path = require("path");
|
|
7
11
|
const https = require("https");
|
|
@@ -9,24 +13,21 @@ const crypto = require("crypto");
|
|
|
9
13
|
const { version } = require("./package.json");
|
|
10
14
|
|
|
11
15
|
const REPO = "anythink-cloud/anythink-cli";
|
|
16
|
+
const RELEASES = `https://github.com/${REPO}/releases`;
|
|
12
17
|
|
|
13
|
-
// node platform-arch -> release asset
|
|
14
|
-
const
|
|
15
|
-
"darwin-arm64": "
|
|
16
|
-
"darwin-x64": "
|
|
17
|
-
"linux-x64": "
|
|
18
|
-
"linux-arm64": "
|
|
19
|
-
"win32-x64": "
|
|
20
|
-
"win32-arm64": "
|
|
18
|
+
// node platform-arch -> release asset suffix
|
|
19
|
+
const SUFFIX = {
|
|
20
|
+
"darwin-arm64": "osx-arm64",
|
|
21
|
+
"darwin-x64": "osx-x64",
|
|
22
|
+
"linux-x64": "linux-x64",
|
|
23
|
+
"linux-arm64": "linux-arm64",
|
|
24
|
+
"win32-x64": "win-x64.exe",
|
|
25
|
+
"win32-arm64": "win-arm64.exe",
|
|
21
26
|
};
|
|
22
27
|
|
|
23
|
-
const RELEASES = `https://github.com/${REPO}/releases`;
|
|
24
|
-
|
|
25
28
|
function fail(message) {
|
|
26
29
|
console.error(`[anythink-mcp] ${message}`);
|
|
27
|
-
console.error(
|
|
28
|
-
`[anythink-mcp] Install a binary manually instead: ${RELEASES}/latest`
|
|
29
|
-
);
|
|
30
|
+
console.error(`[anythink-mcp] Install binaries manually instead: ${RELEASES}/latest`);
|
|
30
31
|
process.exit(1);
|
|
31
32
|
}
|
|
32
33
|
|
|
@@ -35,11 +36,7 @@ function fetch(url, redirects = 0) {
|
|
|
35
36
|
if (redirects > 10) return reject(new Error("too many redirects"));
|
|
36
37
|
https
|
|
37
38
|
.get(url, { headers: { "User-Agent": "anythink-mcp-installer" } }, (res) => {
|
|
38
|
-
if (
|
|
39
|
-
res.statusCode >= 300 &&
|
|
40
|
-
res.statusCode < 400 &&
|
|
41
|
-
res.headers.location
|
|
42
|
-
) {
|
|
39
|
+
if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
|
|
43
40
|
res.resume();
|
|
44
41
|
return resolve(fetch(res.headers.location, redirects + 1));
|
|
45
42
|
}
|
|
@@ -55,48 +52,53 @@ function fetch(url, redirects = 0) {
|
|
|
55
52
|
});
|
|
56
53
|
}
|
|
57
54
|
|
|
55
|
+
function verify(buf, asset, checksums) {
|
|
56
|
+
if (!checksums) return;
|
|
57
|
+
const sha = crypto.createHash("sha256").update(buf).digest("hex");
|
|
58
|
+
const match = checksums
|
|
59
|
+
.toString("utf8")
|
|
60
|
+
.split("\n")
|
|
61
|
+
.map((l) => l.trim().split(/\s+/))
|
|
62
|
+
.find((parts) => parts[1] === asset);
|
|
63
|
+
if (match && match[0].toLowerCase() !== sha.toLowerCase()) {
|
|
64
|
+
fail(`checksum mismatch for ${asset} (expected ${match[0]}, got ${sha})`);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
58
68
|
async function main() {
|
|
59
69
|
const key = `${process.platform}-${process.arch}`;
|
|
60
|
-
const
|
|
61
|
-
if (!
|
|
62
|
-
fail(
|
|
63
|
-
`unsupported platform ${key}. Supported: ${Object.keys(ASSETS).join(", ")}.`
|
|
64
|
-
);
|
|
70
|
+
const suffix = SUFFIX[key];
|
|
71
|
+
if (!suffix) {
|
|
72
|
+
fail(`unsupported platform ${key}. Supported: ${Object.keys(SUFFIX).join(", ")}.`);
|
|
65
73
|
}
|
|
66
74
|
|
|
67
75
|
const base = `${RELEASES}/download/v${version}`;
|
|
68
|
-
const binDir = path.join(__dirname, "bin");
|
|
69
76
|
const isWin = process.platform === "win32";
|
|
70
|
-
const
|
|
71
|
-
|
|
77
|
+
const ext = isWin ? ".exe" : "";
|
|
78
|
+
const binDir = path.join(__dirname, "bin");
|
|
72
79
|
fs.mkdirSync(binDir, { recursive: true });
|
|
73
80
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
]);
|
|
80
|
-
} catch (err) {
|
|
81
|
-
fail(`could not download ${asset} (v${version}): ${err.message}`);
|
|
82
|
-
}
|
|
81
|
+
// local name -> release asset name
|
|
82
|
+
const targets = [
|
|
83
|
+
{ out: `anythink-mcp${ext}`, asset: `anythink-mcp-${suffix}` },
|
|
84
|
+
{ out: `anythink${ext}`, asset: `anythink-${suffix}` },
|
|
85
|
+
];
|
|
83
86
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
const
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
.
|
|
92
|
-
|
|
93
|
-
fail(`checksum mismatch for ${asset} (expected ${match[0]}, got ${sha})`);
|
|
87
|
+
let checksums;
|
|
88
|
+
try {
|
|
89
|
+
checksums = await fetch(`${base}/checksums.txt`).catch(() => null);
|
|
90
|
+
for (const { out, asset } of targets) {
|
|
91
|
+
const buf = await fetch(`${base}/${asset}`);
|
|
92
|
+
verify(buf, asset, checksums);
|
|
93
|
+
const outPath = path.join(binDir, out);
|
|
94
|
+
fs.writeFileSync(outPath, buf);
|
|
95
|
+
if (!isWin) fs.chmodSync(outPath, 0o755);
|
|
94
96
|
}
|
|
97
|
+
} catch (err) {
|
|
98
|
+
fail(`could not download binaries (v${version}): ${err.message}`);
|
|
95
99
|
}
|
|
96
100
|
|
|
97
|
-
|
|
98
|
-
if (!isWin) fs.chmodSync(outPath, 0o755);
|
|
99
|
-
console.log(`[anythink-mcp] installed ${asset} (v${version}).`);
|
|
101
|
+
console.log(`[anythink-mcp] installed anythink-mcp + anythink (v${version}).`);
|
|
100
102
|
}
|
|
101
103
|
|
|
102
104
|
main().catch((err) => fail(err.message));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@anythink-cloud/mcp",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.12",
|
|
4
4
|
"description": "Anythink MCP server — manage the Anythink all-in-one backend (data, auth, search, files, workflows, payments) from AI assistants and agents. Runs the native binary via npx; no .NET required.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"anythink-mcp": "bin/anythink-mcp.js"
|