1102-mcp 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,64 @@
1
+ Metadata-Version: 2.4
2
+ Name: 1102-mcp
3
+ Version: 0.1.0
4
+ Summary: Add your description here
5
+ Requires-Python: >=3.13
6
+ Description-Content-Type: text/markdown
7
+ Requires-Dist: fastmcp>=4.1.5
8
+ Requires-Dist: msgpack>=1.1.0
9
+
10
+ # 搜韵诗词 MCP
11
+
12
+ 基于搜韵网开放接口的 FastMCP 服务,通过 stdio 向 MCP 客户端提供诗词检索、韵典查询和歌词素材汇总工具。
13
+
14
+ ## 环境准备
15
+
16
+ - Python 3.13 或更高版本
17
+ - [uv](https://docs.astral.sh/uv/)
18
+ - 运行时可访问 `api.sou-yun.cn`
19
+
20
+ 在项目目录安装依赖:
21
+
22
+ ```powershell
23
+ uv sync
24
+ ```
25
+
26
+ ## 启动
27
+
28
+ MCP 服务使用 stdio,由 MCP 客户端按需启动并管理进程:
29
+
30
+ ```powershell
31
+ uv run python .\souyun_mcp.py
32
+ ```
33
+
34
+ 也可以直接使用项目虚拟环境:
35
+
36
+ ```powershell
37
+ .\.venv\Scripts\python.exe .\souyun_mcp.py
38
+ ```
39
+
40
+ ## MCP 客户端配置
41
+
42
+ 在客户端的 MCP 配置中添加一个 stdio server。将示例中的目录替换为本机项目的绝对路径:
43
+
44
+ ```json
45
+ {
46
+ "mcpServers": {
47
+ "souyun-poem": {
48
+ "command": "D:\\path\\to\\1102-mcp\\.venv\\Scripts\\python.exe",
49
+ "args": [
50
+ "D:\\path\\to\\1102-mcp\\souyun_mcp.py"
51
+ ]
52
+ }
53
+ }
54
+ }
55
+ ```
56
+
57
+ ## 可用工具
58
+
59
+ - `search_poems`: 按关键词检索诗词。`scope` 支持 `All`、`Author`、`Title`、`Sentence` 或数字 `0` 到 `3`;也可按 `dynasty`、`type_`、`rhyme` 和 `pageno` 筛选,`jsontype` 控制 JSON 返回格式。
60
+ - `get_poem`: 按 `poem_id` 查询单首诗词详情。
61
+ - `rhyme_dictionary`: 按 `char` 查询韵典;`qtype` 为 `0` 查全部、`1` 查韵目、`2` 查词末典故、`3` 查词首、`4` 查词末、`5` 查句末诗例。可通过 `page_no` 翻页。
62
+ - `couplet_words`: 查询与 `word` 对仗的词汇。
63
+ - `rhyme_category`: 不传 `rhyme` 时查询平水韵总目;传入韵部时查询该韵包含的字。
64
+ - `collect_lyrics_material`: 按 `theme` 汇总候选诗词、诗句和韵部建议。可设置 `top_n`、`dynasty`、`type_`;传入 `rhyme_char` 时还会返回相关对仗词和典故。
@@ -0,0 +1,8 @@
1
+ README.md
2
+ pyproject.toml
3
+ souyun_mcp.py
4
+ 1102_mcp.egg-info/PKG-INFO
5
+ 1102_mcp.egg-info/SOURCES.txt
6
+ 1102_mcp.egg-info/dependency_links.txt
7
+ 1102_mcp.egg-info/requires.txt
8
+ 1102_mcp.egg-info/top_level.txt
@@ -0,0 +1,2 @@
1
+ fastmcp>=4.1.5
2
+ msgpack>=1.1.0
@@ -0,0 +1 @@
1
+ souyun_mcp
@@ -0,0 +1,64 @@
1
+ Metadata-Version: 2.4
2
+ Name: 1102-mcp
3
+ Version: 0.1.0
4
+ Summary: Add your description here
5
+ Requires-Python: >=3.13
6
+ Description-Content-Type: text/markdown
7
+ Requires-Dist: fastmcp>=4.1.5
8
+ Requires-Dist: msgpack>=1.1.0
9
+
10
+ # 搜韵诗词 MCP
11
+
12
+ 基于搜韵网开放接口的 FastMCP 服务,通过 stdio 向 MCP 客户端提供诗词检索、韵典查询和歌词素材汇总工具。
13
+
14
+ ## 环境准备
15
+
16
+ - Python 3.13 或更高版本
17
+ - [uv](https://docs.astral.sh/uv/)
18
+ - 运行时可访问 `api.sou-yun.cn`
19
+
20
+ 在项目目录安装依赖:
21
+
22
+ ```powershell
23
+ uv sync
24
+ ```
25
+
26
+ ## 启动
27
+
28
+ MCP 服务使用 stdio,由 MCP 客户端按需启动并管理进程:
29
+
30
+ ```powershell
31
+ uv run python .\souyun_mcp.py
32
+ ```
33
+
34
+ 也可以直接使用项目虚拟环境:
35
+
36
+ ```powershell
37
+ .\.venv\Scripts\python.exe .\souyun_mcp.py
38
+ ```
39
+
40
+ ## MCP 客户端配置
41
+
42
+ 在客户端的 MCP 配置中添加一个 stdio server。将示例中的目录替换为本机项目的绝对路径:
43
+
44
+ ```json
45
+ {
46
+ "mcpServers": {
47
+ "souyun-poem": {
48
+ "command": "D:\\path\\to\\1102-mcp\\.venv\\Scripts\\python.exe",
49
+ "args": [
50
+ "D:\\path\\to\\1102-mcp\\souyun_mcp.py"
51
+ ]
52
+ }
53
+ }
54
+ }
55
+ ```
56
+
57
+ ## 可用工具
58
+
59
+ - `search_poems`: 按关键词检索诗词。`scope` 支持 `All`、`Author`、`Title`、`Sentence` 或数字 `0` 到 `3`;也可按 `dynasty`、`type_`、`rhyme` 和 `pageno` 筛选,`jsontype` 控制 JSON 返回格式。
60
+ - `get_poem`: 按 `poem_id` 查询单首诗词详情。
61
+ - `rhyme_dictionary`: 按 `char` 查询韵典;`qtype` 为 `0` 查全部、`1` 查韵目、`2` 查词末典故、`3` 查词首、`4` 查词末、`5` 查句末诗例。可通过 `page_no` 翻页。
62
+ - `couplet_words`: 查询与 `word` 对仗的词汇。
63
+ - `rhyme_category`: 不传 `rhyme` 时查询平水韵总目;传入韵部时查询该韵包含的字。
64
+ - `collect_lyrics_material`: 按 `theme` 汇总候选诗词、诗句和韵部建议。可设置 `top_n`、`dynasty`、`type_`;传入 `rhyme_char` 时还会返回相关对仗词和典故。
@@ -0,0 +1,55 @@
1
+ # 搜韵诗词 MCP
2
+
3
+ 基于搜韵网开放接口的 FastMCP 服务,通过 stdio 向 MCP 客户端提供诗词检索、韵典查询和歌词素材汇总工具。
4
+
5
+ ## 环境准备
6
+
7
+ - Python 3.13 或更高版本
8
+ - [uv](https://docs.astral.sh/uv/)
9
+ - 运行时可访问 `api.sou-yun.cn`
10
+
11
+ 在项目目录安装依赖:
12
+
13
+ ```powershell
14
+ uv sync
15
+ ```
16
+
17
+ ## 启动
18
+
19
+ MCP 服务使用 stdio,由 MCP 客户端按需启动并管理进程:
20
+
21
+ ```powershell
22
+ uv run python .\souyun_mcp.py
23
+ ```
24
+
25
+ 也可以直接使用项目虚拟环境:
26
+
27
+ ```powershell
28
+ .\.venv\Scripts\python.exe .\souyun_mcp.py
29
+ ```
30
+
31
+ ## MCP 客户端配置
32
+
33
+ 在客户端的 MCP 配置中添加一个 stdio server。将示例中的目录替换为本机项目的绝对路径:
34
+
35
+ ```json
36
+ {
37
+ "mcpServers": {
38
+ "souyun-poem": {
39
+ "command": "D:\\path\\to\\1102-mcp\\.venv\\Scripts\\python.exe",
40
+ "args": [
41
+ "D:\\path\\to\\1102-mcp\\souyun_mcp.py"
42
+ ]
43
+ }
44
+ }
45
+ }
46
+ ```
47
+
48
+ ## 可用工具
49
+
50
+ - `search_poems`: 按关键词检索诗词。`scope` 支持 `All`、`Author`、`Title`、`Sentence` 或数字 `0` 到 `3`;也可按 `dynasty`、`type_`、`rhyme` 和 `pageno` 筛选,`jsontype` 控制 JSON 返回格式。
51
+ - `get_poem`: 按 `poem_id` 查询单首诗词详情。
52
+ - `rhyme_dictionary`: 按 `char` 查询韵典;`qtype` 为 `0` 查全部、`1` 查韵目、`2` 查词末典故、`3` 查词首、`4` 查词末、`5` 查句末诗例。可通过 `page_no` 翻页。
53
+ - `couplet_words`: 查询与 `word` 对仗的词汇。
54
+ - `rhyme_category`: 不传 `rhyme` 时查询平水韵总目;传入韵部时查询该韵包含的字。
55
+ - `collect_lyrics_material`: 按 `theme` 汇总候选诗词、诗句和韵部建议。可设置 `top_n`、`dynasty`、`type_`;传入 `rhyme_char` 时还会返回相关对仗词和典故。
@@ -0,0 +1,13 @@
1
+ [project]
2
+ name = "1102-mcp"
3
+ version = "0.1.0"
4
+ description = "Add your description here"
5
+ readme = "README.md"
6
+ requires-python = ">=3.13"
7
+ dependencies = [
8
+ "fastmcp>=4.1.5",
9
+ "msgpack>=1.1.0",
10
+ ]
11
+
12
+ [tool.setuptools]
13
+ py-modules = ["souyun_mcp"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,176 @@
1
+ """FastMCP server for the Souyun open poem APIs."""
2
+
3
+ import json
4
+ from typing import Any
5
+ from urllib.parse import urlencode
6
+ from urllib.request import Request, urlopen
7
+
8
+ from fastmcp import FastMCP
9
+
10
+ API_BASE = "https://api.sou-yun.cn/open"
11
+ REQUEST_TIMEOUT_SECONDS = 25
12
+
13
+ mcp = FastMCP("搜韵诗词")
14
+
15
+
16
+ def _get(path: str, params: dict[str, Any]) -> Any:
17
+ query = urlencode(
18
+ {key: value for key, value in params.items() if value is not None}
19
+ )
20
+ request = Request(
21
+ f"{API_BASE}{path}?{query}",
22
+ headers={"User-Agent": "Mozilla/5.0", "Accept": "application/json"},
23
+ )
24
+ with urlopen(request, timeout=REQUEST_TIMEOUT_SECONDS) as response:
25
+ return json.loads(response.read().decode("utf-8"))
26
+
27
+
28
+ def _text(node: Any) -> str:
29
+ if isinstance(node, dict):
30
+ return node.get("Content") or node.get("content") or ""
31
+ if isinstance(node, str):
32
+ return node
33
+ return ""
34
+
35
+
36
+ def _search_poems(
37
+ keyword: str,
38
+ scope: str | int = "All",
39
+ dynasty: str | None = None,
40
+ type_: str | None = None,
41
+ rhyme: str | None = None,
42
+ pageno: int = 0,
43
+ jsontype: bool = True,
44
+ ) -> Any:
45
+ params: dict[str, Any] = {
46
+ "key": keyword,
47
+ "scope": scope,
48
+ "jsontype": str(jsontype).lower(),
49
+ "pageno": pageno,
50
+ }
51
+ if dynasty:
52
+ params["dynasty"] = dynasty
53
+ if type_:
54
+ params["type"] = type_
55
+ if rhyme:
56
+ params["rhyme"] = rhyme
57
+ return _get("/poem", params)
58
+
59
+
60
+ def _rhyme_dictionary(char: str, qtype: int = 0, page_no: int = 0) -> Any:
61
+ return _get("/rhymeDictionary", {"id": char, "qtype": qtype, "pageNo": page_no})
62
+
63
+
64
+ def _couplet_words(word: str) -> Any:
65
+ return _get("/coupletwords", {"id": word})
66
+
67
+
68
+ def _rhyme_category(rhyme: str | None = None) -> Any:
69
+ if rhyme:
70
+ return _get("/RhymeCategory", {"id": rhyme})
71
+ return _get("/RhymeCategory", {"list": ""})
72
+
73
+
74
+ def _collect_lyrics_material(
75
+ theme: str,
76
+ top_n: int = 8,
77
+ rhyme_char: str | None = None,
78
+ dynasty: str | None = None,
79
+ type_: str | None = None,
80
+ ) -> dict[str, Any]:
81
+ poems = _search_poems(theme, scope="All", dynasty=dynasty, type_=type_, pageno=0)
82
+ poem_rows = (poems.get("ShiData") or [])[:top_n]
83
+
84
+ candidate_poems = []
85
+ candidate_lines = []
86
+ rhyme_count: dict[str, int] = {}
87
+ for poem in poem_rows:
88
+ candidate_poems.append(
89
+ {
90
+ "id": poem.get("Id"),
91
+ "title": _text(poem.get("Title")),
92
+ "author": poem.get("Author"),
93
+ "dynasty": poem.get("Dynasty"),
94
+ "type": poem.get("Type"),
95
+ "rhyme": poem.get("Rhyme"),
96
+ }
97
+ )
98
+ rhyme = poem.get("Rhyme")
99
+ if rhyme:
100
+ rhyme_count[rhyme] = rhyme_count.get(rhyme, 0) + 1
101
+ for clause in poem.get("Clauses") or []:
102
+ line = _text(clause)
103
+ if line:
104
+ candidate_lines.append(line)
105
+
106
+ result: dict[str, Any] = {
107
+ "theme": theme,
108
+ "candidate_poems": candidate_poems,
109
+ "candidate_lines": candidate_lines,
110
+ "rhyme_suggestions": rhyme_count,
111
+ }
112
+ if rhyme_char:
113
+ result["couplet_words"] = _couplet_words(rhyme_char)
114
+ dictionary = _rhyme_dictionary(rhyme_char)
115
+ result["allusions"] = (
116
+ dictionary.get("Allusions") if isinstance(dictionary, dict) else None
117
+ )
118
+ return result
119
+
120
+
121
+ @mcp.tool
122
+ def search_poems(
123
+ keyword: str,
124
+ scope: str | int = "All",
125
+ dynasty: str | None = None,
126
+ type_: str | None = None,
127
+ rhyme: str | None = None,
128
+ pageno: int = 0,
129
+ jsontype: bool = True,
130
+ ) -> Any:
131
+ """按关键词检索诗词;scope 可选 All、Author、Title、Sentence 或 0 到 3。"""
132
+ return _search_poems(keyword, scope, dynasty, type_, rhyme, pageno, jsontype)
133
+
134
+
135
+ @mcp.tool
136
+ def get_poem(poem_id: str) -> Any:
137
+ """按诗词 ID 获取单首详情。"""
138
+ return _get("/poem", {"key": poem_id, "jsontype": "true"})
139
+
140
+
141
+ @mcp.tool
142
+ def rhyme_dictionary(char: str, qtype: int = 0, page_no: int = 0) -> Any:
143
+ """查询韵典;qtype 为 0 查全部,1 查韵目,2 查词末典故,3/4 查词首/词末,5 查句末诗例。"""
144
+ return _rhyme_dictionary(char, qtype, page_no)
145
+
146
+
147
+ @mcp.tool
148
+ def couplet_words(word: str) -> Any:
149
+ """查询与输入字词对仗的词汇参考。"""
150
+ return _couplet_words(word)
151
+
152
+
153
+ @mcp.tool
154
+ def rhyme_category(rhyme: str | None = None) -> Any:
155
+ """查询平水韵总目,或查询指定韵部包含的字。"""
156
+ return _rhyme_category(rhyme)
157
+
158
+
159
+ @mcp.tool
160
+ def collect_lyrics_material(
161
+ theme: str,
162
+ top_n: int = 8,
163
+ rhyme_char: str | None = None,
164
+ dynasty: str | None = None,
165
+ type_: str | None = None,
166
+ ) -> dict[str, Any]:
167
+ """汇总主题相关诗词、诗句、韵部建议,可选附加对仗词和典故。"""
168
+ return _collect_lyrics_material(theme, top_n, rhyme_char, dynasty, type_)
169
+
170
+
171
+ def main() -> None:
172
+ mcp.run(transport="stdio")
173
+
174
+
175
+ if __name__ == "__main__":
176
+ main()