MyAnimeList API代理服务

一个将MyAnimeList v2 API转换为MCP协议的Cloudflare Worker,支持读写操作和OAuth 2.0认证,可用于查询和更新动漫、漫画列表。

  • by Leander-Andersen
  • TypeScript
  • 本地部署
  • 1 星标
  • 更新于
在 GitHub 查看 Leander-Andersen/mal-mcp-worker

使用说明

MAL MCP工人

Cloudflare Worker暴露 MyAnimeList v2 API 作为完整的读/写 MCP(模型上下文协议) 使用OAuth 2.0身份验证的服务器。

将其连接到Claude.ai(或任何MCP客户端)并询问以下问题:

  • “搜索类似于《攻击泰坦》的动漫”
  • “MAL有史以来十大动漫是什么?”
  • “2025年春季有什么节目?”
  • “显示我完成的动画列表和分数”
  • “Mark Fullmetal炼金术士:兄弟会以10分完成”
  • “将牛仔Bebop添加到我的计划观察名单中”

MCP工具

所有工具都需要OAuth登录—— /mcp 端点为未经身份验证的请求返回401,这会自动触发MCP客户端的登录流。

阅读——动漫

工具 描述 必需参数
mal_search_anime 按关键字搜索动漫 query
mal_get_anime 一个或多个动漫的完整细节(按ID) id 或 ids[]
mal_get_rankings 按排名类型排列的顶级动漫 --
mal_get_seasonal 季节性动漫图表 year, season
mal_get_user_list 公共用户的动漫列表,包括个人分数、开始和完成日期 username

阅读——漫画与轻小说

涵盖漫画、轻小说、长篇小说、漫画、漫画、单镜头和同人小说——检查每个结果 media_type 区分格式。

工具 描述 必需参数
mal_search_manga 按关键字搜索漫画/轻小说 query
mal_get_manga 按ID列出的一个或多个条目的完整详细信息(作者、序列化) id 或 ids[]
mal_get_manga_rankings 按排名类型排列的顶级漫画(使用 novels 轻小说) --
mal_get_user_manga_list 公共用户的漫画列表,包括个人分数、开始和完成日期 username

写

工具 描述 必需参数
mal_update_anime_status 更新状态、分数、观看的剧集、开始/结束日期 anime_id
mal_delete_anime_from_list 从列表中删除动漫 anime_id
mal_update_manga_status 更新状态、分数、已读章节/卷、开始/结束日期 manga_id
mal_delete_manga_from_list 从列表中删除漫画 manga_id
mal_get_my_profile 您的MAL资料和动漫统计 --

笔记: MAL没有漫画的季节图,其配置文件端点仅显示动漫统计数据,因此没有 mal_get_seasonal 或漫画统计等效物。


身份验证的工作原理

工人使用OAuth 2.0和PKCE。每个用户都使用自己的MAL帐户进行身份验证——没有凭据与应用程序共享。

1. MCP client connects → receives 401
2. Client discovers OAuth metadata at /.well-known/oauth-authorization-server
3. Client opens the login page at /oauth/authorize
4. User clicks "Sign in with MyAnimeList" → redirected to MAL
5. User logs in and approves on MAL's own page
6. Worker exchanges the code for MAL tokens, stores them in Cloudflare KV
7. Worker issues a signed session token to the MCP client
8. All subsequent requests use Authorization: Bearer <token>
9. MAL tokens are silently refreshed when they expire (31-day sessions)

用户会话存储在Cloudflare KV中,30天后过期,之后用户只需再次登录即可。


设置

1.注册MAL OAuth应用程序

  1. 登录地址: myanimelist.net
  2. 首选 myanimelist.net/apiconfig → 创建ID
  3. 填写:
    • 应用程序名称:任何你喜欢的
    • 应用程序类型: 网络
    • 应用重定向URL: https://<your-worker>.workers.dev/auth/callback
  4. 复制这两个 客户端ID 和 客户端密钥

在知道工作URL后,您可以稍后添加更多重定向URI。


2.部署Worker

选项A——从该仓库部署(无需本地设置)

  1. 登录地址: dash.cloudflare.com
  2. 工人和页面→ 创建→ 从Git导入
  3. 连接GitHub并选择此仓库
  4. 生成设置:
    • 构建命令: (留空)
    • 部署命令: npx wrangler deploy
  5. 点击 保存和部署

选项B——分叉和自主机

与选项A相同,但首先分叉仓库,让您完全控制自己的更改。

选项C——通过CLI部署

git clone https://github.com/Leander-Andersen/mal-mcp-worker.git
cd mal-mcp-worker
npm install
npm run deploy

3.创建KV命名空间

wrangler kv namespace create MAL_KV
wrangler kv namespace create MAL_KV --preview

将两个ID粘贴到 wrangler.toml:

[[kv_namespaces]]
binding = "MAL_KV"
id = "<prod-id>"
preview_id = "<preview-id>"

或者通过Cloudflare仪表板创建命名空间(工人和页面→ KV → 创建)并将ID粘贴到这两个字段中。


4.设定秘密

在Cloudflare仪表板中: 工人→ 你的工人→ 设置→ 变量与机密→ Add

名称 类型 值
MAL_CLIENT_ID 秘密 来自myanimelist.net/apiconfig
MAL_CLIENT_SECRET 秘密 来自myanimelist.net/apiconfig
SESSION_SECRET Secret 随机64个字符的十六进制字符串(见下文)

生成 SESSION_SECRET --将此粘贴到浏览器控制台中(F12):

Array.from(crypto.getRandomValues(new Uint8Array(32)))
  .map(b => b.toString(16).padStart(2, '0'))
  .join('')

或者通过CLI:

wrangler secret put MAL_CLIENT_ID
wrangler secret put MAL_CLIENT_SECRET
wrangler secret put SESSION_SECRET

5.更新MAL应用重定向URI

回去 myanimelist.net/apiconfig 并确保重定向URI与部署的worker匹配:

https://<your-worker>.workers.dev/auth/callback

连接到Claude.ai

  1. 打开 Claude.ai → 设置→ 集成→ Add
  2. 输入您的Worker URL:
    https://<your-worker>.workers.dev/mcp
    
  3. Claude将提示您使用MAL帐户登录
  4. 登录页面打开→ click 使用MyAnimeList登录
  5. 批准MAL→ 你已连接。所有8个工具现在都可用。

共享: 任何人都可以将您的工作URL粘贴到他们的MCP客户端,并使用自己的MAL帐户登录。每个用户都有自己的独立会话。


本地开发

cp .dev.vars.example .dev.vars
# Fill in MAL_CLIENT_ID, MAL_CLIENT_SECRET, SESSION_SECRET in .dev.vars

npm run dev   # starts at http://localhost:8787

手动测试OAuth流程:

# Health check (should show version 2.0.0)
curl http://localhost:8787/

# OAuth metadata discovery
curl http://localhost:8787/.well-known/oauth-authorization-server

# Start auth flow (open in browser)
open "http://localhost:8787/oauth/authorize?response_type=code&client_id=test&redirect_uri=http://localhost:9999/cb&state=abc&code_challenge=myverifier&code_challenge_method=plain"

# Exchange code for session token
curl -X POST http://localhost:8787/oauth/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=authorization_code&code=<CODE>&code_verifier=myverifier&redirect_uri=http://localhost:9999/cb"

# Authenticated tool call
curl -X POST http://localhost:8787/mcp \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <TOKEN>" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"mal_get_my_profile","arguments":{}}}'

建筑

src/index.ts    — Request routing, CORS, Env interface, session resolution
src/auth.ts     — OAuth 2.0 proxy (authorize, callback, token, revoke, refresh)
src/kv.ts       — Typed Cloudflare KV helpers (sessions, PKCE state, auth codes)
src/mcp.ts      — MCP/JSON-RPC protocol (initialize, tools/list, tools/call)
src/tools.ts    — Tool definitions + dispatch + response formatting
src/mal.ts      — MAL v2 API client (read + write, Bearer token support)
src/version.ts  — Version constant

OAuth端点:

终点 目的
GET /.well-known/oauth-authorization-server RFC 8414 MCP客户端自动发现元数据
GET /oauth/authorize 登录页面→ 将用户重定向到MAL
GET /auth/callback MAL重定向目标--交换代码,存储会话
POST /oauth/token MCP客户端交换会话令牌的身份验证码
POST /oauth/revoke 使会话无效

运输: 流式HTTP(MCP规范2025-03-26)——客户端POST JSON-RPC到 /mcp,服务器以SSE响应。


备注

  • 自由奔跑 --Cloudflare Workers+KV免费套餐足以供个人使用
  • 每个用户会话 --每个用户都使用自己的MAL帐户进行身份验证;会话是隔离的
  • 秘密从不在源头 --所有凭据都是在运行时注入的Cloudflare机密
  • 自动令牌刷新 --MAL访问令牌在过期之前会自动刷新
  • 持续集成 --TypeScript类型检查通过GitHub Actions在每次推送时运行