ganjoor-mcp-server について
ganjoor-mcp-server は、Ganjoor のペルシャ古典詩 API をエージェントや研究者向けに読み取り専用で提供します。44 個のツールで詩人、作品、韻律、朗誦、解説、人物関係を扱い、API キーは不要です。
主な機能
- 01詩人と作品集の閲覧
- 02全文・意味検索による詩の検索
- 03ペルシャ詩の韻律・押韻分析
- 04朗誦と解説の検索
- 05人物関係・家系図の探索
活用シーン
- 01テーマに合うペルシャ詩の検索
- 02詩の韻律や押韻の分析
- 03詩人や歴史上の人物の関係調査
- 04詩の朗誦や解説の検索
MCP 対応
Ganjoor API 向けの読み取り専用 MCP サーバーです。44 個のツールを MCP クライアントに公開し、詩の閲覧、韻律・押韻の分析、関連資料の検索を可能にします。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
44掲載時のツール一覧 · 5 日前に更新
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| page | integer | いいえ | ページ番号。1 から始まります。 |
| page_size | integer | いいえ | 1 ページあたりに返す項目の最大数(1-100、デフォルト 20)。 |
| response_format | enum | いいえ | 出力形式:人が読みやすいテキストは 'markdown'(デフォルト)、機械可読な構造化データは 'json'。markdown | json |
詳細
英語 | فارسی
Ganjoor MCP Server — Ganjoor のペルシャ詩 API 用 Model Context Protocol サーバーです。
エージェントは、詩人や詩集を閲覧し、詩とその詩句を読み、韻律や押韻を分析し、詩人をまたいで返歌をたどり、朗読や注釈を検索し、関連人物や家系図のグラフを調べることができます。
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 が起動します。
以下のバッジをクリックするだけで、Ganjoor MCP サーバーを VS Code ワークスペースにインストールできます。サーバーは .vscode/mcp.json 設定ファイルに自動的に追加されます。
または、.vscode/mcp.json に追加します。
{
"servers": {
"io.github.ehsanghaffar/ganjoor-mcp-server": {
"command": "npx",
"args": [
"-y",
"ganjoor-mcp-server"
],
"env": {}
}
}
}
VS Code CLI:
code --add-mcp '{\"name\":\"io.github.ehsanghaffar/ganjoor-mcp-server\",\"command\":\"npx\",\"args\":[\"-y\",\"ganjoor-mcp-server\"],\"env\":{}}'
Claude Desktop / Cursor
以下のバッジをクリックするだけで、Ganjoor MCP サーバーを Claude Desktop または Cursor アプリにインストールできます。サーバーは MCP 設定に自動的に追加されます。
または、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 を使った対話型セットアップ
- GitHub Copilot CLI を対話モードで開きます。
/mcp addを実行します。- サーバー名に「
io.github.ehsanghaffar/ganjoor-mcp-server」を入力します。 - サーバーの種類を選択します:
- コマンドベースのサーバーには
STDIO - リモートサーバーには
HTTP
- コマンドベースのサーバーには
- 上記の標準設定からコマンド/URLの設定を入力し、ツールを
*に設定します。 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"]
}
}
}
ストリーミング可能な HTTP(リモート/共有デプロイ)
HTTP=true PORT=3000 npm start
MCP エンドポイントは POST /mcp で、GET /health はサーバーとアップストリームの状態を報告します。HTTP トランスポートはステートレスで実行される(リクエストごとに新しいサーバーインスタンスを起動する)ため、水平スケーリングが可能です。デフォルトでは 127.0.0.1 にバインドし、DNS リバインディング攻撃を防ぐために Origin ヘッダーを検証します。ループバック以外のオリジンが必要な場合は、ALLOWED_ORIGINS(カンマ区切り)を設定してください。
MCP Inspector
npm run inspector
Docker
マルチステージの Dockerfile と docker-compose.yml が含まれています。イメージは
node:22-alpine をベースに構築され、コンパイル済みの出力と本番用の依存関係のみが含まれます。
docker compose up --build
Compose ファイルは、http://localhost:3000/mcp でストリーミング可能な HTTP モードのサーバーを起動し、
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 を使う場合
ローカルの Node インストールではなく Docker 経由でサーバーを実行するには:
{
"mcpServers": {
"ganjoor": {
"command": "docker",
"args": ["run", "--rm", "-i", "ganjoor-mcp"]
}
}
}
設定
すべての設定は環境変数で、必須のものはありません。
| 変数 | デフォルト | 用途 |
|---|---|---|
HTTP | (未設定) | true に設定すると、stdio の代わりにストリーミング可能な HTTP でサービスを提供します。 |
PORT | 3000 | HTTP ポートです。 |
HOST | 127.0.0.1 | HTTP のバインドアドレスです。 |
ALLOWED_ORIGINS | (空) | 追加で許可する Origin 値をカンマ区切りで指定します。 |
GANJOOR_API_BASE_URL | https://api.ganjoor.net | アップストリーム API のベース URL です。開発時はローカルの RMuseum インスタンスを指定します。 |
GANJOOR_SITE_BASE_URL | https://ganjoor.net | クリック可能なリンクの作成に使用するフロントエンドのベース URL です。 |
概念
Ganjoor のデータモデルは、3 つの階層で構成されています。これらを正しく理解しているかどうかが、エージェントとのセッションを実りあるものにするか、無駄に終わらせるかの分かれ目です。
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、ガザルは24です。 - 詩 — 1 つのテキストで、数値 ID と
hafez/ghazal/sh494のような URL スラッグで識別されます。 - 詩句 — 半句です。連続する 2 つの詩句で
couplet(versePosition0 と 1)を構成します。
URL スラッグには先頭のスラッシュが必要です。 上流 API は
?url=hafez/ghazal/sh494に対して 404 を返しますが、?url=/hafez/ghazal/sh494なら解決できます。このサーバーが正規化するため、どちらの形式でも使用できます。
ペルシア語のテキストは原文のまま返されます。 右から左に書かれ、韻律を示すためにアラビア文字の発音記号が使われています。ユーザーから明示的に求められない限り、ローマ字に転写したり翻訳したりしないでください。
ツールリファレンス
詩人と詩集
| ツール | 説明 |
|---|---|
ganjoor_list_poets | 略歴、生没年、出身地を含む、公開済みのすべての詩人を取得します。ページネーションに対応しています。 |
ganjoor_get_poet | ID またはスラッグで詩人を取得します。略歴と最上位の書物・セクションも含まれます。 |
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 のガザルを取得します。 |
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 | 詩の構成上のセクション(連、マスナヴィーの区分、三行詩)を取得します。 |
ganjoor_get_section | 詩句と関連セクションを含む、1 つのセクションを取得します。 |
ganjoor_get_related_sections | この詩と同じ韻律と押韻を持つ、ほかの詩のセクションを取得します。 |
ganjoor_get_couplet_sections | 指定した対句がどのセクションに属するかを取得します。 |
ganjoor_get_language_tagged_sections | ペルシア語以外の言語コードがタグ付けされた詩節を取得します。 |
音声朗読
| ツール | 説明 |
|---|---|
ganjoor_search_recitations | 朗読者、詩人、またはカテゴリで朗読を検索します。 |
ganjoor_get_recitation | 音声 URL を含む、1 件の朗読を取得します。 |
ganjoor_get_recitation_sync_info | 音声に合わせて読み進めるための、詩句ごとのタイミング情報を取得します。 |
ganjoor_get_poem_recitations | 1 つの詩について公開されているすべての朗読を取得します。 |
ganjoor_get_category_top_recitations | カテゴリ内で最も多く賛成票を集めた朗読を取得します。 |
人物
| ツール | 説明 |
|---|---|
ganjoor_list_people | Ganjoor のナレッジグラフに登録された歴史上・文学上の人物。 |
ganjoor_get_person | ある人物の略歴、生没年、ゆかりの地。 |
ganjoor_get_person_poems | ある人物のタグが付いた詩。 |
ganjoor_get_person_relations | ある人物の親族関係と所属関係。 |
ganjoor_get_person_family_tree | ある人物を起点とする、つながった親族関係全体。 |
注釈、FAQ、補足資料
| ツール | 説明 |
|---|---|
ganjoor_get_recent_comments | 最近公開された読者の注釈。 |
ganjoor_list_faq_categories | Ganjoor の編集者向け FAQ カテゴリー。 |
ganjoor_get_faq_items | 1 つの FAQ カテゴリーに属するすべての Q&A 項目。 |
ganjoor_get_faq_item | ID で指定した 1 つの FAQ 項目。 |
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 フラグを付けて切り詰めます。
上流の 2 つのエンドポイント(/api/ganjoor/poets と /api/ganjoor/rhythms)はページネーションのパラメーターを無視し、常にコレクション全体を返します。サーバーはこの挙動を検出して、要求された範囲をローカルで切り出すため、すべてのリストツールで page と has_more は正確かつ一貫した値になります。
エラーはプロトコルエラーではなくツールの結果として返され、エンドポイントを示すメッセージと次の手順が提示されます。たとえば、404 の場合は、有効な ID を探すために ganjoor_list_poets を案内します。
使用例
「ハーフェズとはどのような人物ですか?」
ganjoor_get_poet { "url": "hafez" }
「ハーフェズのガザル 494 を見せてください」
ganjoor_get_poem { "url": "hafez/ghazal/sh494", "include_recitations": true }
「ハーフェズの詩のうち、صبر という語を含むのはどれですか?」
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 }
「私の質問について、ハーフェズは何と言っていますか?」
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
コードベース全体では、次の 2 つの規約が採用されています。
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の名前付き作品集を対象としていますが、主要な詩人の一部は含まれていません。Hafez の項目はありません。代わりにinclude_cats: trueを指定してganjoor_get_poetを使うと、各詩人のセクションをルートカテゴリから直接取得できます。 - ページ分割されたエンドポイントには総件数がありません。 上流の API は総件数を報告せずにページ分割するため、総数が不明な場合は
totalを省略します。has_moreは、ページの行数より1つ多く取得して推定します。 - 詩のテキストのカバー範囲は厳選されています。 人物タグ、地理タグ、言語タグはもともと不完全です。通常、結果が空なのはカバー範囲の不足によるものであり、存在しないことの証明ではありません。
- 日付フィールドは近似値の場合があります。 Ganjoor は確度の低い日付にフラグを付けます(
validBirthDate/validDeathDate)。呼び出し元が絞り込みできるよう、ツールはこれらのフラグを公開します。
評価
evaluation/evaluation.xml には、検証済みの回答がある読み取り専用の質問が10件含まれています。各質問に回答するには複数のツール呼び出しが必要で、記録する前にライブ API と照合して確認済みです。
npx tsx tests/verify-evaluation.ts # replays every question through the MCP tools
これらの質問は、単一の検索で答えられるような雑学を意図的に避けています。詩人と世紀を相互に照合し、親族関係のグラフをたどり、詩の韻律をコーパス全体の韻律リストと比較し、引用記録を通じて返歌の連鎖を解決します。
貢献
CONTRIBUTING.md を参照してください。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。