mcpField
G
ganjoor-mcp-server

ganjoor-mcp-server

本地服务
github.com/ganjoor游戏娱乐75 天前更新

关于 ganjoor-mcp-server

ganjoor-mcp-server 将 Ganjoor 波斯古典诗歌 API 提供给 Agent 和研究者,支持只读浏览与分析。其 44 个工具覆盖诗人、作品、韵律、朗诵、注释及人物关系,无需 API 密钥。

主要功能

  1. 01浏览诗人与诗歌集
  2. 02全文及语义诗歌搜索
  3. 03分析波斯诗歌韵律与押韵
  4. 04查询朗诵与注释
  5. 05探索人物关系与家谱图

适用场景

  1. 01查找特定主题的波斯诗歌
  2. 02分析诗歌格律和押韵
  3. 03研究诗人及历史人物关系
  4. 04检索诗歌朗诵与评论

MCP 相关

这是面向 Ganjoor API 的只读 MCP 服务,提供 44 个工具供 MCP 客户端浏览诗歌数据、分析韵律与押韵,并查询相关资料。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"ehsanghaffar-ganjoor": {
"command": "npx",
"args": [
"-y",
"ganjoor-mcp-server"
]
}
}
}
启动命令npx -y ganjoor-mcp-server

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
npmganjoor-mcp-server0.1.1

工具

44

收录的工具列表 · 更新于 5 天前

参数类型必填说明
pageinteger否页码,从 1 开始。
page_sizeinteger否每页最多返回的项目数(1-100,默认值 20)。
response_formatenum否输出格式:'markdown' 表示适合人类阅读的文本(默认值),'json' 表示适合机器读取的结构化数据。markdown | json

详细介绍

GANJOOR MCP SERVER:Ganjoor(گنجور)波斯古典诗歌 API 的 MCP 服务

版本:0.1.0 平台:Node >=18.17 许可证:MIT Ganjoor 在 mcprush 上的评分

英语 | فارسی

Ganjoor MCP 服务 — 用于 Ganjoor 波斯诗歌 API 的模型上下文协议服务。

它支持 Agent 浏览诗人和诗集、阅读诗歌及其诗句、进行韵律和押韵分析、追踪不同诗人之间的唱和诗、查找吟诵和评注,以及探索相关人物和家谱图。

44 个工具,只读访问。无需 API 密钥。


目录


安装

需要 Node.js 18.17 或更高版本。

npm install ganjoor-mcp-server # for locally installed stdio transport. no need if using VS Code or Claude Desktop / Cursor.
VS Code

无需安装 npm 包——MCP 服务会在进程内运行,并由 VS Code 在需要时启动。

只需点击下方徽章,即可在 VS Code 工作区安装 Ganjoor MCP 服务。它会自动将该服务添加到你的 .vscode/mcp.json 配置中。

在 VS Code 中安装

或者添加到 .vscode/mcp.json:

{
  "servers": {
    "io.github.ehsanghaffar/ganjoor-mcp-server": {
      "command": "npx",
      "args": [
        "-y",
        "ganjoor-mcp-server"
      ],
      "env": {}
    }
  }
}

VS Code 命令行:

code --add-mcp '{\"name\":\"io.github.ehsanghaffar/ganjoor-mcp-server\",\"command\":\"npx\",\"args\":[\"-y\",\"ganjoor-mcp-server\"],\"env\":{}}'
Claude Desktop / Cursor

只需点击下方徽章,即可在 Claude Desktop 或 Cursor 应用中安装 Ganjoor MCP 服务。它会自动将该服务添加到你的 MCP 配置中。

在 Cursor 中安装

或者添加到你的 MCP 配置文件:

{
  "mcpServers": {
    "io.github.ehsanghaffar/ganjoor-mcp-server": {
      "command": "npx",
      "args": [
        "-y",
        "ganjoor-mcp-server"
      ],
      "env": {},
      "type": "local",
      "tools": [
        "*"
      ]
    }
  }
}
其他客户端
Claude Code

使用 Claude Code CLI 添加 io.github.ehsanghaffar/ganjoor-mcp-server MCP 服务:

claude mcp add io.github.ehsanghaffar/ganjoor-mcp-server npx -y ganjoor-mcp-server
Claude Desktop

按照 MCP 安装指南,使用上面的标准配置。

Codex

创建或编辑配置文件 ~/.codex/config.toml 并添加:

[mcp_servers.ganjoor-mcp-server]
command = "npx"
args = ["-y", "ganjoor-mcp-server"]

更多信息请参阅 Codex MCP 文档。

Gemini CLI

按照 MCP 安装指南,使用上面的标准配置。

OpenCode

请参阅 MCP 服务文档。例如,在 ~/.config/opencode/opencode.json 中:

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "io.github.ehsanghaffar/ganjoor-mcp-server": {
      "type": "local",
      "command": [
        "npx",
        "-y",
        "ganjoor-mcp-server"
      ],
      "enabled": true
    }
  }
}
GitHub Copilot CLI

GitHub Copilot CLI 支持通过交互方式和配置文件添加 MCP 服务。

选项 1:使用 /mcp add 交互式设置
  1. 以交互模式打开 GitHub Copilot CLI。
  2. 运行 /mcp add。
  3. 输入 Server Name:io.github.ehsanghaffar/ganjoor-mcp-server。
  4. 选择 Server Type:
    • STDIO,用于基于命令的服务
    • HTTP,用于远程服务
  5. 根据上面的标准配置填写命令/URL 设置,并将 Tools 设为 *。
  6. 按 Ctrl+S 保存。
选项 2:编辑 ~/.copilot/mcp-config.json
{
  "mcpServers": {
    "io.github.ehsanghaffar/ganjoor-mcp-server": {
      "command": "npx",
      "args": [
        "-y",
        "ganjoor-mcp-server"
      ],
      "env": {},
      "type": "local",
      "tools": [
        "*"
      ]
    }
  }
}

更多信息,请参阅 GitHub Copilot CLI MCP 文档。

GitHub Copilot Coding Agent

GitHub Copilot Coding Agent 可以使用 MCP 服务扩展其功能。请使用专为 Coding Agent 格式化的以下配置:

{
  "mcpServers": {
    "ganjoor-mcp-server": {
      "command": "npx",
      "args": [
        "-y",
        "ganjoor-mcp-server"
      ],
      "env": {},
      "type": "local",
      "tools": [
        "*"
      ]
    }
  }
}

将此配置添加到仓库设置中的 Copilot > Coding agent 下。"tools": ["*"] 设置会启用 MCP 服务提供的所有可用工具。

更多信息,请参阅 GitHub Copilot Coding Agent MCP 文档。

从此源安装
npm install
npm run build
npm start            # stdio transport (default)
VS Code

添加到 .vscode/mcp.json:

{
  "servers": {
    "ganjoor": {
      "type": "stdio",
      "command": "node",
      "args": ["${workspaceFolder}/dist/index.js"]
    }
  }
}
Claude Desktop / Cursor

添加到 MCP 配置文件:

{
  "mcpServers": {
    "ganjoor": {
      "command": "node",
      "args": ["/absolute/path/to/ganjoor-mcp/dist/index.js"]
    }
  }
}
Streamable HTTP(远程/共享部署)
HTTP=true PORT=3000 npm start

MCP 端点为 POST /mcp,GET /health 会报告服务和上游状态。HTTP 传输以无状态方式运行(每个请求都会创建一个新的服务实例),因此可以水平扩展。默认绑定到 127.0.0.1,并会验证 Origin 标头以阻止 DNS 重绑定攻击;如果需要非环回源,请设置 ALLOWED_ORIGINS(以逗号分隔)。

MCP Inspector
npm run inspector

Docker

项目包含多阶段 Dockerfile 和 docker-compose.yml。镜像基于 node:22-alpine 构建,仅包含编译后的输出和生产依赖项。

docker compose up --build

compose 文件会以 streamable HTTP 模式在 http://localhost:3000/mcp 上启动服务,GET /health 会报告服务和上游状态。HOST 设为 0.0.0.0,以便从主机访问发布的端口;下表中的所有配置变量都可作为普通环境变量使用。若要在不使用 compose 的情况下运行单个容器:

docker build -t ganjoor-mcp .
docker run --rm -p 3000:3000 -e HTTP=true -e HOST=0.0.0.0 ganjoor-mcp
通过 Docker 使用 stdio 传输

自行启动服务(而非通过 HTTP 连接)的客户端可以使用 stdio 配置文件,该模式会打开 stdin 作为协议流,且不会启动 HTTP 监听器:

docker compose --profile stdio run --rm ganjoor-mcp-stdio
配合 Claude Desktop 使用

若要通过 Docker 运行服务,而不是使用本地 Node 安装:

{
  "mcpServers": {
    "ganjoor": {
      "command": "docker",
      "args": ["run", "--rm", "-i", "ganjoor-mcp"]
    }
  }
}

配置

所有设置均为环境变量;没有必填项。

变量默认值用途
HTTP(未设置)设为 true 可使用 streamable HTTP,而不是 stdio。
PORT3000HTTP 端口。
HOST127.0.0.1HTTP 绑定地址。
ALLOWED_ORIGINS(空)额外允许的 Origin 值,以逗号分隔。
GANJOOR_API_BASE_URLhttps://api.ganjoor.net上游 API 基础 URL——开发时可指向本地 RMuseum 实例。
GANJOOR_SITE_BASE_URLhttps://ganjoor.net用于生成可点击链接的前端基础 URL。

概念

Ganjoor 的数据模型分为三个嵌套层级。理清这些层级,是高效完成 Agent 会话与徒劳无功的区别。

graph TD
    P["Poet — e.g. Hafez, id 2, slug /hafez"] --> C1["Category — e.g. Ghazals, id 24"]
    P --> C2["Category — e.g. Qeta, id 25"]
    C1 --> M1["Poem — e.g. Ghazal 494, id 2623, /hafez/ghazal/sh494"]
    C2 --> M2["Poem"]
    M1 --> V["Verses (hemistichs, paired into couplets)"]
    M1 --> S["Sections (nested stanzas with metre + rhyme)"]
    M1 --> R["Recitations (audio)"]
    M1 --> CM["Comments (reader commentary)"]
    M1 --> Q["Quoted / related poems"]
  • 诗人 — 作者。Hafez 的诗人 id 为 2,Saadi 为 7,Rumi 为 5,Khayyam 为 3,Ferdowsi 为 4。ganjoor_list_poets 可将姓名解析为 id。
  • 类别 — 诗人作品中的书籍或章节(CatType 0 表示通用类别,1 表示诗歌,2 表示书籍)。Hafez 的根类别是 9;他的 ghazal 类别是 24。
  • 诗作 — 一篇文本,通过数字 id 和 URL slug 标识,例如 hafez/ghazal/sh494。
  • 诗句 — 半行诗。连续两句构成一个 couplet(versePosition 为 0 和 1)。

URL slug 前面需要加斜杠。 上游 API 对 ?url=hafez/ghazal/sh494 返回 404,但可以解析 ?url=/hafez/ghazal/sh494。此服务会为你进行规范化,因此两种形式均可使用。

波斯语文本会原样返回。 文本采用从右向左的书写方向,并使用阿拉伯文字的变音符号来标注韵律。除非用户明确要求,否则不要转写或翻译。


工具参考

诗人与诗集
工具描述
ganjoor_list_poets所有已发布诗人的信息,包括传记、年代和地点。支持分页。
ganjoor_get_poet根据 id 或 slug 获取一位诗人的信息,包括传记和顶层书籍/章节。
ganjoor_get_poets_by_century按历史半世纪分组的所有诗人。
ganjoor_list_books命名诗集,可按诗人或名称子字符串筛选。
类别
工具描述
ganjoor_get_category获取类别及其面包屑导航、子章节和所含诗作。
ganjoor_list_category_poems获取类别中的诗作,支持分页和可选标题筛选。
ganjoor_get_category_geotags获取类别子树下标记的地理/历史地点。
ganjoor_get_category_people_graph获取类别“人物”标签页背后的人物网络。
诗作
工具描述
ganjoor_search_poems在诗作中进行全文搜索,可限定诗人或类别。
ganjoor_semantic_search_poems按含义搜索诗作(“查找一首关于……的诗”)。
ganjoor_get_poem根据 URL 获取完整诗作,并按联句分组诗句。
ganjoor_get_poem_by_id根据数字 id 获取同一内容。
ganjoor_get_poem_verses仅获取诗句,比获取整首诗更轻量。
ganjoor_get_random_poem获取一首随机诗作,可选限定诗人。
ganjoor_get_hafez_faal获取一首随机的 Hafez ghazal,用于波斯占卜。
ganjoor_get_page_url将任意页面 id(诗作、类别、诗人)解析为网页 URL。
ganjoor_get_redirect_url将旧版 Ganjoor URL 解析为当前地址。
韵律、押韵与结构
工具描述
ganjoor_list_rhythms所有波斯诗律及其使用次数。
ganjoor_analyze_poem_rhythm检测诗作的韵律格律。
ganjoor_analyze_poem_rhyme检测诗作的押韵字母和押韵模式。
ganjoor_find_similar_poems查找共享韵律格律和押韵的诗作——应答诗图谱。
ganjoor_get_poem_sections获取诗作的结构段落(联结、masnavi 段、三行诗节)。
ganjoor_get_section获取一个段落及其中的诗句和相关段落。
ganjoor_get_related_sections获取其他诗作中与此段落韵律格律和押韵相符的段落。
ganjoor_get_couplet_sections获取指定联句所属的段落。
ganjoor_get_language_tagged_sections获取标记了非波斯语语言代码的诗节。
音频朗诵
工具描述
ganjoor_search_recitations按朗诵者、诗人或类别搜索朗诵。
ganjoor_get_recitation获取一条朗诵及其音频 URL。
ganjoor_get_recitation_sync_info获取逐句时间信息,以便跟随音频收听。
ganjoor_get_poem_recitations获取为一首诗作发布的所有朗诵。
ganjoor_get_category_top_recitations获取类别中获赞最多的朗诵。
人物
工具描述
ganjoor_list_peopleGanjoor 知识图谱中的历史人物和文学人物。
ganjoor_get_person一个人物的传记、日期和地点。
ganjoor_get_person_poems标记了某个人物的诗歌。
ganjoor_get_person_relations一个人物的亲属关系和隶属关系边。
ganjoor_get_person_family_tree从某个人物出发,获取完整的关联亲属关系网络。
评论、常见问题和补充材料
工具描述
ganjoor_get_recent_comments最近发布的读者评论。
ganjoor_list_faq_categoriesGanjoor 的编辑部常见问题类别。
ganjoor_get_faq_items某个常见问题类别中的所有问答条目。
ganjoor_get_faq_item按 ID 获取单个常见问题条目。
ganjoor_get_poem_images手稿和影印图像。
ganjoor_get_poem_quoted_poems此诗引用的诗歌,以及引用此诗的诗歌。
ganjoor_get_poem_effective_corrections文本修订的编辑前后记录。
ganjoor_get_poem_geotags标记到某首诗的地点和纪念日期。

每个工具都带有 readOnlyHint、idempotentHint 和 openWorldHint 注解,并且它们都不会 修改 Ganjoor 上的状态。


响应格式

每个工具都接受一个 response_format 参数:

  • markdown(默认)——包含标题、列表和可点击链接的易读输出。
  • json ——相同数据,以结构化对象形式返回;也会作为 MCP structuredContent 返回,因此 支持此格式的客户端无需解析文本即可直接读取字段。

列表工具使用统一的分页封装:

{
  "total": 842,
  "count": 20,
  "page": 1,
  "page_size": 20,
  "has_more": true,
  "next_page": 2,
  "poems": [{ "id": 2623, "title": "غزل شمارهٔ ۴۹۴", "full_url": "/hafez/ghazal/sh494" }]
}

page 和 page_size 均从 1 开始;page_size 上限为 100。超过 25,000 个字符的响应会被截断,并明确设置 truncated 标志,而非静默截断。

两个上游端点(/api/ganjoor/poets 和 /api/ganjoor/rhythms)会忽略分页参数,始终返回整个集合。 服务会检测这种情况,并在本地切分出请求的范围,从而确保每个列表工具的 page 和 has_more 都准确且一致。

错误会作为工具结果返回(而非协议错误),并附带指出端点且建议后续操作的消息——例如,404 会引导你使用 ganjoor_list_poets 查找有效 ID。


用法

“Hafez 是谁?”

ganjoor_get_poet { "url": "hafez" }

“给我看看 Hafez 的第 494 首 ghazal”

ganjoor_get_poem { "url": "hafez/ghazal/sh494", "include_recitations": true }

“Hafez 的哪些诗包含 صبر 这个词?”

ganjoor_search_poems { "term": "صبر", "poet_id": 2, "page_size": 10 }

“这首诗采用什么格律?还有谁写过这种格律的诗?”

ganjoor_analyze_poem_rhythm { "poem_id": 2623 }
ganjoor_list_rhythms { "page_size": 100 }
ganjoor_find_similar_poems { "metre": "<rhythm from the previous step>", "page_size": 10 }

“这个人物的祖先有哪些人?”

ganjoor_get_person { "person_id": 22 }
ganjoor_get_person_family_tree { "person_id": 22 }

“Hafez 对我的问题有什么说法?”

ganjoor_get_hafez_faal { }

架构

src/
├── index.ts            # Process entry: stdio or streamable HTTP transport
├── server.ts           # createServer() — registers every tool
├── client.ts           # fetch wrapper, error mapping, pagination helpers
├── types.ts            # TypeScript interfaces for Ganjoor's payloads
├── constants.ts        # Base URLs, limits, server identity
├── schemas.ts          # Shared Zod schemas (pagination, URL slugs, ids)
├── format.ts           # Markdown rendering and formatting helpers
└── tools/
    ├── registry.ts     # defineTool() wrapper: consistent errors + both formats
    ├── poets.ts        # Poet discovery
    ├── categories.ts   # Category browsing
    ├── poems.ts        # Poem retrieval, search, URL resolution
    ├── analysis.ts     # Prosody, rhyme, sections
    ├── audio.ts        # Recitations
    ├── content.ts      # Images, quotations, corrections, geo tags
    └── people.ts       # People graph, comments, FAQ

代码库中贯穿着两项约定:

  • **defineTool() 封装每项注册。**它确保每个工具都以带有可操作消息的 isError 结果报告失败, 以一致的方式呈现 markdown 或 JSON,并在文本之外返回 structuredContent。
  • **md() 用于构建文档。**它保留显式空行,确保 markdown 标题和列表正确分隔,同时移除 null/false,使条件片段能够干净地消失。

上游接口的特殊情况会在 client.ts 和工具模块中规范化,而不会暴露给调用方—— 例如类别端点的 { poet, cat } 封装、诗歌负载中嵌套的 category.cat,以及 URL 参数必须带前导斜杠的要求。


开发

npm run build       # compile to dist/
npm run typecheck   # type-check without emitting
npm test            # live smoke test against api.ganjoor.net
npm run inspect     # print real tool output for review
npm run clean

npm test 会通过内存传输启动服务,断言每个工具都有详尽的描述,并针对在线 API 调用全部 44 个工具;任何错误响应都会导致测试失败。


已知限制

  • 可能禁用语义搜索。 Ganjoor 的嵌入后端是可选的;如果部署时将其关闭,ganjoor_semantic_search_poems 会返回 503。该工具会显示清晰的提示,并建议改用波斯语关键词调用 ganjoor_search_poems。
  • 重定向解析较少。 Ganjoor 只会为实际更改过名称的路径保存重定向,因此大多数有效 URL 返回的都是 has_redirect: false,而不是目标地址。
  • 某些工具始终需要身份验证。 需要 Ganjoor 账户的端点(书签、发布评论、上传更正)按设计不在支持范围内——此服务为只读且匿名。
  • 书目经过筛选。 ganjoor_list_books 涵盖约 168 个有名称的诗集,但未收录一些重要诗人——其中没有哈菲兹的条目。请改用 ganjoor_get_poet 并设置 include_cats: true,该工具会直接从每位诗人的根类别读取其分区。
  • 分页端点不提供总数。 上游 API 仅提供分页结果,不报告总数,因此总数未知时会省略 total;has_more 则通过多获取一条记录来推断。
  • 诗歌文本的标注覆盖经过筛选。 人物标签、地理标签和语言标签本身并不完整——结果为空通常表示覆盖不足,并不能证明相关内容不存在。
  • 日期字段有时是近似值。 Ganjoor 会标记不确定的日期(validBirthDate / validDeathDate);工具会公开这些标记,供调用方筛选。

评估

evaluation/evaluation.xml 包含 10 个带有已验证答案的只读问题。回答每个问题都需要调用多个工具,并且在记录答案前已对照实时 API 进行核验:

npx tsx tests/verify-evaluation.ts   # replays every question through the MCP tools

这些问题刻意避开只需单次查询即可回答的冷知识。它们会交叉比对诗人与世纪、沿亲属关系图谱追溯、将一首诗的格律与全语料的韵律列表进行比较,并通过引用记录解析唱和诗链。


贡献

请参阅 CONTRIBUTING.md。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。