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 +21 -0
- cuqu_mcp-1.0.0/PKG-INFO +102 -0
- cuqu_mcp-1.0.0/README.md +60 -0
- cuqu_mcp-1.0.0/cuqu_mcp.egg-info/PKG-INFO +102 -0
- cuqu_mcp-1.0.0/cuqu_mcp.egg-info/SOURCES.txt +9 -0
- cuqu_mcp-1.0.0/cuqu_mcp.egg-info/dependency_links.txt +1 -0
- cuqu_mcp-1.0.0/cuqu_mcp.egg-info/entry_points.txt +2 -0
- cuqu_mcp-1.0.0/cuqu_mcp.egg-info/top_level.txt +1 -0
- cuqu_mcp-1.0.0/pyproject.toml +36 -0
- cuqu_mcp-1.0.0/server.py +255 -0
- cuqu_mcp-1.0.0/setup.cfg +4 -0
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.
|
cuqu_mcp-1.0.0/PKG-INFO
ADDED
|
@@ -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.)
|
cuqu_mcp-1.0.0/README.md
ADDED
|
@@ -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 @@
|
|
|
1
|
+
|
|
@@ -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"]
|
cuqu_mcp-1.0.0/server.py
ADDED
|
@@ -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()
|
cuqu_mcp-1.0.0/setup.cfg
ADDED