wop-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,23 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+
8
+ jobs:
9
+ test:
10
+ runs-on: ubuntu-latest
11
+ strategy:
12
+ fail-fast: false
13
+ matrix:
14
+ python-version: ["3.10", "3.11", "3.12", "3.13"]
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+ - uses: astral-sh/setup-uv@v5
18
+ with:
19
+ python-version: ${{ matrix.python-version }}
20
+ - name: Install dependencies
21
+ run: uv sync
22
+ - name: Test with coverage gate (>=95%)
23
+ run: uv run pytest --cov=wop_mcp --cov-report=term-missing --cov-fail-under=95
@@ -0,0 +1,59 @@
1
+ name: release
2
+
3
+ on:
4
+ push:
5
+ tags: ['v*']
6
+
7
+ jobs:
8
+ release:
9
+ runs-on: ubuntu-latest
10
+ # PYPI_TOKEN 配置于 org 级 Actions secrets(visibility 覆盖本仓);
11
+ # 不引用 environment,避免依赖环境自动创建策略
12
+ permissions:
13
+ # write 仅用于创建 GitHub Release 条目;PyPI 发布走 PYPI_TOKEN,不占 token 权限
14
+ contents: write
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+ - uses: actions/setup-python@v5
18
+ with:
19
+ python-version: '3.12'
20
+ - name: Verify tag matches pyproject version
21
+ # 版本单一源纪律:tag vX.Y.Z 必须与 pyproject [project].version 严格一致,
22
+ # 不一致即刻 fail(防止 tag 与发布产物版本漂移)
23
+ run: |
24
+ TAG_VERSION="${GITHUB_REF_NAME#v}"
25
+ PROJ_VERSION=$(python -c "import tomllib; print(tomllib.load(open('pyproject.toml','rb'))['project']['version'])")
26
+ if [ "$TAG_VERSION" != "$PROJ_VERSION" ]; then
27
+ echo "::error::tag ${GITHUB_REF_NAME}(${TAG_VERSION})与 pyproject.toml version(${PROJ_VERSION})不一致"
28
+ exit 1
29
+ fi
30
+ - name: Install
31
+ run: |
32
+ python -m pip install --upgrade pip
33
+ # pytest/pytest-cov 属测试工具链而非运行时依赖,CI 显式安装
34
+ pip install -e . pytest pytest-cov
35
+ - name: Test with coverage gate (>= 95%, must pass before publish)
36
+ run: python -m pytest --cov=wop_mcp --cov-fail-under=95
37
+ - name: Build sdist and wheel
38
+ run: |
39
+ pip install build
40
+ python -m build
41
+ - name: Publish to PyPI
42
+ # 发布步骤位于测试全绿之后,失败不留半发布状态
43
+ uses: pypa/gh-action-pypi-publish@release/v1
44
+ with:
45
+ password: ${{ secrets.PYPI_TOKEN }}
46
+ - name: Create GitHub Release
47
+ # 仅在 PyPI 发布成功后执行(前置步骤失败即跳过)——Release 条目 = 已发布信号;
48
+ # 资产:创建即挂 dist/*(sdist+wheel,二进制归档语义);已存在(workflow 重跑)时
49
+ # 补传 --clobber 幂等,不重复建条目;说明用 --generate-notes 基线,发布后可随时人工编辑
50
+ env:
51
+ GH_TOKEN: ${{ github.token }}
52
+ run: |
53
+ VERSION="${GITHUB_REF_NAME#v}"
54
+ if gh release view "$GITHUB_REF_NAME" -R "$GITHUB_REPOSITORY" >/dev/null 2>&1; then
55
+ gh release upload "$GITHUB_REF_NAME" -R "$GITHUB_REPOSITORY" dist/* --clobber
56
+ else
57
+ gh release create "$GITHUB_REF_NAME" -R "$GITHUB_REPOSITORY" \
58
+ --title "wop-mcp ${VERSION}" --generate-notes dist/*
59
+ fi
@@ -0,0 +1,14 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ .venv/
4
+ dist/
5
+ build/
6
+ *.egg-info/
7
+ .pytest_cache/
8
+ .ruff_cache/
9
+ .coverage
10
+ coverage.xml
11
+ htmlcov/
12
+ keys/
13
+ certs/
14
+ .DS_Store
@@ -0,0 +1 @@
1
+ 3.12
wop_mcp-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 wop-platform
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.
wop_mcp-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,153 @@
1
+ Metadata-Version: 2.5
2
+ Name: wop-mcp
3
+ Version: 0.1.0
4
+ Summary: 万联易达开放平台(WOP)MCP Server —— 文档获取与密钥对生成
5
+ Project-URL: Homepage, https://github.com/wop-platform/wop-mcp
6
+ Project-URL: Repository, https://github.com/wop-platform/wop-mcp
7
+ Project-URL: Changelog, https://github.com/wop-platform/wop-mcp/releases
8
+ Project-URL: Issues, https://github.com/wop-platform/wop-mcp/issues
9
+ Author: wop-platform
10
+ License: MIT
11
+ License-File: LICENSE
12
+ Keywords: mcp,open-platform,rsa,sm2,wanlianyida,wop
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Topic :: Security :: Cryptography
22
+ Requires-Python: >=3.10
23
+ Requires-Dist: cryptography>=41
24
+ Requires-Dist: gmssl>=3.2.2
25
+ Requires-Dist: mcp>=2.0
26
+ Requires-Dist: wop-python-sdk>=0.1.7
27
+ Description-Content-Type: text/markdown
28
+
29
+ # wop-mcp
30
+
31
+ **万联易达开放平台(WOP)MCP Server —— 让 AI 助手安全、正确地完成 WOP 对接**
32
+
33
+ [![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
34
+ [![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
35
+ [![MCP](https://img.shields.io/badge/MCP-Server-orange.svg)](https://modelcontextprotocol.io/)
36
+ [![Coverage ≥95%](https://img.shields.io/badge/coverage-%E2%89%A595%25-brightgreen)]()
37
+
38
+ ## 简介
39
+
40
+ `wop-mcp` 是万联易达开放平台(WOP)的 [Model Context Protocol](https://modelcontextprotocol.io/) Server,
41
+ 帮助开发者通过 AI 助手(Claude Desktop、Cursor、Claude Code 等)完成 WOP 对接:
42
+
43
+ - 📚 **文档获取**:接入指南、API 索引、接口详情(自动穿透文档 URL 的时间戳后缀)
44
+ - 🔐 **密钥对生成**:RSA2048 / SM2,公钥按分发契约编码返回,可直接上报平台
45
+ - 🛡️ **安全纪律**:私钥只写入本地 0600 文件,**永不回显进 AI 对话**(对齐 [wop-skills](https://github.com/wop-platform/wop-skills) SECURITY 纪律)
46
+ - 🔌 **即插即用**:stdio transport,`uvx wop-mcp`(PyPI 发布后)一行接入
47
+
48
+ ## 工具总览
49
+
50
+ | 工具 | 说明 |
51
+ |---|---|
52
+ | `wop_overview()` | 接入指南(三步流程、securityReq 组合、公钥编码、SDK 列表)+ 实时 `llms.txt` API 索引 |
53
+ | `wop_api_detail(api)` | API 详情;入参支持 API 路径(如 `/staffing/open/v1/invoice/apply`,可带 POST 前缀、支持省略业务域前缀的后缀匹配)、接口中文名(如 `转账提交`)、完整 `.md` URL |
54
+ | `wop_link_detail(url)` | 文档中心任意子页 / 外链内容(相对路径自动拼接基址,如 `llms-full.txt`) |
55
+ | `wop_gen_key_pair(algorithm)` | `RSA2048`(别名 `RSA`)或 `SM2`;返回 `publicKey`(契约编码)+ `privateKeyFile`(0600 路径) |
56
+
57
+ ## 快速开始
58
+
59
+ ### 方式一:uvx 直接运行(PyPI 发布后)
60
+
61
+ ```bash
62
+ uvx wop-mcp
63
+ ```
64
+
65
+ ### 方式二:源码运行
66
+
67
+ ```bash
68
+ git clone https://github.com/wop-platform/wop-mcp.git
69
+ cd wop-mcp
70
+ uv sync
71
+ uv run wop-mcp
72
+ ```
73
+
74
+ ## 在 AI 工具中配置
75
+
76
+ ### Cursor
77
+
78
+ ```json
79
+ {
80
+ "mcpServers": {
81
+ "wop-mcp": {
82
+ "command": "uvx",
83
+ "args": ["wop-mcp"],
84
+ "timeout": 600,
85
+ "autoApprove": ["wop_overview", "wop_api_detail", "wop_link_detail"]
86
+ }
87
+ }
88
+ }
89
+ ```
90
+
91
+ ### Claude Desktop
92
+
93
+ macOS:`~/Library/Application Support/Claude/claude_desktop_config.json`
94
+ Windows:`%APPDATA%\Claude\claude_desktop_config.json`
95
+
96
+ ```json
97
+ {
98
+ "mcpServers": {
99
+ "wop-mcp": {
100
+ "command": "uvx",
101
+ "args": ["wop-mcp"]
102
+ }
103
+ }
104
+ }
105
+ ```
106
+
107
+ 源码方式将 `command`/`args` 替换为:
108
+
109
+ ```json
110
+ {
111
+ "command": "uv",
112
+ "args": ["--directory", "/path/to/wop-mcp", "run", "wop-mcp"]
113
+ }
114
+ ```
115
+
116
+ > `wop_gen_key_pair` 写本地私钥文件,建议保留人工确认(未列入 autoApprove)。
117
+
118
+ ## 环境变量
119
+
120
+ | 变量 | 默认值 | 说明 |
121
+ |---|---|---|
122
+ | `WOP_DOC_BASE_URL` | `https://assets.wanlianyida.com/gtsp/platformResource/wop/doc-center` | 文档中心基址 |
123
+ | `WOP_KEYS_DIR` | `./keys` | 私钥落盘目录(0600 文件) |
124
+ | `WOP_INDEX_CACHE_TTL` | `300` | `llms.txt` 索引进程内缓存秒数(`0` 关闭) |
125
+ | `WOP_HTTP_TIMEOUT` | `15` | HTTP 超时秒数 |
126
+
127
+ ## 安全纪律
128
+
129
+ - **私钥只落盘不回显**:`wop_gen_key_pair` 返回值不含任何私钥材料;私钥以 0600 权限独占创建于 `WOP_KEYS_DIR`。
130
+ - **公钥即上报格式**:RSA = X.509 SPKI DER 的 Base64;SM2 = 未压缩点 `04‖X‖Y`(65 字节)的 Base64([crypto-strategy-spec](https://github.com/wop-platform/wop-specs) §3.4,D10/D12)。
131
+ - **契约自检**:每次生成后经 [wop-python-sdk](https://github.com/wop-platform/wop-python-sdk) 官方加载器回读(含 SM2 曲线校验),编码不合约即报错。
132
+ - `keys/` 目录已入 `.gitignore`,**严禁**将私钥文件提交入库或粘贴进对话。
133
+
134
+ ## 算法说明(与 spec 的差异)
135
+
136
+ 本工具密钥生成支持 `RSA2048` / `SM2`。`crypto-strategy-spec` v0.4 草案的 securityReq
137
+ 国际族档位为 RSA3072/RSA4096;平台实际接受的 RSA 档位以商户中心审核为准。
138
+ 国密族与国际族禁止跨族组合。
139
+
140
+ ## 开发
141
+
142
+ ```bash
143
+ uv sync # 安装依赖(含 dev 组)
144
+ uv run pytest --cov=wop_mcp --cov-fail-under=95 # 测试 + 覆盖率门禁
145
+ npm i -g lefthook && lefthook install # 激活 git 钩子(commitlint + 覆盖率门禁)
146
+ ```
147
+
148
+ - 提交信息遵循 [Conventional Commits](https://www.conventionalcommits.org/zh-CN/)(commitlint 校验)
149
+ - CI:GitHub Actions,Python 3.10–3.13 矩阵,覆盖率红线 95%
150
+
151
+ ## 许可证
152
+
153
+ [MIT](LICENSE) © 2026 wop-platform
@@ -0,0 +1,125 @@
1
+ # wop-mcp
2
+
3
+ **万联易达开放平台(WOP)MCP Server —— 让 AI 助手安全、正确地完成 WOP 对接**
4
+
5
+ [![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
6
+ [![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
7
+ [![MCP](https://img.shields.io/badge/MCP-Server-orange.svg)](https://modelcontextprotocol.io/)
8
+ [![Coverage ≥95%](https://img.shields.io/badge/coverage-%E2%89%A595%25-brightgreen)]()
9
+
10
+ ## 简介
11
+
12
+ `wop-mcp` 是万联易达开放平台(WOP)的 [Model Context Protocol](https://modelcontextprotocol.io/) Server,
13
+ 帮助开发者通过 AI 助手(Claude Desktop、Cursor、Claude Code 等)完成 WOP 对接:
14
+
15
+ - 📚 **文档获取**:接入指南、API 索引、接口详情(自动穿透文档 URL 的时间戳后缀)
16
+ - 🔐 **密钥对生成**:RSA2048 / SM2,公钥按分发契约编码返回,可直接上报平台
17
+ - 🛡️ **安全纪律**:私钥只写入本地 0600 文件,**永不回显进 AI 对话**(对齐 [wop-skills](https://github.com/wop-platform/wop-skills) SECURITY 纪律)
18
+ - 🔌 **即插即用**:stdio transport,`uvx wop-mcp`(PyPI 发布后)一行接入
19
+
20
+ ## 工具总览
21
+
22
+ | 工具 | 说明 |
23
+ |---|---|
24
+ | `wop_overview()` | 接入指南(三步流程、securityReq 组合、公钥编码、SDK 列表)+ 实时 `llms.txt` API 索引 |
25
+ | `wop_api_detail(api)` | API 详情;入参支持 API 路径(如 `/staffing/open/v1/invoice/apply`,可带 POST 前缀、支持省略业务域前缀的后缀匹配)、接口中文名(如 `转账提交`)、完整 `.md` URL |
26
+ | `wop_link_detail(url)` | 文档中心任意子页 / 外链内容(相对路径自动拼接基址,如 `llms-full.txt`) |
27
+ | `wop_gen_key_pair(algorithm)` | `RSA2048`(别名 `RSA`)或 `SM2`;返回 `publicKey`(契约编码)+ `privateKeyFile`(0600 路径) |
28
+
29
+ ## 快速开始
30
+
31
+ ### 方式一:uvx 直接运行(PyPI 发布后)
32
+
33
+ ```bash
34
+ uvx wop-mcp
35
+ ```
36
+
37
+ ### 方式二:源码运行
38
+
39
+ ```bash
40
+ git clone https://github.com/wop-platform/wop-mcp.git
41
+ cd wop-mcp
42
+ uv sync
43
+ uv run wop-mcp
44
+ ```
45
+
46
+ ## 在 AI 工具中配置
47
+
48
+ ### Cursor
49
+
50
+ ```json
51
+ {
52
+ "mcpServers": {
53
+ "wop-mcp": {
54
+ "command": "uvx",
55
+ "args": ["wop-mcp"],
56
+ "timeout": 600,
57
+ "autoApprove": ["wop_overview", "wop_api_detail", "wop_link_detail"]
58
+ }
59
+ }
60
+ }
61
+ ```
62
+
63
+ ### Claude Desktop
64
+
65
+ macOS:`~/Library/Application Support/Claude/claude_desktop_config.json`
66
+ Windows:`%APPDATA%\Claude\claude_desktop_config.json`
67
+
68
+ ```json
69
+ {
70
+ "mcpServers": {
71
+ "wop-mcp": {
72
+ "command": "uvx",
73
+ "args": ["wop-mcp"]
74
+ }
75
+ }
76
+ }
77
+ ```
78
+
79
+ 源码方式将 `command`/`args` 替换为:
80
+
81
+ ```json
82
+ {
83
+ "command": "uv",
84
+ "args": ["--directory", "/path/to/wop-mcp", "run", "wop-mcp"]
85
+ }
86
+ ```
87
+
88
+ > `wop_gen_key_pair` 写本地私钥文件,建议保留人工确认(未列入 autoApprove)。
89
+
90
+ ## 环境变量
91
+
92
+ | 变量 | 默认值 | 说明 |
93
+ |---|---|---|
94
+ | `WOP_DOC_BASE_URL` | `https://assets.wanlianyida.com/gtsp/platformResource/wop/doc-center` | 文档中心基址 |
95
+ | `WOP_KEYS_DIR` | `./keys` | 私钥落盘目录(0600 文件) |
96
+ | `WOP_INDEX_CACHE_TTL` | `300` | `llms.txt` 索引进程内缓存秒数(`0` 关闭) |
97
+ | `WOP_HTTP_TIMEOUT` | `15` | HTTP 超时秒数 |
98
+
99
+ ## 安全纪律
100
+
101
+ - **私钥只落盘不回显**:`wop_gen_key_pair` 返回值不含任何私钥材料;私钥以 0600 权限独占创建于 `WOP_KEYS_DIR`。
102
+ - **公钥即上报格式**:RSA = X.509 SPKI DER 的 Base64;SM2 = 未压缩点 `04‖X‖Y`(65 字节)的 Base64([crypto-strategy-spec](https://github.com/wop-platform/wop-specs) §3.4,D10/D12)。
103
+ - **契约自检**:每次生成后经 [wop-python-sdk](https://github.com/wop-platform/wop-python-sdk) 官方加载器回读(含 SM2 曲线校验),编码不合约即报错。
104
+ - `keys/` 目录已入 `.gitignore`,**严禁**将私钥文件提交入库或粘贴进对话。
105
+
106
+ ## 算法说明(与 spec 的差异)
107
+
108
+ 本工具密钥生成支持 `RSA2048` / `SM2`。`crypto-strategy-spec` v0.4 草案的 securityReq
109
+ 国际族档位为 RSA3072/RSA4096;平台实际接受的 RSA 档位以商户中心审核为准。
110
+ 国密族与国际族禁止跨族组合。
111
+
112
+ ## 开发
113
+
114
+ ```bash
115
+ uv sync # 安装依赖(含 dev 组)
116
+ uv run pytest --cov=wop_mcp --cov-fail-under=95 # 测试 + 覆盖率门禁
117
+ npm i -g lefthook && lefthook install # 激活 git 钩子(commitlint + 覆盖率门禁)
118
+ ```
119
+
120
+ - 提交信息遵循 [Conventional Commits](https://www.conventionalcommits.org/zh-CN/)(commitlint 校验)
121
+ - CI:GitHub Actions,Python 3.10–3.13 矩阵,覆盖率红线 95%
122
+
123
+ ## 许可证
124
+
125
+ [MIT](LICENSE) © 2026 wop-platform
@@ -0,0 +1,23 @@
1
+ /**
2
+ * commitlint 配置 —— 对齐 wop-skills 治理标准与 Conventional Commits
3
+ * 规则等级:2 = error(阻断)| 1 = warn(警告不阻断)| 0 = 关闭
4
+ */
5
+ module.exports = {
6
+ extends: ['@commitlint/config-conventional'],
7
+ rules: {
8
+ 'type-enum': [
9
+ 2,
10
+ 'always',
11
+ ['feat', 'fix', 'docs', 'style', 'refactor', 'perf', 'test', 'chore', 'revert'],
12
+ ],
13
+ 'scope-enum': [
14
+ 1,
15
+ 'always',
16
+ ['api', 'docs', 'keypair', 'mcp', 'http', 'crypto', 'ci', 'build', 'test', 'security', 'deps'],
17
+ ],
18
+ 'subject-max-length': [2, 'always', 50],
19
+ 'header-max-length': [2, 'always', 72],
20
+ // 中文 subject 不适用英文大小写规则
21
+ 'subject-case': [0],
22
+ },
23
+ };
@@ -0,0 +1,11 @@
1
+ # 治理对齐 wop-skills:commit-msg 走 commitlint;pre-push 跑覆盖率门禁(≥95% 红线)
2
+ # 激活:npm i -g lefthook && lefthook install
3
+ commit-msg:
4
+ commands:
5
+ commitlint:
6
+ run: npx --yes @commitlint/cli@19 --edit {1}
7
+
8
+ pre-push:
9
+ commands:
10
+ coverage-gate:
11
+ run: uv run pytest --cov=wop_mcp --cov-fail-under=95 -q
@@ -0,0 +1,59 @@
1
+ [project]
2
+ name = "wop-mcp"
3
+ version = "0.1.0"
4
+ description = "万联易达开放平台(WOP)MCP Server —— 文档获取与密钥对生成"
5
+ readme = "README.md"
6
+ requires-python = ">=3.10"
7
+ license = { text = "MIT" }
8
+ authors = [{ name = "wop-platform" }]
9
+ keywords = ["wop", "mcp", "wanlianyida", "open-platform", "sm2", "rsa"]
10
+ classifiers = [
11
+ "Development Status :: 4 - Beta",
12
+ "Intended Audience :: Developers",
13
+ "License :: OSI Approved :: MIT License",
14
+ "Programming Language :: Python :: 3",
15
+ "Programming Language :: Python :: 3.10",
16
+ "Programming Language :: Python :: 3.11",
17
+ "Programming Language :: Python :: 3.12",
18
+ "Programming Language :: Python :: 3.13",
19
+ "Topic :: Security :: Cryptography",
20
+ ]
21
+ dependencies = [
22
+ "mcp>=2.0",
23
+ "cryptography>=41",
24
+ "gmssl>=3.2.2",
25
+ "wop-python-sdk>=0.1.7",
26
+ ]
27
+
28
+ [project.urls]
29
+ Homepage = "https://github.com/wop-platform/wop-mcp"
30
+ Repository = "https://github.com/wop-platform/wop-mcp"
31
+ Changelog = "https://github.com/wop-platform/wop-mcp/releases"
32
+ Issues = "https://github.com/wop-platform/wop-mcp/issues"
33
+
34
+ [project.scripts]
35
+ wop-mcp = "wop_mcp.main:main"
36
+
37
+ [dependency-groups]
38
+ dev = [
39
+ "pytest>=8.0",
40
+ "pytest-cov>=5.0",
41
+ ]
42
+
43
+ [build-system]
44
+ requires = ["hatchling"]
45
+ build-backend = "hatchling.build"
46
+
47
+ [tool.hatch.build.targets.wheel]
48
+ packages = ["src/wop_mcp"]
49
+
50
+ [tool.pytest.ini_options]
51
+ testpaths = ["tests"]
52
+ addopts = "-q"
53
+
54
+ [tool.coverage.run]
55
+ source = ["wop_mcp"]
56
+
57
+ [tool.coverage.report]
58
+ fail_under = 95
59
+ show_missing = true
@@ -0,0 +1,4 @@
1
+ # -*- coding: utf-8 -*-
2
+ """wop-mcp:万联易达开放平台(WOP)MCP Server。"""
3
+
4
+ __version__ = "0.1.0"
@@ -0,0 +1,48 @@
1
+ # -*- coding: utf-8 -*-
2
+ """运行配置:环境变量可覆盖,默认值指向生产文档中心 CDN。
3
+
4
+ 环境变量清单:
5
+ - WOP_DOC_BASE_URL 文档中心基址(默认 assets.wanlianyida.com …/doc-center)
6
+ - WOP_KEYS_DIR 密钥对私钥落盘目录(默认 ./keys)
7
+ - WOP_INDEX_CACHE_TTL llms.txt 索引进程内缓存秒数(默认 300;<=0 表示不缓存)
8
+ - WOP_HTTP_TIMEOUT HTTP 超时秒数(默认 15)
9
+ """
10
+ from __future__ import annotations
11
+
12
+ import os
13
+ from pathlib import Path
14
+
15
+ DEFAULT_DOC_BASE_URL = (
16
+ "https://assets.wanlianyida.com/gtsp/platformResource/wop/doc-center"
17
+ )
18
+ DEFAULT_KEYS_DIR = "./keys"
19
+ DEFAULT_INDEX_CACHE_TTL_SECONDS = 300.0
20
+ DEFAULT_HTTP_TIMEOUT_SECONDS = 15.0
21
+
22
+
23
+ def doc_base_url() -> str:
24
+ """文档中心基址(去尾部斜杠)。"""
25
+ return os.environ.get("WOP_DOC_BASE_URL", DEFAULT_DOC_BASE_URL).rstrip("/")
26
+
27
+
28
+ def keys_dir() -> Path:
29
+ """私钥落盘目录。"""
30
+ return Path(os.environ.get("WOP_KEYS_DIR", DEFAULT_KEYS_DIR))
31
+
32
+
33
+ def index_cache_ttl_seconds() -> float:
34
+ """llms.txt 索引缓存 TTL(秒)。"""
35
+ raw = os.environ.get("WOP_INDEX_CACHE_TTL", "")
36
+ try:
37
+ return float(raw)
38
+ except ValueError:
39
+ return DEFAULT_INDEX_CACHE_TTL_SECONDS
40
+
41
+
42
+ def http_timeout_seconds() -> float:
43
+ """HTTP 下载超时(秒)。"""
44
+ raw = os.environ.get("WOP_HTTP_TIMEOUT", "")
45
+ try:
46
+ return float(raw)
47
+ except ValueError:
48
+ return DEFAULT_HTTP_TIMEOUT_SECONDS