关于 myfigurecollection-api
myfigurecollection-api 是 Python 库和本地 MCP 服务,用于读取 MyFigureCollection.net 的公开数据。它解析公开页面,让 Agent 搜索手办和商店、查条码与商品列表,并读取收藏、用户列表和俱乐部信息。
主要功能
- 01搜索手办并查询条码
- 02读取商品详情和商店列表
- 03浏览收藏和用户列表
- 04获取俱乐部详情与成员
- 05通过 Python 库和 CLI 访问数据
- 06可选归档公开商品页面
适用场景
- 01查询手办的发售资料和规格
- 02查看合作商店的商品价格
- 03通过 JAN 或 UPC 条码查找商品
- 04查看用户收藏或俱乐部成员名单
MCP 相关
通过 stdio 在本地运行,并向 MCP 客户端提供 12 个读取 MyFigureCollection.net 数据的工具。它解析公开 HTML,而非依赖公开 API。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
myfigurecollection-api
安装: pip install myfigurecollection-api · 所有格式和校验和
非官方的 MyFigureCollection.net API:一个 Python 库和本地 MCP 服务,让 Agent 能读取手办数据、收藏、列表和社团。
MFC 没有可用的公共 API。它自己的 API 社团(#349) 八年来一直承诺“API v4 即将推出”。这个软件包改为读取公开的 HTML,并将其转换为类型化模型。
刚接触?简而言之
MyFigureCollection 是互联网上最大的动漫手办和周边目录,多年来一直没有方便程序读取它的好方法。 这个项目让你可以在自己的电脑上解决这个问题。安装一次后,Claude 这样的 AI 助手就能帮你在 MFC 上查找信息:“AmiAmi 上这个手办多少钱?”或“列出 10 月发售的所有 Chiikawa 商品。”
sequenceDiagram
participant You
participant Claude
participant api as mfc-api, on your computer
participant MFC as myfigurecollection.net
You->>Claude: How much is the Alice Carroll figure?
Claude->>api: get_partner_listings(287)
api->>MFC: fetch the item's Buy window
MFC-->>api: HTML
api-->>Claude: AmiAmi · Available · ¥11,980
Claude-->>You: AmiAmi has it in stock for ¥11,980
什么是 MCP? Model Context Protocol 是一种标准接口,用于赋予 AI 助手新的能力。MCP 服务是你电脑上的一个小程序,助手可以调用它。这个服务为你的助手提供 12 种 MFC 能力,从商品搜索到条码查询。只需在配置文件中添加一段代码即可接入,详见将其用作 MCP 服务。
为什么不使用 MFC 的官方 API? 因为它并不存在。该网站自己的 API 社团从 2018 年起就在等它推出。
为什么这不是一个可以访问的网站? Cloudflare 会守护 MFC,并根据 IP 信誉等因素决定谁能访问。它信任来自家用电脑的连接,却不信任服务器,因此托管版本会在几天内被拦截,而在你自己的电脑上运行的副本则能继续工作。整个设计都受这一限制影响。
我需要懂 Python 吗? 安装只需两条终端命令(如下)。之后就由你的助手来操作。
为什么要做这个项目(以及为什么显而易见的方法行不通)
MFC 位于 Cloudflare 之后,它会根据 TLS 指纹拦截请求,而不是根据 user-agent。
无论发送什么请求头,requests、httpx 和 aiohttp 都会收到 403 “Just a moment...” 挑战。
这就是较早的 tenji 抓取工具停止工作的原因:它的解析器甚至没有收到 HTML。
这个软件包使用 curl_cffi,并设置
impersonate="chrome",以重现真实的 Chrome 握手并获得 200 响应。这个选择至关重要。 换成普通的 HTTP 客户端会导致一切无法运行。
这也是它作为本地工具而非托管服务发布的原因: Cloudflare 会衡量 IP 信誉,因此运行在数据中心 IP 上的抓取工具会触发验证,并连带影响所有人共用的 IP 地址。请在自己的电脑上运行它。
flowchart LR
A["requests / httpx / aiohttp<br/>(any headers you like)"] -->|"403 Just a moment..."| CF{Cloudflare}
B["Your browser"] -->|200| CF
C["mfc-api via curl_cffi<br/>(Chrome TLS handshake)"] -->|200| CF
CF --> MFC[("myfigurecollection.net")]
安装
需要 Python 3.10+。该软件包已发布到 PyPI:
pip install myfigurecollection-api
在 Mac 上,python3 通常是 Xcode 自带的 3.9,无法运行此代码,因此请明确指定解释器(例如 pip3.12)。如果直接使用克隆的仓库,请运行 pip3.12 install -e .。
然后检查是否安装成功:
mfc-api item 287
如果找不到 mfc-api,说明 shell 的 python3 bin 目录不在 PATH 中。使用 python3.12 -c "import sysconfig; print(sysconfig.get_path('scripts'))" 查找脚本,然后使用该绝对路径。
将其用作 MCP 服务
不带参数运行 mfc-api 会通过 stdio 启动 MCP 服务。将以下内容添加到 MCP 配置中 —
Claude Desktop 的 ~/Library/Application Support/Claude/claude_desktop_config.json,或
Claude Code 项目中的 .mcp.json:
{
"mcpServers": {
"myfigurecollection": {
"command": "uvx",
"args": ["myfigurecollection-api"]
}
}
}
这需要安装 uv;首次运行时,uvx 会从 PyPI 获取该软件包,因此无需进行其他设置。
没有 uv?将 command 指向已安装脚本的绝对路径,例如
/Library/Frameworks/Python.framework/Versions/3.12/bin/mfc-api。路径必须是
绝对路径,因为 MCP 客户端启动服务时使用的 PATH 非常精简,不包含 shell 的 Python bin 目录 —
即使 "command": "mfc-api" 在终端中能正常运行,也会失败。
工具
| 工具 | 返回内容 |
|---|---|
get_item(item_id) | 完整条目:类别、图片、来源、角色、公司、艺术家、发售记录(日期/版本/价格/条形码)、比例、高度、评分、拥有者数量 |
search_items(query, page, category_id) | 每页 50 个条目,支持分页 |
search_by_barcode(barcode) | 按 JAN/UPC 查找条目 — 用于跨商店匹配条目的连接键 |
get_partner_listings(item_id) | 哪些合作商店在售该条目,以及库存情况和价格 |
get_shop(shop_id) | 主页、位置、配送、评分、评论和条目数量 |
search_shops(keywords, page, average_score, partners_only) | 商店目录,每页 10 家 |
get_profile(username) | 加入日期、访问量、等级、简介字段、各类别收藏数量 |
get_collection(username, status, page) | 每页 50 个条目;status 为 owned、ordered、wished 或 favorites |
get_user_lists(username, page) | 用户发布的条目列表 |
get_list(list_id, page) | 列表的所有者、描述、标签和条目 |
get_club(club_id) | 描述、主题、近期评论、工作人员、成员 |
get_club_members(club_id, page) | 完整成员名单 |
get_club 是新增功能 — tenji 从未提供过此功能。
关于商店数据的两点说明
只有 MFC 记录了条形码的条目才有价格。 get_partner_listings 会返回所有合作商店,但 MFC 只能查询已记录 JAN 的条目的实际库存。对于没有条形码的条目,32 家合作商店都会返回 maybe_available,且没有价格。
这表示“未查询”,不是“有库存”。 请按 availability == "available" 进行筛选。
search_by_barcode 是查找功能,不是搜索功能。 已知条形码会在 item 下返回完整条目,并带有 matched: true。未知条形码会返回 matched: false — 其中也包括真实存在但 MFC 从未记录过的条形码,西方发行版本中这种情况很常见。
配置
| 环境变量 | 默认值 | 含义 |
|---|---|---|
MFC_API_RATE_LIMIT | 1.0 | 请求间隔秒数 |
MFC_API_CACHE_TTL | 3600 | 缓存有效期(秒);0 表示禁用 |
MFC_API_CACHE_DIR | ~/.cache/mfc-api | 缓存页面的存放位置 |
MFC_API_LOG_LEVEL | WARNING | 服务日志级别(日志输出到 stderr) |
将其用作库
from mfc_api import MFCClient, CollectionStatus
with MFCClient() as mfc:
item = mfc.get_item(287)
print(item.name) # Aria - Alice Carroll - Maa - 1/6 (Toy's Works)
print(item.releases[0].price) # 6980.0
print([c.name for c in item.characters]) # ['Alice Carroll', 'Maa']
collection = mfc.get_collection("Climbatize", status=CollectionStatus.OWNED)
print(collection.stats.owned, collection.pagination.total_pages)
# Walk every page, politely (one request per second)
for page in mfc.iter_collection("Climbatize", max_pages=3):
print(page.pagination.current_page, len(page.items))
查询某个来源或角色下的所有内容(仅限库和 CLI — 不是 MCP 工具):
with MFCClient() as mfc:
page = mfc.get_entry_items(237138) # Chiikawa, oldest first, 50 per page
print(page.pagination.total_items) # 7247
item = mfc.get_item(page.items[0].id)
print(item.picture_large) # full-size upload/items/2/ picture
Item.picture 是 256px 预览图;Item.picture_large 是原始上传图片。
transport.get_bytes(url) 会通过同一个速率限制器获取图片,遇到 429 时会抛出携带 retry_after 的 MFCRateLimitedError,而不是重试。
输入条形码,获取价格:
from mfc_api import MFCClient
with MFCClient() as mfc:
match = mfc.search_by_barcode("4543341130624")
if match.matched:
for listing in mfc.get_partner_listings(match.item.id).available:
print(listing.shop_name, listing.price, listing.currency) # AmiAmi 11980.0 JPY
从 shell 中使用
mfc-api item 287
mfc-api barcode 4543341130624
mfc-api listings 287
mfc-api shops Japan --partners
mfc-api collection Climbatize --status owned --page 2
所有内容都会以 JSON 格式输出到 stdout;日志输出到 stderr。mfc-api --help 会列出所有子命令。mfc-api-cli 仍作为别名保留。
将条目页存档到 Wayback Machine
今天读到的价格或商品列表,明天可能就无法引用了:页面会发生变化,而且没人必须相信你所说的内容。archive=True 会将公开条目页提交给 Internet Archive 的 Save Page Now,并将结果附加到条目上。
with MFCClient() as mfc:
item = mfc.get_item(287, archive=True)
print(item.releases[0].price, item.archive.wayback_url)
# 6980.0 https://web.archive.org/web/20260903081500/https://myfigurecollection.net/item/287
一个钩子带来三项收获:价格历史序列会在日常读取中逐渐累积,每一行都可由不信任你的人审计,而且数据能留存下来。最后一点并非假设——tenji 已停运,Mandarake 于 2026 年 9 月陷入瘫痪。
绝不会影响读取。 失败会记录为一行,而不是抛出异常:item.archive.status 的值为 success、already(近期已有快照,因此 Archive 拒绝再次创建——这仍算成功保存)、skipped、pending 或 failed,并附带 reason。即使 Internet Archive 宕机,你仍然能获取条目。
绝不存档任何个人信息
MFC 上大多数内容都与个人有关。is_public_item_url 是针对 /item/<id> 的白名单,且 URL 不得带有查询字符串,因此个人资料、收藏集、用户列表和社团名册都会在发出任何请求之前被拒绝:
mfc.snapshot("https://myfigurecollection.net/item/287") # captured
mfc.snapshot("https://myfigurecollection.net/profile/someone") # skipped, never sent
特意使用白名单而非黑名单:这样,新增的个人 URL 格式不会因为规则只列出需要保留的内容而意外泄露。
这是有原因的选择加入功能
读取默认使用 archive=False。存档应当作为一个独立、审慎的流程,用于处理你真正关心的条目,而不是放在对延迟敏感的循环中执行:
- 每周一次。 JSON 账本会记录每个 URL 上次存档的时间;最近 7 天内存档过的内容会跳过,不发出请求。每周一次足以追踪价格曲线,也能减少对 Archive 和 MFC 的影响。提交时还会附带
if_not_archived_within=7d,因此即使账本丢失,Archive 也会执行同样的时间间隔限制。 - 串行处理,每 6 秒一次,每次运行最多 50 个,并遵循 429 响应中的
Retry-After。
| 设置 | 作用 |
|---|---|
MERCH_ARCHIVE=0 | 紧急开关——禁用进程中的所有快照。与同系列的 merch 客户端共享,因此一次批量运行中只需设置一个变量,即可关闭所有存档。 |
MERCH_ARCHIVE_LEDGER | 账本路径,与同系列的客户端共享,使一次流程能为每个 URL 保持统一可靠的存档间隔。 |
MFC_ARCHIVE_LEDGER | 仅供此软件包使用的账本路径。默认值:<cache dir>/archive-ledger.json。 |
IA_ACCESS_KEY / IA_SECRET_KEY | Internet Archive S3 密钥。可从 archive.org/account/s3.php 免费获取。在 macOS 上,也会从 Keychain 服务 ia-s3-access / ia-s3-secret 中读取。 |
缺少凭据时,结果会是 status="failed",并附带说明如何修复的原因——不会崩溃,也不会静默地什么都不做。
每次处理流程创建一个 Archiver 并重复使用(客户端会替你完成此操作),这样速率限制器和每次运行的数量上限就会应用于整个批次,而不会在每次处理时重置。
做一个守规矩的用户
- 默认在整个进程范围内限制为每秒 1 个请求。
- 响应会在磁盘缓存一小时,因此重复的 Agent 调用不会产生额外开销。
- 只读。没有登录、写入或投票操作,也不计划添加这些功能。
- Wayback 快照需主动选择启用,每个 URL 每周最多一次,每次运行设有数量上限,且仅限
/item/<id>页面——绝不存档个人资料、收藏集、列表或社团页面。
如果你对 MFC 的抓取频率高到引人注意,Cloudflare 就会开始质询你的 IP,而你会让所有人的使用体验都变差。不要这样做。
测试
python3 -m pytest
默认测试完全离线——解析器测试会读取于 2026 年 7 月 30 日保存的 HTML 样例。访问线上站点的测试标记为 live,默认不运行:
python3 -m pytest -m live
当 MFC 的标记可能发生变化时运行这些测试;它们是预警信号。
致谢
解析器架构——每个页面对应一个解析器类,接收 HTML 并返回一个
模型——移植自 Nate Shoffner(MIT)开发的
tenji。选择器并非如此:自 tenji 上次发布以来,MFC 的模板已发生变化。tenji 使用的两个端点已彻底失效
(itemlists.v4.php 现在会返回 404),而收藏、个人资料、列表和商店页面的标记也都与它预期的不同。
tenji 有一项内容原样保留了下来:Buy 窗口仍然是向
/item/{id} 发送带有 commit=loadWindow&window=buyItem 的表单 POST 请求,并以 JSON 作答。这个发现来自 tenji,到 2026 年仍然有效。
tenji 的 MIT 声明全文收录于 NOTICE,并附有对哪些内容源自 tenji、哪些没有的准确说明。
免责声明
非官方项目。与 MyFigureCollection.net 或 Tsuki Board 无关,也未获其认可或支持。 本项目会抓取公开页面,MFC 一旦更改 HTML,本项目就可能失效。物品数据归 MFC 及其贡献者所有。
采用 MIT 许可证,详见 LICENSE。
由 Sara Kay 开发。
mcp-name: io.github.ssskay/myfigurecollection-api
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。