uno-mcp-stdio 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.
- uno_mcp_stdio-0.1.0/PKG-INFO +196 -0
- uno_mcp_stdio-0.1.0/README.md +163 -0
- uno_mcp_stdio-0.1.0/claude.md +226 -0
- uno_mcp_stdio-0.1.0/pyproject.toml +68 -0
- uno_mcp_stdio-0.1.0/src/uno_mcp_stdio/__init__.py +8 -0
- uno_mcp_stdio-0.1.0/src/uno_mcp_stdio/auth/__init__.py +11 -0
- uno_mcp_stdio-0.1.0/src/uno_mcp_stdio/auth/callback_server.py +311 -0
- uno_mcp_stdio-0.1.0/src/uno_mcp_stdio/auth/token_manager.py +247 -0
- uno_mcp_stdio-0.1.0/src/uno_mcp_stdio/config.py +80 -0
- uno_mcp_stdio-0.1.0/src/uno_mcp_stdio/gateway/__init__.py +10 -0
- uno_mcp_stdio-0.1.0/src/uno_mcp_stdio/gateway/proxy.py +159 -0
- uno_mcp_stdio-0.1.0/src/uno_mcp_stdio/main.py +52 -0
- uno_mcp_stdio-0.1.0/src/uno_mcp_stdio/stdio_server.py +312 -0
- uno_mcp_stdio-0.1.0/uv.lock +965 -0
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: uno-mcp-stdio
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Uno MCP Stdio Client - Local stdio proxy for Uno MCP Gateway with OAuth authentication
|
|
5
|
+
Project-URL: Homepage, https://github.com/xray918/uno-mcp-stdio
|
|
6
|
+
Project-URL: Repository, https://github.com/xray918/uno-mcp-stdio
|
|
7
|
+
Project-URL: Documentation, https://github.com/xray918/uno-mcp-stdio#readme
|
|
8
|
+
Project-URL: Issues, https://github.com/xray918/uno-mcp-stdio/issues
|
|
9
|
+
Author-email: xray918 <xray918@example.com>
|
|
10
|
+
License: MIT
|
|
11
|
+
Keywords: agent,ai,mcp,oauth,proxy,stdio
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
19
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
20
|
+
Requires-Python: >=3.11
|
|
21
|
+
Requires-Dist: aiofiles>=23.2.0
|
|
22
|
+
Requires-Dist: httpx>=0.27.0
|
|
23
|
+
Requires-Dist: mcp>=1.0.0
|
|
24
|
+
Requires-Dist: pydantic-settings>=2.1.0
|
|
25
|
+
Requires-Dist: pydantic>=2.5.0
|
|
26
|
+
Provides-Extra: dev
|
|
27
|
+
Requires-Dist: black>=24.0.0; extra == 'dev'
|
|
28
|
+
Requires-Dist: isort>=5.13.0; extra == 'dev'
|
|
29
|
+
Requires-Dist: mypy>=1.8.0; extra == 'dev'
|
|
30
|
+
Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
|
|
31
|
+
Requires-Dist: pytest>=7.4.0; extra == 'dev'
|
|
32
|
+
Description-Content-Type: text/markdown
|
|
33
|
+
|
|
34
|
+
# Uno MCP Stdio
|
|
35
|
+
|
|
36
|
+
[](https://pypi.org/project/uno-mcp-stdio/)
|
|
37
|
+
[](https://www.python.org/downloads/)
|
|
38
|
+
[](https://opensource.org/licenses/MIT)
|
|
39
|
+
|
|
40
|
+
**Local stdio proxy for Uno MCP Gateway** - 为不支持 OAuth 认证的 MCP 客户端提供本地代理。
|
|
41
|
+
|
|
42
|
+
## 🎯 解决什么问题
|
|
43
|
+
|
|
44
|
+
许多 MCP 客户端(如 Manus、Cherry Studio)不支持 OAuth 2.0 认证,无法直接连接需要认证的 MCP 服务器。
|
|
45
|
+
|
|
46
|
+
`uno-mcp-stdio` 作为本地代理:
|
|
47
|
+
1. 使用 stdio 模式与 MCP 客户端通信(所有客户端都支持)
|
|
48
|
+
2. 在本地安全存储 OAuth token
|
|
49
|
+
3. 代理请求到远程 Uno Gateway,自动附加认证信息
|
|
50
|
+
|
|
51
|
+
```
|
|
52
|
+
┌─────────────────┐ stdio ┌─────────────────┐ HTTPS ┌─────────────────┐
|
|
53
|
+
│ MCP Client │ ◄────────────► │ uno-mcp-stdio │ ◄────────────► │ Uno Gateway │
|
|
54
|
+
│ (不支持OAuth) │ │ (本地代理) │ + Bearer │ (远程服务) │
|
|
55
|
+
└─────────────────┘ └─────────────────┘ └─────────────────┘
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## 🚀 快速开始
|
|
59
|
+
|
|
60
|
+
### 安装
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
# 使用 uvx 直接运行(推荐)
|
|
64
|
+
uvx uno-mcp-stdio
|
|
65
|
+
|
|
66
|
+
# 或使用 pip 安装
|
|
67
|
+
pip install uno-mcp-stdio
|
|
68
|
+
uno-mcp-stdio
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### 首次运行
|
|
72
|
+
|
|
73
|
+
首次运行时需要 OAuth 认证:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
$ uvx uno-mcp-stdio
|
|
77
|
+
🔐 需要登录认证
|
|
78
|
+
📋 请在浏览器中打开以下链接完成认证:
|
|
79
|
+
https://mcpmarket.cn/oauth/authorize?...
|
|
80
|
+
|
|
81
|
+
⏳ 等待认证完成...
|
|
82
|
+
✅ 认证成功!Token 已保存
|
|
83
|
+
🚀 Uno MCP Stdio 已就绪
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### 配置 MCP 客户端
|
|
87
|
+
|
|
88
|
+
在 MCP 客户端中配置 stdio server:
|
|
89
|
+
|
|
90
|
+
**Manus / Cherry Studio 配置示例:**
|
|
91
|
+
|
|
92
|
+
```json
|
|
93
|
+
{
|
|
94
|
+
"mcpServers": {
|
|
95
|
+
"uno": {
|
|
96
|
+
"command": "uvx",
|
|
97
|
+
"args": ["uno-mcp-stdio"]
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
**如果使用 pip 安装:**
|
|
104
|
+
|
|
105
|
+
```json
|
|
106
|
+
{
|
|
107
|
+
"mcpServers": {
|
|
108
|
+
"uno": {
|
|
109
|
+
"command": "uno-mcp-stdio"
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## ⚙️ 配置
|
|
116
|
+
|
|
117
|
+
### 环境变量
|
|
118
|
+
|
|
119
|
+
| 变量 | 说明 | 默认值 |
|
|
120
|
+
|------|------|--------|
|
|
121
|
+
| `UNO_GATEWAY_URL` | Uno Gateway 地址 | `https://uno.mcpmarket.cn/mcp` |
|
|
122
|
+
| `UNO_CREDENTIALS_PATH` | Token 存储路径 | `~/.uno-mcp/credentials.json` |
|
|
123
|
+
| `UNO_DEBUG` | 调试模式 | `false` |
|
|
124
|
+
|
|
125
|
+
### Token 存储
|
|
126
|
+
|
|
127
|
+
认证后的 token 存储在 `~/.uno-mcp/credentials.json`:
|
|
128
|
+
|
|
129
|
+
```json
|
|
130
|
+
{
|
|
131
|
+
"access_token": "xxx",
|
|
132
|
+
"refresh_token": "xxx",
|
|
133
|
+
"expires_at": 1736345678,
|
|
134
|
+
"token_type": "Bearer"
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### 清除认证
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
# 删除 token 文件重新认证
|
|
142
|
+
rm ~/.uno-mcp/credentials.json
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## 🔐 认证流程
|
|
146
|
+
|
|
147
|
+
```
|
|
148
|
+
1. 启动 uno-mcp-stdio
|
|
149
|
+
│
|
|
150
|
+
▼
|
|
151
|
+
2. 检查 ~/.uno-mcp/credentials.json
|
|
152
|
+
│
|
|
153
|
+
├─ 有效 token → 直接代理请求
|
|
154
|
+
│
|
|
155
|
+
└─ 无/过期 token → 启动认证流程
|
|
156
|
+
│
|
|
157
|
+
▼
|
|
158
|
+
3. 启动临时 HTTP 服务器 (localhost:随机端口)
|
|
159
|
+
│
|
|
160
|
+
▼
|
|
161
|
+
4. 生成 OAuth URL,显示给用户
|
|
162
|
+
│
|
|
163
|
+
▼
|
|
164
|
+
5. 用户在浏览器完成授权
|
|
165
|
+
│
|
|
166
|
+
▼
|
|
167
|
+
6. MCPMarket 回调到本地服务器
|
|
168
|
+
│
|
|
169
|
+
▼
|
|
170
|
+
7. 交换 token,存储到文件
|
|
171
|
+
│
|
|
172
|
+
▼
|
|
173
|
+
8. 关闭临时服务器,开始代理
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
## 🛠️ 开发
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
# 克隆项目
|
|
180
|
+
git clone https://github.com/xray918/uno-mcp-stdio.git
|
|
181
|
+
cd uno-mcp-stdio
|
|
182
|
+
|
|
183
|
+
# 安装依赖
|
|
184
|
+
uv sync
|
|
185
|
+
|
|
186
|
+
# 运行
|
|
187
|
+
uv run uno-mcp-stdio
|
|
188
|
+
|
|
189
|
+
# 调试模式
|
|
190
|
+
UNO_DEBUG=true uv run uno-mcp-stdio
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
## 📄 License
|
|
194
|
+
|
|
195
|
+
MIT
|
|
196
|
+
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
# Uno MCP Stdio
|
|
2
|
+
|
|
3
|
+
[](https://pypi.org/project/uno-mcp-stdio/)
|
|
4
|
+
[](https://www.python.org/downloads/)
|
|
5
|
+
[](https://opensource.org/licenses/MIT)
|
|
6
|
+
|
|
7
|
+
**Local stdio proxy for Uno MCP Gateway** - 为不支持 OAuth 认证的 MCP 客户端提供本地代理。
|
|
8
|
+
|
|
9
|
+
## 🎯 解决什么问题
|
|
10
|
+
|
|
11
|
+
许多 MCP 客户端(如 Manus、Cherry Studio)不支持 OAuth 2.0 认证,无法直接连接需要认证的 MCP 服务器。
|
|
12
|
+
|
|
13
|
+
`uno-mcp-stdio` 作为本地代理:
|
|
14
|
+
1. 使用 stdio 模式与 MCP 客户端通信(所有客户端都支持)
|
|
15
|
+
2. 在本地安全存储 OAuth token
|
|
16
|
+
3. 代理请求到远程 Uno Gateway,自动附加认证信息
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
┌─────────────────┐ stdio ┌─────────────────┐ HTTPS ┌─────────────────┐
|
|
20
|
+
│ MCP Client │ ◄────────────► │ uno-mcp-stdio │ ◄────────────► │ Uno Gateway │
|
|
21
|
+
│ (不支持OAuth) │ │ (本地代理) │ + Bearer │ (远程服务) │
|
|
22
|
+
└─────────────────┘ └─────────────────┘ └─────────────────┘
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## 🚀 快速开始
|
|
26
|
+
|
|
27
|
+
### 安装
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
# 使用 uvx 直接运行(推荐)
|
|
31
|
+
uvx uno-mcp-stdio
|
|
32
|
+
|
|
33
|
+
# 或使用 pip 安装
|
|
34
|
+
pip install uno-mcp-stdio
|
|
35
|
+
uno-mcp-stdio
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### 首次运行
|
|
39
|
+
|
|
40
|
+
首次运行时需要 OAuth 认证:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
$ uvx uno-mcp-stdio
|
|
44
|
+
🔐 需要登录认证
|
|
45
|
+
📋 请在浏览器中打开以下链接完成认证:
|
|
46
|
+
https://mcpmarket.cn/oauth/authorize?...
|
|
47
|
+
|
|
48
|
+
⏳ 等待认证完成...
|
|
49
|
+
✅ 认证成功!Token 已保存
|
|
50
|
+
🚀 Uno MCP Stdio 已就绪
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### 配置 MCP 客户端
|
|
54
|
+
|
|
55
|
+
在 MCP 客户端中配置 stdio server:
|
|
56
|
+
|
|
57
|
+
**Manus / Cherry Studio 配置示例:**
|
|
58
|
+
|
|
59
|
+
```json
|
|
60
|
+
{
|
|
61
|
+
"mcpServers": {
|
|
62
|
+
"uno": {
|
|
63
|
+
"command": "uvx",
|
|
64
|
+
"args": ["uno-mcp-stdio"]
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
**如果使用 pip 安装:**
|
|
71
|
+
|
|
72
|
+
```json
|
|
73
|
+
{
|
|
74
|
+
"mcpServers": {
|
|
75
|
+
"uno": {
|
|
76
|
+
"command": "uno-mcp-stdio"
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## ⚙️ 配置
|
|
83
|
+
|
|
84
|
+
### 环境变量
|
|
85
|
+
|
|
86
|
+
| 变量 | 说明 | 默认值 |
|
|
87
|
+
|------|------|--------|
|
|
88
|
+
| `UNO_GATEWAY_URL` | Uno Gateway 地址 | `https://uno.mcpmarket.cn/mcp` |
|
|
89
|
+
| `UNO_CREDENTIALS_PATH` | Token 存储路径 | `~/.uno-mcp/credentials.json` |
|
|
90
|
+
| `UNO_DEBUG` | 调试模式 | `false` |
|
|
91
|
+
|
|
92
|
+
### Token 存储
|
|
93
|
+
|
|
94
|
+
认证后的 token 存储在 `~/.uno-mcp/credentials.json`:
|
|
95
|
+
|
|
96
|
+
```json
|
|
97
|
+
{
|
|
98
|
+
"access_token": "xxx",
|
|
99
|
+
"refresh_token": "xxx",
|
|
100
|
+
"expires_at": 1736345678,
|
|
101
|
+
"token_type": "Bearer"
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### 清除认证
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
# 删除 token 文件重新认证
|
|
109
|
+
rm ~/.uno-mcp/credentials.json
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## 🔐 认证流程
|
|
113
|
+
|
|
114
|
+
```
|
|
115
|
+
1. 启动 uno-mcp-stdio
|
|
116
|
+
│
|
|
117
|
+
▼
|
|
118
|
+
2. 检查 ~/.uno-mcp/credentials.json
|
|
119
|
+
│
|
|
120
|
+
├─ 有效 token → 直接代理请求
|
|
121
|
+
│
|
|
122
|
+
└─ 无/过期 token → 启动认证流程
|
|
123
|
+
│
|
|
124
|
+
▼
|
|
125
|
+
3. 启动临时 HTTP 服务器 (localhost:随机端口)
|
|
126
|
+
│
|
|
127
|
+
▼
|
|
128
|
+
4. 生成 OAuth URL,显示给用户
|
|
129
|
+
│
|
|
130
|
+
▼
|
|
131
|
+
5. 用户在浏览器完成授权
|
|
132
|
+
│
|
|
133
|
+
▼
|
|
134
|
+
6. MCPMarket 回调到本地服务器
|
|
135
|
+
│
|
|
136
|
+
▼
|
|
137
|
+
7. 交换 token,存储到文件
|
|
138
|
+
│
|
|
139
|
+
▼
|
|
140
|
+
8. 关闭临时服务器,开始代理
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## 🛠️ 开发
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
# 克隆项目
|
|
147
|
+
git clone https://github.com/xray918/uno-mcp-stdio.git
|
|
148
|
+
cd uno-mcp-stdio
|
|
149
|
+
|
|
150
|
+
# 安装依赖
|
|
151
|
+
uv sync
|
|
152
|
+
|
|
153
|
+
# 运行
|
|
154
|
+
uv run uno-mcp-stdio
|
|
155
|
+
|
|
156
|
+
# 调试模式
|
|
157
|
+
UNO_DEBUG=true uv run uno-mcp-stdio
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
## 📄 License
|
|
161
|
+
|
|
162
|
+
MIT
|
|
163
|
+
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
# Uno MCP Stdio - Claude 项目指南
|
|
2
|
+
|
|
3
|
+
## 项目概述
|
|
4
|
+
|
|
5
|
+
`uno-mcp-stdio` 是 Uno MCP Gateway 的本地 stdio 代理客户端。它解决了不支持 OAuth 认证的 MCP 客户端(如 Manus、Cherry Studio)无法连接需要认证的 MCP 服务器的问题。
|
|
6
|
+
|
|
7
|
+
### 核心价值
|
|
8
|
+
|
|
9
|
+
- **兼容所有 MCP 客户端**:使用所有客户端都支持的 stdio 传输
|
|
10
|
+
- **本地认证管理**:在本地安全存储 OAuth token
|
|
11
|
+
- **透明代理**:对客户端透明,就像直接连接 gateway
|
|
12
|
+
|
|
13
|
+
### 架构关系
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
┌─────────────────┐ stdio ┌─────────────────┐ HTTPS ┌─────────────────┐
|
|
17
|
+
│ MCP Client │ ◄────────────► │ uno-mcp-stdio │ ◄────────────► │ Uno Gateway │
|
|
18
|
+
│ (不支持OAuth) │ │ (本地代理) │ + Bearer │ (远程服务) │
|
|
19
|
+
└─────────────────┘ └─────────────────┘ └─────────────────┘
|
|
20
|
+
│
|
|
21
|
+
~/.uno-mcp/credentials.json
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## 技术栈
|
|
25
|
+
|
|
26
|
+
| 组件 | 技术选型 |
|
|
27
|
+
|------|----------|
|
|
28
|
+
| MCP SDK | mcp (官方 Python SDK) |
|
|
29
|
+
| HTTP 客户端 | httpx |
|
|
30
|
+
| 配置管理 | pydantic-settings |
|
|
31
|
+
| 包管理 | uv |
|
|
32
|
+
| Python 版本 | 3.11+ |
|
|
33
|
+
|
|
34
|
+
## 目录结构
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
uno-mcp-stdio/
|
|
38
|
+
├── src/
|
|
39
|
+
│ └── uno_mcp_stdio/
|
|
40
|
+
│ ├── __init__.py # 包初始化
|
|
41
|
+
│ ├── main.py # CLI 入口
|
|
42
|
+
│ ├── config.py # 配置管理
|
|
43
|
+
│ ├── stdio_server.py # MCP stdio server 核心实现
|
|
44
|
+
│ ├── auth/
|
|
45
|
+
│ │ ├── __init__.py
|
|
46
|
+
│ │ ├── token_manager.py # Token 存储、刷新、PKCE
|
|
47
|
+
│ │ └── callback_server.py # OAuth 回调 HTTP 服务器
|
|
48
|
+
│ └── gateway/
|
|
49
|
+
│ ├── __init__.py
|
|
50
|
+
│ └── proxy.py # 代理请求到远程 gateway
|
|
51
|
+
├── pyproject.toml
|
|
52
|
+
├── README.md
|
|
53
|
+
└── claude.md
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## 核心模块说明
|
|
57
|
+
|
|
58
|
+
### 1. stdio_server.py - MCP Server 实现
|
|
59
|
+
|
|
60
|
+
使用 MCP Python SDK 实现 stdio 传输的 server:
|
|
61
|
+
|
|
62
|
+
```python
|
|
63
|
+
class UnoStdioServer:
|
|
64
|
+
# 处理 tools/list - 代理到 gateway 获取工具列表
|
|
65
|
+
# 处理 tools/call - 代理到 gateway 执行工具
|
|
66
|
+
# 处理 uno_auth_required - 启动 OAuth 认证流程
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
关键点:
|
|
70
|
+
- 如果未认证,`tools/list` 返回一个 `uno_auth_required` 工具
|
|
71
|
+
- 用户调用该工具触发 OAuth 认证流程
|
|
72
|
+
- 认证成功后,重新调用 `tools/list` 获取真实工具列表
|
|
73
|
+
|
|
74
|
+
### 2. token_manager.py - Token 管理
|
|
75
|
+
|
|
76
|
+
负责:
|
|
77
|
+
- Token 存储(`~/.uno-mcp/credentials.json`)
|
|
78
|
+
- Token 刷新(使用 refresh_token)
|
|
79
|
+
- PKCE 生成(code_verifier, code_challenge)
|
|
80
|
+
- OAuth URL 构建
|
|
81
|
+
|
|
82
|
+
### 3. callback_server.py - OAuth 回调
|
|
83
|
+
|
|
84
|
+
临时 HTTP 服务器:
|
|
85
|
+
- 动态分配端口(避免冲突)
|
|
86
|
+
- 等待 OAuth 回调
|
|
87
|
+
- 验证 state 参数
|
|
88
|
+
- 返回成功/失败页面
|
|
89
|
+
|
|
90
|
+
### 4. proxy.py - Gateway 代理
|
|
91
|
+
|
|
92
|
+
代理 MCP 请求到远程 gateway:
|
|
93
|
+
- 附加 Authorization header
|
|
94
|
+
- 处理 401 自动刷新/清除 token
|
|
95
|
+
- 转换 JSON-RPC 响应
|
|
96
|
+
|
|
97
|
+
## 认证流程详解
|
|
98
|
+
|
|
99
|
+
```
|
|
100
|
+
1. Client 调用 tools/list
|
|
101
|
+
│
|
|
102
|
+
▼
|
|
103
|
+
2. stdio_server 检查 token
|
|
104
|
+
│
|
|
105
|
+
├─ 有效 → 代理到 gateway 获取工具列表
|
|
106
|
+
│
|
|
107
|
+
└─ 无/过期 → 返回 uno_auth_required 工具
|
|
108
|
+
│
|
|
109
|
+
▼
|
|
110
|
+
3. Client 调用 uno_auth_required
|
|
111
|
+
│
|
|
112
|
+
▼
|
|
113
|
+
4. 启动临时 HTTP 服务器 (localhost:随机端口)
|
|
114
|
+
│
|
|
115
|
+
▼
|
|
116
|
+
5. 生成 OAuth URL (PKCE),尝试打开浏览器
|
|
117
|
+
│
|
|
118
|
+
▼
|
|
119
|
+
6. 用户在浏览器授权
|
|
120
|
+
│
|
|
121
|
+
▼
|
|
122
|
+
7. MCPMarket 回调到 localhost:{port}/callback
|
|
123
|
+
│
|
|
124
|
+
▼
|
|
125
|
+
8. 用 code 交换 token,存储到文件
|
|
126
|
+
│
|
|
127
|
+
▼
|
|
128
|
+
9. 返回认证成功,Client 重新调用 tools/list
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## 配置说明
|
|
132
|
+
|
|
133
|
+
环境变量(前缀 `UNO_`):
|
|
134
|
+
|
|
135
|
+
| 变量 | 说明 | 默认值 |
|
|
136
|
+
|------|------|--------|
|
|
137
|
+
| `UNO_GATEWAY_URL` | Gateway MCP 端点 | `https://uno.mcpmarket.cn/mcp` |
|
|
138
|
+
| `UNO_MCPMARKET_URL` | MCPMarket 地址 | `https://mcpmarket.cn` |
|
|
139
|
+
| `UNO_OAUTH_CLIENT_ID` | OAuth 客户端 ID | `uno-stdio` |
|
|
140
|
+
| `UNO_CREDENTIALS_PATH` | Token 存储路径 | `~/.uno-mcp/credentials.json` |
|
|
141
|
+
| `UNO_DEBUG` | 调试模式 | `false` |
|
|
142
|
+
| `UNO_CALLBACK_TIMEOUT` | OAuth 回调超时 | `300` (秒) |
|
|
143
|
+
|
|
144
|
+
## 开发规范
|
|
145
|
+
|
|
146
|
+
### 日志输出
|
|
147
|
+
|
|
148
|
+
所有日志必须输出到 stderr,避免干扰 stdio 通信:
|
|
149
|
+
|
|
150
|
+
```python
|
|
151
|
+
def _log(self, message: str):
|
|
152
|
+
import sys
|
|
153
|
+
print(f"[Module] {message}", file=sys.stderr)
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### 错误处理
|
|
157
|
+
|
|
158
|
+
定义专用异常:
|
|
159
|
+
|
|
160
|
+
```python
|
|
161
|
+
class AuthenticationRequired(Exception):
|
|
162
|
+
"""需要认证"""
|
|
163
|
+
pass
|
|
164
|
+
|
|
165
|
+
class GatewayError(Exception):
|
|
166
|
+
"""Gateway 错误"""
|
|
167
|
+
pass
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### 异步设计
|
|
171
|
+
|
|
172
|
+
所有 I/O 操作使用 async/await:
|
|
173
|
+
|
|
174
|
+
```python
|
|
175
|
+
async def get_valid_token(self) -> Optional[str]:
|
|
176
|
+
...
|
|
177
|
+
|
|
178
|
+
async def send_request(self, method: str, ...) -> Dict:
|
|
179
|
+
...
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
## 常见开发任务
|
|
183
|
+
|
|
184
|
+
### 添加新的 MCP 方法支持
|
|
185
|
+
|
|
186
|
+
1. 在 `stdio_server.py` 的 `_setup_handlers` 中添加处理器
|
|
187
|
+
2. 在 `proxy.py` 中添加对应的代理方法
|
|
188
|
+
|
|
189
|
+
### 修改 Token 存储位置
|
|
190
|
+
|
|
191
|
+
修改 `config.py` 中的 `credentials_path` 默认值,或设置环境变量 `UNO_CREDENTIALS_PATH`
|
|
192
|
+
|
|
193
|
+
### 测试认证流程
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
# 清除已有 token
|
|
197
|
+
rm ~/.uno-mcp/credentials.json
|
|
198
|
+
|
|
199
|
+
# 调试模式运行
|
|
200
|
+
UNO_DEBUG=true uv run uno-mcp-stdio
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### 本地开发
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
cd uno-mcp-stdio
|
|
207
|
+
uv sync
|
|
208
|
+
uv run uno-mcp-stdio
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
## 与 uno-mcp 的关系
|
|
212
|
+
|
|
213
|
+
| 项目 | 角色 | 运行位置 |
|
|
214
|
+
|------|------|----------|
|
|
215
|
+
| `uno-mcp` | HTTP MCP Gateway | 远程服务器 |
|
|
216
|
+
| `uno-mcp-stdio` | Stdio 代理客户端 | 用户本地 |
|
|
217
|
+
|
|
218
|
+
`uno-mcp-stdio` 是 `uno-mcp` 的客户端,通过 HTTP 调用远程 gateway。
|
|
219
|
+
|
|
220
|
+
## 注意事项
|
|
221
|
+
|
|
222
|
+
1. **不要在 stdout 输出**:会破坏 stdio 通信
|
|
223
|
+
2. **Token 安全**:credentials.json 包含敏感信息,不要提交到 git
|
|
224
|
+
3. **回调端口**:使用动态端口,避免冲突
|
|
225
|
+
4. **超时设置**:OAuth 回调默认等待 5 分钟
|
|
226
|
+
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "uno-mcp-stdio"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "Uno MCP Stdio Client - Local stdio proxy for Uno MCP Gateway with OAuth authentication"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.11"
|
|
7
|
+
license = { text = "MIT" }
|
|
8
|
+
authors = [
|
|
9
|
+
{ name = "xray918", email = "xray918@example.com" }
|
|
10
|
+
]
|
|
11
|
+
keywords = ["mcp", "ai", "agent", "stdio", "oauth", "proxy"]
|
|
12
|
+
classifiers = [
|
|
13
|
+
"Development Status :: 4 - Beta",
|
|
14
|
+
"Intended Audience :: Developers",
|
|
15
|
+
"License :: OSI Approved :: MIT License",
|
|
16
|
+
"Programming Language :: Python :: 3",
|
|
17
|
+
"Programming Language :: Python :: 3.11",
|
|
18
|
+
"Programming Language :: Python :: 3.12",
|
|
19
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
20
|
+
"Topic :: Scientific/Engineering :: Artificial Intelligence",
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
dependencies = [
|
|
24
|
+
"mcp>=1.0.0",
|
|
25
|
+
"httpx>=0.27.0",
|
|
26
|
+
"pydantic>=2.5.0",
|
|
27
|
+
"pydantic-settings>=2.1.0",
|
|
28
|
+
"aiofiles>=23.2.0",
|
|
29
|
+
]
|
|
30
|
+
|
|
31
|
+
[project.optional-dependencies]
|
|
32
|
+
dev = [
|
|
33
|
+
"pytest>=7.4.0",
|
|
34
|
+
"pytest-asyncio>=0.23.0",
|
|
35
|
+
"black>=24.0.0",
|
|
36
|
+
"isort>=5.13.0",
|
|
37
|
+
"mypy>=1.8.0",
|
|
38
|
+
]
|
|
39
|
+
|
|
40
|
+
[build-system]
|
|
41
|
+
requires = ["hatchling"]
|
|
42
|
+
build-backend = "hatchling.build"
|
|
43
|
+
|
|
44
|
+
[tool.hatch.build.targets.wheel]
|
|
45
|
+
packages = ["src/uno_mcp_stdio"]
|
|
46
|
+
|
|
47
|
+
[tool.black]
|
|
48
|
+
line-length = 100
|
|
49
|
+
target-version = ["py311"]
|
|
50
|
+
|
|
51
|
+
[tool.isort]
|
|
52
|
+
profile = "black"
|
|
53
|
+
line_length = 100
|
|
54
|
+
|
|
55
|
+
[tool.mypy]
|
|
56
|
+
python_version = "3.11"
|
|
57
|
+
strict = true
|
|
58
|
+
ignore_missing_imports = true
|
|
59
|
+
|
|
60
|
+
[project.scripts]
|
|
61
|
+
uno-mcp-stdio = "uno_mcp_stdio.main:main"
|
|
62
|
+
|
|
63
|
+
[project.urls]
|
|
64
|
+
Homepage = "https://github.com/xray918/uno-mcp-stdio"
|
|
65
|
+
Repository = "https://github.com/xray918/uno-mcp-stdio"
|
|
66
|
+
Documentation = "https://github.com/xray918/uno-mcp-stdio#readme"
|
|
67
|
+
Issues = "https://github.com/xray918/uno-mcp-stdio/issues"
|
|
68
|
+
|