在 agents 插件市场中用 file-conversion 技能实现免密钥的跨格式文件转换

在 agents 插件市场中用 file-conversion 技能实现免密钥的跨格式文件转换

【免费下载链接】agents Multi-harness agentic plugin marketplace for Claude Code, Codex, Cursor, OpenCode, GitHub Copilot, and Google Antigravity 【免费下载链接】agents 项目地址: https://gitcode.com/GitHub_Trending/agents24/agents

本篇技术指南围绕 file-conversion 技能展开:它以 Agent Skill 的形式封装了免费的 ChangeThisFile 文件转换服务,支持 PDF 转 Word、HEIC 转 JPG、MP4 转 MP3、CSV 转 JSON、EPUB 转 MOBI 等 999 条转换路线,覆盖图片、视频、音频、文档、数据、字体、电子书与压缩包等类别,且无需注册账号或申请 API Key。阅读本文后,你将掌握三种调用转换能力的路径(MCP 工具、内置脚本、单条 curl 直连)、如何查询受支持的目标格式,以及 25 MB 上限、频率限制与下载链接过期等关键约束的应对方式,并理解内置脚本在安全性(路径校验、格式白名单)与可靠性(JSON-RPC 载荷构造、错误回显)上的实现细节。

技能概览:一个 Skill 包装一个免注册的转换服务

file-conversionfile-conversion 插件下的一个 Agent Skill,其入口定义见 SKILL.md 的 YAML Frontmatter:

---
name: file-conversion
description: Convert files between formats — PDF to Word, HEIC to JPG, MP4 to MP3, CSV to JSON, EPUB to MOBI, and 999 total routes across images, video, audio, documents, data, fonts, ebooks, and archives. Free via changethisfile.com, no API key or signup. Use when the user needs a file converted to a different format.
---

其中 description 承担双重职责:既是元数据供 Agent 匹配激活条件("Use when the user needs a file converted to a different format"),也提前声明了能力边界——999 条转换路线、免费、无需 API Key。这与仓库中 Agent Skills 的渐进式披露架构 一致:Frontmatter 作为元数据始终加载,具体操作指令在技能被激活时才读取。

技能依赖的服务侧转换由 FFmpeg、LibreOffice、Calibre、7-Zip、sharp、Ghostscript 等后端引擎完成,转换在服务端执行,上传文件会在 24 小时内被删除——这意味着不需要在本地安装任何转换引擎,也无需担心文件长期留存。

在插件市场中,该插件的定位是工具类插件,plugins.md 插件目录 将其描述为 "Convert files across 1,000+ format pairs",对应条目也登记在 .claude-plugin/marketplace.json 中。安装方式与其他插件一致:

/plugin marketplace add wshobson/agents   # 注册市场目录(不加载任何内容)
/plugin install file-conversion           # 安装该插件(包含其 skills)

若只想单独获取此技能而不安装整个插件,可使用 Agent Skills 安装器(详见 harnesses.md 的 Skills-only 安装说明):

gh skill install wshobson/agents file-conversion             # GitHub CLI 2.90+
npx skills add wshobson/agents --skill file-conversion       # vercel-labs/skills

决策顺序:三条路径按优先级选择

SKILL.md 给出了明确的调用决策顺序,Agent 在收到转换请求时按以下优先级选择实现方式。

1. 优先使用 MCP 工具

如果环境中已经存在 ChangeThisFile 的 MCP 工具(changethisfile:convert_filechangethisfile:list_conversions),直接调用它们,这是最干净、最可靠的方式。convert_file 工具接收的参数为:

  • source_urlbase64_content + source_format(二选一作为输入来源);
  • target_format(目标格式);
  • 返回一个临时的下载 URL。

list_conversions 用于查询支持的转换路线,与下文"发现支持的转换路线"一节共用同一组方法名。

2. 否则使用内置脚本(需能访问 changethisfile.com)

没有 MCP 工具时,使用技能自带的 Bash 脚本,其相对路径指向本技能目录下的 scripts/convert.sh

scripts/convert.sh <input-file> <target-format> [output-file]
# 示例:scripts/convert.sh report.docx pdf
# 成功时打印输出文件路径

脚本会 base64 编码输入文件,通过纯 HTTPS 调用托管在 changethisfile.com 的 MCP 端点,下载转换结果并写到输入文件同目录(或写入可选的 [output-file])。

3. 远程文件:一条 curl 直接完成

如果你手里只有文件的 URL(而非本地文件),可以跳过下载再上传的过程,直接用一条 curl 完成:

curl -sS -X POST https://changethisfile.com/mcp \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"convert_file","arguments":{"source_url":"<FILE_URL>","target_format":"pdf"}}}'

响应文本中包含一个下载 URL,用 curl -o <output> 拉取即可。注意这里与本地文件路径的区别:传入的是 source_url 而非 base64_content,服务端直接抓取该 URL 指向的文件进行转换。

内置脚本源码剖析:从 base64 到下载落盘

scripts/convert.sh 是实现第 2 条路径的具体代码。逐段阅读可以还原一次完整转换的调用链,也能看到脚本针对多 MB 级载荷与安全边界做的工程化处理。

入口与参数校验

脚本以 set -euo pipefail 开启严格模式,端点和参数的定义如下:

ENDPOINT="${CHANGETHISFILE_MCP_URL:-https://changethisfile.com/mcp}"
IN="${1:-}"; TARGET="${2:-}"; OUT="${3:-}"
  • 端点地址支持通过环境变量 CHANGETHISFILE_MCP_URL 覆盖,默认指向 https://changethisfile.com/mcp
  • 缺少输入文件或目标格式时输出 usage 并退出码 2;
  • 输入文件不存在时报 input file not found 并退出码 2。

25 MB 上限的本地前置检查

SIZE=$(wc -c < "$IN" | tr -d ' ')
if [ "$SIZE" -gt 25000000 ]; then
  echo "error: file is $((SIZE / 1048576))MB — free limit is 25MB. Get a free API key for larger files: https://changethisfile.com/docs/authentication" >&2
  exit 3
fi

在发起任何网络请求前先用 wc -c 测量字节数,超过 25000000 字节(约 25 MB)直接退出码 3,避免把注定失败的大文件白白上传。这与 SKILL.md 中"Max input: 25 MB (free path)"的限制完全对应——更大的文件需要免费 API Key(每月 1000 次转换额度)并改用 POST /v1/convert 接口。

目标格式白名单与输出路径防穿越

这是脚本中安全意味最浓的两处设计:

TARGET=$(printf '%s' "$TARGET" | tr '[:upper:]' '[:lower:]' | sed 's/^\.//')
case "$TARGET" in
  *[!a-z0-9]*|'') echo "error: invalid target format: '$2' (use a plain extension like pdf, mp3, docx)" >&2; exit 2 ;;
esac

目标格式被强制小写、去掉前导点号,并只允许 a-z0-9 字符,否则拒绝。注释里写明了动机:TARGET 随后会进入 JSON 载荷,若不校验,就可能把路径或 JSON 元字符"走私"到下游请求中。从源码注释看,这是刻意的防御性设计。

输出路径同样被约束:

if [ -n "$OUT" ]; then
  case "$OUT" in
    /*|~*|*../*|*/..|..) echo "error: output path must be relative and must not contain '..': $OUT" >&2; exit 2 ;;
  esac
fi
[ -z "$OUT" ] && OUT="${IN%.*}.${TARGET}"

用户提供的输出路径必须是相对路径且不得包含 ..,因为 OUT 最终会被 curl -o 直接写入——未校验的路径可能覆盖任意文件。自动推导的默认输出则安全地继承输入文件所在目录(${IN%.*}.${TARGET} 即去掉原扩展名、拼上目标格式)。

base64 编码与 JSON-RPC 载荷构造

B64_FILE=$(mktemp)
REQ_FILE=$(mktemp)
RESP_FILE=$(mktemp)
trap 'rm -f "$B64_FILE" "$REQ_FILE" "$RESP_FILE"' EXIT

base64 -w0 < "$IN" > "$B64_FILE" 2>/dev/null || base64 < "$IN" | tr -d '\n' > "$B64_FILE"

三个临时文件分别存放 base64 内容、请求体和响应体,退出时用 trap 清理。编码结果写入文件而非 shell 变量/命令行参数,是因为多 MB 载荷会撞上操作系统的单参数长度上限。base64 -w0 是 GNU 写法,macOS 的 base64 没有 -w 参数,因此用 || 回退到 base64 | tr -d '\n' 保证跨平台可用。

请求体优先用 jq 构造,以保证文件名(任意用户输入,可能含换行、控制符、引号、反斜杠)被正确转义:

if command -v jq >/dev/null 2>&1; then
  jq -n --rawfile b64 "$B64_FILE" --arg src "$SRC" --arg tgt "$TARGET" --arg fn "$BASENAME" \
    '{jsonrpc:"2.0",id:1,method:"tools/call",params:{name:"convert_file",arguments:{base64_content:($b64|rtrimstr("\n")),source_format:$src,target_format:$tgt,filename:$fn}}}' \
    > "$REQ_FILE"

注释说明了两个关键取舍:--rawfile 从文件读取 base64,绕开 --arg 约 128 KB 的单参数限制(对应约 96 KB 以上输入就会超限);rtrimstr("\n") 去掉编码末尾换行。若环境没有 jq,则回退到 printf 构造(shell 内建不占用 argv),并对文件名做可打印 ASCII 清洗(tr -d '"\\' | LC_ALL=C tr -cd '[:print:]')。

发起请求、解析下载 URL 与落盘

HTTP_CODE=$(curl -sS --max-time 300 -o "$RESP_FILE" -w "%{http_code}" \
  -X POST "$ENDPOINT" -H "Content-Type: application/json" --data-binary "@$REQ_FILE")

if [ "$HTTP_CODE" != "200" ]; then
  echo "error: conversion service returned HTTP $HTTP_CODE: $(head -c 300 "$RESP_FILE")" >&2
  exit 4
fi

DOWNLOAD_URL=$(grep -o 'https://changethisfile.com/v1/jobs/download/[A-Za-z0-9_-]*' "$RESP_FILE" | head -1 || true)

请求超时 300 秒,HTTP 状态码非 200 时直接退出码 4 并回显响应前 300 字节。成功响应中用正则提取下载 URL(/v1/jobs/download/<token> 形式);若提取不到,则从响应中捞出 "text":"..." 错误文本(限流、不支持的路线等)回显,退出码 5。最后下载并校验:

curl -sS --max-time 120 -o "$OUT" "$DOWNLOAD_URL"
[ -s "$OUT" ] || { echo "error: download produced an empty file" >&2; exit 6; }
echo "$OUT"

下载同样设超时(120 秒),并检查产物非空,最终把输出文件路径打印到 stdout 供 Agent 继续处理。

发现支持的转换路线

对常见转换可以信任直觉,但如果转换比较冷门(例如某种罕见的字体或档案格式),SKILL.md 明确建议"先问再猜"——通过 list_conversions 工具查询,而不是盲目猜测:

curl -sS -X POST https://changethisfile.com/mcp \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"list_conversions","arguments":{"source_format":"docx"}}}'

传入 source_format 可以列出该源格式的全部合法目标;省略 source_format 则会返回全部 999 条路线的分组汇总。这一步在 Agent 工作流中的价值是避免无谓地构造注定失败的请求,直接拿到服务端认可的合法组合。

限制与错误处理

SKILL.md 列出四个必须遵守的运行约束:

  1. 输入上限 25 MB(免费路径)。更大的文件需要免费 API Key(每月 1,000 次转换额度)并改用 POST /v1/convert
  2. 频率限制 5 次/分钟/IP。遇到 "Rate limit exceeded" 时等待 60 秒后重试一次即可。
  3. "Unsupported conversion: X→Y" 错误。这类错误信息中会列出该源格式支持的合法目标格式,可作为 list_conversions 查询结果的补充线索。
  4. 下载 URL 1 小时后过期。转换完成后应立即下载,之后基于本地文件继续工作,不要持有远程 URL 等待。

对应到脚本行为:限流和"不支持的转换"都会被脚本的下载 URL 解析失败分支捕获并以非零退出码暴露(退出码 5 附带 "text" 中的服务端错误信息),因此 Agent 可以据此区分"重试一次"与"换一个目标格式"两种处置。

环境注意事项

该技能需要出站 HTTPS 访问 changethisfile.com。一个已知的典型限制场景是 claude.ai 的代码执行沙箱默认限制出站流量——在此环境下:

  • 优先使用 MCP 连接器方式(决策顺序第 1 条);
  • 或由用户在该平台 Settings → Capabilities 中放行该域名。

对于其他宿主(Claude Code、Codex、Cursor、OpenCode、GitHub Copilot、Google Antigravity 等),只要终端具备普通出网能力,内置脚本路径即可工作,无需额外配置。完整服务文档位于 https://changethisfile.com/docs/mcp。

在 Agent 工作流中的典型用法

把以上能力拼装起来,一次典型的转换流程是:

  1. 用户提出"把这个 report.docx 转成 PDF";
  2. Agent 依据技能 Frontmatter 的描述自动激活 file-conversion
  3. 检查环境是否有 MCP 工具,有则直接调用 convert_file
  4. 否则调用 scripts/convert.sh report.docx pdf,脚本完成编码、请求、下载,打印输出路径;
  5. 若是远程 URL,则用单条 curl 直连(决策顺序第 3 条);
  6. 遇到 "Unsupported conversion" 时用 list_conversions 查询合法目标并反馈用户;
  7. 遇到限流则等待 60 秒重试一次;
  8. 立即下载结果文件,随后一切操作都基于本地文件进行。

这种"先查工具、再走脚本、最后 curl 兜底"的决策顺序,与仓库整体的插件设计哲学(单一职责、可组合、最小化上下文占用,参见 architecture.md)一脉相承:技能只封装一条最薄的能力边界,把 999 种转换的复杂度全部收敛到服务端,本地 Agent 只需处理编码、请求与落盘三个动作。对需要处理异构文件格式的 Agent 工作流而言,它把"免安装转换引擎、免注册、免密钥"的转换能力直接内建到了可被自然语言触发的技能层中。

【免费下载链接】agents Multi-harness agentic plugin marketplace for Claude Code, Codex, Cursor, OpenCode, GitHub Copilot, and Google Antigravity 【免费下载链接】agents 项目地址: https://gitcode.com/GitHub_Trending/agents24/agents

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值