skz-quant-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.
- skz_quant_mcp-0.1.0/.github/workflows/ci.yml +84 -0
- skz_quant_mcp-0.1.0/.github/workflows/release.yml +93 -0
- skz_quant_mcp-0.1.0/.gitignore +15 -0
- skz_quant_mcp-0.1.0/.python-version +1 -0
- skz_quant_mcp-0.1.0/LICENSE +21 -0
- skz_quant_mcp-0.1.0/PKG-INFO +325 -0
- skz_quant_mcp-0.1.0/README.md +299 -0
- skz_quant_mcp-0.1.0/connector/skz/connector-meta.json +25 -0
- skz_quant_mcp-0.1.0/connector/skz/icon.svg +1 -0
- skz_quant_mcp-0.1.0/connector/skz/mcp.json +21 -0
- skz_quant_mcp-0.1.0/connector/skz/skills/shengkezhi-quant-skill/SKILL.md +713 -0
- skz_quant_mcp-0.1.0/connector/skz/token-schema.json +22 -0
- skz_quant_mcp-0.1.0/pyproject.toml +52 -0
- skz_quant_mcp-0.1.0/scripts/run_local_workbuddy_mcp.sh +25 -0
- skz_quant_mcp-0.1.0/scripts/validate_connector.py +206 -0
- skz_quant_mcp-0.1.0/src/skz_mcp/__init__.py +3 -0
- skz_quant_mcp-0.1.0/src/skz_mcp/__main__.py +4 -0
- skz_quant_mcp-0.1.0/src/skz_mcp/runner.py +500 -0
- skz_quant_mcp-0.1.0/src/skz_mcp/server.py +100 -0
- skz_quant_mcp-0.1.0/tests/test_mcp_protocol.py +124 -0
- skz_quant_mcp-0.1.0/tests/test_runner.py +252 -0
- skz_quant_mcp-0.1.0/tests/test_skill_contract.py +96 -0
- skz_quant_mcp-0.1.0/uv.lock +1062 -0
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
|
|
12
|
+
concurrency:
|
|
13
|
+
group: ci-${{ github.workflow }}-${{ github.ref }}
|
|
14
|
+
cancel-in-progress: true
|
|
15
|
+
|
|
16
|
+
env:
|
|
17
|
+
UV_CACHE_DIR: ${{ github.workspace }}/.uv-cache
|
|
18
|
+
UV_PYTHON_INSTALL_DIR: ${{ github.workspace }}/.uv-python
|
|
19
|
+
NPM_CONFIG_CACHE: ${{ github.workspace }}/.npm-cache
|
|
20
|
+
|
|
21
|
+
jobs:
|
|
22
|
+
lint:
|
|
23
|
+
name: Lint and validate
|
|
24
|
+
runs-on: ubuntu-latest
|
|
25
|
+
steps:
|
|
26
|
+
- uses: actions/checkout@v7.0.1
|
|
27
|
+
- uses: astral-sh/setup-uv@v10.0.1
|
|
28
|
+
with:
|
|
29
|
+
version: "0.11.8"
|
|
30
|
+
enable-cache: true
|
|
31
|
+
cache-suffix: lint
|
|
32
|
+
- run: uv python install 3.12
|
|
33
|
+
- run: uv sync --locked --all-groups --python 3.12
|
|
34
|
+
- run: uv run ruff check src tests scripts
|
|
35
|
+
- run: uv run ruff format --check src tests scripts
|
|
36
|
+
- run: uv run python scripts/validate_connector.py connector/skz
|
|
37
|
+
|
|
38
|
+
test:
|
|
39
|
+
name: Python ${{ matrix.python-version }}
|
|
40
|
+
runs-on: ubuntu-latest
|
|
41
|
+
strategy:
|
|
42
|
+
fail-fast: false
|
|
43
|
+
matrix:
|
|
44
|
+
python-version: ["3.10", "3.11", "3.12", "3.13"]
|
|
45
|
+
steps:
|
|
46
|
+
- uses: actions/checkout@v7.0.1
|
|
47
|
+
- uses: astral-sh/setup-uv@v10.0.1
|
|
48
|
+
with:
|
|
49
|
+
version: "0.11.8"
|
|
50
|
+
enable-cache: true
|
|
51
|
+
cache-suffix: py-${{ matrix.python-version }}
|
|
52
|
+
- run: uv python install ${{ matrix.python-version }}
|
|
53
|
+
- run: uv sync --locked --all-groups --python ${{ matrix.python-version }}
|
|
54
|
+
- run: uv run pytest
|
|
55
|
+
|
|
56
|
+
build:
|
|
57
|
+
name: Build release artifacts
|
|
58
|
+
runs-on: ubuntu-latest
|
|
59
|
+
needs: [lint, test]
|
|
60
|
+
steps:
|
|
61
|
+
- uses: actions/checkout@v7.0.1
|
|
62
|
+
- uses: astral-sh/setup-uv@v10.0.1
|
|
63
|
+
with:
|
|
64
|
+
version: "0.11.8"
|
|
65
|
+
enable-cache: true
|
|
66
|
+
cache-suffix: build
|
|
67
|
+
- run: uv python install 3.12
|
|
68
|
+
- run: uv sync --locked --all-groups --python 3.12
|
|
69
|
+
- name: Read package version
|
|
70
|
+
run: echo "PACKAGE_VERSION=$(uv run python -c 'import skz_mcp; print(skz_mcp.__version__)')" >> "$GITHUB_ENV"
|
|
71
|
+
- run: uv build --out-dir dist/pypi
|
|
72
|
+
- name: Build WorkBuddy Connector archive
|
|
73
|
+
run: |
|
|
74
|
+
mkdir -p dist/connector
|
|
75
|
+
(cd connector/skz && zip -r "../../dist/connector/shengkezhi-quant-connector-${PACKAGE_VERSION}.zip" . -x '*.DS_Store')
|
|
76
|
+
- name: Validate archives
|
|
77
|
+
run: |
|
|
78
|
+
python -m zipfile -t "dist/pypi/skz_quant_mcp-${PACKAGE_VERSION}-py3-none-any.whl"
|
|
79
|
+
unzip -t "dist/connector/shengkezhi-quant-connector-${PACKAGE_VERSION}.zip"
|
|
80
|
+
- uses: actions/upload-artifact@v7.0.1
|
|
81
|
+
with:
|
|
82
|
+
name: release-artifacts
|
|
83
|
+
path: dist/
|
|
84
|
+
if-no-files-found: error
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v[0-9]+.[0-9]+.[0-9]+"
|
|
7
|
+
|
|
8
|
+
concurrency:
|
|
9
|
+
group: release-${{ github.ref }}
|
|
10
|
+
cancel-in-progress: false
|
|
11
|
+
|
|
12
|
+
env:
|
|
13
|
+
UV_CACHE_DIR: ${{ github.workspace }}/.uv-cache
|
|
14
|
+
UV_PYTHON_INSTALL_DIR: ${{ github.workspace }}/.uv-python
|
|
15
|
+
NPM_CONFIG_CACHE: ${{ github.workspace }}/.npm-cache
|
|
16
|
+
|
|
17
|
+
jobs:
|
|
18
|
+
build:
|
|
19
|
+
name: Verify and build
|
|
20
|
+
runs-on: ubuntu-latest
|
|
21
|
+
permissions:
|
|
22
|
+
contents: read
|
|
23
|
+
steps:
|
|
24
|
+
- uses: actions/checkout@v7.0.1
|
|
25
|
+
- uses: astral-sh/setup-uv@v10.0.1
|
|
26
|
+
with:
|
|
27
|
+
version: "0.11.8"
|
|
28
|
+
enable-cache: true
|
|
29
|
+
cache-suffix: release
|
|
30
|
+
- run: uv python install 3.12
|
|
31
|
+
- run: uv sync --locked --all-groups --python 3.12
|
|
32
|
+
- name: Verify tag matches package version
|
|
33
|
+
run: |
|
|
34
|
+
PACKAGE_VERSION=$(uv run python -c 'import skz_mcp; print(skz_mcp.__version__)')
|
|
35
|
+
test "v${PACKAGE_VERSION}" = "${GITHUB_REF_NAME}"
|
|
36
|
+
echo "PACKAGE_VERSION=${PACKAGE_VERSION}" >> "$GITHUB_ENV"
|
|
37
|
+
- run: uv run ruff check src tests scripts
|
|
38
|
+
- run: uv run ruff format --check src tests scripts
|
|
39
|
+
- run: uv run pytest
|
|
40
|
+
- run: uv run python scripts/validate_connector.py connector/skz
|
|
41
|
+
- run: uv build --out-dir dist/pypi
|
|
42
|
+
- name: Check PyPI metadata
|
|
43
|
+
run: uvx --from twine twine check dist/pypi/*
|
|
44
|
+
- name: Build WorkBuddy Connector archive
|
|
45
|
+
run: |
|
|
46
|
+
mkdir -p dist/connector
|
|
47
|
+
(cd connector/skz && zip -r "../../dist/connector/shengkezhi-quant-connector-${PACKAGE_VERSION}.zip" . -x '*.DS_Store')
|
|
48
|
+
- name: Validate archives
|
|
49
|
+
run: |
|
|
50
|
+
python -m zipfile -t "dist/pypi/skz_quant_mcp-${PACKAGE_VERSION}-py3-none-any.whl"
|
|
51
|
+
unzip -t "dist/connector/shengkezhi-quant-connector-${PACKAGE_VERSION}.zip"
|
|
52
|
+
- uses: actions/upload-artifact@v7.0.1
|
|
53
|
+
with:
|
|
54
|
+
name: release-artifacts
|
|
55
|
+
path: dist/
|
|
56
|
+
if-no-files-found: error
|
|
57
|
+
retention-days: 7
|
|
58
|
+
|
|
59
|
+
publish-pypi:
|
|
60
|
+
name: Publish to PyPI
|
|
61
|
+
runs-on: ubuntu-latest
|
|
62
|
+
needs: build
|
|
63
|
+
environment:
|
|
64
|
+
name: pypi
|
|
65
|
+
url: https://pypi.org/p/skz-quant-mcp
|
|
66
|
+
permissions:
|
|
67
|
+
id-token: write
|
|
68
|
+
steps:
|
|
69
|
+
- uses: actions/download-artifact@v8.0.1
|
|
70
|
+
with:
|
|
71
|
+
name: release-artifacts
|
|
72
|
+
path: dist
|
|
73
|
+
- uses: pypa/gh-action-pypi-publish@v1.14.2
|
|
74
|
+
with:
|
|
75
|
+
packages-dir: dist/pypi
|
|
76
|
+
|
|
77
|
+
github-release:
|
|
78
|
+
name: Create GitHub release
|
|
79
|
+
runs-on: ubuntu-latest
|
|
80
|
+
needs: [build, publish-pypi]
|
|
81
|
+
permissions:
|
|
82
|
+
contents: write
|
|
83
|
+
steps:
|
|
84
|
+
- uses: actions/download-artifact@v8.0.1
|
|
85
|
+
with:
|
|
86
|
+
name: release-artifacts
|
|
87
|
+
path: dist
|
|
88
|
+
- uses: softprops/action-gh-release@v3.0.3
|
|
89
|
+
with:
|
|
90
|
+
generate_release_notes: true
|
|
91
|
+
files: |
|
|
92
|
+
dist/pypi/*
|
|
93
|
+
dist/connector/*
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.12
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Shanghai Shengkezhi Intelligent Technology 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,325 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: skz-quant-mcp
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: MCP bridge for the Shengkezhi skz quant CLI
|
|
5
|
+
Project-URL: Documentation, https://docs.shengkezhi.com/install
|
|
6
|
+
Project-URL: Homepage, https://github.com/sheng-ke-zhi/skz-quant-mcp
|
|
7
|
+
Project-URL: Issues, https://github.com/sheng-ke-zhi/skz-quant-mcp/issues
|
|
8
|
+
Project-URL: Repository, https://github.com/sheng-ke-zhi/skz-quant-mcp.git
|
|
9
|
+
Author: Shengkezhi
|
|
10
|
+
License-Expression: MIT
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Keywords: mcp,quant,shengkezhi,skz,workbuddy
|
|
13
|
+
Classifier: Development Status :: 3 - Alpha
|
|
14
|
+
Classifier: Environment :: Console
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
22
|
+
Requires-Python: >=3.10
|
|
23
|
+
Requires-Dist: mcp<3,>=2.1.1
|
|
24
|
+
Requires-Dist: typing-extensions>=4.12
|
|
25
|
+
Description-Content-Type: text/markdown
|
|
26
|
+
|
|
27
|
+
# SKZ Quant MCP
|
|
28
|
+
|
|
29
|
+
[](https://github.com/sheng-ke-zhi/skz-quant-mcp/actions/workflows/ci.yml)
|
|
30
|
+
[](https://pypi.org/project/skz-quant-mcp/)
|
|
31
|
+
[](https://pypi.org/project/skz-quant-mcp/)
|
|
32
|
+
|
|
33
|
+
`skz-quant-mcp` 是胜可知量化平台的 MCP 服务。它通过官方 `skz` CLI 向 MCP 客户端提供投研、因子、策略和组合能力,并附带符合 WorkBuddy Connector 规范的 Token 表单和 Skill。
|
|
34
|
+
|
|
35
|
+
## 架构
|
|
36
|
+
|
|
37
|
+
MCP 服务提供四个工具:
|
|
38
|
+
|
|
39
|
+
- `skz_status`:检查 SKZ CLI、contract 版本和认证状态。
|
|
40
|
+
- `skz_help`:读取当前 CLI 的真实帮助信息,避免在 MCP 中复制易变化的参数说明。
|
|
41
|
+
- `skz_read`:执行白名单内的只读命令,并强制设置 `SKZ_READ_ONLY=1`。
|
|
42
|
+
- `skz_write`:执行白名单内的写入、付费触发和资产处置命令;每次调用都要求记录用户的明确确认。
|
|
43
|
+
|
|
44
|
+
WorkBuddy 使用 `auth_mode: "token"` 在本地收集 `SKZ_API_KEY`。MCP 进程随后在独立临时 HOME 中通过 stdin 执行 `skz auth add`,不会把 Key 放进命令参数,也不会修改用户全局的 `~/.config/skz/credentials`。
|
|
45
|
+
|
|
46
|
+
SKZ CLI 的解析顺序如下:
|
|
47
|
+
|
|
48
|
+
1. `SKZ_BIN` 指定的可执行文件;
|
|
49
|
+
2. 系统 PATH 中已安装的 `skz`;
|
|
50
|
+
3. WorkBuddy 托管 Node 20 环境中的 `npx --package @shengkezhi-com/skz-quant-cli@0.1.31`。
|
|
51
|
+
|
|
52
|
+
因此 WorkBuddy 用户无需提前安装 SKZ CLI。HTTP 协议、凭据格式、只读策略、退出码和业务 JSON 结构仍以官方 CLI 为唯一契约来源。
|
|
53
|
+
|
|
54
|
+
## 环境要求
|
|
55
|
+
|
|
56
|
+
### WorkBuddy
|
|
57
|
+
|
|
58
|
+
Connector 要求 WorkBuddy `5.0.0` 或更高版本,并由 `mcp.json` 请求托管 Node 20。WorkBuddy 通过 `uvx` 安装和运行 Python MCP 包,通过 `npx` 在需要时提供官方 SKZ CLI。
|
|
59
|
+
|
|
60
|
+
### 本地开发
|
|
61
|
+
|
|
62
|
+
本地开发需要:
|
|
63
|
+
|
|
64
|
+
- Python 3.10 或更高版本;
|
|
65
|
+
- `uv`;
|
|
66
|
+
- 已安装的 SKZ CLI,或者 Node.js 18 及以上版本。
|
|
67
|
+
|
|
68
|
+
安装 SKZ CLI:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
# macOS / Linux
|
|
72
|
+
brew install sheng-ke-zhi/tap/skz
|
|
73
|
+
|
|
74
|
+
# 任意支持 Node.js 的平台
|
|
75
|
+
npm install -g @shengkezhi-com/skz-quant-cli
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
检查版本:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
skz --version
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
预期返回类似:
|
|
85
|
+
|
|
86
|
+
```json
|
|
87
|
+
{"cli":"0.1.31","contract":"4.1"}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## 开发与测试
|
|
91
|
+
|
|
92
|
+
安装开发依赖:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
UV_CACHE_DIR=.uv-cache \
|
|
96
|
+
UV_PYTHON_INSTALL_DIR=.uv-python \
|
|
97
|
+
uv sync
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
运行静态检查、测试和 Connector 校验:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
UV_CACHE_DIR=.uv-cache \
|
|
104
|
+
UV_TOOL_DIR=.uv-tools \
|
|
105
|
+
UV_PYTHON_INSTALL_DIR=.uv-python \
|
|
106
|
+
uvx --from ruff ruff check src tests scripts
|
|
107
|
+
|
|
108
|
+
UV_CACHE_DIR=.uv-cache \
|
|
109
|
+
UV_PYTHON_INSTALL_DIR=.uv-python \
|
|
110
|
+
uv run pytest
|
|
111
|
+
|
|
112
|
+
UV_CACHE_DIR=.uv-cache \
|
|
113
|
+
UV_PYTHON_INSTALL_DIR=.uv-python \
|
|
114
|
+
uv run python scripts/validate_connector.py connector/skz
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
直接启动 MCP stdio 服务:
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
UV_CACHE_DIR=.uv-cache uv run skz-mcp
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
stdio 服务会等待 MCP Host 输入,不显示普通终端提示,这是正常行为。
|
|
124
|
+
|
|
125
|
+
## 使用 MCP Inspector 测试
|
|
126
|
+
|
|
127
|
+
不要把真实 API Key 写进命令历史、源文件、测试夹具或 `mcp.json`。可以先隐藏输入并导出临时环境变量:
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
printf "请输入只读 SKZ API Key: "
|
|
131
|
+
read -s SKZ_API_KEY
|
|
132
|
+
printf "\n"
|
|
133
|
+
export SKZ_API_KEY
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
启动 MCP Inspector:
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
NPM_CONFIG_CACHE="$PWD/.npm-cache" \
|
|
140
|
+
npx -y @modelcontextprotocol/inspector \
|
|
141
|
+
"$PWD/.venv/bin/python" -m skz_mcp
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
在 Inspector 中依次验证:
|
|
145
|
+
|
|
146
|
+
1. `skz_status`:应返回 `ok: true`、`credentialMode: "workbuddy-token"` 和 `auth.present: true`;
|
|
147
|
+
2. `skz_read`,参数 `{"args":["whoami"]}`;
|
|
148
|
+
3. `skz_read`,参数 `{"args":["markets"]}`;
|
|
149
|
+
4. 确认工具列表只包含 `skz_status`、`skz_help`、`skz_read`、`skz_write`。
|
|
150
|
+
|
|
151
|
+
结束后清理当前终端变量:
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
unset SKZ_API_KEY
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## 在 WorkBuddy MCP 管理器中测试本地源码
|
|
158
|
+
|
|
159
|
+
WorkBuddy 的“配置 MCP”页面只编辑 `~/.workbuddy/mcp.json`,不是 Connector ZIP 上传入口。发包前可以让它直接启动当前项目。
|
|
160
|
+
|
|
161
|
+
先准备环境:
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
cd /Users/jun/Documents/vscodePro/skz-mcp
|
|
165
|
+
UV_CACHE_DIR=.uv-cache UV_PYTHON_INSTALL_DIR=.uv-python uv sync
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
安全创建本地测试 Key 文件,不把 Key 写入 `mcp.json` 或 shell 历史:
|
|
169
|
+
|
|
170
|
+
```bash
|
|
171
|
+
mkdir -p "$HOME/.workbuddy"
|
|
172
|
+
umask 077
|
|
173
|
+
printf "请输入只读 SKZ API Key: "
|
|
174
|
+
read -s SKZ_API_KEY
|
|
175
|
+
printf "\n"
|
|
176
|
+
printf '%s\n' "$SKZ_API_KEY" > "$HOME/.workbuddy/skz-quant-mcp-local.key"
|
|
177
|
+
unset SKZ_API_KEY
|
|
178
|
+
chmod 600 "$HOME/.workbuddy/skz-quant-mcp-local.key"
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
在 WorkBuddy 的 MCP 编辑器中保存:
|
|
182
|
+
|
|
183
|
+
```json
|
|
184
|
+
{
|
|
185
|
+
"mcpServers": {
|
|
186
|
+
"skz-quant-local": {
|
|
187
|
+
"type": "stdio",
|
|
188
|
+
"command": "/Users/jun/Documents/vscodePro/skz-mcp/scripts/run_local_workbuddy_mcp.sh",
|
|
189
|
+
"args": [],
|
|
190
|
+
"env": {
|
|
191
|
+
"SKZ_API_KEY_FILE": "/Users/jun/.workbuddy/skz-quant-mcp-local.key",
|
|
192
|
+
"SKZ_BIN": "/opt/homebrew/bin/skz"
|
|
193
|
+
},
|
|
194
|
+
"timeout": 60000
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
保存后新建会话,依次要求调用 `skz_status`、`skz_read` 的 `whoami` 和 `markets`。预期 `credentialMode` 为 `workbuddy-token`、`auth.present` 为 `true`,且能发现四个工具。测试结束后删除本地 Key 文件:
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
rm "$HOME/.workbuddy/skz-quant-mcp-local.key"
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
这个页面只验证 MCP 服务和工具,不会安装 Connector 的 Logo、Token 表单和 Skill;完整 Connector 体验仍需市场包或平台提供的本地 Connector 导入能力。
|
|
207
|
+
|
|
208
|
+
## WorkBuddy Connector
|
|
209
|
+
|
|
210
|
+
提交目录位于 `connector/skz/`:
|
|
211
|
+
|
|
212
|
+
```text
|
|
213
|
+
connector/skz/
|
|
214
|
+
├── connector-meta.json
|
|
215
|
+
├── mcp.json
|
|
216
|
+
├── token-schema.json
|
|
217
|
+
├── icon.svg
|
|
218
|
+
└── skills/
|
|
219
|
+
└── shengkezhi-quant-skill/
|
|
220
|
+
└── SKILL.md
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
当前配置遵循 MCP + Skill Token 模式:
|
|
224
|
+
|
|
225
|
+
- 只包含一个 stdio MCP Server;
|
|
226
|
+
- `auth_mode: "token"`;
|
|
227
|
+
- `token-schema.json` 的 `SKZ_API_KEY` 与 `mcp.json` 中的 `${SKZ_API_KEY}` 一致;
|
|
228
|
+
- 使用 WorkBuddy 托管 Node 20;
|
|
229
|
+
- 最低 WorkBuddy 版本为 `5.0.0`;
|
|
230
|
+
- 元信息和 Token 表单包含中英文文案;
|
|
231
|
+
- Skill 覆盖所有 MCP 工具、分页、重试、写后核对及用户确认边界。
|
|
232
|
+
|
|
233
|
+
正式配置使用以下发布坐标:
|
|
234
|
+
|
|
235
|
+
```text
|
|
236
|
+
skz-quant-mcp==0.1.0
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
发包前如需在 WorkBuddy 中测试,可复制一份 `connector/skz/`,将副本 `mcp.json` 中的发布坐标改为本地 wheel 绝对路径:
|
|
240
|
+
|
|
241
|
+
```text
|
|
242
|
+
/Users/jun/Documents/vscodePro/skz-mcp/dist/skz_quant_mcp-0.1.0-py3-none-any.whl
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
不要修改准备提交的正式 `mcp.json`。
|
|
246
|
+
|
|
247
|
+
## 构建与发布
|
|
248
|
+
|
|
249
|
+
构建 wheel 和源码包:
|
|
250
|
+
|
|
251
|
+
```bash
|
|
252
|
+
UV_CACHE_DIR=.uv-cache \
|
|
253
|
+
UV_PYTHON_INSTALL_DIR=.uv-python \
|
|
254
|
+
uv build
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
产物:
|
|
258
|
+
|
|
259
|
+
```text
|
|
260
|
+
dist/skz_quant_mcp-0.1.0-py3-none-any.whl
|
|
261
|
+
dist/skz_quant_mcp-0.1.0.tar.gz
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
发布后,应从目标包索引重新执行:
|
|
265
|
+
|
|
266
|
+
```bash
|
|
267
|
+
uvx --from skz-quant-mcp==0.1.0 skz-mcp
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
然后再提交 `connector/skz/` 给 WorkBuddy 审核。
|
|
271
|
+
|
|
272
|
+
### GitHub Actions 发布
|
|
273
|
+
|
|
274
|
+
`.github/workflows/ci.yml` 在 main 分支和 Pull Request 上执行:
|
|
275
|
+
|
|
276
|
+
- Ruff lint 和 format check;
|
|
277
|
+
- Python 3.10、3.11、3.12、3.13 测试;
|
|
278
|
+
- Connector 结构和 Skill 契约校验;
|
|
279
|
+
- wheel、sdist 和 Connector ZIP 构建。
|
|
280
|
+
|
|
281
|
+
`.github/workflows/release.yml` 在推送 `vX.Y.Z` tag 时执行完整验证,并通过 PyPI Trusted Publishing 发布。发布前需要在 PyPI 配置一次 Trusted Publisher:
|
|
282
|
+
|
|
283
|
+
```text
|
|
284
|
+
Owner: sheng-ke-zhi
|
|
285
|
+
Repository: skz-quant-mcp
|
|
286
|
+
Workflow: release.yml
|
|
287
|
+
Environment: pypi
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
首次发布前可使用 PyPI 的 Pending Publisher 创建项目;不需要向 GitHub 添加 PyPI API Token。然后发布版本:
|
|
291
|
+
|
|
292
|
+
```bash
|
|
293
|
+
git tag -a v0.1.0 -m "Release 0.1.0"
|
|
294
|
+
git push origin v0.1.0
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
workflow 会校验 tag 与 Python 包版本完全一致,向 PyPI 上传 wheel 和 sdist,并创建附带 Connector ZIP 的 GitHub Release。
|
|
298
|
+
|
|
299
|
+
## 安全边界
|
|
300
|
+
|
|
301
|
+
- MCP 工具禁止调用 `auth`、`plugin` 和 `update`。
|
|
302
|
+
- 所有 CLI 参数通过 `subprocess.run` 参数数组传递,不使用 shell。
|
|
303
|
+
- 拒绝 `--token`、`--api-key`、`--config`、`--base-url` 等敏感覆盖参数。
|
|
304
|
+
- 读写命令使用显式白名单,未知命令默认拒绝。
|
|
305
|
+
- Token 仅通过 stdin 写入隔离临时凭据目录,进程结束后删除。
|
|
306
|
+
- 子进程只继承必要环境变量,不继承其他 Connector 密钥。
|
|
307
|
+
- 输出、错误和异常中的 `sk_` 凭据会统一脱敏。
|
|
308
|
+
- 自动 CLI 回退固定使用官方 npm 包 `0.1.31`,不动态拼接 shell 命令。
|
|
309
|
+
- 读调用强制 `SKZ_READ_ONLY=1`。
|
|
310
|
+
- 写调用不自动重试;写超时返回 `outcome: "unknown"`,必须先查询已有资源。
|
|
311
|
+
- `skz_write` 的确认字段只是审计上下文,不能代替真实用户确认。Skill 要求先展示具体参数和影响,再取得本次直接确认。
|
|
312
|
+
|
|
313
|
+
## 验证状态
|
|
314
|
+
|
|
315
|
+
当前版本已经验证:
|
|
316
|
+
|
|
317
|
+
- MCP 协议初始化和四个工具发现;
|
|
318
|
+
- 工具输入 Schema 和 annotations;
|
|
319
|
+
- 系统 SKZ CLI 路径;
|
|
320
|
+
- PATH 中没有系统 `skz` 时的 npx 自动回退;
|
|
321
|
+
- WorkBuddy Token 隔离认证;
|
|
322
|
+
- 使用临时只读 Key 调用 `whoami` 和 `markets`;
|
|
323
|
+
- 全局 SKZ credentials 不变;
|
|
324
|
+
- MCP 退出后临时 credentials 被删除;
|
|
325
|
+
- wheel 安装后的完整 stdio MCP 调用链。
|