Skip to main content
Glama
brunolm
by brunolm

mal-mcp

一个 模型上下文协议 (Model Context Protocol) 服务器,向 Claude 和其他兼容 MCP 的客户端公开 MyAnimeList v2 API。它使用 TypeScript 编写,可通过 Bun 在本地通过 stdio 运行,或作为托管的多用户服务器部署到 Cloudflare Workers。

工具

设置

  • configure — 仅限 stdio — 存储用户的 MyAnimeList client_id(以及如果已颁发的 client_secret)。必须在任何其他工具之前调用。不在 Worker 上注册;在 Worker 上,每个用户在将服务器添加到其客户端时通过 MCP OAuth 流程登录。

  • authenticate — 仅限 stdio(有意义) — 启动 MAL OAuth 流程;打开浏览器并等待本地回调。在 Worker 上,这是一个为了兼容性而保留的空操作 — 身份验证通过 MCP OAuth 在连接时自动完成。

  • get_auth_status — 检查凭据和用户令牌是否可用。

公共(仅限 Client ID)

  • search_anime — 按标题搜索动漫

  • get_anime_details — 获取动漫 ID 的完整详细信息

  • get_anime_ranking — 排名列表(全部、正在播出、即将播出、电视、OVA、电影、特别篇、按受欢迎程度、收藏)

  • get_seasonal_anime — 按年份 + 季度获取动漫

  • search_manga — 按标题搜索漫画

  • get_manga_details — 获取漫画 ID 的完整详细信息

  • get_manga_ranking — 排名列表(全部、漫画、轻小说、单篇、同人、韩漫、国漫、按受欢迎程度、收藏)

用户范围(需要 OAuth2 访问令牌)

  • get_current_user — 已认证用户的个人资料 + 动漫统计信息

  • get_anime_suggestions — 个性化动漫推荐

  • get_user_anime_list — 读取任何用户的公开动漫列表(或 @me)

  • update_anime_list_status — 添加/更新列表状态、评分、观看集数等。

  • delete_anime_list_item — 从您的列表中删除动漫

  • get_user_manga_list — 读取任何用户的公开漫画列表(或 @me)

  • update_manga_list_status — 添加/更新列表状态、评分、阅读章节数等。

  • delete_manga_list_item — 从您的列表中删除漫画

Related MCP server: Claude Code MCP

选项 1:通过 stdio 在本地运行

1. 安装

bun install

2. 连接到您的 MCP 客户端

添加到 claude_desktop_config.json(Windows: %APPDATA%\Claude\claude_desktop_config.json):

{
  "mcpServers": {
    "mal": {
      "command": "bun",
      "args": ["C:\\BrunoLM\\Projects\\mal-mcp\\src\\index.ts"]
    }
  }
}

对于 Claude Code,请使用 claude mcp add 或将等效块放入 .claude/mcp.json 中。

3. 配置您的 MAL 凭据

在 https://myanimelist.net/apiconfig 创建一个 API 客户端:

  • App Type: other / web

  • App Redirect URL: http://localhost:8765/callback

然后,从您的 MCP 客户端调用 configure 工具并提供您的 client_id(以及如果 MAL 颁发了 client_secret)。凭据将持久化到 ~/.mal-mcp-config.json。

4. (可选) 授权用户范围工具

从您的 MCP 客户端调用 authenticate。浏览器会打开,您批准请求,端口 8765 上的本地服务器捕获重定向,令牌将存入 ~/.mal-mcp-tokens.json。服务器会从那里自动刷新它们。

如果您更喜欢 CLI:

$env:MAL_CLIENT_ID = "your-client-id"
# $env:MAL_CLIENT_SECRET = "your-client-secret"   # only if issued
bun run auth

选项 2:托管在 Cloudflare Workers 上(多用户,MCP OAuth)

单个 Worker 在标准 MCP OAuth 2.1(动态客户端注册)后为每个用户提供服务。所有人使用同一个 URL:https://mal-mcp.<account>.workers.dev/mcp。在登录期间,每个用户提供自己的 MAL client_id(以及如果已颁发的 client_secret);每个用户的状态存储在以这些凭据的哈希值为键的 Durable Object 中。

1. 操作员设置(一次性)

bun install
bunx wrangler login
bunx wrangler kv namespace create OAUTH_KV

将返回的命名空间 id 粘贴到 wrangler.jsonc 中(替换 REPLACE_WITH_KV_ID),然后部署:

bun run worker:deploy

对于本地开发:

bunx wrangler kv namespace create OAUTH_KV --preview
bun run worker:dev

2. 每个用户连接

  1. 在 https://myanimelist.net/apiconfig 创建一个 MAL API 客户端(App Type: other)。将 App Redirect URL 设置为:

    https://mal-mcp.<account>.workers.dev/mal/callback

    (此确切 URL — 对于给定部署的每个用户都相同。)

  2. 将 MCP 服务器添加到您的客户端:

    claude mcp add --transport http mal https://mal-mcp.<account>.workers.dev/mcp

    或者在配置中等效地:

    {
      "mcpServers": {
        "mal": {
          "url": "https://mal-mcp.<account>.workers.dev/mcp"
        }
      }
    }
  3. 您的 MCP 客户端在首次连接时会弹出一个浏览器标签页。Worker 的授权页面会询问您的 MAL client_id(以及如果已颁发的 client_secret),将您重定向到 MyAnimeList 进行批准,然后将您返回到您的 MCP 客户端 — 现在已登录。访问令牌和刷新令牌持久化在您的 Durable Object 中;MAL 访问令牌会自动刷新。

托管部署的安全说明

  • Worker 是 MCP 的自有 OAuth 2.1 授权服务器。颁发给您 MCP 客户端的 Bearer 令牌仅限于您使用;泄露一个令牌会让持有者代表您调用 MAL,直到令牌过期。

  • 不同的 MAL 凭据 → 不同的 Durable Object → 完全独立的状态。不存在跨用户共享状态。

  • Worker 本身不持有任何 MAL 凭据;每个用户提供自己的 MAL API 客户端。

数据存储

stdio

主目录中的两个纯文本 JSON 文件,以 0600 模式创建(仅限所有者读/写):

文件

内容

~/.mal-mcp-config.json

您的 MAL client_id 和(如果已颁发)client_secret。

~/.mal-mcp-tokens.json

authenticate 之后的 MAL access_token、refresh_token 和 expires_at。

删除任一文件以重置相应状态。除了 myanimelist.net 和 api.myanimelist.net 之外,不会向任何地方发送任何内容。

托管 Worker

两个 Cloudflare 存储表面:

OAUTH_KV (Workers KV 命名空间) — 由 @cloudflare/workers-oauth-provider 和 MAL 授权中继使用:

  • 已注册的 OAuth 客户端(动态客户端注册)、授权许可和访问/刷新令牌。提供程序将许可 props 加密存储;加密密钥被封装到颁发的令牌本身中,因此仅凭 KV 快照不足以恢复 props。

  • 短期(10 分钟 TTL)待处理 MAL 授权记录,以随机状态字符串为键。每条记录包含待处理的授权 URL、您的 MAL client_id/client_secret、PKCE 验证器和回调 URL。条目一旦被 MAL 回调消耗就会被删除,否则会自动过期。它们以 纯文本 JSON 存储在 KV 中。

MAL_SESSION (Durable Object,每个用户一个) — 以 u:<32-hex> 为键,其中 hex 是 sha256("v1:" + mal_client_id + ":" + (mal_client_secret ?? "")) 的前 32 个字符。以纯文本形式存储在 DO 的 SQLite 存储中(Cloudflare 在磁盘上对 DO 存储进行静态加密):

  • config: 您的 MAL client_id 和(如果已颁发)client_secret。

  • tokens: MAL access_token、refresh_token、expires_at。

两对不同的 MAL 凭据产生两个不同的哈希值 → 两个完全独立的 Durable Object,没有共享状态。

未存储的内容: 动漫/漫画列表、用户个人资料数据、搜索结果或从 MAL 返回的任何其他内容 — 这些内容在请求时直接流经请求。没有分析,没有超出标准 Cloudflare 可观测性指标之外的请求内容日志。

传输的内容: MAL client_id/client_secret 作为表单字段从您的浏览器通过 HTTPS 提交到授权页面。MAL 访问令牌作为 Authorization: Bearer … 转发到 api.myanimelist.net。

重置用户状态: 从您的 MCP 客户端撤销许可(或重新连接),或联系操作员删除匹配的 Durable Object。使用相同的 MAL 凭据重新授权将重用相同的 DO 及其现有令牌。

环境变量(仅限 stdio)

变量

必需

用途

MAL_CLIENT_ID

否

如果尚未保存任何内容,则在首次启动时为 stdio 配置存储提供种子。

MAL_CLIENT_SECRET

否

同上,适用于已颁发密钥的客户端。

MAL_AUTH_PORT

否

一次性 OAuth 回调监听的端口(默认 8765)。

在托管的 Worker 部署中,不使用这些环境变量;每个最终用户在 MCP OAuth 登录期间通过 Worker 的授权页面提供自己的 MAL 凭据。

开发

bun run dev              # stdio, watch mode
bun run worker:dev       # Worker, local (miniflare)
bun run typecheck        # tsc --noEmit

所有工具都接受一个可选的 fields 字符串,该字符串直接传递给 MAL — 如果您需要覆盖默认值,请参阅 字段规范。

Related MCP Connectors

Related MCP Servers