mcp-uof 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.
- mcp_uof-0.1.0/.env.example +63 -0
- mcp_uof-0.1.0/.github/ISSUE_TEMPLATE/bug_report.yml +77 -0
- mcp_uof-0.1.0/.github/ISSUE_TEMPLATE/config.yml +5 -0
- mcp_uof-0.1.0/.github/ISSUE_TEMPLATE/feature_request.yml +53 -0
- mcp_uof-0.1.0/.github/workflows/ci.yml +41 -0
- mcp_uof-0.1.0/.github/workflows/publish.yml +34 -0
- mcp_uof-0.1.0/.gitignore +43 -0
- mcp_uof-0.1.0/CONTRIBUTING.md +63 -0
- mcp_uof-0.1.0/LICENSE +21 -0
- mcp_uof-0.1.0/PKG-INFO +221 -0
- mcp_uof-0.1.0/README.md +187 -0
- mcp_uof-0.1.0/README.zh-TW.md +135 -0
- mcp_uof-0.1.0/SECURITY.md +29 -0
- mcp_uof-0.1.0/docs/architecture.md +129 -0
- mcp_uof-0.1.0/docs/configuration.md +59 -0
- mcp_uof-0.1.0/docs/design.md +189 -0
- mcp_uof-0.1.0/docs/example-session.md +205 -0
- mcp_uof-0.1.0/docs/form-requirements.md +39 -0
- mcp_uof-0.1.0/docs/integration.md +191 -0
- mcp_uof-0.1.0/docs/testing.md +50 -0
- mcp_uof-0.1.0/docs/tools.md +206 -0
- mcp_uof-0.1.0/docs/web-apply-design.md +157 -0
- mcp_uof-0.1.0/examples/claude_desktop_config.json +29 -0
- mcp_uof-0.1.0/examples/vscode_mcp.json +25 -0
- mcp_uof-0.1.0/pyproject.toml +59 -0
- mcp_uof-0.1.0/src/mcp_uof/__init__.py +4 -0
- mcp_uof-0.1.0/src/mcp_uof/_log.py +15 -0
- mcp_uof-0.1.0/src/mcp_uof/auth/__init__.py +68 -0
- mcp_uof-0.1.0/src/mcp_uof/auth/base.py +176 -0
- mcp_uof-0.1.0/src/mcp_uof/auth/session.py +152 -0
- mcp_uof-0.1.0/src/mcp_uof/auth/token.py +256 -0
- mcp_uof-0.1.0/src/mcp_uof/domains/__init__.py +2 -0
- mcp_uof-0.1.0/src/mcp_uof/domains/dms/__init__.py +2 -0
- mcp_uof-0.1.0/src/mcp_uof/domains/dms/endpoints.py +13 -0
- mcp_uof-0.1.0/src/mcp_uof/domains/eip/__init__.py +2 -0
- mcp_uof-0.1.0/src/mcp_uof/domains/eip/endpoints.py +17 -0
- mcp_uof-0.1.0/src/mcp_uof/domains/system/__init__.py +1 -0
- mcp_uof-0.1.0/src/mcp_uof/domains/system/endpoints.py +8 -0
- mcp_uof-0.1.0/src/mcp_uof/domains/system/tools.py +12 -0
- mcp_uof-0.1.0/src/mcp_uof/domains/uchat/__init__.py +2 -0
- mcp_uof-0.1.0/src/mcp_uof/domains/uchat/endpoints.py +13 -0
- mcp_uof-0.1.0/src/mcp_uof/domains/wkf/__init__.py +1 -0
- mcp_uof-0.1.0/src/mcp_uof/domains/wkf/endpoints.py +9 -0
- mcp_uof-0.1.0/src/mcp_uof/domains/wkf/service.py +807 -0
- mcp_uof-0.1.0/src/mcp_uof/ops/__init__.py +33 -0
- mcp_uof-0.1.0/src/mcp_uof/ops/base.py +84 -0
- mcp_uof-0.1.0/src/mcp_uof/ops/router.py +151 -0
- mcp_uof-0.1.0/src/mcp_uof/ops/soap.py +134 -0
- mcp_uof-0.1.0/src/mcp_uof/ops/web.py +1235 -0
- mcp_uof-0.1.0/src/mcp_uof/ops/web_apply/__init__.py +8 -0
- mcp_uof-0.1.0/src/mcp_uof/ops/web_apply/base.py +35 -0
- mcp_uof-0.1.0/src/mcp_uof/ops/web_apply/helpers.py +80 -0
- mcp_uof-0.1.0/src/mcp_uof/ops/web_apply/purchase_order.py +610 -0
- mcp_uof-0.1.0/src/mcp_uof/ops/web_apply/registry.py +56 -0
- mcp_uof-0.1.0/src/mcp_uof/ops/web_apply/router.py +92 -0
- mcp_uof-0.1.0/src/mcp_uof/server.py +268 -0
- mcp_uof-0.1.0/src/mcp_uof/soap_client.py +220 -0
- mcp_uof-0.1.0/src/mcp_uof/sse_server.py +105 -0
- mcp_uof-0.1.0/uv.lock +2073 -0
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# ──────────────────────────────────────────────
|
|
2
|
+
# UOF MCP Server — 環境變數範本
|
|
3
|
+
# 複製本檔案為 .env 並填入實際值
|
|
4
|
+
# 詳細說明見 docs/configuration.md
|
|
5
|
+
# ──────────────────────────────────────────────
|
|
6
|
+
|
|
7
|
+
# 沒有「模式」要設定:每個工具用哪種機制(SOAP/PublicAPI 或網頁)取得資料,是 server 內部、
|
|
8
|
+
# 開發期決定且對使用者透明的實作細節。你只需填好下列身份與連線設定。
|
|
9
|
+
# 註:清單/搜尋類工具(query_forms)內部以網頁取得(UOF PublicAPI 無此 API),
|
|
10
|
+
# 需先執行一次:uv run playwright install chromium
|
|
11
|
+
# (舊版的 UOF_OPS_MODE / UOF_AUTH_MODE 已不再使用;即使保留也會被忽略,不影響運作。)
|
|
12
|
+
|
|
13
|
+
# UOF WebService 基礎 URL(必填)
|
|
14
|
+
# 格式:https://your-uof-domain.com/VirtualPath(不含尾斜線)
|
|
15
|
+
# 範例:https://your-uof-host.example.com/UOF
|
|
16
|
+
UOF_BASE_URL=https://your-uof-domain.com
|
|
17
|
+
|
|
18
|
+
# 外部系統代號(在 UOF「一般組態設定 → 整合服務 → API」設定)
|
|
19
|
+
UOF_APP_NAME=your_app_name
|
|
20
|
+
|
|
21
|
+
# RSA 公鑰(Base64 編碼,用於加密帳號密碼)
|
|
22
|
+
# 建議以 scripts/generate_no_plus_key.py 產生不含 + 號的 key pair,
|
|
23
|
+
# 避免 UOF Web UI 將 + 存成空白導致 GetToken 解密失敗
|
|
24
|
+
UOF_RSA_PUBLIC_KEY=your_rsa_public_key_base64
|
|
25
|
+
|
|
26
|
+
# MCP Server 執行時的操作帳號與密碼(明文,程式會自動 RSA 加密後送出)
|
|
27
|
+
UOF_ACCOUNT=your_account
|
|
28
|
+
UOF_PASSWORD=your_password
|
|
29
|
+
|
|
30
|
+
# SSL 憑證驗證(true = 嚴格驗證;只有本機或自簽憑證測試環境才建議設 false)
|
|
31
|
+
UOF_VERIFY_SSL=true
|
|
32
|
+
|
|
33
|
+
# SSE Server 啟動設定(預設 127.0.0.1:8001,避免與 UOFX 8000 衝突)
|
|
34
|
+
MCP_SSE_HOST=127.0.0.1
|
|
35
|
+
MCP_SSE_PORT=8001
|
|
36
|
+
|
|
37
|
+
# ──────────────────────────────────────────────
|
|
38
|
+
# 以下為測試專用(僅 tests/manual/ 使用,正式環境可忽略)
|
|
39
|
+
# 三個測試角色共用 UOF_PASSWORD;測試範圍限定這三個帳號與採購單情境
|
|
40
|
+
# ──────────────────────────────────────────────
|
|
41
|
+
|
|
42
|
+
# 管理員(強制結案)
|
|
43
|
+
UOF_ACCOUNT_USER1=admin
|
|
44
|
+
# 簽核主管(第一站簽核者;單站流程可透過 terminate_task 在 MCP 簽核)
|
|
45
|
+
UOF_ACCOUNT_USER2=manager_account
|
|
46
|
+
# 申請人(起單、查詢、撤單)
|
|
47
|
+
UOF_ACCOUNT_USER3=applicant_account
|
|
48
|
+
|
|
49
|
+
# 採購單(WKF 測試唯一允許的表單)
|
|
50
|
+
UOF_TEST_FORM_VERSION_ID=
|
|
51
|
+
UOF_TEST_FORM_ID=
|
|
52
|
+
|
|
53
|
+
# 需改走網頁起單的採購單表單識別碼(逗號分隔,可放 formId 與 recentVersionId)
|
|
54
|
+
# 留空時不啟用採購單 web_apply 靜態分派;工具仍可由 runtime 反查支援已設定的表單。
|
|
55
|
+
UOF_WEB_APPLY_PURCHASE_ORDER_IDS=
|
|
56
|
+
UOF_WEB_APPLY_PURCHASE_ORDER_NAME=採購單
|
|
57
|
+
|
|
58
|
+
# 測試用 DMS 資料夾 ID(dms domain 實作後使用;DMSRoot 為文管根目錄)
|
|
59
|
+
UOF_TEST_FOLDER_ID=DMSRoot
|
|
60
|
+
|
|
61
|
+
# SSE 本機驗證用 Bearer Token 與模擬使用者
|
|
62
|
+
MCP_SSE_TEST_TOKEN=your_local_test_token
|
|
63
|
+
MCP_SSE_TEST_USER=test_user
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
name: Bug Report
|
|
2
|
+
description: Report a reproducible problem with the MCP server.
|
|
3
|
+
title: "bug: "
|
|
4
|
+
labels: [bug]
|
|
5
|
+
body:
|
|
6
|
+
- type: markdown
|
|
7
|
+
attributes:
|
|
8
|
+
value: |
|
|
9
|
+
Thanks for reporting a bug. Do not include accounts, passwords, RSA keys, tokens, or private UOF data.
|
|
10
|
+
- type: textarea
|
|
11
|
+
id: summary
|
|
12
|
+
attributes:
|
|
13
|
+
label: Summary
|
|
14
|
+
description: What went wrong?
|
|
15
|
+
placeholder: Describe the observed behavior and why it is a problem.
|
|
16
|
+
validations:
|
|
17
|
+
required: true
|
|
18
|
+
- type: textarea
|
|
19
|
+
id: steps
|
|
20
|
+
attributes:
|
|
21
|
+
label: Steps To Reproduce
|
|
22
|
+
description: Provide the smallest set of steps that reproduces the issue.
|
|
23
|
+
placeholder: |
|
|
24
|
+
1. Configure ...
|
|
25
|
+
2. Run ...
|
|
26
|
+
3. Call tool ...
|
|
27
|
+
4. Observe ...
|
|
28
|
+
validations:
|
|
29
|
+
required: true
|
|
30
|
+
- type: textarea
|
|
31
|
+
id: expected
|
|
32
|
+
attributes:
|
|
33
|
+
label: Expected Behavior
|
|
34
|
+
description: What did you expect to happen?
|
|
35
|
+
validations:
|
|
36
|
+
required: true
|
|
37
|
+
- type: textarea
|
|
38
|
+
id: actual
|
|
39
|
+
attributes:
|
|
40
|
+
label: Actual Behavior
|
|
41
|
+
description: What happened instead? Include sanitized logs if helpful.
|
|
42
|
+
validations:
|
|
43
|
+
required: true
|
|
44
|
+
- type: dropdown
|
|
45
|
+
id: mode
|
|
46
|
+
attributes:
|
|
47
|
+
label: Runtime Mode
|
|
48
|
+
options:
|
|
49
|
+
- stdio
|
|
50
|
+
- SSE
|
|
51
|
+
- manual test script
|
|
52
|
+
- other
|
|
53
|
+
validations:
|
|
54
|
+
required: true
|
|
55
|
+
- type: input
|
|
56
|
+
id: version
|
|
57
|
+
attributes:
|
|
58
|
+
label: Version Or Commit
|
|
59
|
+
description: Package version, git commit, or branch name.
|
|
60
|
+
placeholder: v0.1.0 or main@abcdef0
|
|
61
|
+
- type: textarea
|
|
62
|
+
id: environment
|
|
63
|
+
attributes:
|
|
64
|
+
label: Environment
|
|
65
|
+
description: OS, Python version, uv version, and relevant sanitized configuration.
|
|
66
|
+
placeholder: |
|
|
67
|
+
OS: macOS 15
|
|
68
|
+
Python: 3.12.x
|
|
69
|
+
uv: 0.x.x
|
|
70
|
+
UOF_VERIFY_SSL: true
|
|
71
|
+
validations:
|
|
72
|
+
required: true
|
|
73
|
+
- type: textarea
|
|
74
|
+
id: additional-context
|
|
75
|
+
attributes:
|
|
76
|
+
label: Additional Context
|
|
77
|
+
description: Add any other sanitized context that may help diagnose the issue.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
name: Feature Request
|
|
2
|
+
description: Suggest an improvement or new capability.
|
|
3
|
+
title: "feat: "
|
|
4
|
+
labels: [enhancement]
|
|
5
|
+
body:
|
|
6
|
+
- type: markdown
|
|
7
|
+
attributes:
|
|
8
|
+
value: |
|
|
9
|
+
Thanks for suggesting an improvement. Do not include private UOF data, credentials, or customer-specific details.
|
|
10
|
+
- type: textarea
|
|
11
|
+
id: problem
|
|
12
|
+
attributes:
|
|
13
|
+
label: Problem
|
|
14
|
+
description: What user or integration problem should this solve?
|
|
15
|
+
placeholder: Describe the current limitation or workflow pain point.
|
|
16
|
+
validations:
|
|
17
|
+
required: true
|
|
18
|
+
- type: textarea
|
|
19
|
+
id: proposal
|
|
20
|
+
attributes:
|
|
21
|
+
label: Proposed Solution
|
|
22
|
+
description: What should change?
|
|
23
|
+
placeholder: Describe the behavior, tool, configuration, or documentation change you want.
|
|
24
|
+
validations:
|
|
25
|
+
required: true
|
|
26
|
+
- type: dropdown
|
|
27
|
+
id: area
|
|
28
|
+
attributes:
|
|
29
|
+
label: Area
|
|
30
|
+
options:
|
|
31
|
+
- Workflow (WKF) tools
|
|
32
|
+
- Document management (DMS) tools
|
|
33
|
+
- EIP tools
|
|
34
|
+
- UChat tools
|
|
35
|
+
- System tools
|
|
36
|
+
- Ops routing (SOAP / web)
|
|
37
|
+
- Authentication
|
|
38
|
+
- SSE transport
|
|
39
|
+
- Documentation
|
|
40
|
+
- Packaging
|
|
41
|
+
- Other
|
|
42
|
+
validations:
|
|
43
|
+
required: true
|
|
44
|
+
- type: textarea
|
|
45
|
+
id: alternatives
|
|
46
|
+
attributes:
|
|
47
|
+
label: Alternatives Considered
|
|
48
|
+
description: Are there existing workarounds or alternative designs?
|
|
49
|
+
- type: textarea
|
|
50
|
+
id: additional-context
|
|
51
|
+
attributes:
|
|
52
|
+
label: Additional Context
|
|
53
|
+
description: Add any sanitized examples, links, or constraints that help explain the request.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
test:
|
|
13
|
+
name: Test
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
if: github.event_name != 'pull_request' || contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.pull_request.author_association)
|
|
16
|
+
|
|
17
|
+
steps:
|
|
18
|
+
- name: Check out repository
|
|
19
|
+
uses: actions/checkout@v4
|
|
20
|
+
|
|
21
|
+
- name: Install uv
|
|
22
|
+
uses: astral-sh/setup-uv@v5
|
|
23
|
+
with:
|
|
24
|
+
enable-cache: true
|
|
25
|
+
|
|
26
|
+
- name: Set up Python
|
|
27
|
+
uses: actions/setup-python@v5
|
|
28
|
+
with:
|
|
29
|
+
python-version: "3.12"
|
|
30
|
+
|
|
31
|
+
- name: Install dependencies
|
|
32
|
+
run: uv sync --locked
|
|
33
|
+
|
|
34
|
+
- name: Run smoke tests
|
|
35
|
+
run: uv run python tests/run.py smoke
|
|
36
|
+
|
|
37
|
+
- name: Compile Python files
|
|
38
|
+
run: uv run python -m compileall src tests
|
|
39
|
+
|
|
40
|
+
- name: Build package
|
|
41
|
+
run: uv build
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
build:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
steps:
|
|
12
|
+
- uses: actions/checkout@v6
|
|
13
|
+
- uses: astral-sh/setup-uv@v8.1.0
|
|
14
|
+
- uses: actions/setup-python@v6
|
|
15
|
+
with:
|
|
16
|
+
python-version: "3.12"
|
|
17
|
+
- run: uv build
|
|
18
|
+
- uses: actions/upload-artifact@v7
|
|
19
|
+
with:
|
|
20
|
+
name: dist
|
|
21
|
+
path: dist/
|
|
22
|
+
|
|
23
|
+
publish:
|
|
24
|
+
needs: build
|
|
25
|
+
runs-on: ubuntu-latest
|
|
26
|
+
environment: pypi
|
|
27
|
+
permissions:
|
|
28
|
+
id-token: write
|
|
29
|
+
steps:
|
|
30
|
+
- uses: actions/download-artifact@v8
|
|
31
|
+
with:
|
|
32
|
+
name: dist
|
|
33
|
+
path: dist/
|
|
34
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
mcp_uof-0.1.0/.gitignore
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Environment & Secrets
|
|
2
|
+
.env
|
|
3
|
+
*.pem
|
|
4
|
+
*.key
|
|
5
|
+
|
|
6
|
+
# WSDL 快照含真實主機名,不入庫;需要時以 scripts/fetch_all_wsdls.py 重新抓取
|
|
7
|
+
references/wsdl/
|
|
8
|
+
|
|
9
|
+
# Python
|
|
10
|
+
__pycache__/
|
|
11
|
+
*.py[cod]
|
|
12
|
+
*$py.class
|
|
13
|
+
*.so
|
|
14
|
+
*.egg-info/
|
|
15
|
+
*.egg
|
|
16
|
+
dist/
|
|
17
|
+
build/
|
|
18
|
+
.eggs/
|
|
19
|
+
|
|
20
|
+
# Virtual Environments
|
|
21
|
+
.venv/
|
|
22
|
+
venv/
|
|
23
|
+
ENV/
|
|
24
|
+
|
|
25
|
+
# IDE
|
|
26
|
+
.idea/
|
|
27
|
+
.vscode/
|
|
28
|
+
.claude/
|
|
29
|
+
*.swp
|
|
30
|
+
*.swo
|
|
31
|
+
*~
|
|
32
|
+
.DS_Store
|
|
33
|
+
|
|
34
|
+
# uv
|
|
35
|
+
.python-version
|
|
36
|
+
|
|
37
|
+
# Testing
|
|
38
|
+
.pytest_cache/
|
|
39
|
+
htmlcov/
|
|
40
|
+
.coverage
|
|
41
|
+
|
|
42
|
+
# Credentials
|
|
43
|
+
.uof/
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
感謝對 `mcp-uof` 的貢獻。本專案是 UOF(一代)平台的 MCP Server,以 Python 撰寫,採用 DDD(Domain-Driven Design)概念依業務邊界分層。
|
|
4
|
+
|
|
5
|
+
## 開發環境
|
|
6
|
+
|
|
7
|
+
需求:Python 3.10+、[uv](https://docs.astral.sh/uv/)
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
uv sync
|
|
11
|
+
cp .env.example .env
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
請在 `.env` 填入實際連線設定與測試帳號。`.env`、憑證、Token、真實主機名稱與本機快取不得提交。
|
|
15
|
+
|
|
16
|
+
## 執行
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
uv run mcp-uof
|
|
20
|
+
uv run mcp-uof-sse
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## 測試
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
uv run python tests/run.py smoke
|
|
27
|
+
uv run python -m compileall src tests
|
|
28
|
+
uv run python tests/run.py e2e
|
|
29
|
+
uv run python tests/run.py mounted
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
測試原則:
|
|
33
|
+
|
|
34
|
+
- `smoke` 為離線測試,應可在 CI 執行。
|
|
35
|
+
- `e2e` 與 `mounted` 需要真實測試環境與 `.env`。
|
|
36
|
+
- 真實層測試只使用 `.env` 中設定的測試帳號。
|
|
37
|
+
- WKF 實測以採購單情境為主;其他表單需後台流程設定,API 無法保證完整覆蓋。
|
|
38
|
+
|
|
39
|
+
## 架構原則
|
|
40
|
+
|
|
41
|
+
- 對外只暴露 MCP tools,使用者不選擇 SOAP 或 web 模式。
|
|
42
|
+
- 工具底層實作由 `src/mcp_uof/ops/router.py` 的 binding 決定。
|
|
43
|
+
- SOAP 能完成的操作優先使用 SOAP/PublicAPI;PublicAPI 無法支援的能力才使用 web/Playwright 補足。
|
|
44
|
+
- 所有異動必須經過 UOF 既有 API 或 UI 流程,不得提供直接修改資料庫的能力。
|
|
45
|
+
|
|
46
|
+
## 程式慣例
|
|
47
|
+
|
|
48
|
+
- 使用 Python 3.10+ type hints。
|
|
49
|
+
- 依賴管理使用 `uv`,不要直接以 `pip` 修改專案依賴。
|
|
50
|
+
- MCP tool 名稱使用全小寫 snake_case,並加上 `uof_custom_` 前綴。
|
|
51
|
+
- 不做 API 的 1:1 包裝;tool 應提供清楚的業務語意。
|
|
52
|
+
- SOAP 呼叫使用 `lxml + httpx` 輕量封裝,不使用 `zeep`。
|
|
53
|
+
|
|
54
|
+
## 文件
|
|
55
|
+
|
|
56
|
+
主要文件位於 `docs/`:
|
|
57
|
+
|
|
58
|
+
- `docs/architecture.md`:架構與身份模型
|
|
59
|
+
- `docs/configuration.md`:環境變數與 RSA 設定
|
|
60
|
+
- `docs/design.md`:工具設計與新增工具流程
|
|
61
|
+
- `docs/tools.md`:工具規格與能力邊界
|
|
62
|
+
- `docs/testing.md`:三層測試法
|
|
63
|
+
- `docs/form-requirements.md`:表單可被 MCP 操作的後台前提
|
mcp_uof-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Asgard AI 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.
|
mcp_uof-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: mcp-uof
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: MCP server wrapping UOF SOAP/ASMX services into AI Agent-callable workflow tools
|
|
5
|
+
Project-URL: Homepage, https://github.com/asgard-ai-platform/mcp-uof
|
|
6
|
+
Project-URL: Repository, https://github.com/asgard-ai-platform/mcp-uof
|
|
7
|
+
Project-URL: Issues, https://github.com/asgard-ai-platform/mcp-uof/issues
|
|
8
|
+
Author: Asgard AI Platform
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: ai-agent,claude,mcp,soap,uof,workflow
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Topic :: Office/Business
|
|
20
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
21
|
+
Requires-Python: >=3.10
|
|
22
|
+
Requires-Dist: fastapi>=0.136.3
|
|
23
|
+
Requires-Dist: fastmcp>=0.1.0
|
|
24
|
+
Requires-Dist: httpx>=0.24.0
|
|
25
|
+
Requires-Dist: lxml>=5.0.0
|
|
26
|
+
Requires-Dist: mcp[cli]>=1.0.0
|
|
27
|
+
Requires-Dist: playwright>=1.40.0
|
|
28
|
+
Requires-Dist: pycryptodome>=3.20.0
|
|
29
|
+
Requires-Dist: pydantic>=2.0.0
|
|
30
|
+
Requires-Dist: python-dotenv>=1.0.0
|
|
31
|
+
Requires-Dist: sse-starlette>=3.4.4
|
|
32
|
+
Requires-Dist: uvicorn>=0.48.0
|
|
33
|
+
Description-Content-Type: text/markdown
|
|
34
|
+
|
|
35
|
+
# MCP UOF
|
|
36
|
+
|
|
37
|
+
[](https://pypi.org/project/mcp-uof/)
|
|
38
|
+
[](https://pypi.org/project/mcp-uof/)
|
|
39
|
+
[](https://opensource.org/licenses/MIT)
|
|
40
|
+
[](https://github.com/asgard-ai-platform/mcp-uof/stargazers)
|
|
41
|
+
[](https://github.com/asgard-ai-platform/mcp-uof/issues)
|
|
42
|
+
[](https://github.com/asgard-ai-platform/mcp-uof/commits/main)
|
|
43
|
+
[](https://modelcontextprotocol.io/)
|
|
44
|
+
|
|
45
|
+
[繁體中文](README.zh-TW.md)
|
|
46
|
+
|
|
47
|
+
An open-source [MCP (Model Context Protocol)](https://modelcontextprotocol.io/) server that wraps UOF (U-Office Force) SOAP/ASMX services into AI-callable tools for workflow automation.
|
|
48
|
+
|
|
49
|
+
Built for Claude Code, Claude Desktop, VS Code, and any MCP-compatible client. It lets AI agents query workflow forms, inspect form schemas, submit forms, track workflow progress, and close workflow tasks through natural language.
|
|
50
|
+
|
|
51
|
+
## What This Does
|
|
52
|
+
|
|
53
|
+
- **12 ready-to-use tools** for UOF workflow operations, including authentication checks, form discovery, schema lookup, workflow preview, form submission, task status, task result, and task closure.
|
|
54
|
+
- **MCP server** over stdio for local AI clients, plus an optional SSE server for HTTP integrations.
|
|
55
|
+
- **Tool-first interface**: users call the same tools regardless of whether the implementation uses SOAP/PublicAPI or browser automation internally.
|
|
56
|
+
- **Single identity model**: one server process represents one UOF account configured through environment variables.
|
|
57
|
+
- **SOAP and web support**: SOAP is used where PublicAPI supports the operation; Playwright-backed web automation fills gaps such as form listing and selected custom form submission flows.
|
|
58
|
+
|
|
59
|
+
## API Reference
|
|
60
|
+
|
|
61
|
+
This project targets UOF first-generation SOAP/ASMX services and selected web flows.
|
|
62
|
+
|
|
63
|
+
- Authentication: UOF account/password encrypted with the configured RSA public key for SOAP token access; web flows reuse a browser session.
|
|
64
|
+
- Base URL: configured with `UOF_BASE_URL`, for example `https://your-uof-domain.com/VirtualPath`.
|
|
65
|
+
- Required UOF settings: see [docs/configuration.md](docs/configuration.md).
|
|
66
|
+
|
|
67
|
+
## Quick Start
|
|
68
|
+
|
|
69
|
+
### Install
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
pip install mcp-uof
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Or use uvx:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
uvx --from mcp-uof mcp-uof
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
For local development from source:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
git clone https://github.com/asgard-ai-platform/mcp-uof.git
|
|
85
|
+
cd mcp-uof
|
|
86
|
+
uv sync
|
|
87
|
+
cp .env.example .env
|
|
88
|
+
uv run playwright install chromium
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Set the required environment variables:
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
export UOF_BASE_URL=https://your-uof-domain.com/VirtualPath
|
|
95
|
+
export UOF_APP_NAME=your_app_name
|
|
96
|
+
export UOF_RSA_PUBLIC_KEY=your_rsa_public_key_base64
|
|
97
|
+
export UOF_ACCOUNT=your_account
|
|
98
|
+
export UOF_PASSWORD=your_password
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Use with Claude Code
|
|
102
|
+
|
|
103
|
+
Add the server via the Claude CLI:
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
claude mcp add --transport stdio uof -- mcp-uof
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Or with environment variables inline:
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
claude mcp add --transport stdio uof \
|
|
113
|
+
-e UOF_BASE_URL=https://your-uof-domain.com/VirtualPath \
|
|
114
|
+
-e UOF_APP_NAME=your_app_name \
|
|
115
|
+
-e UOF_RSA_PUBLIC_KEY=your_rsa_public_key_base64 \
|
|
116
|
+
-e UOF_ACCOUNT=your_account \
|
|
117
|
+
-e UOF_PASSWORD=your_password \
|
|
118
|
+
-- mcp-uof
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
If you clone the repo locally, run it through `uv`:
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
claude mcp add --transport stdio uof -- uv --directory /absolute/path/to/mcp-uof run mcp-uof
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### Use with Claude Desktop
|
|
128
|
+
|
|
129
|
+
Add to your `claude_desktop_config.json`:
|
|
130
|
+
|
|
131
|
+
```json
|
|
132
|
+
{
|
|
133
|
+
"mcpServers": {
|
|
134
|
+
"uof": {
|
|
135
|
+
"command": "mcp-uof",
|
|
136
|
+
"env": {
|
|
137
|
+
"UOF_BASE_URL": "https://your-uof-domain.com/VirtualPath",
|
|
138
|
+
"UOF_APP_NAME": "your_app_name",
|
|
139
|
+
"UOF_RSA_PUBLIC_KEY": "your_rsa_public_key_base64",
|
|
140
|
+
"UOF_ACCOUNT": "your_account",
|
|
141
|
+
"UOF_PASSWORD": "your_password"
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Or with a local checkout:
|
|
149
|
+
|
|
150
|
+
```json
|
|
151
|
+
{
|
|
152
|
+
"mcpServers": {
|
|
153
|
+
"uof": {
|
|
154
|
+
"command": "uv",
|
|
155
|
+
"args": ["--directory", "/absolute/path/to/mcp-uof", "run", "mcp-uof"],
|
|
156
|
+
"env": {
|
|
157
|
+
"UOF_BASE_URL": "https://your-uof-domain.com/VirtualPath",
|
|
158
|
+
"UOF_APP_NAME": "your_app_name",
|
|
159
|
+
"UOF_RSA_PUBLIC_KEY": "your_rsa_public_key_base64",
|
|
160
|
+
"UOF_ACCOUNT": "your_account",
|
|
161
|
+
"UOF_PASSWORD": "your_password"
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
See [docs/integration.md](docs/integration.md) and [examples/](examples/) for more client configuration examples.
|
|
169
|
+
|
|
170
|
+
## Tools (12)
|
|
171
|
+
|
|
172
|
+
All tool names use the `uof_custom_` prefix.
|
|
173
|
+
|
|
174
|
+
| Domain | Tools |
|
|
175
|
+
|--------|-------|
|
|
176
|
+
| System | `check_auth` |
|
|
177
|
+
| WKF Workflow | `get_form_list`, `get_external_form_list`, `query_forms`, `get_form_structure`, `get_form_structure_by_id`, `preview_workflow`, `apply_form`, `get_task_data`, `get_task_result`, `terminate_task`, `sign_next` |
|
|
178
|
+
|
|
179
|
+
Important behavior and constraints:
|
|
180
|
+
|
|
181
|
+
- UOF first-generation PublicAPI does not provide an inbox or pending-task list API. Users must provide a TaskId from the UOF UI or notification email.
|
|
182
|
+
- UOF does not provide a general per-step approval API. Single-step free-flow approvals can be represented through `terminate_task` with `Adopt` or `Reject` when used by the current signer.
|
|
183
|
+
- `terminate_task` can overwrite already-closed results at the API layer; this server checks task status first and blocks repeated closure.
|
|
184
|
+
- Some form submissions use web automation when SOAP intermediary fields cannot represent the full form body.
|
|
185
|
+
|
|
186
|
+
See [docs/tools.md](docs/tools.md) for full tool specs, role model, examples, and operational boundaries.
|
|
187
|
+
|
|
188
|
+
## Project Structure
|
|
189
|
+
|
|
190
|
+
```text
|
|
191
|
+
mcp-uof/
|
|
192
|
+
├── src/mcp_uof/ # MCP server, auth, routing, SOAP/web backends
|
|
193
|
+
├── docs/ # Architecture, configuration, integration, tools, testing
|
|
194
|
+
├── examples/ # Claude Desktop and VS Code MCP config examples
|
|
195
|
+
├── scripts/ # RSA key and WSDL helper scripts
|
|
196
|
+
├── tests/ # smoke / e2e / mounted test layers
|
|
197
|
+
├── .env.example # Environment variable template
|
|
198
|
+
├── README.zh-TW.md # Traditional Chinese README
|
|
199
|
+
└── pyproject.toml
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
## Development
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
uv sync
|
|
206
|
+
uv run python tests/run.py smoke
|
|
207
|
+
uv run python -m compileall src tests
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
Tests that connect to a real UOF test environment require `.env`:
|
|
211
|
+
|
|
212
|
+
```bash
|
|
213
|
+
uv run python tests/run.py e2e
|
|
214
|
+
uv run python tests/run.py mounted
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) and [docs/testing.md](docs/testing.md) for development and testing guidelines.
|
|
218
|
+
|
|
219
|
+
## License
|
|
220
|
+
|
|
221
|
+
MIT
|