@pandanpc/mcp-server 0.1.23 → 0.1.25
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/binary-name.js +8 -0
- package/index.js +2 -1
- package/install.js +73 -39
- package/package.json +2 -1
package/binary-name.js
ADDED
package/index.js
CHANGED
|
@@ -7,8 +7,9 @@
|
|
|
7
7
|
const path = require('path')
|
|
8
8
|
const { spawn } = require('child_process')
|
|
9
9
|
const fs = require('fs')
|
|
10
|
+
const { binaryName } = require('./binary-name')
|
|
10
11
|
|
|
11
|
-
const binName =
|
|
12
|
+
const binName = binaryName()
|
|
12
13
|
const binPath = path.join(__dirname, 'bin', binName)
|
|
13
14
|
|
|
14
15
|
if (!fs.existsSync(binPath)) {
|
package/install.js
CHANGED
|
@@ -10,6 +10,7 @@ const fs = require('fs')
|
|
|
10
10
|
const path = require('path')
|
|
11
11
|
const https = require('https')
|
|
12
12
|
const crypto = require('crypto')
|
|
13
|
+
const { binaryName } = require('./binary-name')
|
|
13
14
|
|
|
14
15
|
const pkg = require('./package.json')
|
|
15
16
|
const VERSION = pkg.version
|
|
@@ -66,6 +67,18 @@ function sha256(file) {
|
|
|
66
67
|
})
|
|
67
68
|
}
|
|
68
69
|
|
|
70
|
+
function checksumFor(sumsText, artifactName) {
|
|
71
|
+
const line = String(sumsText || '')
|
|
72
|
+
.split('\n')
|
|
73
|
+
.map((entry) => entry.trim().split(/\s+/))
|
|
74
|
+
.find((entry) => entry[1] === artifactName)
|
|
75
|
+
const checksum = line?.[0]?.toLowerCase() || ''
|
|
76
|
+
if (!/^[a-f0-9]{64}$/.test(checksum)) {
|
|
77
|
+
throw new Error(`SHA256SUMS has no valid checksum for ${artifactName}`)
|
|
78
|
+
}
|
|
79
|
+
return checksum
|
|
80
|
+
}
|
|
81
|
+
|
|
69
82
|
async function fetchText(url) {
|
|
70
83
|
return new Promise((resolve, reject) => {
|
|
71
84
|
https.get(url, (res) => {
|
|
@@ -80,54 +93,75 @@ async function fetchText(url) {
|
|
|
80
93
|
})
|
|
81
94
|
}
|
|
82
95
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
if (!fs.existsSync(binDir)) fs.mkdirSync(binDir, { recursive: true })
|
|
87
|
-
const localBin = path.join(binDir, process.platform === 'win32' ? 'pandanpc-mcp.exe' : 'pandanpc-mcp')
|
|
88
|
-
|
|
89
|
-
// Skip download if binary already exists (e.g. manually placed for development)
|
|
90
|
-
if (fs.existsSync(localBin) && fs.statSync(localBin).size > 0) {
|
|
91
|
-
console.log(`[pandanpc-mcp] binary already present at ${localBin}, skipping download`)
|
|
92
|
-
return
|
|
96
|
+
function removeTemporaryFile(file) {
|
|
97
|
+
try { fs.unlinkSync(file) } catch (error) {
|
|
98
|
+
if (error?.code !== 'ENOENT') throw error
|
|
93
99
|
}
|
|
100
|
+
}
|
|
94
101
|
|
|
95
|
-
|
|
96
|
-
|
|
102
|
+
async function ensureBinary({
|
|
103
|
+
key,
|
|
104
|
+
artifactName,
|
|
105
|
+
localBin,
|
|
106
|
+
platform = process.platform,
|
|
107
|
+
baseUrl = BASE_URL,
|
|
108
|
+
fetchTextFn = fetchText,
|
|
109
|
+
downloadFn = download,
|
|
110
|
+
sha256Fn = sha256,
|
|
111
|
+
logger = console,
|
|
112
|
+
}) {
|
|
113
|
+
const sumsUrl = `${baseUrl}/SHA256SUMS`
|
|
114
|
+
const expected = checksumFor(await fetchTextFn(sumsUrl), artifactName)
|
|
97
115
|
|
|
98
|
-
|
|
99
|
-
await
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
116
|
+
if (fs.existsSync(localBin) && fs.statSync(localBin).size > 0) {
|
|
117
|
+
const actual = await sha256Fn(localBin)
|
|
118
|
+
if (actual === expected) {
|
|
119
|
+
if (platform !== 'win32') fs.chmodSync(localBin, 0o755)
|
|
120
|
+
logger.log(`[pandanpc-mcp] verified cached binary for ${key}`)
|
|
121
|
+
return { installed: false, checksum: actual }
|
|
122
|
+
}
|
|
123
|
+
logger.warn(`[pandanpc-mcp] cached binary checksum is stale; downloading ${artifactName}`)
|
|
104
124
|
}
|
|
105
125
|
|
|
106
|
-
|
|
126
|
+
const temporaryBin = `${localBin}.download-${process.pid}-${Date.now()}`
|
|
127
|
+
const url = `${baseUrl}/${artifactName}`
|
|
128
|
+
logger.log(`[pandanpc-mcp] downloading ${url} -> ${localBin}`)
|
|
129
|
+
|
|
107
130
|
try {
|
|
108
|
-
|
|
109
|
-
const
|
|
110
|
-
if (
|
|
111
|
-
|
|
112
|
-
const actual = await sha256(localBin)
|
|
113
|
-
if (expected !== actual) {
|
|
114
|
-
fs.unlinkSync(localBin)
|
|
115
|
-
throw new Error(`SHA256 mismatch: expected ${expected}, got ${actual}`)
|
|
116
|
-
}
|
|
117
|
-
console.log(`[pandanpc-mcp] SHA256 verified`)
|
|
131
|
+
await downloadFn(url, temporaryBin)
|
|
132
|
+
const actual = await sha256Fn(temporaryBin)
|
|
133
|
+
if (actual !== expected) {
|
|
134
|
+
throw new Error(`SHA256 mismatch: expected ${expected}, got ${actual}`)
|
|
118
135
|
}
|
|
119
|
-
|
|
120
|
-
|
|
136
|
+
if (platform !== 'win32') fs.chmodSync(temporaryBin, 0o755)
|
|
137
|
+
fs.renameSync(temporaryBin, localBin)
|
|
138
|
+
logger.log('[pandanpc-mcp] SHA256 verified')
|
|
139
|
+
logger.log(`[pandanpc-mcp] installed for ${key}`)
|
|
140
|
+
return { installed: true, checksum: actual }
|
|
141
|
+
} catch (error) {
|
|
142
|
+
removeTemporaryFile(temporaryBin)
|
|
143
|
+
throw error
|
|
121
144
|
}
|
|
145
|
+
}
|
|
122
146
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
147
|
+
async function main() {
|
|
148
|
+
const { key, name: artifactName } = detectPlatform()
|
|
149
|
+
const binDir = path.join(__dirname, 'bin')
|
|
150
|
+
if (!fs.existsSync(binDir)) fs.mkdirSync(binDir, { recursive: true })
|
|
151
|
+
const localBin = path.join(binDir, binaryName())
|
|
152
|
+
|
|
153
|
+
await ensureBinary({ key, artifactName, localBin })
|
|
154
|
+
}
|
|
126
155
|
|
|
127
|
-
|
|
156
|
+
if (require.main === module) {
|
|
157
|
+
main().catch((err) => {
|
|
158
|
+
console.error('[pandanpc-mcp] install failed:', err.message)
|
|
159
|
+
console.error('[pandanpc-mcp] Build from source if the release artifact is unavailable: https://github.com/pandanpc/mcp-server')
|
|
160
|
+
process.exit(1)
|
|
161
|
+
})
|
|
128
162
|
}
|
|
129
163
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
}
|
|
164
|
+
module.exports = {
|
|
165
|
+
checksumFor,
|
|
166
|
+
ensureBinary,
|
|
167
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pandanpc/mcp-server",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.25",
|
|
4
4
|
"description": "PandaNpc MCP Server — PandaNote and Agent connection management for Codex, Claude Code, and other MCP clients",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"mcp",
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
"pandanpc-mcp": "index.js"
|
|
21
21
|
},
|
|
22
22
|
"files": [
|
|
23
|
+
"binary-name.js",
|
|
23
24
|
"index.js",
|
|
24
25
|
"install.js",
|
|
25
26
|
"README.md"
|