dreamd-mcp 0.1.0-rc.1

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/README.md ADDED
@@ -0,0 +1,23 @@
1
+ # dreamd-mcp
2
+
3
+ Node shim for the dreamd MCP server. Downloads the right prebuilt binary for your OS/arch and starts the MCP server.
4
+
5
+ ## Install
6
+
7
+ ```sh
8
+ # 1. Scaffold .agent/ into your project
9
+ npx dreamd-mcp init
10
+
11
+ # 2. Point Claude Code, Cursor, or any MCP-aware harness at the server
12
+ npx dreamd-mcp
13
+ ```
14
+
15
+ No Rust installation required. Supports Linux x86_64/aarch64, macOS x86_64/aarch64.
16
+
17
+ ## Override
18
+
19
+ Set `DREAMD_BIN=/path/to/dreamd` to skip download and use a local build.
20
+
21
+ ## License
22
+
23
+ Apache-2.0
@@ -0,0 +1,161 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ const https = require('https');
5
+ const fs = require('fs');
6
+ const path = require('path');
7
+ const os = require('os');
8
+ const crypto = require('crypto');
9
+ const { execFileSync, spawnSync } = require('child_process');
10
+ const zlib = require('zlib');
11
+
12
+ const VERSION = '0.1.0-rc.1';
13
+ const MANIFEST = require('../manifest.json');
14
+
15
+ function getPlatformTarget() {
16
+ const { platform, arch } = process;
17
+ if (platform === 'linux' && arch === 'x64') return 'linux-x86_64';
18
+ if (platform === 'linux' && arch === 'arm64') return 'linux-aarch64';
19
+ if (platform === 'darwin' && arch === 'x64') return 'darwin-x86_64';
20
+ if (platform === 'darwin' && arch === 'arm64') return 'darwin-aarch64';
21
+ if (platform === 'win32' && arch === 'x64') return 'windows-x86_64';
22
+ return null;
23
+ }
24
+
25
+ function getCacheDir() {
26
+ if (process.platform === 'win32') {
27
+ const localAppData = process.env.LOCALAPPDATA || os.homedir();
28
+ return path.join(localAppData, 'dreamd-mcp', 'cache', VERSION);
29
+ }
30
+ return path.join(os.homedir(), '.cache', 'dreamd-mcp', VERSION);
31
+ }
32
+
33
+ function getBinaryName() {
34
+ return process.platform === 'win32' ? 'dreamd.exe' : 'dreamd';
35
+ }
36
+
37
+ function sha256File(filePath) {
38
+ const hash = crypto.createHash('sha256');
39
+ hash.update(fs.readFileSync(filePath));
40
+ return hash.digest('hex');
41
+ }
42
+
43
+ function verifyBinary(binaryPath, expectedSha256) {
44
+ if (expectedSha256 === '0000000000000000000000000000000000000000000000000000000000000000') {
45
+ // Pre-release placeholder — verification intentionally skipped.
46
+ // Replace with real hashes in manifest.json when release binaries are cut (v0.1 launch).
47
+ return;
48
+ }
49
+ const actual = sha256File(binaryPath);
50
+ if (actual !== expectedSha256) {
51
+ process.stderr.write(`[dreamd-mcp] sha256 mismatch!\n expected: ${expectedSha256}\n actual: ${actual}\n`);
52
+ process.stderr.write('[dreamd-mcp] Cached binary may be corrupt. Delete ~/.cache/dreamd-mcp and retry.\n');
53
+ process.exit(1);
54
+ }
55
+ }
56
+
57
+ function downloadFile(url, destPath) {
58
+ return new Promise((resolve, reject) => {
59
+ const file = fs.createWriteStream(destPath);
60
+ function get(u) {
61
+ https.get(u, (res) => {
62
+ // GitHub Releases redirects the download to S3; follow one hop.
63
+ if (res.statusCode === 301 || res.statusCode === 302) {
64
+ return get(res.headers.location);
65
+ }
66
+ if (res.statusCode !== 200) {
67
+ return reject(new Error(`HTTP ${res.statusCode} fetching ${u}`));
68
+ }
69
+ res.pipe(file);
70
+ file.on('finish', () => file.close(resolve));
71
+ file.on('error', reject);
72
+ }).on('error', reject);
73
+ }
74
+ get(url);
75
+ });
76
+ }
77
+
78
+ function extractTarGz(archivePath, destDir) {
79
+ const result = spawnSync('tar', ['-xzf', archivePath, '-C', destDir], { stdio: 'inherit' });
80
+ if (result.status !== 0) {
81
+ throw new Error(`tar extraction failed with status ${result.status}`);
82
+ }
83
+ }
84
+
85
+ async function ensureBinary(target, binaryPath, expectedSha256) {
86
+ const cacheDir = path.dirname(binaryPath);
87
+ fs.mkdirSync(cacheDir, { recursive: true });
88
+
89
+ const archiveName = `${target}.tar.gz`;
90
+ const archivePath = path.join(cacheDir, archiveName);
91
+ const downloadUrl = `https://github.com/botzrDev/dreamd/releases/download/v${VERSION}/${archiveName}`;
92
+
93
+ process.stderr.write(`[dreamd-mcp] Downloading dreamd v${VERSION} for ${target}...\n`);
94
+ await downloadFile(downloadUrl, archivePath);
95
+
96
+ process.stderr.write('[dreamd-mcp] Extracting...\n');
97
+ extractTarGz(archivePath, cacheDir);
98
+ fs.unlinkSync(archivePath);
99
+
100
+ if (!fs.existsSync(binaryPath)) {
101
+ throw new Error(`Binary not found at ${binaryPath} after extraction`);
102
+ }
103
+ fs.chmodSync(binaryPath, 0o755);
104
+ }
105
+
106
+ async function main() {
107
+ const args = process.argv.slice(2);
108
+ const dreamdArgs = args[0] === 'init' ? args : ['mcp', ...args];
109
+
110
+ // DREAMD_BIN override: skip download, exec directly
111
+ if (process.env.DREAMD_BIN) {
112
+ const overridePath = process.env.DREAMD_BIN;
113
+ const target = getPlatformTarget();
114
+ if (target && MANIFEST.binaries[target]) {
115
+ const expected = MANIFEST.binaries[target].sha256;
116
+ if (expected !== '0000000000000000000000000000000000000000000000000000000000000000') {
117
+ process.stderr.write('[dreamd-mcp] WARNING: DREAMD_BIN set — skipping sha256 verification for custom build\n');
118
+ }
119
+ }
120
+ execFileSync(overridePath, dreamdArgs, { stdio: 'inherit' });
121
+ return;
122
+ }
123
+
124
+ const target = getPlatformTarget();
125
+ if (!target) {
126
+ process.stderr.write(
127
+ `No prebuilt binary for ${process.platform}/${process.arch}. Install via:\n` +
128
+ ` cargo install dreamd\n` +
129
+ `Then set DREAMD_BIN=/path/to/dreamd and re-run.\n`
130
+ );
131
+ process.exit(1);
132
+ }
133
+
134
+ const binaryEntry = MANIFEST.binaries[target];
135
+ if (!binaryEntry) {
136
+ process.stderr.write(
137
+ `No prebuilt binary for ${target}. Install via:\n` +
138
+ ` cargo install dreamd\n` +
139
+ `Then set DREAMD_BIN=/path/to/dreamd and re-run.\n`
140
+ );
141
+ process.exit(1);
142
+ }
143
+
144
+ const cacheDir = getCacheDir();
145
+ const binaryName = getBinaryName();
146
+ const binaryPath = path.join(cacheDir, binaryName);
147
+
148
+ if (!fs.existsSync(binaryPath)) {
149
+ await ensureBinary(target, binaryPath, binaryEntry.sha256);
150
+ }
151
+
152
+ // Verify sha256 before every exec (not just on download)
153
+ verifyBinary(binaryPath, binaryEntry.sha256);
154
+
155
+ execFileSync(binaryPath, dreamdArgs, { stdio: 'inherit' });
156
+ }
157
+
158
+ main().catch((err) => {
159
+ process.stderr.write(`[dreamd-mcp] Fatal error: ${err.message}\n`);
160
+ process.exit(1);
161
+ });
package/manifest.json ADDED
@@ -0,0 +1,14 @@
1
+ {
2
+ "version": "0.1.0-rc.1",
3
+ "binaries": {
4
+ "linux-x86_64": {
5
+ "sha256": "59333e808f7c047ef54d150295a5696cb7c87301385e1056e83dcd4f97492b4b"
6
+ },
7
+ "darwin-x86_64": {
8
+ "sha256": "acfb3b8a9d56449cd72163175106d63cf8a7db78ba0d9d104ed5adf19dae5eb2"
9
+ },
10
+ "darwin-aarch64": {
11
+ "sha256": "06557be01efd67075d793fbc34926d944eceed133ae9fd1f0aff192401a9fb9c"
12
+ }
13
+ }
14
+ }
package/package.json ADDED
@@ -0,0 +1,22 @@
1
+ {
2
+ "name": "dreamd-mcp",
3
+ "mcpName": "io.github.botzrDev/dreamd",
4
+ "version": "0.1.0-rc.1",
5
+ "description": "npx shim for dreamd MCP server — downloads the right prebuilt Rust binary for your OS/arch",
6
+ "bin": {
7
+ "dreamd-mcp": "bin/dreamd-mcp.js"
8
+ },
9
+ "files": [
10
+ "bin/",
11
+ "manifest.json",
12
+ "README.md"
13
+ ],
14
+ "engines": {
15
+ "node": ">=18"
16
+ },
17
+ "license": "Apache-2.0",
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "https://github.com/botzrDev/dreamd.git"
21
+ }
22
+ }