提交qiming-mcp-proxy
This commit is contained in:
412
qiming-mcp-proxy/docs/analysis/NPM_DEPENDENCY_UPDATE_ANALYSIS.md
Normal file
412
qiming-mcp-proxy/docs/analysis/NPM_DEPENDENCY_UPDATE_ANALYSIS.md
Normal file
@@ -0,0 +1,412 @@
|
||||
# mcp-proxy npm 包依赖更新机制分析
|
||||
|
||||
## 问题
|
||||
**用户关注**: mcp-proxy 打包到 npm 时,内部依赖的平台二进制文件是否是最新的(下载的)?
|
||||
|
||||
## 快速回答
|
||||
❌ **当前机制**: cargo-dist 生成的 npm 包中的二进制文件**不是**从 npm registry 下载的最新版本,而是**构建时打包进去的**。
|
||||
|
||||
✅ **这实际上是正确的行为**: 这确保了版本一致性和可靠性。
|
||||
|
||||
---
|
||||
|
||||
## cargo-dist npm 安装器工作机制
|
||||
|
||||
### 1. 构建阶段(GitHub Actions)
|
||||
|
||||
```yaml
|
||||
# .github/workflows/release.yml
|
||||
targets = [
|
||||
"aarch64-apple-darwin",
|
||||
"aarch64-unknown-linux-gnu",
|
||||
"x86_64-apple-darwin",
|
||||
"x86_64-unknown-linux-gnu",
|
||||
"x86_64-pc-windows-msvc"
|
||||
]
|
||||
```
|
||||
|
||||
**流程**:
|
||||
```
|
||||
Tag 推送 (v0.1.39)
|
||||
↓
|
||||
GitHub Actions 触发
|
||||
↓
|
||||
为每个平台构建二进制文件
|
||||
├─ Linux x86_64: mcp-proxy (ELF)
|
||||
├─ Linux ARM64: mcp-proxy (ELF)
|
||||
├─ macOS x86_64: mcp-proxy (Mach-O)
|
||||
├─ macOS ARM64: mcp-proxy (Mach-O)
|
||||
└─ Windows: mcp-proxy.exe (PE)
|
||||
↓
|
||||
cargo-dist 打包成 tarball
|
||||
├─ mcp-stdio-proxy-aarch64-apple-darwin.tar.xz
|
||||
├─ mcp-stdio-proxy-x86_64-unknown-linux-gnu.tar.xz
|
||||
└─ mcp-stdio-proxy-x86_64-pc-windows-msvc.zip
|
||||
↓
|
||||
生成 npm 安装器包
|
||||
└─ mcp-stdio-proxy-0.1.39-npm-package.tar.gz
|
||||
```
|
||||
|
||||
### 2. npm 包结构
|
||||
|
||||
cargo-dist 生成的 npm 包包含:
|
||||
|
||||
```
|
||||
mcp-stdio-proxy-0.1.39-npm-package.tar.gz
|
||||
└── package/
|
||||
├── package.json
|
||||
│ ├── "version": "0.1.39"
|
||||
│ ├── "name": "mcp-stdio-proxy"
|
||||
│ ├── "bin": { "mcp-proxy": "./install.js" }
|
||||
│ └── "artifactDownloadUrl": "https://github.com/.../v0.1.39"
|
||||
├── install.js # 安装脚本
|
||||
└── (可能的其他元数据)
|
||||
```
|
||||
|
||||
**package.json 关键字段**:
|
||||
```json
|
||||
{
|
||||
"name": "mcp-stdio-proxy",
|
||||
"version": "0.1.39",
|
||||
"bin": {
|
||||
"mcp-proxy": "./install.js"
|
||||
},
|
||||
"artifactDownloadUrl": "https://github.com/nuwax-ai/mcp-proxy/releases/download/v0.1.39"
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 用户安装流程
|
||||
|
||||
```bash
|
||||
npm install -g mcp-stdio-proxy@0.1.39
|
||||
```
|
||||
|
||||
**实际发生的事情**:
|
||||
|
||||
1. **下载 npm 包**:
|
||||
```
|
||||
npm registry → mcp-stdio-proxy-0.1.39-npm-package.tar.gz
|
||||
```
|
||||
|
||||
2. **运行 install.js**:
|
||||
```javascript
|
||||
// install.js (由 cargo-dist 生成)
|
||||
const version = "0.1.39";
|
||||
const platform = detectPlatform(); // e.g., "x86_64-pc-windows-msvc"
|
||||
const artifactUrl = `${baseUrl}/mcp-stdio-proxy-${platform}.tar.xz`;
|
||||
|
||||
// 下载平台特定的二进制包
|
||||
download(artifactUrl);
|
||||
extract(artifact);
|
||||
symlinkBinary("mcp-proxy");
|
||||
```
|
||||
|
||||
3. **下载的二进制文件来源**:
|
||||
```
|
||||
https://github.com/nuwax-ai/mcp-proxy/releases/download/v0.1.39/mcp-stdio-proxy-x86_64-pc-windows-msvc.zip
|
||||
```
|
||||
或者(如果 OSS 同步成功):
|
||||
```
|
||||
https://nuwa-packages.oss-rg-china-mainland.aliyuncs.com/mcp-stdio-proxy/v0.1.39/mcp-stdio-proxy-x86_64-pc-windows-msvc.zip
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 关键点:版本锁定机制
|
||||
|
||||
### ✅ 版本是锁定的(这是正确的)
|
||||
|
||||
| 组件 | 版本来源 | 更新时机 |
|
||||
|------|---------|---------|
|
||||
| **npm 包版本** | Cargo.toml `version = "0.1.39"` | 手动更新 + Git Tag |
|
||||
| **二进制文件** | 该版本构建时编译的二进制 | 构建时生成 |
|
||||
| **依赖的 crate** | Cargo.lock 锁定 | 更新 Cargo.lock |
|
||||
| **下载 URL** | package.json `artifactDownloadUrl` | 自动生成(包含版本号) |
|
||||
|
||||
**示例**:
|
||||
```
|
||||
用户安装: npm install -g mcp-stdio-proxy@0.1.39
|
||||
↓
|
||||
下载 npm 包(包含版本信息)
|
||||
↓
|
||||
install.js 读取 artifactDownloadUrl
|
||||
↓
|
||||
下载: https://.../v0.1.39/mcp-stdio-proxy-x86_64-pc-windows-msvc.zip
|
||||
↓
|
||||
解压得到的二进制文件就是 v0.1.39 构建时的版本
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 依赖更新策略
|
||||
|
||||
### 场景 A: Rust 依赖更新(如 rmcp, tokio 等)
|
||||
|
||||
**问题**: 如果 `rmcp` 发布了新版本,用户安装 `mcp-stdio-proxy@0.1.39` 会用到新版本吗?
|
||||
|
||||
**答案**: ❌ 不会,因为二进制文件已经编译好了
|
||||
|
||||
**更新方法**:
|
||||
```bash
|
||||
# 1. 在项目中更新依赖
|
||||
cd mcp-proxy
|
||||
cargo update -p rmcp
|
||||
|
||||
# 2. 测试
|
||||
cargo test
|
||||
|
||||
# 3. 更新版本号
|
||||
# 编辑 mcp-proxy/Cargo.toml
|
||||
version = "0.1.40"
|
||||
|
||||
# 4. 提交并打标签
|
||||
git commit -am "chore: bump version to 0.1.40 with updated rmcp"
|
||||
git tag v0.1.40
|
||||
git push origin v0.1.40
|
||||
|
||||
# 5. GitHub Actions 自动构建并发布
|
||||
# 新的 npm 包 mcp-stdio-proxy@0.1.40 将包含更新后的 rmcp
|
||||
```
|
||||
|
||||
### 场景 B: 系统依赖(如 OpenSSL、glibc)
|
||||
|
||||
**问题**: 构建的二进制依赖的系统库版本是什么?
|
||||
|
||||
**答案**: 取决于 GitHub Actions runner 的环境
|
||||
|
||||
**当前配置** (`.github/workflows/release.yml`):
|
||||
```yaml
|
||||
matrix:
|
||||
runner: "ubuntu-22.04" # Ubuntu 22.04 的 glibc 版本
|
||||
```
|
||||
|
||||
**潜在问题**:
|
||||
- 如果在 Ubuntu 22.04 上构建,二进制可能依赖较新的 glibc
|
||||
- 在旧系统(如 CentOS 7)上可能无法运行
|
||||
|
||||
**解决方案**:
|
||||
```yaml
|
||||
# 使用容器构建以控制依赖版本
|
||||
matrix:
|
||||
container:
|
||||
image: "quay.io/pypa/manylinux2014_x86_64" # 兼容性更好
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 当前流程的优缺点
|
||||
|
||||
### ✅ 优点
|
||||
|
||||
1. **版本一致性**:
|
||||
- `mcp-stdio-proxy@0.1.39` 永远下载的是 v0.1.39 构建时的二进制
|
||||
- 不会因为依赖更新导致意外行为
|
||||
|
||||
2. **确定性构建**:
|
||||
- Cargo.lock 锁定所有依赖版本
|
||||
- 可复现的构建结果
|
||||
|
||||
3. **无运行时编译**:
|
||||
- 用户安装时不需要 Rust 工具链
|
||||
- 安装速度快(直接下载预编译二进制)
|
||||
|
||||
4. **平台特定优化**:
|
||||
- 为每个平台单独编译优化
|
||||
- 无跨平台兼容性损失
|
||||
|
||||
### ❌ 潜在问题
|
||||
|
||||
1. **依赖无法自动更新**:
|
||||
- 用户不能通过 `npm update` 获取新的 Rust 依赖
|
||||
- 必须发布新版本
|
||||
|
||||
2. **二进制体积大**:
|
||||
- 每个平台的二进制都需要打包
|
||||
- npm 包本身较小(只是安装器),但下载的二进制较大
|
||||
|
||||
3. **系统兼容性**:
|
||||
- 需要确保目标系统有合适的运行时库
|
||||
- 可能在旧系统上无法运行
|
||||
|
||||
---
|
||||
|
||||
## 对比其他方案
|
||||
|
||||
### 方案 A: 当前方案(cargo-dist)
|
||||
|
||||
```
|
||||
npm install -g mcp-stdio-proxy
|
||||
↓
|
||||
下载安装器 npm 包(~1KB)
|
||||
↓
|
||||
install.js 下载平台二进制(~10MB)
|
||||
↓
|
||||
解压到 ~/.npm/bin/
|
||||
```
|
||||
|
||||
**特点**: 预编译二进制,版本锁定
|
||||
|
||||
---
|
||||
|
||||
### 方案 B: 纯 npm 包(不适用)
|
||||
|
||||
```
|
||||
npm install -g mcp-stdio-proxy
|
||||
↓
|
||||
下载 JavaScript 代码
|
||||
↓
|
||||
运行时执行
|
||||
```
|
||||
|
||||
**特点**: 不适用,因为 mcp-proxy 是 Rust 项目
|
||||
|
||||
---
|
||||
|
||||
### 方案 C: npm 包 + 源码编译(不推荐)
|
||||
|
||||
```
|
||||
npm install -g mcp-stdio-proxy
|
||||
↓
|
||||
下载源码 + package.json
|
||||
↓
|
||||
postinstall: cargo build --release
|
||||
↓
|
||||
编译二进制
|
||||
```
|
||||
|
||||
**特点**:
|
||||
- ❌ 需要用户有 Rust 工具链
|
||||
- ❌ 安装时间长(编译需要几分钟)
|
||||
- ✅ 可以获取最新依赖
|
||||
- ✅ 针对用户系统优化
|
||||
|
||||
---
|
||||
|
||||
## 建议
|
||||
|
||||
### ✅ 保持当前方案
|
||||
|
||||
**理由**:
|
||||
1. cargo-dist 是 Rust 社区标准方案
|
||||
2. 版本锁定是**优点**而非缺点(确保稳定性)
|
||||
3. 用户体验好(无需 Rust 工具链,安装快)
|
||||
|
||||
### 🔧 优化建议
|
||||
|
||||
#### 1. 明确依赖更新流程
|
||||
|
||||
创建文档说明如何更新依赖并发布新版本:
|
||||
|
||||
```markdown
|
||||
# 依赖更新指南
|
||||
|
||||
## 更新 Rust 依赖
|
||||
1. `cargo update -p <crate_name>`
|
||||
2. `cargo test` 确保无破坏性更改
|
||||
3. 更新 `Cargo.toml` 版本号
|
||||
4. `git tag v<new_version>` 触发发布
|
||||
|
||||
## 发布检查清单
|
||||
- [ ] 所有测试通过
|
||||
- [ ] CHANGELOG.md 已更新
|
||||
- [ ] 版本号已同步(Cargo.toml)
|
||||
- [ ] Git tag 格式正确(v0.1.40)
|
||||
```
|
||||
|
||||
#### 2. 添加版本信息到二进制
|
||||
|
||||
```rust
|
||||
// mcp-proxy/src/main.rs
|
||||
#[derive(Parser)]
|
||||
#[command(version = env!("CARGO_PKG_VERSION"))]
|
||||
struct Cli {
|
||||
// ...
|
||||
}
|
||||
|
||||
// 运行时显示依赖版本
|
||||
fn print_version_info() {
|
||||
println!("mcp-proxy {}", env!("CARGO_PKG_VERSION"));
|
||||
println!(" rmcp: {}", env!("CARGO_PKG_VERSION_rmcp"));
|
||||
println!(" tokio: {}", env!("CARGO_PKG_VERSION_tokio"));
|
||||
}
|
||||
```
|
||||
|
||||
#### 3. 自动化依赖检查
|
||||
|
||||
```yaml
|
||||
# .github/workflows/dependency-check.yml
|
||||
name: Dependency Check
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 0 * * 1' # 每周一检查
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
check-outdated:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- run: cargo outdated --exit-code 1
|
||||
```
|
||||
|
||||
#### 4. 添加系统兼容性说明
|
||||
|
||||
在 README.md 中明确说明:
|
||||
|
||||
```markdown
|
||||
## 系统要求
|
||||
|
||||
### Linux
|
||||
- glibc >= 2.31 (Ubuntu 20.04+, Debian 11+, RHEL 8+)
|
||||
- 或使用 musl 构建版本(待支持)
|
||||
|
||||
### macOS
|
||||
- macOS 10.15+ (Catalina or later)
|
||||
|
||||
### Windows
|
||||
- Windows 10 / Windows Server 2019 或更高版本
|
||||
- 需要 Visual C++ Redistributable 2015-2022
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 总结
|
||||
|
||||
### 问题回答
|
||||
|
||||
**Q: mcp-proxy 打包的内部平台依赖是否是最新的(下载的)?**
|
||||
|
||||
**A**:
|
||||
- ❌ **不是"下载的最新"**: 二进制文件在构建时编译,版本锁定
|
||||
- ✅ **这是正确的行为**: 确保版本一致性和可靠性
|
||||
- 🔄 **更新方式**: 通过发布新版本(如 v0.1.40)获取更新的依赖
|
||||
|
||||
### 版本管理流程
|
||||
|
||||
```
|
||||
Rust 依赖更新
|
||||
↓
|
||||
cargo update
|
||||
↓
|
||||
测试验证
|
||||
↓
|
||||
版本号递增 (0.1.39 → 0.1.40)
|
||||
↓
|
||||
Git Tag (v0.1.40)
|
||||
↓
|
||||
GitHub Actions 构建
|
||||
↓
|
||||
发布到 npm (mcp-stdio-proxy@0.1.40)
|
||||
↓
|
||||
用户 npm install -g mcp-stdio-proxy@latest
|
||||
↓
|
||||
获取包含最新依赖的二进制
|
||||
```
|
||||
|
||||
### 最佳实践
|
||||
|
||||
1. ✅ **保持当前 cargo-dist 方案**
|
||||
2. ✅ **定期检查和更新依赖**
|
||||
3. ✅ **清晰的版本发布流程**
|
||||
4. ✅ **文档化系统要求**
|
||||
5. ✅ **自动化依赖检查(GitHub Actions)**
|
||||
Reference in New Issue
Block a user