routebase-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.
- package/bin/routebase-mcp.js +99 -0
- package/checksums.json +6 -0
- package/package.json +24 -0
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// routebase-mcp npm shim (MIT) — downloads the self-contained CLI binary for
|
|
3
|
+
// this platform from releases.routebase.dev (pinned to this package version,
|
|
4
|
+
// SHA-256 verified against the checksums baked in at publish time), caches it
|
|
5
|
+
// under ~/.routebase/bin/<version>/, then execs it.
|
|
6
|
+
//
|
|
7
|
+
// IMPORTANT: the CLI speaks MCP over stdio — stdout belongs to the protocol.
|
|
8
|
+
// All shim output goes to stderr. The downloaded binary is governed by the
|
|
9
|
+
// Routebase terms (https://routebase.dev/); this shim itself is MIT.
|
|
10
|
+
"use strict";
|
|
11
|
+
|
|
12
|
+
const fs = require("node:fs");
|
|
13
|
+
const os = require("node:os");
|
|
14
|
+
const path = require("node:path");
|
|
15
|
+
const https = require("node:https");
|
|
16
|
+
const crypto = require("node:crypto");
|
|
17
|
+
const { spawnSync } = require("node:child_process");
|
|
18
|
+
|
|
19
|
+
const pkg = require("../package.json");
|
|
20
|
+
const checksums = require("../checksums.json");
|
|
21
|
+
|
|
22
|
+
const RID_MAP = {
|
|
23
|
+
"darwin arm64": "osx-arm64",
|
|
24
|
+
"darwin x64": "osx-x64",
|
|
25
|
+
"win32 x64": "win-x64",
|
|
26
|
+
"linux x64": "linux-x64",
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
function fail(message) {
|
|
30
|
+
process.stderr.write(`routebase-mcp: ${message}\n`);
|
|
31
|
+
process.exit(1);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const rid = RID_MAP[`${process.platform} ${process.arch}`];
|
|
35
|
+
if (!rid) {
|
|
36
|
+
fail(
|
|
37
|
+
`unsupported platform ${process.platform}/${process.arch} — supported: macOS (arm64/x64), Windows (x64), Linux (x64)`,
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const ext = rid === "win-x64" ? ".exe" : "";
|
|
42
|
+
const fileName = `routebase-mcp-${rid}${ext}`;
|
|
43
|
+
const expectedSha = checksums[fileName];
|
|
44
|
+
if (!expectedSha) {
|
|
45
|
+
fail(`no checksum for ${fileName} in this package — refusing to download`);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const cacheDir = path.join(os.homedir(), ".routebase", "bin", pkg.version);
|
|
49
|
+
const binPath = path.join(cacheDir, fileName);
|
|
50
|
+
|
|
51
|
+
function download(url, dest, redirects = 0) {
|
|
52
|
+
return new Promise((resolve, reject) => {
|
|
53
|
+
if (redirects > 3) return reject(new Error("too many redirects"));
|
|
54
|
+
https
|
|
55
|
+
.get(url, (res) => {
|
|
56
|
+
if (res.statusCode >= 301 && res.statusCode <= 308 && res.headers.location) {
|
|
57
|
+
res.resume();
|
|
58
|
+
return resolve(download(res.headers.location, dest, redirects + 1));
|
|
59
|
+
}
|
|
60
|
+
if (res.statusCode !== 200) {
|
|
61
|
+
res.resume();
|
|
62
|
+
return reject(new Error(`HTTP ${res.statusCode} for ${url}`));
|
|
63
|
+
}
|
|
64
|
+
const tmp = `${dest}.download`;
|
|
65
|
+
const out = fs.createWriteStream(tmp, { mode: 0o755 });
|
|
66
|
+
res.pipe(out);
|
|
67
|
+
out.on("finish", () => out.close(() => resolve(tmp)));
|
|
68
|
+
out.on("error", reject);
|
|
69
|
+
})
|
|
70
|
+
.on("error", reject);
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function sha256(file) {
|
|
75
|
+
return crypto.createHash("sha256").update(fs.readFileSync(file)).digest("hex");
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
async function ensureBinary() {
|
|
79
|
+
if (fs.existsSync(binPath)) return;
|
|
80
|
+
const url = `https://releases.routebase.dev/cli/${pkg.version}/${fileName}`;
|
|
81
|
+
process.stderr.write(`routebase-mcp: downloading ${url} (first run)\n`);
|
|
82
|
+
fs.mkdirSync(cacheDir, { recursive: true });
|
|
83
|
+
const tmp = await download(url, binPath);
|
|
84
|
+
const actual = sha256(tmp);
|
|
85
|
+
if (actual !== expectedSha) {
|
|
86
|
+
fs.rmSync(tmp, { force: true });
|
|
87
|
+
fail(`checksum mismatch for ${fileName} (expected ${expectedSha}, got ${actual})`);
|
|
88
|
+
}
|
|
89
|
+
fs.renameSync(tmp, binPath);
|
|
90
|
+
process.stderr.write(`routebase-mcp: cached at ${binPath}\n`);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
ensureBinary()
|
|
94
|
+
.then(() => {
|
|
95
|
+
const result = spawnSync(binPath, process.argv.slice(2), { stdio: "inherit" });
|
|
96
|
+
if (result.error) fail(result.error.message);
|
|
97
|
+
process.exit(result.status ?? 1);
|
|
98
|
+
})
|
|
99
|
+
.catch((err) => fail(err.message));
|
package/checksums.json
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
{
|
|
2
|
+
"routebase-mcp-linux-x64": "9f5da21332a63bb54e56edb9133aafbef53843770beaf58f5bb2aa3aba52752c",
|
|
3
|
+
"routebase-mcp-osx-arm64": "078e3f64e78027f646c300c9d3e2c5876bb66c411a0cf344a6c5419b5713e8a8",
|
|
4
|
+
"routebase-mcp-osx-x64": "71ca1241b2251c6b25aa8623107383f08365e40e7b777b3bc6949aa94b0d60f9",
|
|
5
|
+
"routebase-mcp-win-x64.exe": "e85a3b92f30a1b3752104ab21618a14a59ed170334a2e8c6b0ea0e0f589262c4"
|
|
6
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "routebase-mcp",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Routebase MCP server CLI — connect AI agents (Claude Code, Cursor, VS Code) to your Routebase APIs over stdio. Downloads the platform binary from releases.routebase.dev on first run.",
|
|
5
|
+
"bin": {
|
|
6
|
+
"routebase-mcp": "bin/routebase-mcp.js"
|
|
7
|
+
},
|
|
8
|
+
"files": [
|
|
9
|
+
"bin/",
|
|
10
|
+
"checksums.json"
|
|
11
|
+
],
|
|
12
|
+
"engines": {
|
|
13
|
+
"node": ">=18"
|
|
14
|
+
},
|
|
15
|
+
"license": "MIT",
|
|
16
|
+
"homepage": "https://routebase.dev/mcp-server/",
|
|
17
|
+
"keywords": [
|
|
18
|
+
"mcp",
|
|
19
|
+
"model-context-protocol",
|
|
20
|
+
"api",
|
|
21
|
+
"openapi",
|
|
22
|
+
"routebase"
|
|
23
|
+
]
|
|
24
|
+
}
|