关于 AskSakina Islamic Knowledge
AskSakina Islamic Knowledge 是供 AI Agent 和客户端查阅精选伊斯兰文本的参考服务,提供《古兰经》经文、祈祷词和真主的 99 个尊名,并附呈现指引及危机处理。它是资料库,不提供宗教咨询。
主要功能
- 01按章节经文编号或主题查经文
- 02按生活情境查找祈祷词
- 03查询真主的 99 个尊名
- 04提供学习提示词和参考资源
- 05附带呈现指引与危机资源
适用场景
- 01检索含阿拉伯文和译文的经文
- 02查找适合某种生活情境的祈祷词
- 03在学习过程中了解真主的尊名
- 04对危机相关查询仅返回求助资源
MCP 相关
通过 MCP 提供四种查询工具、四个学习旅程提示词和七项资源。响应附带元数据及供调用 Agent 使用的呈现指引。
配置
远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。
https://sakina-mcp.fly.dev/mcpclaude mcp add --transport http com-asksakina-islamic-knowledge https://sakina-mcp.fly.dev/mcp{"mcpServers":{"com-asksakina-islamic-knowledge":{"type":"http","url":"https://sakina-mcp.fly.dev/mcp"}}}在 Cursor 中打开{"servers":{"com-asksakina-islamic-knowledge":{"type":"http","url":"https://sakina-mcp.fly.dev/mcp"}}}在 VS Code 中打开{"mcpServers":{"com-asksakina-islamic-knowledge":{"type":"http","url":"https://sakina-mcp.fly.dev/mcp"}}}{"mcpServers":{"com-asksakina-islamic-knowledge":{"serverUrl":"https://sakina-mcp.fly.dev/mcp"}}}命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。
工具
4| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| ayah | integer | 是 | 苏拉中的阿耶(经文)编号 |
| surah | integer | 是 | 苏拉编号,1–114 |
| locale | enum | 否 | 译文区域设置;默认值为 "en"(Pickthall)。目前尚无乌尔都语和印度尼西亚语译文:"ur" 和 "id" 会返回附带说明的 Pickthall 英语译文。en | id | ur | ar |
| audience | enum | 否 | 可选:curious、revert 或 practising。有可用内容时,返回预先编写的教学背景;省略时返回标准记录。curious | revert | practising |
详细介绍
AskSakina 伊斯兰知识 MCP 服务
经专业 AI 审核的伊斯兰知识,供 AI Agent 使用。 古兰经经文、精选的祈祷词语料库,以及安拉的 99 个尊名——由 AskSakina 的结构化专业 AI 审核链依据逊尼派四大主流学派(哈乃斐派、马立克派、沙斐仪派、罕百里派)进行审核,但这不能替代合格学者的指导。每条回复都附带展示约定,防止 Agent 在不知不觉中歪曲内容。
架构理念: “AskSakina 提供记录,Agent 给出答案。” 该服务是参考资料库,而非顾问。每条回复都包含一个 _sakina_meta 信封,其中含有免责声明、大模型指令、展示约定和教育背景。调用该服务的 Agent 如何处理记录,由其自行负责:每条回复都附带明确的处理说明,但服务无法让其他 AI 遵循这些说明。
提供的内容
通过模型上下文协议提供四个查询工具、四个学习旅程提示词和七项资源。所有记录均来自 AskSakina 主应用(asksakina.com),因此每个 MCP 版本都与其构建时公开应用所呈现的内容一致。
| 工具 | 功能 |
|---|---|
get_quran_verse | 按 surah:ayah 查询古兰经经文原文 |
get_dua | 按生活情境(焦虑、早晨、旅行等)查询精选祈祷词语料库 |
get_name_of_allah | 按编号(1–99)或字符串查询 99 个尊名之一 |
find_verses | 根据主题关键词,从 AskSakina 的主题经文索引中查找古兰经经文 |
understand_a_verse(提示词) | 按 surah 和 ayah 获取一节经文,然后结合其教学注释(如有)进行介绍 |
explore_names_of_allah(提示词) | 按编号获取一个尊名(未提供编号时默认为 1),然后介绍该尊名并提供下一个尊名 |
what_muslims_believe(提示词) | 古兰经《忠诚章》、尊名 Ar-Rahman、经审核的信仰纲要与五功介绍,以及古兰经 2:256 |
first_steps_new_muslim(提示词) | 为新穆斯林提供循序渐进的指引(1-4):独一的真主与祂的慈悯、过去的罪过已获宽恕、一步步学习礼拜、你的社群 |
sakina://about(资源) | 阅读一次即可的简报——七项核心指令,以及三篇经 Gem 审核的宣教文本(古兰经的保存、圣训分级、学派归属) |
sakina://learn/...(资源,2.5.0) | 提供两段学习旅程所用的六篇经审核文本原文 |
工具
get_quran_verse
按 surah:ayah 查询古兰经经文原文。返回标准 AskSakina 信封,包含阿拉伯语文本、译文、章名(阿拉伯语和英语),以及 quran 展示约定;该约定指示 Agent 不得改述、必须注明 surah:ayah,并将译文标注为“意义译文”。
参数
| 名称 | 类型 | 必填 | 说明 |
|---|---|---|---|
surah | 1..114 | 是 | 章编号 |
ayah | 1..286 | 是 | 章内经文编号 |
locale | 'en' | 'id' | 'ur' | 'ar' | 'tr' | 否,默认为 en | 译文语言。ar 返回阿拉伯语原文及匹克索尔英语译文。乌尔都语、印度尼西亚语和土耳其语译文尚未提供(等待授权):ur、id 和 tr 会返回匹克索尔英语译文、translation_language: "en",以及说明这一情况的 translation_note |
响应示例(已截断)
{
"_sakina_meta": {
"version": "1.0",
"content_type": "quran_verse",
"presentation_contract": {
"quran": {
"no_paraphrase": true,
"require_citation": "surah:ayah",
"translation_label": "Translation of the Meaning"
}
}
/* … */
},
"content": {
"surah": { "number": 2, "name_arabic": "البقرة", "name_english": "Al-Baqarah" },
"ayah": 186,
"arabic": "وَإِذَا سَأَلَكَ عِبَادِي عَنِّي فَإِنِّي قَرِيبٌ ۖ …",
"translation": "And when My servants ask you concerning Me — indeed I am near. …"
}
}
get_dua
返回与生活情境(焦虑、悲伤、清晨、旅行等)匹配的 du'a。系统会根据规范类别 slug、别名映射和标签维度解析情境。自然语言短语(“失去母亲后的悲伤”)也能解析:服务会对其进行标准化,并以确定性方式匹配其中已知的类别、别名、标签和同义词,以及少量多词短语,不使用 AI。content.matched_by 会说明解析方式。**悲伤(WO#386):**查询提及提问者自身的悲伤(“我失去了母亲”“失去母亲后的悲伤”“我父亲去世了”“丧亲”)时,会解析为情境 bereaved;葬礼仪式或已故者(“葬礼”“为亡者祈祷”“去我母亲的坟前探望”)则仍解析为 deceased。**父母(WO#430):**查询同时提及父母(mother、mum、mom、father、dad、parent、parents)和死亡相关词语(late、dead、passed、grave、burial、janaza、janazah、cemetery、funeral、died、death、deceased、lost)时,会采用此悲伤解析路径,绝不返回 mothers 或 fathers;查询中有父母和 “miss” 但没有死亡相关词语时,只返回适用于在世或已故父母的 du'a;普通的父母查询(“我母亲”“父母”)保持不变。单独出现死亡相关词语(例如 “grave”)时,不会解析出任何结果。bereaved 会按照 fiqh 审核者(Gem 4)裁定的顺序返回七条 du'a,并附带一条关于阿拉伯语中阳性形式的 teaching_note,且始终至少附带一条温和的支持提示。危机检测会先对完整原始输入进行。自残和虐待会分别使用独立的区块(crisis_type):虐待区块包含家庭暴力相关内容和针对虐待情境的指示。出现任何严重危机(自残或虐待)时,均不返回 du'a:content_type 为 crisis_resource_only,且危机资源构成完整响应。每个区块都先列出全天候热线,并注明任何服务时间有限的热线的开放时间。如果情境中包含危机关键词(根据主应用的 detectCrisis 关键词列表匹配),响应会包含必需的 crisis_resource 区块,其中提供适当的热线和亲社会指示。
参数
| 名称 | 类型 | 必填 | 说明 |
|---|---|---|---|
context | string | context 或 id 二选一 | 自由格式的生活情境 |
id | string | context 或 id 二选一 | 从先前响应中的 related 引用获取的 du'a ID(WO#390) |
locale | 'en' | 'id' | 'ur' | 'ar' | 'tr' | 否,默认为 en | 无论 locale 为何,du'a 记录均为英文;危机资源使用请求中的 locale(2.2.1);省略 locale 或设为 en 时,严重危机资源使用匹配到的危机关键词所对应的语言(id、ur、ar 或 tr;2.2.2) |
audience | 'curious' | 'revert' | 'practising' | 否 | 仅根据用户对自身情况的描述填写。会作为 teach.audience 原样返回;若省略,教学区块会显示 unknown(2.2.0) |
limit | 整数,1 到 10 | 否,默认为 3 | 情境查询返回的记录数量(2.2.0)。bereaved 集合和虐待白名单始终完整返回。与 id 一起使用时忽略 |
offset | 整数,0 或更大 | 否,默认为 0 | 使用 limit 分页时,指定本页之前要跳过的记录数(2.2.0)。与 id 一起使用或用于 bereaved 时忽略 |
**结果处理(2.2.0)。**情境查询会从 offset 开始,按该路径现有顺序(数据包顺序;bereaved 使用 Gem 4 固定的顺序)返回 limit 条记录。如果后面还有记录,content.total_available 会给出总数,content.truncated 为 true,且 content.more 会包含提示:“此情境还有 N 条 du'a;调用 get_dua 并设置 offset 和 limit 查看。”CRITICAL_RULES 中也会包含相同的提示。content.offset 仅在其值不为 0 时出现。某个类别中的每条记录都可以通过分页获取。
响应示例(已截断)
{
"_sakina_meta": {
"content_type": "dua_collection",
"presentation_contract": {
"hadith": { "require_grading": "per_record" /* true when every record is graded */ }
}
/* … */
},
"content": {
"context": "stress-anxiety",
"duas": [
{
"dua_block": "Arabic: …\nTransliteration: …\nTranslation: …\nOrigin: Quran 21:87\nSource: Quran 21:87\nGrading: Quranic",
"title": "Dua to Deal with Distress & Depression",
"arabic": "وَذَا ٱلنُّونِ إِذ ذَّهَبَ …",
"source": "Quran 21:87",
"grading": "Quranic",
"grading_status": "quranic",
"origin": "quran",
"quran_citation": "Quran 21:87"
},
{
"title": "Dua to Remove Sorrow & Grief:",
"source": "Source not recorded in AskSakina corpus",
"grading": "Not graded in AskSakina corpus",
"grading_status": "not_recorded"
/* … */
}
/* … */
],
"total_results": 3,
"total_available": 12,
"truncated": true,
"more": "9 more du'as for this context; call get_dua with offset and limit to see them.",
"grading_summary": { "quranic": 2, "graded": 0, "not_a_narration": 0, "not_recorded": 1 }
}
// crisis_resource block added if context triggers the crisis keyword list
}
分级状态。 每条 du'a 记录都带有 grading_status:quranic(文本是《古兰经》经文或经文片段)、graded(已记录圣训分级)、not_a_narration(一般祈祷词,并非先知传述;记录中带有说明这一点的 grading_directive),或 not_recorded(AskSakina 语料库没有该条内容的分级记录)。目前语料库的大部分记录均为 not_recorded;Source 和 Grading 行会如实说明,而不会暗示存在分级。已核实《古兰经》出处的 du'a 带有 origin: "quran" 和 quran_citation,其阿拉伯语文本是在打包时通过 AskSakina 的经文模块解析得到的 Tanzil Uthmani 文本。
get_name_of_allah
按编号(1–99)或字符串(转写、阿拉伯语或英文释义)查询。返回阿拉伯语、转写、本地化释义、默想内容和《古兰经》出处。
参数 — 以下二选一:
| 名称 | 类型 | 说明 |
|---|---|---|
number | 1..99 | 主要查询方式 |
name | string | 转写、阿拉伯语或英文释义 |
另有可选参数 locale(tr 会返回英文释义和默想内容)。
响应示例(已截断)
{
"_sakina_meta": { "content_type": "name_of_allah" /* … */ },
"content": {
"number": 29,
"arabic": "الحَكَم",
"transliteration": "Al-Hakam",
"meaning": "The Judge",
"reflection": "Allah is the absolute Judge…",
"quran_references": ["6:114", "13:41"]
}
}
find_verses
按主题查询,与 get_quran_verse 的出处查询并列(WO#386)。系统会规范化查询内容,并将其中每个词与 AskSakina 主题经文索引中的主题(anxiety、gratitude、patience、trust、grief、hope、forgiveness、morning、friday、ramadan、encouragement)进行匹配,匹配方式为主题名称或固定同义词列表。结果是确定性的:不使用嵌入,也不调用 AI。
2.5.0(WO#495)新增了十五个主题,每个主题的经文均按规则顺序排列:companionship、family_and_marriage、hereafter、parents、night_and_rest、character、justice、protection、quran_and_knowledge、faith_and_guidance、prophets_and_creation、seasons、provision、healing 和 certainty。companionship(孤独)与 grief 一样,带有温和支持内容块,不包含教导内容。healing 还带有一条额外指示:这些经文提供精神慰藉,不能替代医疗护理。若查询中含有危机检测器无法单独识别的虐待词语("abuse"、"abusive"、"violence" 及其变体),则不会匹配这十五个主题中的任何一个,响应方式与 2.4 相同。自 2.5.1(WO#500)起,以这些词语构成的披露短语("abusing me"、"abusive husband"、"my father is violent",以及 Gem 3 中以乌尔都语、阿拉伯语、印度尼西亚语、孟加拉语和波斯语写出的短语)属于危机关键词:系统会在匹配任何主题前返回虐待资源内容块。
每节经文都包含 reference(章:节)、arabic(经文模块提供的完整经文,Tanzil Uthmani 文本,逐字节一致)、translation(完整经文的 Pickthall 译文,获取方式与 get_quran_verse 相同)、章名,以及说明该经文列于哪些主题中的 relevance_note。该说明不是注释。如果上游服务无法访问,仍会提供阿拉伯语文本,而 translation 会为 null,并附带说明。
如果没有匹配项,则返回 content_type: "not_found"、verses: []、no_results: true 以及可用主题列表,而不是错误。危机检测优先运行,与 get_dua 一样:任何严重危机(自残或虐待)都会返回 crisis_resource_only,不包含经文或主题列表。
参数
| 名称 | 类型 | 必填 | 说明 |
|---|---|---|---|
query | string | 是 | 主题或关键词,例如 patience、grief、gratitude |
limit | 1..10 | 否,默认 5 | 经文数量 |
locale | 'en' | 'id' | 'ur' | 'ar' | 'tr' | 否,默认 en | 选择当地危机资源。译文为 Pickthall 英文译文;ur、id 和 tr 会附带暂未提供译文的说明 |
资源:sakina://about
使用工具前请先阅读此资源。它包含七条核心指示,以及三篇经 Gem 审核通过的教育性 dawah 文本。大多数 MCP 客户端会在首次连接时自动获取此资源。
服务端 instructions(2.2.0)
初始化结果包含 instructions(1,529 个字符,低于 1,801 个字符的限制):引文和教学规则、2026 年 10 月 20 日裁定的宣教礼仪条款(原文照录),以及附带条件的敞开之门表述(仅当用户对伊斯兰本身感兴趣时才提及,每次对话最多一次,用户陷入困境时绝不提及,绝不将其作为回答的条件,用户拒绝后绝不提及)。会呈现 instructions 的客户端会在每个会话中向其模型提供这些规则一次;无论客户端是否呈现,_sakina_meta.llm_directives 中的逐条响应规则都适用。
教学(2.2.0,“教学,不转手”)
如果某条记录有对应的教学条目(src/teach/entries.ts;目前有六条记录),记录就会包含 teach 区块和 related 列表,audience 字段则可有可无。指令规定了教学顺序:先逐字引用记录(阿拉伯语、译文、出处、等级);然后仅依据 teach 区块进行解释,并说明内容来自 AskSakina 的笔记,而非经注或教法裁定;笔记未涉及之处,应明确说明并指向公认的经注或合格的学者;原文提供反思问题,但不得作答;最多提供一个相关的后续步骤。支持区块、哀伤流程或危机响应中不会附加任何内容;指令还要求,只有在用户已透露自己陷入困境、哀伤或危机后,Agent 才能引用记录。如果没有提供 teach 区块,Agent 只能依据记录自身提供的字段进行解释,并注明内容来自 AskSakina 的笔记,然后以相同方式转介。
提示词:学习旅程(2.4.0)
两个提示词,适用于会显示 MCP 提示词的客户端(例如将其显示为斜杠命令的客户端)。每个提示词都会返回一条用户消息,告知 Agent 调用一个工具,然后依照该响应自带的规则呈现响应(_sakina_meta.llm_directives.CRITICAL_RULES 和 presentation_contract,只要提供了 teach 区块,其中就包含教学顺序),并遵循服务端逐字照录的宣教礼仪。提示词不会增加任何宗教内容:用户看到的所有内容都来自工具的记录,以及其中可能存在的、经 Gem 批准的教学条目。
| 提示词 | 参数 | 调用的工具 | 后续步骤 |
|---|---|---|---|
understand_a_verse | surah(1-114)、ayah(1-286),均为必填 | get_quran_verse | teach 区块自身提供的相关步骤(如果有) |
explore_names_of_allah | number(1-99),可选;未提供时默认为 1 | get_name_of_allah | 名称 number + 1,仅提供一次(99 之后不再提供) |
- 参数必须为数字字符串,提示词运行前会进行检查;其他任何输入都会以
-32602拒绝,且不会回显该值。某节经文是否存在于其章中,由工具通过not_found响应告知,与直接调用时相同。 - 如果响应包含
crisis_resource区块(危机或温和支持),消息会告知 Agent 遵循该区块的指令,不添加任何内容:不提供反思问题,也不提供后续步骤。 - 提示词参数绝不会被记录或计数。
/stats只按名称统计每个提示词被获取的次数。
提示词:两种使用流程(2.5.0)
| 提示词 | 参数 | 要求 Agent 执行的操作 |
|---|---|---|
what_muslims_believe | audience(curious、revert 或 practising),可选;未提供时为 curious | 阅读 sakina://about;获取 112:1-4、第 1 个真主尊名、资源 sakina://learn/what-muslims-believe 和 2:256;后续内容只能来自这些记录;提供一个下一步;至多出现一次开放邀请,不得出现在危机提示或困扰之后 |
first_steps_new_muslim | step(1 到 4),可选;未提供时为 1 | 每次获取一个步骤,audience 始终为 revert:1 念作证词(不得要求用户念诵)、112:1-4、第 1 和第 2 个真主尊名;2 8:38、关于宽恕的资源、第 34 个真主尊名、39:53 和 du'a Sahih al-Bukhari 744(get_dua id D00234);3 小净和第一次礼拜、1:1;4 寻找社群。不得提供开放邀请。 |
- 提示词运行前会检查参数;其他任何值都会被拒绝,并返回
-32602,且不会回显该值。 - 这些资源(
sakina://learn/what-muslims-believe、sakina://learn/first-steps#shahada、#forgiven、#wudu、#first-prayer、#community)由脚本根据应用自身经过审核的种子模块和 Gems 的裁定生成(scripts/wo495-learn-content.ts);如果提交的文本不一致,构建将失败。 - 给新穆斯林的说明(
audience_note)。 当audience: "revert"时,有六条记录包含 AskSakina 给新穆斯林的说明(112:1、1:1、第 1、第 2 和第 34 个真主尊名,以及 du'a D00234),并附有各自的引文和必须原样引用的note_block。凡是 teach 被禁止的情况(危机、支持提示、悲伤、非英语区域设置),均不提供此说明。
响应封装
每个工具都会返回相同结构:
{
"_sakina_meta": {
"version": "1.0",
"source": "AskSakina Islamic Knowledge Server (asksakina.com)",
"content_type": "quran_verse" | "dua_collection" | "name_of_allah" | "not_found" | "crisis_resource_only",
"disclaimer": "AskSakina provides curated Islamic reference content for educational purposes. …",
"llm_directives": { "CRITICAL_RULES": ["…"] },
"presentation_contract": {
"quran": { "no_paraphrase": true, "require_citation": "surah:ayah" /* … */ },
"hadith": { "require_grading": true, "require_source": true /* … */ },
"name_of_allah": { "no_paraphrase_arabic": true /* … */ }
},
"educational_context": "…"
},
"content": { /* tool-specific record; a record with a teaching entry also carries "teach" and "related" (2.2.0) */ },
// get_dua and find_verses, when crisis keywords detected:
"crisis_resource": { "level": "hard" | "soft", "crisis_type": "self-harm" | "abuse", "locale": "…", "directive": "…", "text": "…" }
}
该封装是约定:_sakina_meta.presentation_contract 会告知 Agent 如何呈现记录,disclaimer 会说明 Agent 不能凭自身权威作出哪些声明,而 crisis_resource 要求当用户的困扰达到安全阈值时,Agent 必须优先提供危机资源。这些是给客户端 AI 的指令;服务端无法强制另一个 AI 遵循这些指令。
结构化输出(2.4.2)
每个工具都会发布一个 outputSchema,并以两种形式返回封装:作为对象的 structuredContent,以及作为文本内容的 JSON 文本(与早期版本相同,未经更改)。两者始终包含相同的数据。各工具的架构见 src/contracts/output-schemas.ts:
| 工具 | content_type | content |
|---|---|---|
get_quran_verse | quran_verse、not_found | 经文(苏拉编号和名称、阿亚、arabic_text、translation、translation_source、translation_language;可选的 teach、related),或 { requested, reason } |
get_dua | dua_collection、not_found、crisis_resource_only | { context, matched_by, duas[], total_results, total_available, truncated, grading_summary },或 { requested, reason },或 { requested, withheld, reason } |
get_name_of_allah | name_of_allah、not_found、crisis_resource_only | 真主尊名(name_block、number、arabic、transliteration、english_meaning、reflection、quranic_references;可选的 teach、related),或 { requested, reason },或 { requested, withheld, reason } |
find_verses | verse_collection、not_found、crisis_resource_only | { query, matched_themes[], verses[], total_results, no_results },或未匹配时的结构(available_themes),或 { requested, withheld, reason } |
每个响应都包含 _sakina_meta(version、source、content_type、disclaimer、可选的 disclaimer_locale、llm_directives.CRITICAL_RULES、presentation_contract、educational_context);如果适用危机提示或轻度支持提示,还会包含 crisis_resource(level、可选的 crisis_type、locale、directive、text)。每个对象都允许扩展:后续版本添加字段时,不会导致验证对象的客户端失败。
快速开始
通过 npx 运行(无需安装)
npx -y @asksakina/islamic-knowledge-mcp --stdio
使用 --stdio 时,程序会通过标准输入/输出使用 MCP;将其接入任意 MCP 客户端即可。不带此标志时,程序会在 $PORT 上启动 Streamable HTTP 服务(默认端口为 3030,提供 POST /mcp 和 GET /health),与托管端点的运行方式相同。在 2.1.0 之前,sakina-mcp 命令会直接退出,不会启动任何服务(WO#444)。
通过远程 Streamable HTTP 连接
https://sakina-mcp.fly.dev/mcp
适用于更倾向使用托管端点而非本地子进程的 Agent。工具、消息封装和速率限制均相同。
Claude Desktop
将以下内容添加到 ~/Library/Application Support/Claude/claude_desktop_config.json(macOS)或 %APPDATA%/Claude/claude_desktop_config.json(Windows):
{
"mcpServers": {
"sakina": {
"command": "npx",
"args": ["-y", "@asksakina/islamic-knowledge-mcp", "--stdio"]
}
}
}
重启 Claude Desktop。工具选择器中会显示这四个工具和 sakina://about 资源。
Cursor
将以下内容添加到 ~/.cursor/mcp.json(或工作区的 .cursor/mcp.json):
{
"mcpServers": {
"sakina": {
"command": "npx",
"args": ["-y", "@asksakina/islamic-knowledge-mcp", "--stdio"]
}
}
}
VS Code(搭配支持 MCP 的扩展)
将以下内容添加到工作区中的 .vscode/mcp.json:
{
"servers": {
"sakina-islamic-knowledge": {
"command": "npx",
"args": ["-y", "@asksakina/islamic-knowledge-mcp", "--stdio"]
}
}
}
通过远程 HTTP 使用通用 MCP 客户端
{
"mcpServers": {
"sakina": {
"type": "streamable-http",
"url": "https://sakina-mcp.fly.dev/mcp"
}
}
}
使用场景
此 MCP 服务面向任何需要精选伊斯兰来源资料的 Agent 或应用,并会明确指示其原文引用,不得改述。
- 构建带有出处引用的伊斯兰聊天机器人。 将
get_quran_verse和get_dua接入对话流程;呈现约定会指示 Agent 原文引用并保留等级标注,每条回复还会注明内容类型;对于祈祷词,则会注明每条记录的等级。 - 为 Agent 添加结合礼拜时间的灵性内容。 将《古兰经》和祈祷词工具与礼拜时间 API 结合,在一天中恰当的时刻呈现真主的话语。
- 根据用户情境推荐祈祷词。
get_dua中的危机关键词过滤器可处理危险的边缘情况(自残相关措辞、虐待),确保在遇到涉及安全的紧急消息时,助手不会以通用祈祷词作答。 - 回答有关 99 个尊名的问题。
get_name_of_allah可通过编号或名称查询,并返回规范阿拉伯语、转写、含义和释义,以及《古兰经》出处。 - 保持神学包容性。 此服务旨在避免将有争议的教法裁决当作普遍适用的答案。
内容完整性
新的和已更改的内容在发布前,都会经过 AskSakina 的“Gem”专业 AI 审核链审核。其中 4 位审核者负责把关每次伊斯兰知识内容的发布:
- 《古兰经》与译文核验。 经文准确性、苏拉/经文引文正确性、圣训等级判定、来源审核。
- 教法多元性(多学派)。 跨学派准确性、对有争议的主题不采用单一学派视角、语言包容。
- 伊斯兰心理学与牧灵关怀。 安慰窗口的安全性、危机过滤覆盖范围、不以愧疚感作为激励。
- 探索者/伊斯兰信仰新手易用性。 为非穆斯林读者解释阿拉伯语术语、通俗易懂的教法内容、不预设信仰背景的反思。
已在代码中实现的架构行为:
- 每个数据加载器边界都会将 Unicode 先知祝福语(U+FDFA,ﷺ)替换为
(peace be upon him)。响应构建器会拒绝任何包含该符号的输出。 - 每条 du'a 记录都带有
grading_status(quranic、graded、not_a_narration、not_recorded)。只有当每条返回记录都经过等级判定或属于《古兰经》内容时,hadith呈现契约才会设置require_grading: true;否则会设为"per_record",确保响应信封不会声称数据中并不存在的等级判定。 - 每次
get_dua请求都会进行危机关键词检测,使用的关键词列表与主应用安全关卡所用的列表相同。
神圣用途许可证。 本服务根据神圣用途许可证分发(参见 LICENSE)。允许的用途主要包括宣教、教育、个人礼拜,以及以尊重的方式集成到服务穆斯林的应用中。该许可证禁止将伊斯兰知识包装成稀缺或付费墙内容来变现。许可证条款的公开摘要位于 https://www.asksakina.com/en/mcp。
隐私。 请参见 隐私与分析。
本地运行以进行开发
cd mcp-server
npm install
npm run bundle-data # snapshot data from main repo into data/
npm run typecheck # tsc --noEmit
npm run start # HTTP server on :3030 via tsx
npm run test:tools # exercise each tool, prints sample JSON
# Or build + run from compiled output:
npm run build # tsc -> dist/, postbuild adds shebang + dist/package.json
npm run start:dist # node dist/server.js
POST /mcp 接受标准 MCP JSON-RPC 2.0。GET /health 返回 { "status": "ok", "name", "version" }。
速率限制
默认值:每个 IP 每分钟 60 个请求。
- 设置
UPSTASH_REDIS_REST_URL+UPSTASH_REDIS_REST_TOKEN→ 使用分布式 Upstash Redis 固定窗口。 - 否则 → 使用进程内存令牌桶。
响应包含 X-RateLimit-Limit、X-RateLimit-Remaining、X-RateLimit-Reset。超出限制时返回状态码为 429、错误码为 -32029 的响应。
身份验证
v1 版本无需身份验证即可使用。v1 会接受可选的 X-Sakina-App-Id 标头,但不会强制要求或记录该标头。v2 将要求提供该标头。
隐私与分析
本服务采用仅汇总数据的模型(WO#360;每日总计 WO#456;教学计数器 WO#477)。对于每个工具,服务器都会持续统计不同结果(ok、not_found、error)的调用次数、处理程序耗时总和(用于报告运行平均值),以及包含教学区块的响应数量。对于所有工具,服务器还会统计每个可选 audience 参数值(curious、revert、practising、unknown 或无)的调用次数,以及每条学习提示词被获取的次数。这些都只是总计,通过 /stats 端点报告。
- 不进行持久化跟踪: 应用不会将单次请求日志或客户端标识符写入磁盘或任何数据库。
- 临时处理 IP: 客户端 IP 地址仅用于执行速率限制。每个地址都会在速率限制窗口(60 秒)内作为速率限制键保存在 Upstash Redis 中,之后过期。如果 Upstash 不可用,内存回退机制会在同一窗口内将其保存在进程内存中,随后丢弃。应用绝不会持久化原始 IP 地址,也绝不会将其写入日志。
- 不记录载荷: 不会捕获或记录请求参数(例如上下文值、经文引用、Name 编号、提示词参数或区域设置)及响应载荷。唯一会计数的参数是
audience,且仅按其四个固定值和“无”进行计数;该值本身绝不会与调用、工具或其他任何内容一同存储。 - 启动以来的计数器:
/stats在by_tool下报告的总计仅存在于 RAM 中,服务器进程重启时会重置。 - 服务器本地磁盘上的每日总计: 在托管服务器上,每个 UTC 日对各工具的调用次数(按结果
ok、not_found、error分类)、处理程序耗时总和、包含教学区块的数量、audience值的计数,以及每条学习提示词的获取次数,都会写入服务器本地磁盘,以便在重启后保留。数据最多保留 90 天;更早的数据会被删除。数据不包含 IP 地址、用户代理、客户端标识符、单次调用时间、参数或载荷,也无法关联到任何请求或个人。只有在设置了MCP_USAGE_DIR时才会写入这些数据:本地运行npx或--stdio时不会写入任何数据。 - 不按个人计数: 不会针对客户端、会话、用户或对话单独保存任何计数器。教学、audience 和提示词计数器与各工具的调用次数属于同一类数字:所有调用者的累计总数。
法规说明(英国 GDPR):由于超出速率限制窗口后不会保留任何可识别个人身份的信息,因此不存在可供访问或删除的记录。请注意,虽然应用本身不会持久化个人数据,但我们的基础设施提供商(Fly.io)会在边缘层临时处理 IP 地址,以进行标准网络路由和平台安全保护。
/stats 端点
需要身份验证的摘要端点:
curl -H "Authorization: Bearer $MCP_STATS_TOKEN" https://sakina-mcp.fly.dev/stats
必须设置 MCP_STATS_TOKEN 环境变量(否则端点会返回 503,并拒绝提供未经身份验证的服务)。令牌比较采用恒定时间算法。
负载结构:
{
"privacy": "aggregate-only counters; no per-request records, no IPs, no user-agents, no client identifiers, no geolocation, no params beyond a tally of audience values, no payloads; since-start totals reset on restart; daily totals (per tool: ok, not_found, error, summed duration, teach served; plus audience tally and prompt fetches by name) kept on the server's own disk for at most 90 days",
"since": "2026-09-25T…",
"total_requests": N,
"by_tool": {
"get_quran_verse": { "total": N, "ok": N, "not_found": N, "error": N, "avg_response_ms": N, "teach_served": N },
"get_dua": { "total": N, "ok": N, "not_found": N, "error": N, "avg_response_ms": N, "teach_served": N },
"get_name_of_allah": { "total": N, "ok": N, "not_found": N, "error": N, "avg_response_ms": N, "teach_served": N },
"find_verses": { "total": N, "ok": N, "not_found": N, "error": N, "avg_response_ms": N, "teach_served": N }
},
"audience": { "curious": N, "revert": N, "practising": N, "unknown": N, "absent": N },
"prompts": { "understand_a_verse": N, "explore_names_of_allah": N, "what_muslims_believe": N, "first_steps_new_muslim": N },
"rate_limiter": {
"state": "upstash",
"upstash_configured": true,
"upstash_failures": 0,
"last_failure": null,
"last_failure_at": null,
"last_success_at": "2026-09-25T…",
"startup_check": "Upstash reachable (PING ok, 12 ms); state: upstash"
},
"basmala_prefix_mismatch": 0,
"daily": {
"retention_days": 90,
"days": [
{ "date": "2026-10-12", "total": N,
"by_tool": { "get_dua": { "total": N, "ok": N, "not_found": N, "error": N, "avg_response_ms": N, "teach_served": N }, … },
"audience": { "curious": N, "revert": N, "practising": N, "unknown": N, "absent": N },
"prompts": { "understand_a_verse": N, "explore_names_of_allah": N, "what_muslims_believe": N, "first_steps_new_muslim": N } }
]
}
}
daily 列出已存储的日期,按时间从近到远排列,并包含今天尚未写入的调用;未设置 MCP_USAGE_DIR 时,其值为 null,此时 privacy 行仅列出内存中的计数器(“仅聚合的内存计数器,包括按工具统计的 teach-served、受众值的计数,以及按名称统计的提示词获取次数;……重启后重置”)。
teach_served 统计包含 teach 块的响应(WO#488)。audience 按四个固定值统计每次工具调用可选的 audience 参数;对于未发送该参数的调用,记为 absent。这是所有工具的总计,绝不会与某个工具、某次调用或精度高于 UTC 日的时间关联。prompts 按名称统计每个学习提示词的获取次数;不会读取提示词参数。
rate_limiter.state 的值为 upstash(Upstash 正常响应)、degraded(已配置 Upstash,但出现故障:请求由内存备用方案限流,绝不会放行)或 memory(未配置 Upstash)。故障原因会包含 HTTP 状态码或错误,但绝不包含客户端 IP。basmala_prefix_mismatch 统计上游提供的第 1 节经文文本既不以记录的两种 basmala 形式开头、又未经更改直接提供的次数。这只是聚合计数;对应的日志行不包含经文引用。
在 Fly 上进行一次性设置
fly secrets set MCP_STATS_TOKEN=$(openssl rand -hex 32)
fly deploy
服务器只会向 fly.toml 挂载的 /data 卷写入一类内容:每日总计,每个 UTC 日期在 /data/usage(MCP_USAGE_DIR)中对应一个文件,每 5 分钟写入一次,并在 Fly 停止机器时写入。自 WO#360 起,LOG_DIR(/data/logs)便未再使用。
数据源
| 工具 | 来源 |
|---|---|
get_quran_verse | 英语(2.1.0,WO#444): AskSakina 修订后的 Pickthall 译本,作为 data/pickthall.json 打包,来源为应用的 public/quran/en.pickthall(全部 6,236 节经文,包含针对 1930 年文本的 WO#442 修订,不含经文末尾标点,与应用阅读器中的显示一致),适用于所有区域设置:ur 和 id 会附带说明(其译文因许可问题暂缓提供;1.4.1)。阿拉伯语和苏拉名称: 运行时从 alquran.cloud 获取(源自 Tanzil 的 Uthmani 版本)。会移除开头的字节顺序标记。上游还会在除第 1 和第 9 章之外的每章第 1 节经文前添加太斯米。根据 Gem 2(太斯米仅在 1:1 中属于第 1 节经文),会从第 2–8 章和第 10–114 章的第 1 节经文中移除该确切前缀,并匹配上游发送的两种字节形式。经文其余部分按原始字节提供。无法识别的开头会原样提供,并在 /stats 中计数(basmala_prefix_mismatch)。所有内容均按节逐条获取(/ayah/{surah}:{ayah})。不提供 Saheeh International 译本(已于 1.2.0 移除,WO#245)。每节经文 + 版本在进程内缓存 24 小时。 |
get_dua | AskSakina 的祈祷词语料库(2.1.0 版共 440 条),在 npm run bundle-data 时从 ../src/data/duas 快照到 data/duas.json。带有已核实《古兰经》出处的祈祷词,会在同一步从 scripture 模块(../src/lib/scripture,Tanzil Uthmani 版本)获取阿拉伯语文本。 |
get_name_of_allah | AskSakina 的真主 99 个尊名,在 npm run bundle-data 时从 ../src/lib/data/99-names 快照。 |
find_verses | AskSakina 的主题经文索引(../src/lib/data/thematic-verses),在 npm run bundle-data 时快照到 data/thematic-verses.json。仅从索引中获取每节经文的出处和主题;阿拉伯语文本在同一步从 scripture 模块获取,Pickthall 译文则从打包的 data/pickthall.json 获取(2.1.0;苏拉名称仍在运行时从 alquran.cloud 获取,与 get_quran_verse 使用相同缓存)。 |
祈祷词和尊名数据是主应用数据文件的快照,因此任何更新都会在下次运行 npm run bundle-data 时同步到此处(部署工作流会运行该命令)。已发布的软件包包含构建时的快照。
v1 暂不包含
根据 Phase 3 规划文档:
- 语义搜索 /
search_islamic_guidance— 需要由 Gem 审核的评估集。(find_verses是索引查找,不是语义搜索。) explain_islamic_concept— 在 Architect 级别作出裁定之前,与 CLAUDE.md 中“AI 绝不提供精神或教法建议”的规则直接冲突。get_pastoral_guidance— Gem 3 的表述依赖 AskSakina 控制的界面;未经单独审核,不能通过 MCP 发布。check_halal_ingredient— 因 WO#61 恢复工作受阻。- HMAC 签名强制执行 — v1 会接受
X-Sakina-App-Id标头,但会忽略它。
部署
发布时无需依赖主应用:npm run bundle-data 会将祈祷词语料库、99 个尊名以及规范安全模块从主 AskSakina 单体仓库快照到 data/ 和 src/safety/_synced/。编译后的 dist/ 和打包的 data/ 目录在运行时不依赖主应用。
bundle-data 会通过 prebuild 脚本自动运行(WO#138),因此在全新检出后,npm run build 即可独立完成,无需手动打包。src/safety/_synced/ 目录已提交到 git,因此主应用安全模块的任何偏差都会显示在不同提交之间的 git diff 中。
docker build 不会运行 prebuild(它只复制 mcp-server/ 目录,而不复制单体仓库)。在运行 docker build 前,请先在主机上运行 npm run bundle-data,以填充 data/。从全新克隆构建时也一样——运行 docker build 前先执行 npm install && npm run bundle-data。
CI 部署(规范流程 — WO#249)
所有 MCP 版本发布都通过 MCP Server Deploy GitHub Actions 工作流
(.github/workflows/mcp-deploy.yml)进行——开发者的机器上无需保存 flyctl 或 npm
身份验证信息。架构师在仓库的 Actions 选项卡中通过
workflow_dispatch 触发此工作流,并设置两个布尔输入:
deploy_fly(默认值true)——构建并通过flyctl deploy部署到sakina-mcp.fly.dev。sync_mirror(默认值true)——将构建好的软件包推送到公开镜像 (github.com/yserrag/asksakina-mcp),并在那里创建v<version>标签。镜像自身的 工作流随后会通过可信发布和来源证明(WO#444)将@asksakina/islamic-knowledge-mcp发布到 npm;本仓库不保存 npm 令牌。
该作业会在 main 上运行完整的 Gem 10 操作手册:npm ci → npm run bundle-data
(关键步骤)→ flyctl deploy → 轮询 /health → 实时 Pickthall 字节检查
2:255 和 9:129 → 实时 Dhun-Nun 检查 → 速率限制器探测(仅警告)→ 实时发布防护检查 → Agent 评测(仅警告;自 WO#386 起放在防护检查之后,因此阻止发布的防护检查会优先获得速率限制预算)→ 镜像同步和打标签(由镜像执行发布)。字节检查会对实时端点运行 MCP initialize 握手 + tools/call get_quran_verse:"save Him"(Pickthall)通过;"except Him"(Saheeh
International)或无法访问的 /mcp 都会导致作业失败,且不会执行镜像同步,
同时输出 flyctl status + 日志,并打印手动回滚命令。9:129 必须显示
"There is no God save Him",只有已打包的修正文案包含这一内容。
密钥 FLY_API_TOKEN 和 ASKSAKINA_MCP_DEPLOY_KEY 保存在仓库设置中,绝不会回显。
自动回滚到上一镜像是 Gem 10 的最终目标,但目前暂缓实施:当前的线上镜像本身有问题,因此暂时没有已知正常的镜像可供自动恢复。首次运行只会在失败时明确报错,并仅支持手动回滚。
Fly.io(手动 / 紧急处理)
优先使用上面的 CI 工作流。以下命令是底层操作方式,适用于已完成 flyctl 身份验证的机器:
cd mcp-server
fly launch # first time only — picks up fly.toml
fly secrets set \
UPSTASH_REDIS_REST_URL=... \
UPSTASH_REDIS_REST_TOKEN=...
npm run bundle-data # load-bearing: docker build copies host data/
fly deploy
fly status
curl https://<app>.fly.dev/health
生产应用:sakina-mcp.fly.dev。应用 sakina-mcp,区域 lhr,内部端口 3030,强制使用 HTTPS,每 30 s 在 /health 上执行健康检查,空闲时自动停止,1 个共享 CPU,256 MB RAM。
部署后验证和回滚
每次执行 fly deploy 后,都要从线上端点检查一节《古兰经》经文的字节,并与锁定的 Pickthall 表(docs/wo-cert/si-pickthall-LOCKED-final.json)进行比对,以确认译本是 Pickthall,而不是 Saheeh International:
curl -s https://sakina-mcp.fly.dev/mcp ... # call get_quran_verse for a known ref
# compare the returned translation to the locked Pickthall text for that ref
如果字节检查失败(提供的是 SI 文本,或译文与 Pickthall 不匹配),先回滚,再诊断。在进行任何进一步调查或修复之前,立即重新部署上一镜像:
fly releases --app sakina-mcp # find the last-good release / image
fly deploy --app sakina-mcp --image <previous-image-ref>
线上出现 SI 回归问题时,不要尝试直接向前修复——先恢复已知正常的镜像,确认该镜像通过字节检查,然后在离线环境中诊断有问题的构建。
本地容器测试
docker compose up --build
curl http://localhost:3030/health
其他目标平台
该软件包只是一个 Node.js HTTP 服务端,因此可运行在任何支持 Dockerfile 或 Node 进程的平台上:Railway、Render、小型 VPS、Cloudflare Workers(使用 streamable-http 传输)、Vercel Functions(使用轻量适配器)。如果未配置 Upstash,内存速率限制器会自动回退。
npm 发布
发布通过 MCP Server Deploy 工作流进行(参见 CI 部署),并设置 publish_npm: true——架构师从 Actions 选项卡触发该工作流;NPM_TOKEN 保存在仓库设置中。手动等效操作(紧急处理,需要本地 npm 身份验证):
cd mcp-server
npm login # to the @asksakina org
npm publish --access public
prepublishOnly 会依次运行 bundle-data → build → test:tools,确保发布的 tarball 始终包含最新数据且构建干净。files 字段会将文件范围限制为 dist/、data/、README.md、LICENSE 和 .mcp/server.json。
先运行 npm pack --dry-run,检查将要发布的 tarball 内容。
MCP Registry 提交
mcp-server/.mcp/server.json 声明了 AskSakina 在官方 MCP Registry 中的身份:
- 服务名称:
com.asksakina/islamic-knowledge - 软件包:
@asksakina/islamic-knowledge-mcp(npm,stdio 传输) - 远程服务:
https://sakina-mcp.fly.dev/mcp(Streamable HTTP)
发布流程:MCP Registry Publish GitHub Actions 工作流(主仓库中的 .github/workflows/mcp-registry-publish.yml,手动触发)。该工作流会检查 server.json、package.json 和 npm 是否一致,然后运行:
mcp-publisher login dns --domain asksakina.com --private-key <KEY> # or: login http
mcp-publisher publish .mcp/server.json
curl "https://registry.modelcontextprotocol.io/v0/servers?search=com.asksakina"
com.asksakina 的域名所有权证明使用 Ed25519 密钥:公钥位于 asksakina.com 的 DNS TXT 记录中(v=MCPv1; k=ed25519; p=<base64>,自 2026 年 5 月起),或位于 https://asksakina.com/.well-known/mcp-registry-auth;私钥位于仓库密钥 MCP_REGISTRY_PRIVATE_KEY 中。
Smithery 重新发布(版本升级后)
版本号分布在三个位置,升级时需同时更新:
package.json("version")mcp-server/.mcp/server.json(顶层version以及packages[0].version)mcp-server/src/server.ts(SERVER_VERSION常量——显示在/health和/.well-known/mcp/server-card.json中)
升级版本时的重新发布检查清单:
cd mcp-server
npm run typecheck && npm run test:tools && npm run test:analytics
npm run bundle-data
npm publish # npm registry
mcp-publisher publish .mcp/server.json # MCP Registry
fly deploy # Smithery scanner picks up the new card via /.well-known/mcp/server-card.json
Smithery 会自动扫描 /.well-known/mcp/server-card.json,并在几分钟内重新编入索引——无需手动调用 Smithery API。
链接
- 网站: asksakina.com
- MCP 展示页: asksakina.com/en/mcp
- MCP 注册表: registry.modelcontextprotocol.io — com.asksakina/islamic-knowledge
- npm: npmjs.com/@asksakina/islamic-knowledge-mcp
- 源代码: github.com/yserrag/asksakina-mcp(主仓库中
mcp-server/的镜像) - 问题 / 咨询: github.com/yserrag/asksakina-mcp/issues
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。