원클릭으로
mcp-deploy
部署 MCP Server 專案(編譯、打包 mcpb、建立 GitHub Release)
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
部署 MCP Server 專案(編譯、打包 mcpb、建立 GitHub Release)
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Turn a journal / reference article PDF into a faithful, compile-verified LaTeX "article record" — metadata frontmatter + every theorem, definition and numbered equation (original numbers preserved) + references + flagged editorial notes — saved next to the PDF as year_author_title.tex. Reach for this whenever the user wants to transcribe, OCR, extract, "make a record of", or pull the theorems / equations out of a paper or PDF into LaTeX, or adds a reference PDF and wants it turned into a structured .tex — even when they literally say "OCR it": this skill checks for a text layer first and deliberately avoids OCR on born-digital PDFs, because re-recognizing rendered math is less accurate than reading the embedded text. Especially valuable for math-heavy papers where equation fidelity matters.
發布或更新 MCP Server 到官方 MCP Registry 及第三方平台(Glama、awesome-mcp-servers)
Unblock Apple notarization / signed releases when blocked by an updated or expired Apple Developer Program License Agreement (the notarytool / Transporter HTTP 403 "A required agreement is missing or has expired"). Accepts the pending agreement on developer.apple.com via Safari + AppleScript, then re-verifies and resumes the release. Use when: `xcrun notarytool` / `make release-signed` fails with 403 "required agreement", or user says "notarization blocked", "公證被擋", "Apple 協議過期", "accept apple agreement", "Program License Agreement", "notary 403", "release 卡在 Apple 協議". Do NOT use for 401 "Invalid credentials" (that is an app-specific-password / key problem — re-run `xcrun notarytool store-credentials`, a user-only action).
macOS native browser automation via Safari + AppleScript. Use when the user needs to automate websites that require login (Plaud, Elementor, banking, social media) — Safari preserves localStorage and cookies permanently. Also use when agent-browser fails due to session/auth issues, or when the user explicitly asks to use Safari. Triggers on: "login to site", "automate with Safari", "use Safari", "session expired with agent-browser", "Plaud upload", or any website automation where persistent auth is needed.
更新 Plugin 到最新版本(marketplace.json 同步 + marketplace update + plugin update + 安裝檢查)。當修改了任何 plugin 原始碼後需要同步、或用戶提到「更新 plugin」、「同步 plugin」、「plugin 沒生效」、「reload plugins」時使用。
LaTeX source 編譯前的 static check — punct_check(半形/全形標點)+ fonts_check(字型缺字,需既有 .log)+ source-level pattern audit。當用戶說「precompile check」「編譯前檢查」「跑 make check」「source audit」「掃半形標點」「掃缺字」時使用。對應暑期班 typesetting-checklist 的
| name | mcp-deploy |
| description | 部署 MCP Server 專案(編譯、打包 mcpb、建立 GitHub Release) |
| argument-hint | ["version"] |
| allowed-tools | Read, Write, Edit, Bash(swift:*), Bash(lipo:*), Bash(file:*), Bash(shasum:*), Bash(git:*), Bash(gh:*), Bash(zip:*), Bash(rm:*), Bash(cp:*), Bash(mkdir:*), Bash(ls:*), Bash(chmod:*), Bash(npm:*), Bash(python:*), Bash(pip:*), Bash(codesign:*), Grep, Glob, AskUserQuestion |
| disable-model-invocation | true |
完整的 MCP 專案部署流程:編譯 → 打包 → 發布。
建立新專案請用 /mcp-tools:mcp-new-app
$1 = 版本號(可選,如 1.0.0)動任何事之前先用 TaskCreate 建 stage-level todo list:
TaskCreate(name="detect_project", description="Phase 0: 確認 MCP 專案目錄 + 識別語言 + 讀當前版本 + 確認新版本號")
TaskCreate(name="compile_binary", description="Phase 1: 編譯(Swift/Python/TS),Swift 要做 universal binary + codesign")
TaskCreate(name="update_version_and_package", description="Phase 2: manifest.json + CHANGELOG + README + 打包 .mcpb + 驗證格式")
TaskCreate(name="publish_to_github", description="Phase 3: git commit/push + gh release create + curl upload assets(大 binary 必須 curl)")
TaskCreate(name="verify_binary_consistency", description="Phase 3.5 (Swift only):hash 比對 + 架構確認")
TaskCreate(name="publish_plugin", description="Phase 4 (可選):發布為 Claude Code Plugin,更新 marketplace.json + cache 同步")
TaskCreate(name="report_completion", description="Phase 5: 輸出版本資訊、Release URL、下一步提示")
完成每一步立即 TaskUpdate → completed。靜默完成 = 違規。
為什麼強制:mcp-deploy 有 5+ phases、每個 phase 有多個 step(總共 ~30 sub-steps),沒 task list 很容易漏步——特別是 Phase 3.5 binary consistency check 和 Phase 4 Phase 4 的 plugin sync(兩者都是 silent failure 的常見點)。
檢查當前目錄是否為 MCP 專案:
pwd
ls -la
必須存在的檔案/目錄:
mcpb/ 目錄mcpb/manifest.json如果不存在,提示使用者:
請先
cd到 MCP 專案目錄,或使用/mcp-tools:mcp-new-app建立新專案
| 檔案 | 語言 |
|---|---|
Package.swift | Swift |
pyproject.toml 或 setup.py | Python |
package.json + tsconfig.json | TypeScript |
cat mcpb/manifest.json | grep '"version"'
如果提供了 $1,使用該版本號。
否則使用 AskUserQuestion 詢問新版本號。
版本號規則(Semantic Versioning):
MAJOR.MINOR.PATCH1.0.0、0.8.1、2.1.0根據語言類型執行對應的編譯流程。
rm -rf .build 2>/dev/null || true
swift build -c release --arch arm64
swift build -c release --arch x86_64
# 取得 binary 名稱(從 Package.swift)
BINARY_NAME=$(grep -A5 'executableTarget' Package.swift | grep 'name:' | head -1 | sed 's/.*"\([^"]*\)".*/\1/')
lipo -create \
.build/arm64-apple-macosx/release/$BINARY_NAME \
.build/x86_64-apple-macosx/release/$BINARY_NAME \
-output mcpb/server/$BINARY_NAME
# 清除 Dropbox xattr 汙染(從 Dropbox 目錄 build 的 binary 帶 com.dropbox.attrs,macOS 會靜默 hang)
xattr -cr mcpb/server/$BINARY_NAME
# 重新簽名(lipo 會破壞原始 code signature,未簽名會被 macOS SIGKILL)
#
# 注意:這裡是 ad-hoc 簽名(`-` 表示無 identity),**僅適用 macOS ≤ 25 dev/test**。
# macOS 26 上 ad-hoc binary 無法觸發 Calendar / Reminders / AppleEvents 等 TCC dialog;
# 若 MCP 會打到隱私 API,必須走 Developer ID 簽章 + notarization。
#
# **若你的 MCP 走 macOS 26 production path**:
# 1. 確認專案已裝簽章 pipeline(`scripts/sign-and-notarize.sh` 存在?)
# 2. 沒裝 → 提示使用者跑 `/mcp-tools:mcp-sign-pipeline` 補裝(一次性 setup)
# 3. 已裝 → 改成呼叫 `./scripts/sign-and-notarize.sh mcpb/server/$BINARY_NAME`
# (要求 `DEVELOPER_ID` + `NOTARY_PROFILE` env vars 已設)
#
# 偵測邏輯建議:
# if [ -f "scripts/sign-and-notarize.sh" ] && [ -n "$DEVELOPER_ID" ]; then
# ./scripts/sign-and-notarize.sh mcpb/server/$BINARY_NAME
# else
# codesign --force --sign - mcpb/server/$BINARY_NAME # ad-hoc fallback
# echo "⚠ ad-hoc signed; macOS 26 users will hit TCC blockage"
# echo " Install signing pipeline: /mcp-tools:mcp-sign-pipeline"
# fi
codesign --force --sign - mcpb/server/$BINARY_NAME
file mcpb/server/$BINARY_NAME
lipo -info mcpb/server/$BINARY_NAME
預期輸出:
mcpb/server/YourMCP: Mach-O universal binary with 2 architectures: [x86_64:Mach-O 64-bit executable x86_64] [arm64]
Architectures in the fat file: mcpb/server/YourMCP are: x86_64 arm64
python3 -m venv .venv 2>/dev/null || true
source .venv/bin/activate
pip install -e .
# 建立 wrapper script
cat > mcpb/server/run.sh << 'EOF'
#!/bin/bash
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
cd "$SCRIPT_DIR/../.."
source .venv/bin/activate 2>/dev/null || true
python -m {project_name}
EOF
chmod +x mcpb/server/run.sh
注意:Python MCP 通常不打包成 binary,而是使用 wrapper script。
npm install
npm run build
cat > mcpb/server/run.sh << 'EOF'
#!/bin/bash
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
node "$SCRIPT_DIR/../../dist/index.js"
EOF
chmod +x mcpb/server/run.sh
讀取並更新版本號:
# 使用 Edit 工具更新 "version": "x.x.x"
確保所有地方的版本號一致:
mcpb/manifest.jsonServer.swift 中的 version: "x.x.x"pyproject.tomlpackage.json在 CHANGELOG.md 頂部加入新版本:
## [{version}] - {date}
### Added
- 新功能描述
### Changed
- 變更描述
### Fixed
- 修復描述
使用 AskUserQuestion 詢問這個版本的變更摘要。
重要:更新所有語言版本的 README(如 README.md、README_zh-TW.md 等)
需要更新的內容:
Technical Details / 技術細節 區塊的版本號
Current Version: v{version}Version History / 版本歷史 表格加入新版本:
## Version History
| Version | Changes |
|---------|---------|
| v{version} | {change-summary} |
| ... | ... |
檢查清單:
如果 README.md 沒有 Version History 區塊,在 ## Installation 之前加入。
如果此版本新增了重要功能或 breaking change,除了 Version History 表格外,還需更新 README 中的功能說明。
使用 AskUserQuestion 確認:
這個版本有需要更新 README 功能文檔的重大變更嗎?
- 是(新增工具參數 / response format 變更 / 新功能)
- 否(只是 bug fix 或小改動,Version History 就夠了)
如果選「是」,根據 CHANGELOG 的變更內容,更新 README 中對應的段落:
| 變更類型 | Version History | Tool 描述 | 使用範例 | 新功能區塊 |
|---|---|---|---|---|
| Bug fix (PATCH) | ✅ | ❌ | ❌ | ❌ |
| 小功能 (MINOR) | ✅ | ✅ | 可選 | ❌ |
| 大功能/Breaking (MAJOR) | ✅ | ✅ | ✅ | ✅ |
具體更新項目:
提醒:所有語言版本的 README 都要同步更新。
規則見 rules/tool-readme-sync.md。這步是上兩步 README 更新的驗證,不是重複。
# 1. 實際 tool count(從 Server source 數,或啟動後打 tools/list)
ACTUAL_COUNT=$(grep -oE 'name:\s*"[a-z_]+"' Sources/*/Server.swift 2>/dev/null | sort -u | wc -l | tr -d ' ')
# 若 Python / TS project,改用對應抓法
# 2. README 宣稱的 count
README_COUNT_EN=$(grep -oE '[0-9]+ (MCP )?[Tt]ools' README.md | head -1 | grep -oE '[0-9]+')
README_COUNT_ZH=$(grep -oE '[0-9]+ 個 MCP 工具' README_zh-TW.md 2>/dev/null | head -1 | grep -oE '[0-9]+')
echo "Actual: $ACTUAL_COUNT / README EN: $README_COUNT_EN / README zh-TW: $README_COUNT_ZH"
# 3. Comparison table 的數字
grep -E 'Tools Count|工具數量' README*.md
BLOCKING:如果 actual ≠ README(任何一種語言),停止 deploy,要求先更新 README。 使用者可明確覆蓋(「我知道這次 tool count 沒變」)才繼續。
補救清單(出現不一致時):
規則見 rules/tool-readme-sync.md 的 GitHub Repo About Metadata 章節。
非 BLOCKING,但 minor / major bump 時強烈建議同步;patch 一般可略。
# 先確認 gh 已登入,且這個 repo 在 GitHub 上
gh auth status >/dev/null 2>&1 || { echo "⚠️ gh 未登入,跳過 metadata audit"; exit 0; }
REPO_SLUG=$(gh repo view --json nameWithOwner -q .nameWithOwner 2>/dev/null)
[ -z "$REPO_SLUG" ] && { echo "⚠️ 非 GitHub repo 或無權限"; exit 0; }
# 1. Description 長度與時效
DESC=$(gh repo view --json description -q .description)
DESC_LEN=${#DESC}
echo "Description ($DESC_LEN chars): $DESC"
[ "$DESC_LEN" -lt 50 ] && echo "⚠️ Description 太短(<50 chars),建議補到 200-350 chars"
# 2. Description 是否反映目前 tool count
TOOL_COUNT=$(grep -oE 'name:\s*"[a-z_]+"' Sources/*/Server.swift 2>/dev/null | sort -u | wc -l | tr -d ' ')
if [ "$TOOL_COUNT" -gt 0 ]; then
echo "$DESC" | grep -qE "$TOOL_COUNT (MCP |tools|tool)" || echo "⚠️ Description 未反映 $TOOL_COUNT tools"
fi
# 3. Topics
TOPIC_COUNT=$(gh repo view --json repositoryTopics -q '.repositoryTopics | length')
echo "Topics: $TOPIC_COUNT 個"
[ "$TOPIC_COUNT" -lt 5 ] && echo "⚠️ Topics 太少($TOPIC_COUNT < 5),search visibility 幾乎是零"
[ "$TOPIC_COUNT" -lt 15 ] && echo "💡 建議補到 15-20 個 topics"
# 4. Homepage URL
HOMEPAGE=$(gh repo view --json homepageUrl -q .homepageUrl)
[ -z "$HOMEPAGE" ] && echo "💡 建議設 Homepage = https://github.com/$REPO_SLUG/releases"
發現問題時,詢問使用者要不要順手 gh repo edit 更新:
AskUserQuestion "Repo metadata 和 README 不一致,要順便更新嗎?"
- 是,現在更新(我提供新 description + topics 草案)
- 否,deploy 後手動處理
- Dry run 看草案再決定
AI 草擬 description + topics 時的模板見 rules/tool-readme-sync.md。
rm -f mcpb/*.mcpb 2>/dev/null || true
# 取得專案名稱
PROJECT_NAME=$(cat mcpb/manifest.json | grep '"id"' | head -1 | sed 's/.*"\([^"]*\)".*/\1/' | tr -d ' ')
# 打包到 mcpb/ 目錄內
cd mcpb && zip -r ${PROJECT_NAME}.mcpb . -x ".*" -x "*.mcpb" && cd ..
ls -lh mcpb/*.mcpb
unzip -l mcpb/*.mcpb | head -20
必須包含:
manifest.jsonPRIVACY.mdserver/ 目錄(含 binary 或 script)icon.png(推薦)重要:manifest.json 必須符合 MCPB 0.3 規範,否則 Claude Desktop 會顯示 "Invalid manifest" 錯誤。
必要欄位:
{
"manifest_version": "0.3",
"name": "{project-name}",
"version": "{version}",
"description": "{description}",
"author": {
"name": "Che Cheng"
},
"server": {
"type": "binary",
"entry_point": "server/{BinaryName}",
"mcp_config": {
"command": "${__dirname}/server/{BinaryName}",
"args": [],
"env": {}
}
}
}
常見錯誤:
| 錯誤格式 | 正確格式 |
|---|---|
"author": "Name" | "author": { "name": "Name" } |
"repository": "url" | "repository": { "type": "git", "url": "..." } |
"entrypoint": {...} | "server": {...} |
缺少 manifest_version | "manifest_version": "0.3" |
"path": "..." | "entry_point": "..." |
不支援的欄位(會導致錯誤):
idnameplatformscapabilitiesdisplay_nametoolsgit status
git add -A
git commit -m "v{version}: {change-summary}
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>"
git push origin main
注意:如果使用 Git LFS,會自動上傳大型檔案。
使用 AskUserQuestion 詢問:
v{version})Release Notes 模板:
在 CHANGELOG 內容之前加入安裝指引(用 --- 分隔):
## Install
### Claude Desktop (One-Click)
Download `{project-name}.mcpb` below and double-click to install.
### Claude Code (CLI)
\```bash
curl -L https://github.com/{owner}/{repo}/releases/download/v{version}/{BinaryName} -o ~/bin/{BinaryName}
chmod +x ~/bin/{BinaryName}
claude mcp add --scope user --transport stdio {project-name} -- ~/bin/{BinaryName}
\```
### MCP Registry
Published as `io.github.{owner}/{project-name}` on the [Official MCP Registry](https://registry.modelcontextprotocol.io).
---
{CHANGELOG 內容}
gh release create 上傳大型 binary 容易卡住或 timeout。改用分步驟方式更可靠:
# 準備變數
PROJECT_NAME=$(cat mcpb/manifest.json | grep '"name"' | head -1 | sed 's/.*"\([^"]*\)".*/\1/' | tr -d ' ')
BINARY_NAME=$(ls mcpb/server/ | grep -v '.sh' | grep -v '.gitkeep' | head -1)
MCPB_FILE=$(ls mcpb/*.mcpb | head -1)
OWNER_REPO=$(gh repo view --json nameWithOwner --jq '.nameWithOwner')
# Step 1: 建立 Release(不帶 assets,秒完成)
RELEASE_ID=$(gh api repos/$OWNER_REPO/releases --method POST \
-f tag_name="v{version}" \
-f target_commitish="main" \
-f name="v{version} - {title}" \
-f body="{release-notes}" \
-F draft=false \
-F prerelease=false \
--jq '.id')
echo "Release created: ID=$RELEASE_ID"
# Step 2: 用 curl 上傳 Binary(支援進度條,不會 timeout)
TOKEN=$(gh auth token)
curl -L -X POST \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/octet-stream" \
"https://uploads.github.com/repos/$OWNER_REPO/releases/$RELEASE_ID/assets?name=$BINARY_NAME" \
--data-binary "@mcpb/server/$BINARY_NAME" \
--progress-bar -o /dev/null -w "Binary upload: HTTP %{http_code}, %{size_upload} bytes\n"
# Step 3: 用 curl 上傳 MCPB
MCPB_FILENAME=$(basename $MCPB_FILE)
curl -L -X POST \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/octet-stream" \
"https://uploads.github.com/repos/$OWNER_REPO/releases/$RELEASE_ID/assets?name=$MCPB_FILENAME" \
--data-binary "@$MCPB_FILE" \
--progress-bar -o /dev/null -w "MCPB upload: HTTP %{http_code}, %{size_upload} bytes\n"
# Step 4: 驗證
gh release view v{version} --json assets --jq '.assets[] | "\(.name) (\(.size) bytes)"'
為什麼不用 gh release create 帶 assets:
curl 有進度條且不會 timeout只適合 binary < 10MB 的小型專案:
gh release create v{version} \
--title "v{version} - {title}" \
--notes "{release-notes}" \
mcpb/server/$BINARY_NAME \
$MCPB_FILE
注意:如果遇到 workflow scope may be required 錯誤,必須改用方法 A。
如果工具數量、主要功能、或支援範圍有變更,更新 repo 的 About 描述:
gh repo edit {owner}/{repo} --description "{updated-description}"
常見需更新的情況:
用 gh repo view --json description 先確認現有描述,再決定是否需要更新。
使用 AskUserQuestion 詢問:
是否要將 binary 安裝到 ~/bin?(如果使用 plugin wrapper 的自動下載機制,可以跳過)
如果選擇「是」:
cp mcpb/server/$BINARY_NAME ~/bin/
chmod +x ~/bin/$BINARY_NAME
xattr -cr ~/bin/$BINARY_NAME
codesign --force --sign - ~/bin/$BINARY_NAME
驗證:
file ~/bin/$BINARY_NAME
lipo -info ~/bin/$BINARY_NAME
codesign -dv ~/bin/$BINARY_NAME
如果選擇「否」,跳到 Phase 4。Binary 已在 mcpb/server/ 和 GitHub Release 中,plugin wrapper 會在需要時自動下載。
注意:此 Phase 只適用於 Swift 專案且已安裝到 ~/bin 的情況。
echo "=== Binary Consistency Check ==="
shasum -a 256 mcpb/server/$BINARY_NAME ~/bin/$BINARY_NAME
預期:兩個 hash 完全一致(因為剛從 mcpb/server 複製到 ~/bin)。
echo "=== mcpb/server ==="
lipo -info mcpb/server/$BINARY_NAME
echo "=== ~/bin ==="
lipo -info ~/bin/$BINARY_NAME
預期:兩者都顯示 x86_64 arm64(universal binary)。
如果 hash 不一致,停止並報錯:
❌ Binary 一致性驗證失敗!mcpb/server 和 ~/bin 的 binary 不一致。 請使用
/mcp-tools:mcp-sync修復。
使用 AskUserQuestion 詢問:
是否要同時發布為 Claude Code Plugin?
如果選擇「否」,跳到 Phase 5。
在開始之前,動態取得所有需要的路徑和名稱(避免硬編碼):
# 1. 當前 MCP 專案的 GitHub owner/repo
MCP_REPO_FULL=$(gh repo view --json nameWithOwner -q '.nameWithOwner')
MCP_OWNER="${MCP_REPO_FULL%%/*}"
# 2. 找到 plugins marketplace repo 的本地路徑
# 搜尋包含此 project 的 marketplace.json
PLUGINS_REPO=$(find ~/Developer ~/Library/CloudStorage -maxdepth 5 -name "marketplace.json" -path "*/.claude-plugin/*" -exec grep -l "{project-name}" {} \; 2>/dev/null | head -1 | sed 's|/.claude-plugin/marketplace.json||')
# 3. 衍生變數
MARKETPLACE_NAME=$(basename "$PLUGINS_REPO")
PLUGIN_DIR="$PLUGINS_REPO/plugins/{project-name}"
MARKETPLACE_JSON="$PLUGINS_REPO/.claude-plugin/marketplace.json"
如果 PLUGINS_REPO 找不到,使用 AskUserQuestion 詢問 plugins marketplace repo 的本地路徑。
mkdir -p "$PLUGIN_DIR/.claude-plugin"
mkdir -p "$PLUGIN_DIR/bin"
cat > "$PLUGIN_DIR/.mcp.json" << 'EOF'
{
"{project-name}": {
"type": "stdio",
"command": "${CLAUDE_PLUGIN_ROOT}/bin/{project-name}-wrapper.sh",
"description": "{description}"
}
}
EOF
cat > "$PLUGIN_DIR/.claude-plugin/plugin.json" << 'EOF'
{
"name": "{project-name}",
"version": "{version}",
"description": "{description}",
"author": { "name": "Che Cheng" },
"license": "MIT",
"keywords": ["mcp", "{keywords}"]
}
EOF
Wrapper script 會自動從 GitHub Release 下載 binary(如果本機沒有)。
cat > "$PLUGIN_DIR/bin/{project-name}-wrapper.sh" << 'WRAPPER'
#!/bin/bash
# Auto-download wrapper for {BinaryName}
REPO="$MCP_REPO_FULL"
BINARY_NAME="{BinaryName}"
INSTALL_DIR="$HOME/bin"
BINARY=""
for loc in "$INSTALL_DIR/$BINARY_NAME" "/usr/local/bin/$BINARY_NAME" "$HOME/.local/bin/$BINARY_NAME"; do
[[ -x "$loc" ]] && BINARY="$loc" && break
done
if [[ -z "$BINARY" ]]; then
echo "$BINARY_NAME not found. Downloading from GitHub..." >&2
mkdir -p "$INSTALL_DIR"
URL=$(curl -sL "https://api.github.com/repos/$REPO/releases/latest" \
| grep '"browser_download_url"' | grep "$BINARY_NAME" | head -1 \
| sed 's/.*"\(https[^"]*\)".*/\1/')
if [[ -z "$URL" ]]; then
echo "ERROR: No download URL found. Install manually: https://github.com/$REPO/releases" >&2
exit 1
fi
curl -sL "$URL" -o "$INSTALL_DIR/$BINARY_NAME" && chmod +x "$INSTALL_DIR/$BINARY_NAME" \
|| { echo "ERROR: Download failed." >&2; exit 1; }
BINARY="$INSTALL_DIR/$BINARY_NAME"
echo "Installed $BINARY_NAME to $INSTALL_DIR/" >&2
fi
exec "$BINARY" "$@"
WRAPPER
chmod +x "$PLUGIN_DIR/bin/{project-name}-wrapper.sh"
從專案的 README.md 複製並簡化,或使用 manifest.json 中的資訊生成:
# {project-name}
**{description}**
## 安裝
### 1. 編譯 Binary
\```bash
cd /path/to/{project-name}
swift build -c release
cp .build/release/{BinaryName} ~/bin/
\```
### 2. 安裝 Plugin
\```bash
claude /plugin {project-name}
\```
## 版本
- **當前版本**: {version}
- **GitHub**: https://github.com/$MCP_REPO_FULL
INSTALLED_DIR="$HOME/.claude/plugins/marketplaces/$MARKETPLACE_NAME/plugins/{project-name}"
mkdir -p "$INSTALLED_DIR/.claude-plugin"
mkdir -p "$INSTALLED_DIR/bin"
cp "$PLUGIN_DIR/.mcp.json" "$INSTALLED_DIR/.mcp.json"
cp "$PLUGIN_DIR/.claude-plugin/plugin.json" "$INSTALLED_DIR/.claude-plugin/plugin.json"
cp "$PLUGIN_DIR/bin/{project-name}-wrapper.sh" "$INSTALLED_DIR/bin/"
這一步經常被遺忘,會導致 /plugin 顯示舊版本號。
讀取並更新 marketplace.json 中對應 plugin 的 version 和 description:
MARKETPLACE="$MARKETPLACE_JSON"
# 用 Edit 工具更新 marketplace.json 中 {project-name} 的 version 和 description
必須更新的欄位:
"version": "{version}" — 新版本號"description": "..." — 如果 tool 數量或功能描述有變更新 ~/.claude/plugins/installed_plugins.json 中對應 plugin 的記錄:
# 用 Edit 工具更新以下欄位:
# - "installPath": 指向新版本的 cache 目錄
# - "version": 新版本號
# - "lastUpdated": 當前時間 (ISO 8601)
# - "gitCommitSha": plugins marketplace repo 的最新 commit SHA
同時同步 cache 目錄:
CACHE_DIR="$HOME/.claude/plugins/cache/$MARKETPLACE_NAME/{project-name}/{version}"
mkdir -p "$CACHE_DIR/.claude-plugin" "$CACHE_DIR/bin"
cp "$PLUGIN_DIR/.claude-plugin/plugin.json" "$CACHE_DIR/.claude-plugin/"
cp "$PLUGIN_DIR/.mcp.json" "$CACHE_DIR/"
cp "$PLUGIN_DIR/bin/{project-name}-wrapper.sh" "$CACHE_DIR/bin/"
cp "$PLUGIN_DIR/README.md" "$CACHE_DIR/" 2>/dev/null || true
cd "$PLUGINS_REPO"
git add plugins/{project-name} .claude-plugin/marketplace.json
git commit -m "Update {project-name} plugin to v{version}
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>"
git push origin main
# MCP 部署完成
## 版本資訊
- 專案: {project-name}
- 版本: v{version}
- 語言: Swift / Python / TypeScript
## 發布的檔案
- Binary: `mcpb/server/{BinaryName}`
- MCPB: `{project-name}.mcpb`
## GitHub Release
- URL: https://github.com/$MCP_REPO_FULL/releases/tag/v{version}
## 本地安裝
- [ ] 已安裝到 ~/bin(如選擇安裝)
- [ ] 未安裝(plugin wrapper 會在需要時自動從 GitHub Release 下載)
## Claude Code Plugin(如有發布)
- Plugin 目錄: `$MARKETPLACE_NAME/plugins/{project-name}`
- 已同步到: `~/.claude/plugins/marketplaces/$MARKETPLACE_NAME/plugins/{project-name}`
## 下一步
- 測試: `claude mcp list` 確認 MCP 已連線
- 重啟 Claude Code 以載入新版本
| 變更類型 | 版本變更 | 範例 |
|---|---|---|
| 新功能 | MINOR +1 | 1.0.0 → 1.1.0 |
| Bug 修復 | PATCH +1 | 1.0.0 → 1.0.1 |
| 破壞性變更 | MAJOR +1 | 1.0.0 → 2.0.0 |
| 文檔更新 | PATCH +1 | 1.0.0 → 1.0.1 |
## [版本] - 日期
### Added(新功能)
### Changed(變更)
### Fixed(修復)
### Removed(移除)
| 問題 | 解決方案 |
|---|---|
| Dropbox 衝突導致 build 失敗 | rm -rf .build 後重新編譯 |
| lipo 失敗 | 確認兩種架構都編譯成功 |
| gh release create 卡住(大型 binary) | 改用方法 A(gh api + curl,見 Step 4) |
| gh release 失敗(workflow scope) | 改用方法 A(gh api + curl) |
| Release 變成 untagged draft | gh release delete 清理後重建 |
| Fork tag 衝突 | git tag -d vX.Y.Z 刪本地舊 tag,或 git fetch fork --no-tags |
| LFS lock 認證錯誤 | GIT_LFS_SKIP_PUSH=1 git push 跳過 LFS lock 驗證 |
| curl 上傳 binary 失敗 | 確認 gh auth token 有效,檔案路徑正確 |
| MCP Server | Binary 名稱 |
|---|---|
| che-things-mcp | CheThingsMCP |
| che-ical-mcp | CheICalMCP |
| che-apple-mail-mcp | CheAppleMailMCP |
| che-word-mcp | CheWordMCP |