theseus-kit 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.
- theseus_kit-0.1.0/.gitignore +14 -0
- theseus_kit-0.1.0/CHANGELOG.md +21 -0
- theseus_kit-0.1.0/CONTRIBUTING.md +17 -0
- theseus_kit-0.1.0/LICENSE +22 -0
- theseus_kit-0.1.0/PKG-INFO +392 -0
- theseus_kit-0.1.0/README.md +368 -0
- theseus_kit-0.1.0/docs/architecture.md +126 -0
- theseus_kit-0.1.0/docs/auth-oauth-design.md +263 -0
- theseus_kit-0.1.0/docs/oauth-operations.md +190 -0
- theseus_kit-0.1.0/docs/progressive-disclosure.md +208 -0
- theseus_kit-0.1.0/docs/releasing.md +45 -0
- theseus_kit-0.1.0/docs/upstream/tfrobotserver-oauth-token-inquiry.md +93 -0
- theseus_kit-0.1.0/docs/upstream/tfrs-auth-oauth-feature-request.md +110 -0
- theseus_kit-0.1.0/pyproject.toml +121 -0
- theseus_kit-0.1.0/src/theseus_kit/__init__.py +126 -0
- theseus_kit-0.1.0/src/theseus_kit/__main__.py +4 -0
- theseus_kit-0.1.0/src/theseus_kit/config.py +155 -0
- theseus_kit-0.1.0/src/theseus_kit/credentials.py +60 -0
- theseus_kit-0.1.0/src/theseus_kit/errors.py +166 -0
- theseus_kit-0.1.0/src/theseus_kit/models.py +494 -0
- theseus_kit-0.1.0/src/theseus_kit/oauth.py +134 -0
- theseus_kit-0.1.0/src/theseus_kit/redaction.py +150 -0
- theseus_kit-0.1.0/src/theseus_kit/resources.py +67 -0
- theseus_kit-0.1.0/src/theseus_kit/routing.py +55 -0
- theseus_kit-0.1.0/src/theseus_kit/server.py +555 -0
- theseus_kit-0.1.0/src/theseus_kit/services/__init__.py +19 -0
- theseus_kit-0.1.0/src/theseus_kit/services/config_reader.py +939 -0
- theseus_kit-0.1.0/src/theseus_kit/services/draft_creator.py +93 -0
- theseus_kit-0.1.0/src/theseus_kit/services/draft_editor.py +118 -0
- theseus_kit-0.1.0/src/theseus_kit/services/draft_validator.py +75 -0
- theseus_kit-0.1.0/src/theseus_kit/services/llms_doc_reader.py +114 -0
- theseus_kit-0.1.0/src/theseus_kit/services/publisher.py +137 -0
- theseus_kit-0.1.0/src/theseus_kit/services/template_saver.py +118 -0
- theseus_kit-0.1.0/src/theseus_kit/skills/__init__.py +46 -0
- theseus_kit-0.1.0/src/theseus_kit/skills/_analyze_config.py +215 -0
- theseus_kit-0.1.0/src/theseus_kit/skills/_content.py +10 -0
- theseus_kit-0.1.0/src/theseus_kit/skills/_manage_topology.py +164 -0
- theseus_kit-0.1.0/src/theseus_kit/skills/_publish_config.py +140 -0
- theseus_kit-0.1.0/src/theseus_kit/skills/_registry.py +93 -0
- theseus_kit-0.1.0/src/theseus_kit/skills/_save_template.py +111 -0
- theseus_kit-0.1.0/src/theseus_kit/skills/_tune_config.py +271 -0
- theseus_kit-0.1.0/src/theseus_kit/tokens.py +54 -0
- theseus_kit-0.1.0/src/theseus_kit/transport.py +408 -0
- theseus_kit-0.1.0/tests/__init__.py +0 -0
- theseus_kit-0.1.0/tests/_fakeserver.py +237 -0
- theseus_kit-0.1.0/tests/test_auth_routing.py +623 -0
- theseus_kit-0.1.0/tests/test_config_reader.py +511 -0
- theseus_kit-0.1.0/tests/test_draft_creator.py +303 -0
- theseus_kit-0.1.0/tests/test_draft_editor.py +376 -0
- theseus_kit-0.1.0/tests/test_e2e_robot.py +55 -0
- theseus_kit-0.1.0/tests/test_llms_doc_reader.py +197 -0
- theseus_kit-0.1.0/tests/test_oauth_rs.py +416 -0
- theseus_kit-0.1.0/tests/test_package.py +57 -0
- theseus_kit-0.1.0/tests/test_publisher.py +381 -0
- theseus_kit-0.1.0/tests/test_release.py +51 -0
- theseus_kit-0.1.0/tests/test_resources.py +275 -0
- theseus_kit-0.1.0/tests/test_robot_client.py +318 -0
- theseus_kit-0.1.0/tests/test_skills.py +418 -0
- theseus_kit-0.1.0/tests/test_static_token.py +268 -0
- theseus_kit-0.1.0/tests/test_template_saver.py +432 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
本项目的显著变更都会记录在此文件中。
|
|
4
|
+
|
|
5
|
+
格式遵循 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.1.0/),
|
|
6
|
+
版本号遵循 [PEP 440](https://peps.python.org/pep-0440/) 与语义化版本意图。
|
|
7
|
+
|
|
8
|
+
## [0.1.0] — 2026-08-12
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- MCP Server 骨架,基于 FastMCP,支持 stdio 传输
|
|
13
|
+
- TFRobot 认证与路由层:X-TF-* 头部强制校验、user_pat token-exchange 换发、AsyncCachingTokenSource
|
|
14
|
+
- 渐进披露契约(方案 A):无状态索引 + 结构化选择器,4 个 MCP 只读工具(get_config_summary → list_config_nodes → get_config_detail → get_config_value)
|
|
15
|
+
- 配置变更工具:update_draft(content-hash 冲突保护)、validate_draft、create_draft、save_template、publish_config
|
|
16
|
+
- A2C-SMCP 兼容层:window:// 和 skill:// 资源投影
|
|
17
|
+
- OAuth 认证路径:TokenVerifier 适配器、RS PRM + Bearer 校验、StaticTokenSource
|
|
18
|
+
- GitHub Actions CI/CD:质量门禁(format/lint/typecheck/tests)+ OIDC Trusted Publishing
|
|
19
|
+
- Python 3.11-3.13 支持
|
|
20
|
+
- Redaction 安全最后防线:PAT/JWT/OAuth token 泄漏防护
|
|
21
|
+
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
Development targets the `develop` branch. Keep each change tied to a GitHub
|
|
4
|
+
issue in the active milestone.
|
|
5
|
+
|
|
6
|
+
Before opening a pull request, run:
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
uv sync --locked --all-groups
|
|
10
|
+
uv run poe ci
|
|
11
|
+
uv run poe build
|
|
12
|
+
uv run poe package-check
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Protocol-facing changes must preserve standard MCP interoperability. A2C-SMCP
|
|
16
|
+
metadata and URI schemes are additive extensions and must not be required for
|
|
17
|
+
using the server from a generic MCP client.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 A2C-SMCP contributors
|
|
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.
|
|
22
|
+
|
|
@@ -0,0 +1,392 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: theseus-kit
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: MCP server for safely inspecting, editing, templating, and publishing TFRobot configurations
|
|
5
|
+
Project-URL: Repository, https://github.com/A2C-SMCP/theseus-kit
|
|
6
|
+
Project-URL: Issues, https://github.com/A2C-SMCP/theseus-kit/issues
|
|
7
|
+
Author: A2C-SMCP contributors
|
|
8
|
+
License: MIT
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Keywords: a2c-smcp,agent,configuration,mcp
|
|
11
|
+
Classifier: Development Status :: 2 - Pre-Alpha
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
17
|
+
Requires-Python: <4.0,>=3.11
|
|
18
|
+
Requires-Dist: httpx<1.0.0,>=0.28.0
|
|
19
|
+
Requires-Dist: mcp<2.0.0,>=1.15.0
|
|
20
|
+
Requires-Dist: pydantic-settings<3.0.0,>=2.10.0
|
|
21
|
+
Requires-Dist: pydantic<3.0.0,>=2.11.0
|
|
22
|
+
Requires-Dist: tfrs-auth[httpx]<1.0.0,>=0.2.1
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
|
|
25
|
+
# theseus-kit
|
|
26
|
+
|
|
27
|
+
`theseus-kit` 是一个 MCP 服务器,用于安全地检查、编辑、模板化和发布 TFRobot 配置。
|
|
28
|
+
通过标准 MCP 协议运行,同时暴露可选的 A2C-SMCP 兼容 `window://` 和 `skill://` 资源。
|
|
29
|
+
|
|
30
|
+
## 目录
|
|
31
|
+
|
|
32
|
+
- [快速开始](#快速开始)
|
|
33
|
+
- [MCP 工具](#mcp-工具)
|
|
34
|
+
- [Skill 资源](#skill-资源)
|
|
35
|
+
- [使用指南](#使用指南)
|
|
36
|
+
- [配置方式](#配置方式)
|
|
37
|
+
- [MCP Client 集成](#mcp-client-集成)
|
|
38
|
+
- [工作原理](#工作原理)
|
|
39
|
+
- [架构分层](#架构分层)
|
|
40
|
+
- [认证体系](#认证体系)
|
|
41
|
+
- [数据流](#数据流)
|
|
42
|
+
- [安全模型](#安全模型)
|
|
43
|
+
- [开发](#开发)
|
|
44
|
+
|
|
45
|
+
## 快速开始
|
|
46
|
+
|
|
47
|
+
**环境要求**:Python 3.11+,[uv](https://docs.astral.sh/uv/)。
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
# 安装
|
|
51
|
+
uv sync --locked --all-groups
|
|
52
|
+
|
|
53
|
+
# 启动 MCP 服务器(stdio 传输)
|
|
54
|
+
uv run theseus-kit
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### 最小配置
|
|
58
|
+
|
|
59
|
+
通过环境变量或 `.env` 文件配置目标机器人和凭证:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
# 机器人路由信息
|
|
63
|
+
export THESEUS_ROBOT__ROBOT_ID="my-robot"
|
|
64
|
+
export THESEUS_ROBOT__NAMESPACE="default"
|
|
65
|
+
export THESEUS_ROBOT__ROBOT_TYPE="tfrobot"
|
|
66
|
+
export THESEUS_ROBOT__API_BASE_URL="https://api.example.com"
|
|
67
|
+
export THESEUS_ROBOT__MANAGER_BASE_URL="https://manager.example.com"
|
|
68
|
+
|
|
69
|
+
# 凭证(二选一)
|
|
70
|
+
# 方式 1:用户个人令牌(推荐——theseus-kit 是人管配置的工具,非 A2A)
|
|
71
|
+
export THESEUS_CREDENTIAL__KIND="user_pat"
|
|
72
|
+
export THESEUS_CREDENTIAL__PAT="tfp_xxx"
|
|
73
|
+
export THESEUS_CREDENTIAL__ROBOT_PUBLIC_ID="myorg:000042"
|
|
74
|
+
|
|
75
|
+
# 方式 2:OAuth 2.0(MCP Client 驱动授权)
|
|
76
|
+
export THESEUS_CREDENTIAL__KIND="oauth"
|
|
77
|
+
export THESEUS_CREDENTIAL__AUTHORIZATION_SERVER="https://manager.example.com"
|
|
78
|
+
export THESEUS_CREDENTIAL__SCOPES="config:read config:write"
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## MCP 工具
|
|
82
|
+
|
|
83
|
+
theseus-kit 提供 **9 个 MCP 工具**,覆盖配置的完整生命周期:
|
|
84
|
+
|
|
85
|
+
### 只读工具
|
|
86
|
+
|
|
87
|
+
| 工具 | 说明 | 所需 Scope |
|
|
88
|
+
|------|------|------------|
|
|
89
|
+
| `get_config_summary` | 获取机器人身份 + 三态(草稿/模板/线上)配置概览 | `config:read` |
|
|
90
|
+
| `list_config_nodes` | 在配置森林的任意层级列出子节点,支持游标分页和过滤 | `config:read` |
|
|
91
|
+
| `get_config_detail` | 读取单个配置节点的有界、脱敏详情(默认 8 KiB,上限 32 KiB) | `config:read` |
|
|
92
|
+
| `get_template` | 按 ID 读取模板(支持仅元数据或完整详情两种模式) | `config:read` |
|
|
93
|
+
| `get_llms_doc` | 读取机器人运行时 `llms.txt` Schema 文档(索引 + 具体页面) | `config:read` |
|
|
94
|
+
|
|
95
|
+
### 变更工具
|
|
96
|
+
|
|
97
|
+
| 工具 | 说明 | 所需 Scope |
|
|
98
|
+
|------|------|------------|
|
|
99
|
+
| `update_draft` | 更新草稿配置项,支持 `expected_hash` 乐观并发控制 | `config:write` |
|
|
100
|
+
| `validate_draft` | 验证草稿配置是否满足上线条件(全量预检或指定节点),返回逐节点校验结果 | `config:write` |
|
|
101
|
+
| `save_template` | 将草稿子树保存为可复用模板 | `config:write` |
|
|
102
|
+
| `publish_config` | 将所有草稿发布到线上,要求 `acknowledge_publish=true` 显式确认 | `config:publish` |
|
|
103
|
+
|
|
104
|
+
### 工具协作流程
|
|
105
|
+
|
|
106
|
+
```
|
|
107
|
+
get_config_summary ← 入口:发现有哪些配置
|
|
108
|
+
↓
|
|
109
|
+
list_config_nodes ← 导航:探索配置树
|
|
110
|
+
↓
|
|
111
|
+
get_config_detail ← 读取:获取具体内容(含 content_hash)
|
|
112
|
+
↓
|
|
113
|
+
get_llms_doc ← Schema:了解字段/校验规则
|
|
114
|
+
↓
|
|
115
|
+
update_draft ← 修改:带冲突保护的写入
|
|
116
|
+
↓
|
|
117
|
+
validate_draft ← 校验:发布前预检
|
|
118
|
+
↓
|
|
119
|
+
publish_config ← 发布:显式确认 + root_hash 校验
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Skill 资源
|
|
123
|
+
|
|
124
|
+
theseus-kit 通过 `skill://` 资源暴露 **3 个中文技能指南**,为 LLM 提供结构化的操作流程:
|
|
125
|
+
|
|
126
|
+
| Skill | 资源 URI | 说明 |
|
|
127
|
+
|-------|----------|------|
|
|
128
|
+
| 查看配置 | `skill://com.a2c-smcp.theseus-kit/inspect-robot-config` | 标准探索流程:概览 → Schema → 列表 → 详情 → 模板,含脱敏和分页处理指南 |
|
|
129
|
+
| 编辑草稿 | `skill://com.a2c-smcp.theseus-kit/edit-robot-draft` | 读取-检查-写入循环:Schema 优先、乐观并发控制、校验错误处理、模板保存 |
|
|
130
|
+
| 发布配置 | `skill://com.a2c-smcp.theseus-kit/publish-robot-config` | 预检 → 审批边界 → 发布 → 验证,含显式 `acknowledge_publish` 机制和失败处理矩阵 |
|
|
131
|
+
|
|
132
|
+
每个 Skill 定义了允许使用的工具、所需 Scope、标准操作流程和关键约束,
|
|
133
|
+
确保 LLM 按「最佳实践」而非自由发挥来操作配置。
|
|
134
|
+
|
|
135
|
+
### 实时状态窗口:`window://`
|
|
136
|
+
|
|
137
|
+
2 个 `window://` 资源提供配置状态的实时快照,在每次变更操作后自动通知更新:
|
|
138
|
+
|
|
139
|
+
| 资源 | URI | 说明 |
|
|
140
|
+
|------|-----|------|
|
|
141
|
+
| 配置摘要 | `window://com.a2c-smcp.theseus-kit/config/summary` | 机器人身份 + 三态概览,每次变更后刷新 |
|
|
142
|
+
| 最近详情 | `window://com.a2c-smcp.theseus-kit/config/recent` | 最近打开的配置详情,无打开时返回空状态 |
|
|
143
|
+
|
|
144
|
+
## 使用指南
|
|
145
|
+
|
|
146
|
+
### 配置方式
|
|
147
|
+
|
|
148
|
+
#### 1. 显式凭证模式(user_pat)
|
|
149
|
+
|
|
150
|
+
有明确配置的凭证时,theseus-kit 走「凭证换发」路径:用户的 PAT 作为 subject_token,Manager 通过 token-exchange(RFC 8693)换发目标机器人 scope 的短 JWT。这是**人管配置**的正确鉴权模型。
|
|
151
|
+
|
|
152
|
+
```
|
|
153
|
+
配置的凭证 → Manager 换发端点 → 短 JWT(aud=robot:{public_id})
|
|
154
|
+
→ 注入 X-TF-* 路由头 → 调用 TFRobotServer
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
这是**确定性最强**的模式:凭证固定,无需浏览器交互,适合自动化 / CI / 后台场景。
|
|
158
|
+
|
|
159
|
+
#### 2. OAuth 2.0 模式
|
|
160
|
+
|
|
161
|
+
无显式凭证时,走 MCP 标准 OAuth 授权:
|
|
162
|
+
|
|
163
|
+
```
|
|
164
|
+
MCP Client → TFRSManager AS(Authorization Code + PKCE)
|
|
165
|
+
→ OAuth AS token(aud={issuer}/robots/<id>, typ=at+jwt)
|
|
166
|
+
→ theseus-kit 校验(tfrs-auth RS256 + JWKS + scope)
|
|
167
|
+
→ 直传 TFRobotServer(无需换发)
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
适合**交互式使用**:用户在 MCP Client 中完成授权,无需手动管理令牌。
|
|
171
|
+
|
|
172
|
+
> **凭证选择不变式**:显式凭证(user_pat)始终优先;OAuth 仅在无显式凭证时启用。
|
|
173
|
+
> 配置错误不会静默降级,而是抛出明确的 `ConfigError`。
|
|
174
|
+
|
|
175
|
+
### MCP Client 集成
|
|
176
|
+
|
|
177
|
+
在 Claude Desktop 或任意兼容 MCP Client 的配置中添加:
|
|
178
|
+
|
|
179
|
+
```json
|
|
180
|
+
{
|
|
181
|
+
"mcpServers": {
|
|
182
|
+
"theseus-kit": {
|
|
183
|
+
"command": "uv",
|
|
184
|
+
"args": ["run", "theseus-kit"],
|
|
185
|
+
"env": {
|
|
186
|
+
"THESEUS_ROBOT__ROBOT_ID": "my-robot",
|
|
187
|
+
"THESEUS_ROBOT__NAMESPACE": "default",
|
|
188
|
+
"THESEUS_ROBOT__ROBOT_TYPE": "tfrobot",
|
|
189
|
+
"THESEUS_ROBOT__API_BASE_URL": "https://api.example.com",
|
|
190
|
+
"THESEUS_ROBOT__MANAGER_BASE_URL": "https://manager.example.com",
|
|
191
|
+
"THESEUS_CREDENTIAL__KIND": "user_pat",
|
|
192
|
+
"THESEUS_CREDENTIAL__PAT": "tfp_xxx",
|
|
193
|
+
"THESEUS_CREDENTIAL__ROBOT_PUBLIC_ID": "myorg:000042"
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
OAuth 模式下的配置:
|
|
201
|
+
|
|
202
|
+
```json
|
|
203
|
+
{
|
|
204
|
+
"mcpServers": {
|
|
205
|
+
"theseus-kit": {
|
|
206
|
+
"command": "uv",
|
|
207
|
+
"args": ["run", "theseus-kit"],
|
|
208
|
+
"env": {
|
|
209
|
+
"THESEUS_ROBOT__ROBOT_ID": "my-robot",
|
|
210
|
+
"THESEUS_ROBOT__NAMESPACE": "default",
|
|
211
|
+
"THESEUS_ROBOT__ROBOT_TYPE": "tfrobot",
|
|
212
|
+
"THESEUS_ROBOT__API_BASE_URL": "https://api.example.com",
|
|
213
|
+
"THESEUS_ROBOT__MANAGER_BASE_URL": "https://manager.example.com",
|
|
214
|
+
"THESEUS_CREDENTIAL__KIND": "oauth",
|
|
215
|
+
"THESEUS_CREDENTIAL__AUTHORIZATION_SERVER": "https://manager.example.com",
|
|
216
|
+
"THESEUS_CREDENTIAL__SCOPES": "config:read config:write"
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
## 工作原理
|
|
224
|
+
|
|
225
|
+
### 架构分层
|
|
226
|
+
|
|
227
|
+
```
|
|
228
|
+
┌──────────────────────────────────────────┐
|
|
229
|
+
│ MCP 表面层(server.py) │
|
|
230
|
+
│ FastMCP · 9 工具 · 2 window:// 资源 │
|
|
231
|
+
│ 3 skill:// 资源 · OAuth PRM 路由 │
|
|
232
|
+
├──────────────────────────────────────────┤
|
|
233
|
+
│ 应用服务层(services/) │
|
|
234
|
+
│ ConfigReader · DraftEditor · Publisher │
|
|
235
|
+
│ DraftValidator · TemplateSaver │
|
|
236
|
+
│ LlmsDocReader │
|
|
237
|
+
├──────────────────────────────────────────┤
|
|
238
|
+
│ 资源投影层(resources/ · skills/) │
|
|
239
|
+
│ window:// 实时快照 · skill:// 中文指南 │
|
|
240
|
+
├──────────────────────────────────────────┤
|
|
241
|
+
│ TFRobot 客户端(transport.py) │
|
|
242
|
+
│ RobotClient · RobotAuth · 令牌源双路径 │
|
|
243
|
+
├──────────────────────────────────────────┤
|
|
244
|
+
│ 认证层(oauth.py · tokens.py · │
|
|
245
|
+
│ credentials.py) │
|
|
246
|
+
│ JwtVerifier 适配 · 令牌换发 · AS 发现 │
|
|
247
|
+
├──────────────────────────────────────────┤
|
|
248
|
+
│ 模型层(models.py · config.py · │
|
|
249
|
+
│ routing.py · errors.py) │
|
|
250
|
+
│ TFSResponse · 渐进披露模型 · 路由上下文 │
|
|
251
|
+
└──────────────────────────────────────────┘
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
### 认证体系
|
|
255
|
+
|
|
256
|
+
theseus-kit 支持**两条凭证路径**,在 `RobotClient` 层自然收敛:
|
|
257
|
+
|
|
258
|
+
#### 路径 1:显式凭证(user_pat)
|
|
259
|
+
|
|
260
|
+
```
|
|
261
|
+
UserPatConfig
|
|
262
|
+
→ build_credential() # 构造 tfrs-auth PatCredential
|
|
263
|
+
→ AsyncCachingTokenSource # token-exchange + 缓存 + single-flight + 临期刷新 + 退避
|
|
264
|
+
→ RobotAuth # 注入 Authorization: Bearer <jwt> + X-TF-*
|
|
265
|
+
→ TFRobotServer
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
#### 路径 2:OAuth 2.0
|
|
269
|
+
|
|
270
|
+
```
|
|
271
|
+
OAuthConfig
|
|
272
|
+
→ TheseusTokenVerifier # tfrs-auth JwtVerifier → MCP SDK TokenVerifier
|
|
273
|
+
→ RFC 8414 AS 发现 # fetch_as_metadata() → jwks_uri + issuer
|
|
274
|
+
→ 校验: RS256 + scope + exp # JwtVerifier.verify(required_scope=)
|
|
275
|
+
→ StaticTokenSource # 静态持有已验 token,不换发
|
|
276
|
+
→ RobotAuth # 注入 Authorization: Bearer + X-TF-*
|
|
277
|
+
→ TFRobotServer # 原生接受 aud={issuer}/robots/<id> + typ=at+jwt
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
#### 两条路径对比
|
|
281
|
+
|
|
282
|
+
| | user_pat | OAuth 2.0 |
|
|
283
|
+
|---|---|---|
|
|
284
|
+
| 令牌来源 | Manager 换发(RFC 8693 token-exchange) | MCP Client 授权后直传 |
|
|
285
|
+
| 换发 | 是 | 否 |
|
|
286
|
+
| 缓存/刷新 | AsyncCachingTokenSource 内置 | MCP Client 侧负责 |
|
|
287
|
+
| 适用场景 | 人管配置(自动化 / CI / 后台) | 交互式使用 |
|
|
288
|
+
|
|
289
|
+
### 数据流
|
|
290
|
+
|
|
291
|
+
以**读取配置详情**为例,一次完整的请求经过以下路径:
|
|
292
|
+
|
|
293
|
+
```
|
|
294
|
+
1. MCP Client 调用 get_config_detail(locator="...")
|
|
295
|
+
|
|
296
|
+
2. server.py 工具处理函数
|
|
297
|
+
→ ConfigReader(robot_id=...).get_detail(client, locator, depth, max_bytes)
|
|
298
|
+
|
|
299
|
+
3. RobotClient.from_settings(settings)
|
|
300
|
+
→ RobotAuth(token_source, context).async_auth_flow()
|
|
301
|
+
→ token_source.token() 获取 Bearer(换发或静态)
|
|
302
|
+
→ context.routing_headers() 获取 X-TF-Namespace / X-TF-RobotId / X-TF-RobotType
|
|
303
|
+
→ httpx.AsyncClient 发送 GET 请求到 TFRobotServer
|
|
304
|
+
|
|
305
|
+
4. TFRobotServer 响应的 JSON 被反序列化为 TFSResponse[ConfigDetail]
|
|
306
|
+
→ code / message / data 信封解包
|
|
307
|
+
→ ConfigDetail 包含 content_hash / bytes_returned / truncated / redacted[] 等元数据
|
|
308
|
+
|
|
309
|
+
5. 结果返回给 MCP Client
|
|
310
|
+
→ 同时更新 window:// 资源的 last_locator(用于 recent 快照)
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
### 安全模型
|
|
314
|
+
|
|
315
|
+
- **令牌不出进程**:所有凭证保留在 MCP 服务器进程中,绝不进入工具输出、资源、日志或 SKILL 内容
|
|
316
|
+
- **SecretStr 保护**:pydantic `SecretStr` 字段默认 `repr` 不暴露密钥
|
|
317
|
+
- **redaction 最后防线**:`redaction.py` 用正则清除 PAT(`tfp_*`)、JWT、OAuth token/auth-code/state 形式的令牌
|
|
318
|
+
- **显式发布确认**:`publish_config` 要求 `acknowledge_publish=true`,防止意外发布
|
|
319
|
+
- **乐观并发控制**:`update_draft` 的 `expected_hash` 和 `publish_config` 的 `expected_root_hash` 防止丢失更新
|
|
320
|
+
- **渐进披露**:配置读取默认 8 KiB / 硬上限 32 KiB,敏感字段自动脱敏为 `<<redacted>>`
|
|
321
|
+
|
|
322
|
+
### 关键模块
|
|
323
|
+
|
|
324
|
+
| 模块 | 职责 |
|
|
325
|
+
|------|------|
|
|
326
|
+
| `server.py` | FastMCP 组合根,工具/资源注册,OAuth PRM 路由 |
|
|
327
|
+
| `config.py` | `TheseusSettings`(pydantic-settings),三种凭证配置的判别联合 |
|
|
328
|
+
| `transport.py` | `RobotClient` + `RobotAuth`(Bearer + X-TF-* 注入)+ `StaticTokenSource` |
|
|
329
|
+
| `oauth.py` | `TheseusTokenVerifier`(tfrs-auth → MCP SDK 适配)+ RFC 8414 发现 |
|
|
330
|
+
| `tokens.py` | `build_token_source()` — `AsyncCachingTokenSource` 组装 |
|
|
331
|
+
| `credentials.py` | `build_credential()` — user_pat → tfrs-auth PatCredential |
|
|
332
|
+
| `routing.py` | `RequestContext` — X-TF-* 头部构建与校验 |
|
|
333
|
+
| `errors.py` | 类型化异常层级 + `map_exchange_error()` |
|
|
334
|
+
| `redaction.py` | 令牌脱敏最后防线(PAT / JWT / OAuth token / code / state) |
|
|
335
|
+
| `models.py` | `TFSResponse[T]` 信封 + 渐进披露数据模型 |
|
|
336
|
+
| `services/` | `ConfigReader`、`DraftEditor`、`DraftValidator`、`Publisher`、`TemplateSaver`、`LlmsDocReader` |
|
|
337
|
+
| `resources/` | `window://` 实时快照构建 |
|
|
338
|
+
| `skills/` | `skill://` 静态中文指南 |
|
|
339
|
+
|
|
340
|
+
## 开发
|
|
341
|
+
|
|
342
|
+
```bash
|
|
343
|
+
uv sync --locked --all-groups # 安装全部依赖
|
|
344
|
+
uv run poe check # 顺序执行 format-check → lint → typecheck
|
|
345
|
+
uv run poe ci # CI 完整流程:lock-check → check → test-cov
|
|
346
|
+
uv run poe test # 运行测试(pytest,asyncio 模式 auto)
|
|
347
|
+
uv run poe test-cov # 测试覆盖率(需要 ≥80%)
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
### E2E 测试(需要真实机器人)
|
|
351
|
+
|
|
352
|
+
```bash
|
|
353
|
+
THESEUS_E2E=1 \
|
|
354
|
+
THESEUS_ROBOT__ROBOT_ID=<rid> \
|
|
355
|
+
THESEUS_ROBOT__NAMESPACE=<ns> \
|
|
356
|
+
THESEUS_ROBOT__ROBOT_TYPE=tfrobot \
|
|
357
|
+
THESEUS_ROBOT__API_BASE_URL=https://api.<clusterDomain> \
|
|
358
|
+
THESEUS_ROBOT__MANAGER_BASE_URL=https://<manager-host> \
|
|
359
|
+
THESEUS_CREDENTIAL__KIND=user_pat \
|
|
360
|
+
THESEUS_CREDENTIAL__PAT=<tfp_...> \
|
|
361
|
+
THESEUS_CREDENTIAL__ROBOT_PUBLIC_ID=<orgSlug>:<employeeNo> \
|
|
362
|
+
uv run pytest tests/test_e2e_robot.py -v -m e2e
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
### 发布前准备
|
|
366
|
+
|
|
367
|
+
```bash
|
|
368
|
+
uv run poe ci && uv run poe build && uv run poe package-check
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
发布流程见 [发布文档](docs/releasing.md):版本号由 `bump-my-version` 管理,通过 GitHub Release + OIDC Trusted Publishing 发布到 PyPI。
|
|
372
|
+
|
|
373
|
+
## 关键设计文档
|
|
374
|
+
|
|
375
|
+
- `docs/architecture.md` — 架构基线、分层、安全不变量
|
|
376
|
+
- `docs/progressive-disclosure.md` — 大配置渐进披露规格(已冻结)
|
|
377
|
+
- `docs/auth-oauth-design.md` — OAuth 2.0 授权登录技术设计
|
|
378
|
+
- `docs/releasing.md` — 发布流程
|
|
379
|
+
|
|
380
|
+
## 协议参考
|
|
381
|
+
|
|
382
|
+
- [Model Context Protocol](https://modelcontextprotocol.io/)
|
|
383
|
+
- [A2C-SMCP protocol](https://github.com/A2C-SMCP/a2c-smcp-protocol)
|
|
384
|
+
- RFC 8414 — OAuth 2.0 Authorization Server Metadata
|
|
385
|
+
- RFC 8693 — OAuth 2.0 Token Exchange
|
|
386
|
+
- RFC 8707 — Resource Indicators for OAuth 2.0
|
|
387
|
+
- RFC 9068 — JSON Web Token (JWT) Profile for OAuth 2.0 Access Tokens
|
|
388
|
+
- RFC 9728 — OAuth 2.0 Protected Resource Metadata
|
|
389
|
+
|
|
390
|
+
## License
|
|
391
|
+
|
|
392
|
+
MIT
|