cuqu-mcp 1.0.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.
cuqu_mcp-1.0.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 光天科技(深圳)有限公司 (Guangtian Technology (Shenzhen) Co., Ltd.)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,102 @@
1
+ Metadata-Version: 2.4
2
+ Name: cuqu-mcp
3
+ Version: 1.0.0
4
+ Summary: MCP server for CUQU (找搭子) — find and book offline group events in 10+ China cities, or publish your own event.
5
+ Author: CUQU / 光天科技(深圳)有限公司
6
+ License: MIT License
7
+
8
+ Copyright (c) 2026 光天科技(深圳)有限公司 (Guangtian Technology (Shenzhen) Co., Ltd.)
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+
28
+ Project-URL: Homepage, https://cuqu.net
29
+ Project-URL: Repository, https://github.com/cuqu-net/cuqu-skill
30
+ Project-URL: MCP endpoint, https://agent.cuqu.net/mcp
31
+ Project-URL: llms.txt, https://cuqu.net/llms.txt
32
+ Keywords: mcp,cuqu,model-context-protocol,activities,social,events,shenzhen
33
+ Classifier: Programming Language :: Python :: 3
34
+ Classifier: License :: OSI Approved :: MIT License
35
+ Classifier: Operating System :: OS Independent
36
+ Classifier: Intended Audience :: Developers
37
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
38
+ Requires-Python: >=3.9
39
+ Description-Content-Type: text/markdown
40
+ License-File: LICENSE
41
+ Dynamic: license-file
42
+
43
+ # CUQU (找搭子) MCP Server
44
+
45
+ Open-source MCP server giving AI agents live access to **[CUQU (找搭子)](https://cuqu.net)** — a local offline social activities platform in China (Shenzhen-based, 10+ cities incl. Hong Kong, China). Users discover and book offline interest-based group activities (board games, frisbee, hiking, badminton, fishing, anime and 100+ more categories); organizers publish and run events.
46
+
47
+ **Live demo endpoint (hosted):** `https://agent.cuqu.net/mcp` (Streamable HTTP, per-user `cq-sk-` keys — see [llms.txt](https://cuqu.net/llms.txt))
48
+ **Agent Card:** https://cuqu.net/.well-known/agent.json
49
+
50
+ ## What this repository contains
51
+
52
+ | Path | What it is |
53
+ |---|---|
54
+ | `server.py` | **The MCP server implementation** — zero-dependency Python, JSON-RPC 2.0 over stdio. Read tools call CUQU's public live activity API; write tools forward to the hosted gateway with a user key. |
55
+ | `Dockerfile` | One-command container build for the server (glama.ai / docker / any MCP host). |
56
+ | `glama.json` | glama.ai directory metadata & maintainership. |
57
+ | `scripts/check-mcp.py` | Connectivity check for the hosted gateway. |
58
+ | `skills/`, `docs/` | Agent skill manifests and platform integration docs (Qwen/Dify/Yuanqi). |
59
+
60
+ ## Tools (8)
61
+
62
+ | Tool | Type | Description |
63
+ |---|---|---|
64
+ | `query_activities` | read (no key) | Search live activities by type / city / date — 100+ categories, real-time public data |
65
+ | `get_activity_card` | read (no key) | Full detail card for one activity (time, venue, price, booking progress, organizer, cover) |
66
+ | `query_venues` | read (no key) | Curated partner venue directory (capacity, per-head price) |
67
+ | `generate_urllink` | read (no key) | Share link + WeChat mini-program path for an activity |
68
+ | `create_activity` | write (key) | Organizer publishes a new event |
69
+ | `register_event` | write (key) | Book a user into an activity |
70
+ | `create_payment` | write (key) | Create WeChat Pay for a booking order |
71
+ | `check_in` | write (key) | On-site check-in / redemption |
72
+
73
+ Write tools are executed by the hosted gateway and require `CUQU_API_KEY` (`cq-sk-...`, issued via scan-to-issue flow documented in [llms.txt](https://cuqu.net/llms.txt)).
74
+
75
+ ## Quick start
76
+
77
+ ```bash
78
+ # stdio, zero dependencies, Python 3.9+
79
+ python -u server.py
80
+
81
+ # or via Docker
82
+ docker build -t cuqu-mcp .
83
+ docker run -i cuqu-mcp
84
+ ```
85
+
86
+ Claude Desktop / any stdio MCP client:
87
+
88
+ ```json
89
+ {
90
+ "mcpServers": {
91
+ "cuqu": {
92
+ "command": "python",
93
+ "args": ["-u", "/path/to/server.py"],
94
+ "env": { "CUQU_API_KEY": "cq-sk-...(optional, enables write tools)" }
95
+ }
96
+ }
97
+ }
98
+ ```
99
+
100
+ ## License
101
+
102
+ MIT — © 2026 光天科技(深圳)有限公司 (Guangtian Technology (Shenzhen) Co., Ltd.)
@@ -0,0 +1,60 @@
1
+ # CUQU (找搭子) MCP Server
2
+
3
+ Open-source MCP server giving AI agents live access to **[CUQU (找搭子)](https://cuqu.net)** — a local offline social activities platform in China (Shenzhen-based, 10+ cities incl. Hong Kong, China). Users discover and book offline interest-based group activities (board games, frisbee, hiking, badminton, fishing, anime and 100+ more categories); organizers publish and run events.
4
+
5
+ **Live demo endpoint (hosted):** `https://agent.cuqu.net/mcp` (Streamable HTTP, per-user `cq-sk-` keys — see [llms.txt](https://cuqu.net/llms.txt))
6
+ **Agent Card:** https://cuqu.net/.well-known/agent.json
7
+
8
+ ## What this repository contains
9
+
10
+ | Path | What it is |
11
+ |---|---|
12
+ | `server.py` | **The MCP server implementation** — zero-dependency Python, JSON-RPC 2.0 over stdio. Read tools call CUQU's public live activity API; write tools forward to the hosted gateway with a user key. |
13
+ | `Dockerfile` | One-command container build for the server (glama.ai / docker / any MCP host). |
14
+ | `glama.json` | glama.ai directory metadata & maintainership. |
15
+ | `scripts/check-mcp.py` | Connectivity check for the hosted gateway. |
16
+ | `skills/`, `docs/` | Agent skill manifests and platform integration docs (Qwen/Dify/Yuanqi). |
17
+
18
+ ## Tools (8)
19
+
20
+ | Tool | Type | Description |
21
+ |---|---|---|
22
+ | `query_activities` | read (no key) | Search live activities by type / city / date — 100+ categories, real-time public data |
23
+ | `get_activity_card` | read (no key) | Full detail card for one activity (time, venue, price, booking progress, organizer, cover) |
24
+ | `query_venues` | read (no key) | Curated partner venue directory (capacity, per-head price) |
25
+ | `generate_urllink` | read (no key) | Share link + WeChat mini-program path for an activity |
26
+ | `create_activity` | write (key) | Organizer publishes a new event |
27
+ | `register_event` | write (key) | Book a user into an activity |
28
+ | `create_payment` | write (key) | Create WeChat Pay for a booking order |
29
+ | `check_in` | write (key) | On-site check-in / redemption |
30
+
31
+ Write tools are executed by the hosted gateway and require `CUQU_API_KEY` (`cq-sk-...`, issued via scan-to-issue flow documented in [llms.txt](https://cuqu.net/llms.txt)).
32
+
33
+ ## Quick start
34
+
35
+ ```bash
36
+ # stdio, zero dependencies, Python 3.9+
37
+ python -u server.py
38
+
39
+ # or via Docker
40
+ docker build -t cuqu-mcp .
41
+ docker run -i cuqu-mcp
42
+ ```
43
+
44
+ Claude Desktop / any stdio MCP client:
45
+
46
+ ```json
47
+ {
48
+ "mcpServers": {
49
+ "cuqu": {
50
+ "command": "python",
51
+ "args": ["-u", "/path/to/server.py"],
52
+ "env": { "CUQU_API_KEY": "cq-sk-...(optional, enables write tools)" }
53
+ }
54
+ }
55
+ }
56
+ ```
57
+
58
+ ## License
59
+
60
+ MIT — © 2026 光天科技(深圳)有限公司 (Guangtian Technology (Shenzhen) Co., Ltd.)
@@ -0,0 +1,102 @@
1
+ Metadata-Version: 2.4
2
+ Name: cuqu-mcp
3
+ Version: 1.0.0
4
+ Summary: MCP server for CUQU (找搭子) — find and book offline group events in 10+ China cities, or publish your own event.
5
+ Author: CUQU / 光天科技(深圳)有限公司
6
+ License: MIT License
7
+
8
+ Copyright (c) 2026 光天科技(深圳)有限公司 (Guangtian Technology (Shenzhen) Co., Ltd.)
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+
28
+ Project-URL: Homepage, https://cuqu.net
29
+ Project-URL: Repository, https://github.com/cuqu-net/cuqu-skill
30
+ Project-URL: MCP endpoint, https://agent.cuqu.net/mcp
31
+ Project-URL: llms.txt, https://cuqu.net/llms.txt
32
+ Keywords: mcp,cuqu,model-context-protocol,activities,social,events,shenzhen
33
+ Classifier: Programming Language :: Python :: 3
34
+ Classifier: License :: OSI Approved :: MIT License
35
+ Classifier: Operating System :: OS Independent
36
+ Classifier: Intended Audience :: Developers
37
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
38
+ Requires-Python: >=3.9
39
+ Description-Content-Type: text/markdown
40
+ License-File: LICENSE
41
+ Dynamic: license-file
42
+
43
+ # CUQU (找搭子) MCP Server
44
+
45
+ Open-source MCP server giving AI agents live access to **[CUQU (找搭子)](https://cuqu.net)** — a local offline social activities platform in China (Shenzhen-based, 10+ cities incl. Hong Kong, China). Users discover and book offline interest-based group activities (board games, frisbee, hiking, badminton, fishing, anime and 100+ more categories); organizers publish and run events.
46
+
47
+ **Live demo endpoint (hosted):** `https://agent.cuqu.net/mcp` (Streamable HTTP, per-user `cq-sk-` keys — see [llms.txt](https://cuqu.net/llms.txt))
48
+ **Agent Card:** https://cuqu.net/.well-known/agent.json
49
+
50
+ ## What this repository contains
51
+
52
+ | Path | What it is |
53
+ |---|---|
54
+ | `server.py` | **The MCP server implementation** — zero-dependency Python, JSON-RPC 2.0 over stdio. Read tools call CUQU's public live activity API; write tools forward to the hosted gateway with a user key. |
55
+ | `Dockerfile` | One-command container build for the server (glama.ai / docker / any MCP host). |
56
+ | `glama.json` | glama.ai directory metadata & maintainership. |
57
+ | `scripts/check-mcp.py` | Connectivity check for the hosted gateway. |
58
+ | `skills/`, `docs/` | Agent skill manifests and platform integration docs (Qwen/Dify/Yuanqi). |
59
+
60
+ ## Tools (8)
61
+
62
+ | Tool | Type | Description |
63
+ |---|---|---|
64
+ | `query_activities` | read (no key) | Search live activities by type / city / date — 100+ categories, real-time public data |
65
+ | `get_activity_card` | read (no key) | Full detail card for one activity (time, venue, price, booking progress, organizer, cover) |
66
+ | `query_venues` | read (no key) | Curated partner venue directory (capacity, per-head price) |
67
+ | `generate_urllink` | read (no key) | Share link + WeChat mini-program path for an activity |
68
+ | `create_activity` | write (key) | Organizer publishes a new event |
69
+ | `register_event` | write (key) | Book a user into an activity |
70
+ | `create_payment` | write (key) | Create WeChat Pay for a booking order |
71
+ | `check_in` | write (key) | On-site check-in / redemption |
72
+
73
+ Write tools are executed by the hosted gateway and require `CUQU_API_KEY` (`cq-sk-...`, issued via scan-to-issue flow documented in [llms.txt](https://cuqu.net/llms.txt)).
74
+
75
+ ## Quick start
76
+
77
+ ```bash
78
+ # stdio, zero dependencies, Python 3.9+
79
+ python -u server.py
80
+
81
+ # or via Docker
82
+ docker build -t cuqu-mcp .
83
+ docker run -i cuqu-mcp
84
+ ```
85
+
86
+ Claude Desktop / any stdio MCP client:
87
+
88
+ ```json
89
+ {
90
+ "mcpServers": {
91
+ "cuqu": {
92
+ "command": "python",
93
+ "args": ["-u", "/path/to/server.py"],
94
+ "env": { "CUQU_API_KEY": "cq-sk-...(optional, enables write tools)" }
95
+ }
96
+ }
97
+ }
98
+ ```
99
+
100
+ ## License
101
+
102
+ MIT — © 2026 光天科技(深圳)有限公司 (Guangtian Technology (Shenzhen) Co., Ltd.)
@@ -0,0 +1,9 @@
1
+ LICENSE
2
+ README.md
3
+ pyproject.toml
4
+ server.py
5
+ cuqu_mcp.egg-info/PKG-INFO
6
+ cuqu_mcp.egg-info/SOURCES.txt
7
+ cuqu_mcp.egg-info/dependency_links.txt
8
+ cuqu_mcp.egg-info/entry_points.txt
9
+ cuqu_mcp.egg-info/top_level.txt
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ cuqu-mcp = server:main
@@ -0,0 +1 @@
1
+ server
@@ -0,0 +1,36 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "cuqu-mcp"
7
+ version = "1.0.0"
8
+ description = "MCP server for CUQU (找搭子) — find and book offline group events in 10+ China cities, or publish your own event."
9
+ readme = "README.md"
10
+ requires-python = ">=3.9"
11
+ license = { file = "LICENSE" }
12
+ authors = [
13
+ { name = "CUQU / 光天科技(深圳)有限公司" }
14
+ ]
15
+ keywords = ["mcp", "cuqu", "model-context-protocol", "activities", "social", "events", "shenzhen"]
16
+ classifiers = [
17
+ "Programming Language :: Python :: 3",
18
+ "License :: OSI Approved :: MIT License",
19
+ "Operating System :: OS Independent",
20
+ "Intended Audience :: Developers",
21
+ "Topic :: Software Development :: Libraries :: Python Modules",
22
+ ]
23
+ # 零依赖实现(仅用标准库),便于在任何 MCP 宿主里直接跑
24
+ dependencies = []
25
+
26
+ [project.urls]
27
+ Homepage = "https://cuqu.net"
28
+ Repository = "https://github.com/cuqu-net/cuqu-skill"
29
+ "MCP endpoint" = "https://agent.cuqu.net/mcp"
30
+ "llms.txt" = "https://cuqu.net/llms.txt"
31
+
32
+ [project.scripts]
33
+ cuqu-mcp = "server:main"
34
+
35
+ [tool.setuptools]
36
+ py-modules = ["server"]
@@ -0,0 +1,255 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """
4
+ CUQU (找搭子) MCP Server — reference implementation
5
+ ====================================================
6
+ An open-source MCP server (JSON-RPC 2.0 over stdio) that gives AI agents
7
+ live access to CUQU's local offline social activities platform
8
+ (Shenzhen-based, 10+ cities incl. Hong Kong, China).
9
+
10
+ Tools
11
+ -----
12
+ Read tools (work out of the box, no key required):
13
+ - query_activities → live data from CUQU's public activity API
14
+ - get_activity_card → details for a single activity
15
+ - query_venues → curated partner venue directory (bundled data)
16
+ - generate_urllink → share-link / mini-program path generator
17
+
18
+ Write tools (forwarded to the hosted gateway https://agent.cuqu.net/mcp,
19
+ require a per-user key `cq-sk-...` in env CUQU_API_KEY — see
20
+ https://cuqu.net/llms.txt for how to get one):
21
+ - create_activity, register_event, create_payment, check_in
22
+
23
+ Zero dependencies, Python 3.9+. Run: python -u server.py
24
+ """
25
+ import json
26
+ import os
27
+ import sys
28
+ import urllib.parse
29
+ import urllib.request
30
+ from datetime import datetime, timedelta, timezone
31
+
32
+ CN = timezone(timedelta(hours=8))
33
+ API = os.environ.get("CUQU_API_BASE", "https://cuqu.net/api/activity")
34
+ GATEWAY = os.environ.get("CUQU_MCP_URL", "https://agent.cuqu.net/mcp")
35
+ API_KEY = os.environ.get("CUQU_API_KEY", "")
36
+ UA = {"User-Agent": "cuqu-mcp-server/1.0 (+https://github.com/cuqu-net/cuqu-skill)"}
37
+
38
+ VENUES = [
39
+ {"name": "南山体育中心羽毛球馆", "district": "南山", "types": ["羽毛球", "匹克球"],
40
+ "capacity": 24, "per_head": 30, "note": "6片场地, 可租拍"},
41
+ {"name": "科兴科学园·桌游吧", "district": "南山", "types": ["桌游", "二次元", "读书会"],
42
+ "capacity": 16, "per_head": 38, "note": "300+盒收藏, 含饮品"},
43
+ {"name": "深圳湾日出草坪", "district": "南山", "types": ["飞盘", "徒步"],
44
+ "capacity": 40, "per_head": 0, "note": "公共草坪, 免费, 自备装备"},
45
+ {"name": "福田体育公园", "district": "福田", "types": ["羽毛球", "飞盘"],
46
+ "capacity": 30, "per_head": 32, "note": "多项目场馆"},
47
+ {"name": "华侨城创意园·咖啡书吧", "district": "南山", "types": ["读书会", "烘焙"],
48
+ "capacity": 20, "per_head": 45, "note": "含场地费+基础饮品"},
49
+ {"name": "蛇口海上世界钓点", "district": "南山", "types": ["钓鱼", "海上娱乐"],
50
+ "capacity": 15, "per_head": 120, "note": "海排钓, 含装备租"},
51
+ ]
52
+
53
+ TOOLS = [
54
+ {"name": "query_activities",
55
+ "description": "查询CUQU找搭子平台上的线下活动(桌游/飞盘/徒步/羽毛球/二次元/钓鱼等100+品类,覆盖深圳等10+城市,含中国香港)。数据为平台实时公开数据。",
56
+ "inputSchema": {"type": "object", "properties": {
57
+ "activity_type": {"type": "string", "description": "活动类型关键词,如 桌游/羽毛球/飞盘"},
58
+ "city": {"type": "string", "description": "城市,默认 深圳"},
59
+ "date": {"type": "string", "description": "日期 YYYY-MM-DD,筛选当天活动"}}}},
60
+ {"name": "get_activity_card",
61
+ "description": "获取指定活动的完整详情卡片(时间地点、费用、报名进度、主理人、封面图、报名链接)。",
62
+ "inputSchema": {"type": "object", "properties": {
63
+ "activity_id": {"type": "string"}}, "required": ["activity_id"]}},
64
+ {"name": "query_venues",
65
+ "description": "查询合作场地目录(按城市和活动类型匹配,含容量与人均价)。",
66
+ "inputSchema": {"type": "object", "properties": {
67
+ "city": {"type": "string"}, "activity_type": {"type": "string"}},
68
+ "required": ["city"]}},
69
+ {"name": "generate_urllink",
70
+ "description": "生成活动的分享链接与小程序路径(可直接用于唤起微信)。",
71
+ "inputSchema": {"type": "object", "properties": {
72
+ "activity_id": {"type": "string"}}, "required": ["activity_id"]}},
73
+ {"name": "create_activity",
74
+ "description": "主理人发布新活动(写操作,经托管网关提交,需 CUQU_API_KEY)。",
75
+ "inputSchema": {"type": "object", "properties": {
76
+ "title": {"type": "string"}, "activity_type": {"type": "string"},
77
+ "date": {"type": "string"}, "time": {"type": "string"},
78
+ "location": {"type": "string"}, "max_participants": {"type": "number"},
79
+ "price": {"type": "number"}, "description": {"type": "string"}},
80
+ "required": ["title", "activity_type", "date", "time", "location"]}},
81
+ {"name": "register_event",
82
+ "description": "为用户报名指定活动(写操作,需 CUQU_API_KEY)。",
83
+ "inputSchema": {"type": "object", "properties": {
84
+ "activity_id": {"type": "string"}, "user_id": {"type": "string"}},
85
+ "required": ["activity_id"]}},
86
+ {"name": "create_payment",
87
+ "description": "为报名订单创建微信支付(写操作,需 CUQU_API_KEY)。",
88
+ "inputSchema": {"type": "object", "properties": {
89
+ "order_id": {"type": "string"}}, "required": ["order_id"]}},
90
+ {"name": "check_in",
91
+ "description": "活动现场签到核销(写操作,需 CUQU_API_KEY)。",
92
+ "inputSchema": {"type": "object", "properties": {
93
+ "activity_id": {"type": "string"}, "code": {"type": "string"}},
94
+ "required": ["activity_id"]}},
95
+ ]
96
+ WRITE_TOOLS = {"create_activity", "register_event", "create_payment", "check_in"}
97
+
98
+
99
+ # ---------------- 数据层(真实实现) ----------------
100
+ def fetch_activities():
101
+ req = urllib.request.Request(API, headers=UA)
102
+ with urllib.request.urlopen(req, timeout=30) as r:
103
+ d = json.loads(r.read())
104
+ if d.get("code") != 0:
105
+ raise RuntimeError(f"api error: {d.get('msg')}")
106
+ return d["data"]["list"]
107
+
108
+
109
+ def norm(a):
110
+ st = datetime.fromtimestamp(a.get("start_time", 0) / 1000, tz=CN)
111
+ et = datetime.fromtimestamp(a.get("end_time", 0) / 1000, tz=CN)
112
+ aid = a.get("_id", "")
113
+ return {
114
+ "id": aid,
115
+ "title": a.get("title"),
116
+ "type": a.get("preference"),
117
+ "date": st.strftime("%Y-%m-%d"),
118
+ "time": f"{st.strftime('%H:%M')}-{et.strftime('%H:%M')}",
119
+ "weekday": "一二三四五六日"[st.weekday()],
120
+ "location": a.get("location"),
121
+ "price": a.get("price"),
122
+ "fee_type": a.get("fee_type"),
123
+ "current_participants": a.get("current_participants"),
124
+ "max_participants": a.get("max_participants"),
125
+ "organizer": a.get("creator_name"),
126
+ "cover": a.get("cover"),
127
+ "url": f"https://cuqu.net/activities/list/{aid}.html",
128
+ }
129
+
130
+
131
+ def tool_query_activities(args):
132
+ atype = (args.get("activity_type") or "").strip()
133
+ city = (args.get("city") or "").strip()
134
+ date = (args.get("date") or "").strip()
135
+ items = [norm(a) for a in fetch_activities()]
136
+ if atype:
137
+ items = [x for x in items if atype in (x["type"] or "")]
138
+ if date:
139
+ items = [x for x in items if x["date"] == date]
140
+ if city and city != "深圳":
141
+ items = [x for x in items if city in (x["location"] or "")]
142
+ return {"total": len(items), "note": "数据来自CUQU公开活动API(实时)",
143
+ "items": items[:20]}
144
+
145
+
146
+ def tool_get_activity_card(args):
147
+ aid = (args.get("activity_id") or "").strip()
148
+ for a in fetch_activities():
149
+ if a.get("_id") == aid:
150
+ return norm(a)
151
+ return {"error": f"未找到活动 {aid}(可能已结束或不在最新列表)",
152
+ "hint": "先用 query_activities 获取有效 id"}
153
+
154
+
155
+ def tool_query_venues(args):
156
+ atype = (args.get("activity_type") or "").strip()
157
+ hits = [v for v in VENUES if not atype or atype in v["types"]]
158
+ return {"city": args.get("city") or "深圳", "venues": hits or VENUES[:3]}
159
+
160
+
161
+ def tool_generate_urllink(args):
162
+ aid = (args.get("activity_id") or "").strip()
163
+ return {"url": f"https://cuqu.net/activities/list/{aid}.html",
164
+ "mini_program_path": f"pages/activity/detail?id={aid}",
165
+ "mini_program": "微信搜小程序「CUQU找搭子」"}
166
+
167
+
168
+ def forward_write(name, args):
169
+ if not API_KEY:
170
+ return {"content": [{"type": "text", "text":
171
+ f"{name} 为写操作,需要 CUQU_API_KEY(cq-sk- 开头)。"
172
+ "申领方式见 https://cuqu.net/llms.txt"}], "isError": True}
173
+ body = json.dumps({"jsonrpc": "2.0", "id": 1, "method": "tools/call",
174
+ "params": {"name": name, "arguments": args}}).encode()
175
+ req = urllib.request.Request(
176
+ GATEWAY, data=body, method="POST",
177
+ headers={"Content-Type": "application/json",
178
+ "Accept": "application/json, text/event-stream",
179
+ "Authorization": "Bearer " + API_KEY})
180
+ raw = urllib.request.urlopen(req, timeout=60).read().decode("utf-8", "ignore")
181
+ for line in raw.splitlines():
182
+ line = line.strip()
183
+ if line.startswith("data:"):
184
+ r = json.loads(line[5:].strip())
185
+ return r.get("result", r)
186
+ r = json.loads(raw)
187
+ return r.get("result", r)
188
+
189
+
190
+ IMPL = {"query_activities": tool_query_activities,
191
+ "get_activity_card": tool_get_activity_card,
192
+ "query_venues": tool_query_venues,
193
+ "generate_urllink": tool_generate_urllink}
194
+
195
+
196
+ # ---------------- MCP 协议层 ----------------
197
+ def reply(rid, result=None, error=None):
198
+ msg = {"jsonrpc": "2.0", "id": rid}
199
+ if error is not None:
200
+ msg["error"] = error
201
+ else:
202
+ msg["result"] = result
203
+ sys.stdout.write(json.dumps(msg, ensure_ascii=False) + "\n")
204
+ sys.stdout.flush()
205
+
206
+
207
+ def handle(msg):
208
+ method, rid = msg.get("method"), msg.get("id")
209
+ if method == "initialize":
210
+ reply(rid, {"protocolVersion": msg.get("params", {}).get(
211
+ "protocolVersion", "2024-11-05"),
212
+ "capabilities": {"tools": {}},
213
+ "serverInfo": {"name": "cuqu-mcp", "version": "1.0.0"}})
214
+ elif method in ("notifications/initialized", "notifications/cancelled"):
215
+ pass
216
+ elif method == "ping":
217
+ reply(rid, {})
218
+ elif method == "tools/list":
219
+ reply(rid, {"tools": TOOLS})
220
+ elif method == "tools/call":
221
+ params = msg.get("params") or {}
222
+ name, args = params.get("name", ""), params.get("arguments") or {}
223
+ try:
224
+ if name in IMPL:
225
+ result = IMPL[name](args)
226
+ elif name in WRITE_TOOLS:
227
+ reply(rid, forward_write(name, args))
228
+ return
229
+ else:
230
+ reply(rid, error={"code": -32602,
231
+ "message": f"unknown tool: {name}"})
232
+ return
233
+ reply(rid, {"content": [{"type": "text", "text": json.dumps(
234
+ result, ensure_ascii=False, indent=2)}]})
235
+ except Exception as e: # noqa: BLE001
236
+ reply(rid, {"content": [{"type": "text",
237
+ "text": f"tool error: {e}"}],
238
+ "isError": True})
239
+ elif rid is not None:
240
+ reply(rid, error={"code": -32601, "message": "method not found"})
241
+
242
+
243
+ def main():
244
+ for line in sys.stdin:
245
+ line = line.strip()
246
+ if not line:
247
+ continue
248
+ try:
249
+ handle(json.loads(line))
250
+ except Exception as e: # noqa: BLE001
251
+ sys.stderr.write(f"bad line: {e}\n")
252
+
253
+
254
+ if __name__ == "__main__":
255
+ main()
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+