mdymcp 0.1.2__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.
mdymcp-0.1.2/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026
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.
mdymcp-0.1.2/PKG-INFO ADDED
@@ -0,0 +1,222 @@
1
+ Metadata-Version: 2.4
2
+ Name: mdymcp
3
+ Version: 0.1.2
4
+ Summary: Unified MCP server for Mingdao — v1 collaboration API + HAP gateway (worksheets, records, apps)
5
+ Author-email: Andy Lei <andy.lei@mingdao.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/andyleimc-source/mdmcp
8
+ Project-URL: Repository, https://github.com/andyleimc-source/mdmcp
9
+ Project-URL: Issues, https://github.com/andyleimc-source/mdmcp/issues
10
+ Keywords: mcp,mingdao,hap,worksheet,collaboration,claude
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Programming Language :: Python :: 3.14
21
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
22
+ Requires-Python: >=3.10
23
+ Description-Content-Type: text/markdown
24
+ License-File: LICENSE
25
+ Requires-Dist: mcp[cli]>=1.0.0
26
+ Requires-Dist: certifi>=2024.2.2
27
+ Dynamic: license-file
28
+
29
+ # mdmcp
30
+
31
+ **明道(Mingdao)统一 MCP Server** — 一次安装,获得 **v1 协作 API 50 个工具 + HAP 网关 48 个工具**,共计 ~98 个工具。
32
+
33
+ 由 [雷码工坊](https://github.com/andyleimc-source) 维护。取代早期的 [`md-cloud`](https://github.com/andyleimc-source/md-cloud)(只含 v1)和 [`hap-mcp-cloud-refresh`](https://github.com/andyleimc-source/hap-mcp-cloud-refresh)(Node.js 只含 HAP)。
34
+
35
+ ---
36
+
37
+ ## 一键安装
38
+
39
+ > 要求:macOS / Linux,Python ≥ 3.10(推荐 Homebrew `python@3.12` 或更高),项目目录**不要放 iCloud 同步路径**(如 `~/Desktop`、`~/Documents`),建议放 `~/Downloads`、`~/code` 等本地目录。
40
+
41
+ ```bash
42
+ git clone https://github.com/andyleimc-source/mdmcp.git
43
+ cd mdmcp
44
+ python3 install.py
45
+ ```
46
+
47
+ 交互脚本会自动:
48
+
49
+ 1. 建 `.venv` 并装依赖
50
+ 2. 浏览器 OAuth 拿 v1 凭据 → 写入 `.env`
51
+ 3. **提示你粘贴 HAP 凭据**(refresh_token + access token,下面教你怎么拿)→ 自动 register 拿 `hap_key` → 写入 `.env`
52
+ 4. **自动检测**你装的 MCP 客户端,注册到 **Claude Code** 和/或 **Codex CLI**(用户级,全局生效)
53
+ 5. 验证 token 可拉
54
+
55
+ > **多客户端支持**:脚本会扫 `claude` 和 `codex` 两个 CLI,**装哪个就自动注册到哪个**,都装就都配。手动指定客户端:`--client=claude` / `--client=codex` / `--client=both`。
56
+ >
57
+ > **注册范围**:步骤 4 会问"用户级 / 项目级 / 两个都配"(默认用户级,全局生效)。CI / 想跳过这个问题:加 `--project` 强制项目级 + 用户级。
58
+
59
+ 装完重启 Claude Code,直接对话即可:
60
+
61
+ - "帮我看看最近公司动态" → `post_get_all_posts`(v1)
62
+ - "列出我的全部应用" → `get_app_list`(HAP)
63
+ - "在 XX 工作表新增一行记录" → `create_record`(HAP)
64
+
65
+ > 调试模式:`MDMCP_INSTALL_DEBUG=1 python3 install.py` 或 `python3 install.py --debug`,会逐步显示每个 hook 的请求体/响应并 y/n 拦截,仅开发者用。
66
+
67
+ ---
68
+
69
+ ## 怎么拿 HAP 的 refresh_token 和 access token
70
+
71
+ HAP 网关需要在明道**集成中心**做一次个人授权,拿到一对 `refresh_token` + `access_token` 喂给 install 脚本。
72
+
73
+ ### 第 1 步:集成中心 → API 库 → HAP API(个人授权)→ 立即授权
74
+
75
+ ![step1](docs/images/hap-step1-authorize.png)
76
+
77
+ 进入「集成 → API 库」,找到 **HAP API(个人授权)**,点右上角「立即授权」走完 OAuth 流程。
78
+
79
+ ### 第 2 步:「我的连接 → 授权」tab,找到刚授权的连接
80
+
81
+ ![step2](docs/images/hap-step2-connections.png)
82
+
83
+ ### 第 3 步:进入连接,在账户行点 `...` → 查看日志
84
+
85
+ ![step3](docs/images/hap-step3-account-menu.png)
86
+
87
+ ### 第 4 步:在日志列表中找一条「获取 token」→ 点查看详情
88
+
89
+ ![step4](docs/images/hap-step4-log-list.png)
90
+
91
+ ### 第 5 步:在「返回值」标签里复制 `access_token` 和 `refresh_token`
92
+
93
+ ![step5](docs/images/hap-step5-tokens.png)
94
+
95
+ 把这两个值在 install.py 提示时分别粘到:
96
+ - `MD_HAP_TOKEN:` ← 粘 `access_token`
97
+ - `MD_HAP_REFRESH_TOKEN:` ← 粘 `refresh_token`
98
+
99
+ > 这两个 token 只在 `install.py` 时用一次(用于把你的账号绑定到服务端,换出长期 `hap_key`)。绑定完成后 Claude Code 运行时只用 `hap_key` + `account_id` 调 token hook 拿当天的 HAP token,不再需要它们。
100
+
101
+ ---
102
+
103
+ ## 功能总览
104
+
105
+ ### 一、v1 协作 API 工具(50 个,本地实现)
106
+
107
+ | 模块 | 数量 | 主要能力 |
108
+ |------|-----|---------|
109
+ | 动态 (post) | 9 | 全公司/我的/用户/群组动态、详情、评论、发布、删除 |
110
+ | 日程 (calendar) | 8 | 列表、详情、邀请、搜索、创建、编辑、删除 |
111
+ | 私信 (webchat) | 6 | 会话、消息、未读、发送 |
112
+ | 收件箱 (message) | 2 | 系统通知、动态相关通知 |
113
+ | 群组 (group) | 10 | 详情、成员、加入/创建、管理员管理 |
114
+ | 用户 (user) | 6 | 联系人、组织成员、@搜索、按手机/邮箱查找 |
115
+ | 组织 (company) | 3 | 组织、部门、按 ID 查询 |
116
+ | 个人账户 (passport) | 4 | 当前用户详情、设置、未读、名片 |
117
+
118
+ 工具签名与 `md-cloud` / `mdold` 完全一致,drop-in 可替换。
119
+
120
+ ### 二、HAP 网关工具(48 个,透明代理)
121
+
122
+ 启动时自动拉取 `api2.mingdao.com/mcp` 的工具清单并注册到本地 MCP。覆盖:
123
+
124
+ - **应用管理**:`get_app_list` / `get_app_info` / `create_app` / `update_app` / `delete_app`
125
+ - **工作表**:`get_app_worksheets_list` / `get_worksheet_structure` / `create_worksheet` / `update_worksheet` / `delete_worksheet`
126
+ - **记录**:`get_record_list` / `get_record_details` / `create_record` / `update_record` / `delete_record` / 批量增删改 / `get_record_logs` / `get_record_relations` / `get_record_discussions` / `get_record_share_link` / `get_record_pivot_data`
127
+ - **角色/成员**:`get_role_list` / `create_role` / `delete_role` / `add_member_to_role` / `remove_member_from_role` / `find_member` / `find_department` / `leave_all_roles`
128
+ - **工作流 / 审批**:`get_workflow_list` / `get_workflow_details` / `trigger_workflow` / `get_approval_list_by_row` / `get_approval_detail`
129
+ - **图表 / 自定义页**:`create_chart` / `save_custom_page`
130
+ - **选项集 / 知识库 / 地区 / 组织**:`create_optionset` / `update_optionset` / `delete_optionset` / `get_optionset_list` / `knowledge_search` / `get_app_knowledge_list` / `get_regions` / `get_org_list`
131
+ - **工具**:`get_time`
132
+
133
+ HAP 工具由远端网关动态提供;具体参数 schema 以启动时 `tools/list` 返回的为准。
134
+
135
+ ---
136
+
137
+ ## 架构与 Token 机制
138
+
139
+ ```
140
+ ┌──────────────┐ stdio ┌──────────────────────────────┐
141
+ │ Claude Code │──────▶│ mdmcp.server │
142
+ └──────────────┘ ├──────────────────────────────┤
143
+ │ [静态注册] 50 个 v1 工具 │──┐
144
+ ├──────────────────────────────┤ │HTTP
145
+ │ [动态注册] HapGateway │──┤
146
+ │ 48 个 HAP 工具(透明代理) │ │
147
+ └──────────────────────────────┘ ▼
148
+ ┌──────────────────────────────────────┐
149
+ │ api.mingdao.com/v1/* (v1 API) │
150
+ │ api2.mingdao.com/mcp (HAP gateway) │
151
+ └──────────────────────────────────────┘
152
+ ```
153
+
154
+ **Token 刷新**:
155
+
156
+ | | v1 access_token | HAP token |
157
+ |---|---|---|
158
+ | install 时 | OAuth → `MD_KEY` 写入 `.env` | register(一次性)→ `MD_HAP_KEY` 写入 `.env` |
159
+ | 运行时拉 token | 1 次请求:v1 token hook | 1 次请求:HAP token hook |
160
+ | 缓存 TTL | 到本地次日 00:00 | 到本地次日 00:00 |
161
+ | 每天 token 请求数 | 1 | 1 |
162
+
163
+ 每天首次调用时拉一次 token、缓存到本地次日 00:00;不持久化到磁盘。HAP 网关握手失败时**不崩 server**,仅跳过远端工具注册,v1 工具仍可用。
164
+
165
+ ---
166
+
167
+ ## 配置
168
+
169
+ `.env`(或 Claude Code `.mcp.json` 的 env):
170
+
171
+ ```env
172
+ # 必填:v1 协作 API
173
+ MD_ACCOUNT_ID=你的明道账号 UUID
174
+ MD_KEY=你的接入 key
175
+
176
+ # HAP 网关(install.py 走完后自动写入)
177
+ MD_HAP_REFRESH_TOKEN= # install 时粘贴
178
+ MD_HAP_TOKEN= # install 时粘贴
179
+ MD_HAP_KEY= # install.py 自动写入
180
+
181
+ # 可选(通常不用动)
182
+ # MD_HOOK_URL=<自部署 v1 token hook>
183
+ # MD_HAP_REGISTER_HOOK=<自部署 HAP register hook>
184
+ # MD_HAP_TOKEN_HOOK=<自部署 HAP token hook>
185
+ # MD_APP_KEY=<自定义 OAuth app_key>
186
+ # MD_REGISTER_URL=<自定义 v1 OAuth 注册 hook>
187
+ # MD_CALLBACK_PORT=8080
188
+ ```
189
+
190
+ ---
191
+
192
+ ## 故障排查
193
+
194
+ | 现象 | 原因 | 解决 |
195
+ |------|------|------|
196
+ | `Missing MD_ACCOUNT_ID or MD_KEY` | .env 没配 | 跑 `python3 install.py` 或手工填 `.env` |
197
+ | `Missing MD_ACCOUNT_ID or MD_HAP_KEY` | HAP 没注册 | 重跑 `python3 install.py` 走 HAP 步骤 |
198
+ | `HAP token 接口返回空` | hap_key 在服务端失效(refresh_token 过期等) | 按上面文档重新拿一对 token + refresh_token,重跑 install |
199
+ | 启动显示 `HAP 网关工具 0 个` | `/mcp` 握手失败 | 网络问题;v1 工具不受影响 |
200
+ | HAP 工具返回 `Http Headers verification failed` | HAP 后端对该工具有额外鉴权要求 | HAP 侧既有问题(Node 版也有),非 mdmcp bug |
201
+ | `ensurepip` 失败、venv 装不上 | python.org 的 3.14 安装包 ensurepip 有 bug;或目录在 iCloud 同步范围被吞文件 | 换 Homebrew `python@3.12`;项目挪出 `~/Desktop` / `~/Documents` |
202
+
203
+ ---
204
+
205
+ ## 与前代项目
206
+
207
+ | 项目 | 覆盖 | 状态 |
208
+ |------|-----|------|
209
+ | `mdold` | v1 + 本地 OAuth | 已停止维护 |
210
+ | `md-cloud` | v1 + 云端 token | 已由 mdmcp 取代 |
211
+ | `hap-mcp-cloud-refresh` | HAP 代理(Node) | 已由 mdmcp 取代 |
212
+ | **mdmcp** | v1 + HAP | **推荐使用** |
213
+
214
+ ---
215
+
216
+ ## API 参考
217
+
218
+ 明道开放平台:<https://open.mingdao.com/document>
219
+
220
+ ## License
221
+
222
+ MIT
mdymcp-0.1.2/README.md ADDED
@@ -0,0 +1,194 @@
1
+ # mdmcp
2
+
3
+ **明道(Mingdao)统一 MCP Server** — 一次安装,获得 **v1 协作 API 50 个工具 + HAP 网关 48 个工具**,共计 ~98 个工具。
4
+
5
+ 由 [雷码工坊](https://github.com/andyleimc-source) 维护。取代早期的 [`md-cloud`](https://github.com/andyleimc-source/md-cloud)(只含 v1)和 [`hap-mcp-cloud-refresh`](https://github.com/andyleimc-source/hap-mcp-cloud-refresh)(Node.js 只含 HAP)。
6
+
7
+ ---
8
+
9
+ ## 一键安装
10
+
11
+ > 要求:macOS / Linux,Python ≥ 3.10(推荐 Homebrew `python@3.12` 或更高),项目目录**不要放 iCloud 同步路径**(如 `~/Desktop`、`~/Documents`),建议放 `~/Downloads`、`~/code` 等本地目录。
12
+
13
+ ```bash
14
+ git clone https://github.com/andyleimc-source/mdmcp.git
15
+ cd mdmcp
16
+ python3 install.py
17
+ ```
18
+
19
+ 交互脚本会自动:
20
+
21
+ 1. 建 `.venv` 并装依赖
22
+ 2. 浏览器 OAuth 拿 v1 凭据 → 写入 `.env`
23
+ 3. **提示你粘贴 HAP 凭据**(refresh_token + access token,下面教你怎么拿)→ 自动 register 拿 `hap_key` → 写入 `.env`
24
+ 4. **自动检测**你装的 MCP 客户端,注册到 **Claude Code** 和/或 **Codex CLI**(用户级,全局生效)
25
+ 5. 验证 token 可拉
26
+
27
+ > **多客户端支持**:脚本会扫 `claude` 和 `codex` 两个 CLI,**装哪个就自动注册到哪个**,都装就都配。手动指定客户端:`--client=claude` / `--client=codex` / `--client=both`。
28
+ >
29
+ > **注册范围**:步骤 4 会问"用户级 / 项目级 / 两个都配"(默认用户级,全局生效)。CI / 想跳过这个问题:加 `--project` 强制项目级 + 用户级。
30
+
31
+ 装完重启 Claude Code,直接对话即可:
32
+
33
+ - "帮我看看最近公司动态" → `post_get_all_posts`(v1)
34
+ - "列出我的全部应用" → `get_app_list`(HAP)
35
+ - "在 XX 工作表新增一行记录" → `create_record`(HAP)
36
+
37
+ > 调试模式:`MDMCP_INSTALL_DEBUG=1 python3 install.py` 或 `python3 install.py --debug`,会逐步显示每个 hook 的请求体/响应并 y/n 拦截,仅开发者用。
38
+
39
+ ---
40
+
41
+ ## 怎么拿 HAP 的 refresh_token 和 access token
42
+
43
+ HAP 网关需要在明道**集成中心**做一次个人授权,拿到一对 `refresh_token` + `access_token` 喂给 install 脚本。
44
+
45
+ ### 第 1 步:集成中心 → API 库 → HAP API(个人授权)→ 立即授权
46
+
47
+ ![step1](docs/images/hap-step1-authorize.png)
48
+
49
+ 进入「集成 → API 库」,找到 **HAP API(个人授权)**,点右上角「立即授权」走完 OAuth 流程。
50
+
51
+ ### 第 2 步:「我的连接 → 授权」tab,找到刚授权的连接
52
+
53
+ ![step2](docs/images/hap-step2-connections.png)
54
+
55
+ ### 第 3 步:进入连接,在账户行点 `...` → 查看日志
56
+
57
+ ![step3](docs/images/hap-step3-account-menu.png)
58
+
59
+ ### 第 4 步:在日志列表中找一条「获取 token」→ 点查看详情
60
+
61
+ ![step4](docs/images/hap-step4-log-list.png)
62
+
63
+ ### 第 5 步:在「返回值」标签里复制 `access_token` 和 `refresh_token`
64
+
65
+ ![step5](docs/images/hap-step5-tokens.png)
66
+
67
+ 把这两个值在 install.py 提示时分别粘到:
68
+ - `MD_HAP_TOKEN:` ← 粘 `access_token`
69
+ - `MD_HAP_REFRESH_TOKEN:` ← 粘 `refresh_token`
70
+
71
+ > 这两个 token 只在 `install.py` 时用一次(用于把你的账号绑定到服务端,换出长期 `hap_key`)。绑定完成后 Claude Code 运行时只用 `hap_key` + `account_id` 调 token hook 拿当天的 HAP token,不再需要它们。
72
+
73
+ ---
74
+
75
+ ## 功能总览
76
+
77
+ ### 一、v1 协作 API 工具(50 个,本地实现)
78
+
79
+ | 模块 | 数量 | 主要能力 |
80
+ |------|-----|---------|
81
+ | 动态 (post) | 9 | 全公司/我的/用户/群组动态、详情、评论、发布、删除 |
82
+ | 日程 (calendar) | 8 | 列表、详情、邀请、搜索、创建、编辑、删除 |
83
+ | 私信 (webchat) | 6 | 会话、消息、未读、发送 |
84
+ | 收件箱 (message) | 2 | 系统通知、动态相关通知 |
85
+ | 群组 (group) | 10 | 详情、成员、加入/创建、管理员管理 |
86
+ | 用户 (user) | 6 | 联系人、组织成员、@搜索、按手机/邮箱查找 |
87
+ | 组织 (company) | 3 | 组织、部门、按 ID 查询 |
88
+ | 个人账户 (passport) | 4 | 当前用户详情、设置、未读、名片 |
89
+
90
+ 工具签名与 `md-cloud` / `mdold` 完全一致,drop-in 可替换。
91
+
92
+ ### 二、HAP 网关工具(48 个,透明代理)
93
+
94
+ 启动时自动拉取 `api2.mingdao.com/mcp` 的工具清单并注册到本地 MCP。覆盖:
95
+
96
+ - **应用管理**:`get_app_list` / `get_app_info` / `create_app` / `update_app` / `delete_app`
97
+ - **工作表**:`get_app_worksheets_list` / `get_worksheet_structure` / `create_worksheet` / `update_worksheet` / `delete_worksheet`
98
+ - **记录**:`get_record_list` / `get_record_details` / `create_record` / `update_record` / `delete_record` / 批量增删改 / `get_record_logs` / `get_record_relations` / `get_record_discussions` / `get_record_share_link` / `get_record_pivot_data`
99
+ - **角色/成员**:`get_role_list` / `create_role` / `delete_role` / `add_member_to_role` / `remove_member_from_role` / `find_member` / `find_department` / `leave_all_roles`
100
+ - **工作流 / 审批**:`get_workflow_list` / `get_workflow_details` / `trigger_workflow` / `get_approval_list_by_row` / `get_approval_detail`
101
+ - **图表 / 自定义页**:`create_chart` / `save_custom_page`
102
+ - **选项集 / 知识库 / 地区 / 组织**:`create_optionset` / `update_optionset` / `delete_optionset` / `get_optionset_list` / `knowledge_search` / `get_app_knowledge_list` / `get_regions` / `get_org_list`
103
+ - **工具**:`get_time`
104
+
105
+ HAP 工具由远端网关动态提供;具体参数 schema 以启动时 `tools/list` 返回的为准。
106
+
107
+ ---
108
+
109
+ ## 架构与 Token 机制
110
+
111
+ ```
112
+ ┌──────────────┐ stdio ┌──────────────────────────────┐
113
+ │ Claude Code │──────▶│ mdmcp.server │
114
+ └──────────────┘ ├──────────────────────────────┤
115
+ │ [静态注册] 50 个 v1 工具 │──┐
116
+ ├──────────────────────────────┤ │HTTP
117
+ │ [动态注册] HapGateway │──┤
118
+ │ 48 个 HAP 工具(透明代理) │ │
119
+ └──────────────────────────────┘ ▼
120
+ ┌──────────────────────────────────────┐
121
+ │ api.mingdao.com/v1/* (v1 API) │
122
+ │ api2.mingdao.com/mcp (HAP gateway) │
123
+ └──────────────────────────────────────┘
124
+ ```
125
+
126
+ **Token 刷新**:
127
+
128
+ | | v1 access_token | HAP token |
129
+ |---|---|---|
130
+ | install 时 | OAuth → `MD_KEY` 写入 `.env` | register(一次性)→ `MD_HAP_KEY` 写入 `.env` |
131
+ | 运行时拉 token | 1 次请求:v1 token hook | 1 次请求:HAP token hook |
132
+ | 缓存 TTL | 到本地次日 00:00 | 到本地次日 00:00 |
133
+ | 每天 token 请求数 | 1 | 1 |
134
+
135
+ 每天首次调用时拉一次 token、缓存到本地次日 00:00;不持久化到磁盘。HAP 网关握手失败时**不崩 server**,仅跳过远端工具注册,v1 工具仍可用。
136
+
137
+ ---
138
+
139
+ ## 配置
140
+
141
+ `.env`(或 Claude Code `.mcp.json` 的 env):
142
+
143
+ ```env
144
+ # 必填:v1 协作 API
145
+ MD_ACCOUNT_ID=你的明道账号 UUID
146
+ MD_KEY=你的接入 key
147
+
148
+ # HAP 网关(install.py 走完后自动写入)
149
+ MD_HAP_REFRESH_TOKEN= # install 时粘贴
150
+ MD_HAP_TOKEN= # install 时粘贴
151
+ MD_HAP_KEY= # install.py 自动写入
152
+
153
+ # 可选(通常不用动)
154
+ # MD_HOOK_URL=<自部署 v1 token hook>
155
+ # MD_HAP_REGISTER_HOOK=<自部署 HAP register hook>
156
+ # MD_HAP_TOKEN_HOOK=<自部署 HAP token hook>
157
+ # MD_APP_KEY=<自定义 OAuth app_key>
158
+ # MD_REGISTER_URL=<自定义 v1 OAuth 注册 hook>
159
+ # MD_CALLBACK_PORT=8080
160
+ ```
161
+
162
+ ---
163
+
164
+ ## 故障排查
165
+
166
+ | 现象 | 原因 | 解决 |
167
+ |------|------|------|
168
+ | `Missing MD_ACCOUNT_ID or MD_KEY` | .env 没配 | 跑 `python3 install.py` 或手工填 `.env` |
169
+ | `Missing MD_ACCOUNT_ID or MD_HAP_KEY` | HAP 没注册 | 重跑 `python3 install.py` 走 HAP 步骤 |
170
+ | `HAP token 接口返回空` | hap_key 在服务端失效(refresh_token 过期等) | 按上面文档重新拿一对 token + refresh_token,重跑 install |
171
+ | 启动显示 `HAP 网关工具 0 个` | `/mcp` 握手失败 | 网络问题;v1 工具不受影响 |
172
+ | HAP 工具返回 `Http Headers verification failed` | HAP 后端对该工具有额外鉴权要求 | HAP 侧既有问题(Node 版也有),非 mdmcp bug |
173
+ | `ensurepip` 失败、venv 装不上 | python.org 的 3.14 安装包 ensurepip 有 bug;或目录在 iCloud 同步范围被吞文件 | 换 Homebrew `python@3.12`;项目挪出 `~/Desktop` / `~/Documents` |
174
+
175
+ ---
176
+
177
+ ## 与前代项目
178
+
179
+ | 项目 | 覆盖 | 状态 |
180
+ |------|-----|------|
181
+ | `mdold` | v1 + 本地 OAuth | 已停止维护 |
182
+ | `md-cloud` | v1 + 云端 token | 已由 mdmcp 取代 |
183
+ | `hap-mcp-cloud-refresh` | HAP 代理(Node) | 已由 mdmcp 取代 |
184
+ | **mdmcp** | v1 + HAP | **推荐使用** |
185
+
186
+ ---
187
+
188
+ ## API 参考
189
+
190
+ 明道开放平台:<https://open.mingdao.com/document>
191
+
192
+ ## License
193
+
194
+ MIT
@@ -0,0 +1,45 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68.0"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "mdymcp"
7
+ version = "0.1.2"
8
+ description = "Unified MCP server for Mingdao — v1 collaboration API + HAP gateway (worksheets, records, apps)"
9
+ readme = "README.md"
10
+ license = {text = "MIT"}
11
+ requires-python = ">=3.10"
12
+ authors = [
13
+ {name = "Andy Lei", email = "andy.lei@mingdao.com"},
14
+ ]
15
+ keywords = ["mcp", "mingdao", "hap", "worksheet", "collaboration", "claude"]
16
+ classifiers = [
17
+ "Development Status :: 4 - Beta",
18
+ "Intended Audience :: Developers",
19
+ "License :: OSI Approved :: MIT License",
20
+ "Operating System :: OS Independent",
21
+ "Programming Language :: Python :: 3",
22
+ "Programming Language :: Python :: 3.10",
23
+ "Programming Language :: Python :: 3.11",
24
+ "Programming Language :: Python :: 3.12",
25
+ "Programming Language :: Python :: 3.13",
26
+ "Programming Language :: Python :: 3.14",
27
+ "Topic :: Software Development :: Libraries :: Python Modules",
28
+ ]
29
+ dependencies = [
30
+ "mcp[cli]>=1.0.0",
31
+ "certifi>=2024.2.2",
32
+ ]
33
+
34
+ [project.urls]
35
+ Homepage = "https://github.com/andyleimc-source/mdmcp"
36
+ Repository = "https://github.com/andyleimc-source/mdmcp"
37
+ Issues = "https://github.com/andyleimc-source/mdmcp/issues"
38
+
39
+ [project.scripts]
40
+ mdmcp = "mdmcp.server:main"
41
+ mdmcp-auth = "mdmcp.cli_auth:main"
42
+ mdmcp-install = "mdmcp.cli_install:main"
43
+
44
+ [tool.setuptools.packages.find]
45
+ where = ["src"]
mdymcp-0.1.2/setup.cfg ADDED
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1 @@
1
+ """mdmcp — MCP Server for Mingdao Collaboration v1 API (cloud-token mode)."""
@@ -0,0 +1,55 @@
1
+ """HTTP client for Mingdao v1 API."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import json
6
+ import urllib.parse
7
+ import urllib.request
8
+ from typing import Any
9
+
10
+ from .auth import BASE_API_URL, ensure_access_token
11
+
12
+
13
+ def _get(endpoint: str, params: dict[str, Any] | None = None) -> dict[str, Any]:
14
+ token = ensure_access_token()
15
+ all_params: dict[str, Any] = {"access_token": token, "format": "json"}
16
+ if params:
17
+ all_params.update({k: v for k, v in params.items() if v is not None and v != ""})
18
+ query = urllib.parse.urlencode(all_params)
19
+ url = f"{BASE_API_URL}{endpoint}?{query}"
20
+ req = urllib.request.Request(
21
+ url,
22
+ headers={"Accept": "application/json", "User-Agent": "mdmcp/0.1"},
23
+ method="GET",
24
+ )
25
+ with urllib.request.urlopen(req, timeout=30) as resp:
26
+ return json.loads(resp.read().decode("utf-8"))
27
+
28
+
29
+ def _post(endpoint: str, data: dict[str, Any] | None = None) -> dict[str, Any]:
30
+ token = ensure_access_token()
31
+ all_data: dict[str, Any] = {"access_token": token, "format": "json"}
32
+ if data:
33
+ all_data.update({k: v for k, v in data.items() if v is not None and v != ""})
34
+ body = urllib.parse.urlencode(all_data).encode("utf-8")
35
+ url = f"{BASE_API_URL}{endpoint}"
36
+ req = urllib.request.Request(
37
+ url,
38
+ data=body,
39
+ headers={
40
+ "Content-Type": "application/x-www-form-urlencoded",
41
+ "Accept": "application/json",
42
+ "User-Agent": "mdmcp/0.1",
43
+ },
44
+ method="POST",
45
+ )
46
+ with urllib.request.urlopen(req, timeout=30) as resp:
47
+ return json.loads(resp.read().decode("utf-8"))
48
+
49
+
50
+ def api_get(endpoint: str, **kwargs: Any) -> dict[str, Any]:
51
+ return _get(endpoint, kwargs if kwargs else None)
52
+
53
+
54
+ def api_post(endpoint: str, **kwargs: Any) -> dict[str, Any]:
55
+ return _post(endpoint, kwargs if kwargs else None)