内容
# styx-mcp
[](LICENSE)
[](https://go.dev/)
[](https://modelcontextprotocol.io/)
[](https://github.com/N0va-7/styx-mcp/stargazers)
** | [简体中文](README_ZH.md)
> 受MCP工具控制的多跳代理 — 为Cursor / Claude提供类似Stowaway的跳转网络,无需单独的管理员TUI。
```text
LLM (Cursor) --MCP/stdio--> controller <--> agent <--> agent …
| |
SOCKS / 反向 出口流量
```
## 免责声明
> **仅限授权使用。** 仅在您拥有或有明确书面许可测试的系统上使用(实验室、CTF / 考试范围、RoE涵盖的参与)。未经授权使用是违法的。您对如何使用此软件单独负责。
**请在使用前阅读此README(尤其是[SOCKS与转发和反向](#socks-vs-forward-vs-backward))。**
## 为什么选择styx-mcp?
| | [Stowaway](https://github.com/ph4ntonn/Stowaway) | **styx-mcp** |
| :--- | :--- | :--- |
| 控制平面 | 交互式管理员TUI | **MCP工具**(LLM / Cursor原生) |
| SOCKS监听 | 管理员侧 | **控制器**(相同想法) |
| 主要用户 | 人类操作员 | 代理 + 人类 |
| 远程Shell / 下载 | 是 | 暂无 |
灵感来自Stowaway的多跳模型;为**模型上下文协议**客户端重新定位。
## 功能
- 树拓扑:主动(`-c`)/ 被动(`-l`),多跳中继
- 相互**HMAC**预认证 + 可选**TLS** / WebSocket传输
- **SOCKS5**在控制器上 — 本地工具通过选定的节点退出
- 每流**字节窗口流量控制**(无静默SOCKS丢弃;需要匹配的控制器/代理)
- **转发**(在代理上监听)& **反向**(在控制器上监听)
- **异步`start_cmd`**(非交互式`sh -c`,返回`task_id`)
- **异步`pull_file`** / `upload_file`(任务 + 本地路径;非交互式Shell)
- **上传**文件到节点(路径遍历已消毒)
- 异步任务 + `get_task_status`
- 跨编译:Linux / Windows / macOS(`make build-all`)
<details>
<summary><strong>暂未包含</strong></summary>
- 交互式远程Shell
- 从节点下载到控制器
- SOCKS用户名/密码
- 完整的Stowaway风格管理员UI
</details>
## 目录
- [快速开始](#quick-start)
- [Cursor MCP设置](#cursor-mcp-setup)
- [MCP工具](#mcp-tools)
- [示例](#examples)
- [CLI标志](#cli-flags)
- [安全注意事项](#security-notes)
- [项目布局](#project-layout)
- [致谢](#acknowledgments)
- [许可证](#license)
## 快速开始
```bash
git clone https://github.com/N0va-7/styx-mcp.git
cd styx-mcp
make build # → release/<os>-<arch>/
```
```bash
# 终端A — 控制器(保留MCP的标准输入输出;仅用于CLI测试)
./release/$(uname -s | tr A-Z a-z)-$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/')/controller \
-s change-me -l 127.0.0.1:19137
# 终端B — 代理
./release/.../agent -s change-me -c 127.0.0.1:19137
```
更喜欢**Cursor**? 跳过终端A并使用下面的[包装器](#cursor-mcp-setup),然后仅启动代理。
```bash
make build-all # linux-amd64 / windows-amd64 / darwin-arm64
make test
```
## Cursor MCP设置
1. `make build` 以确保 `release/<os>-<arch>/controller` 存在。
2. `~/.cursor/mcp.json`(或项目 `.cursor/mcp.json`):
```json
{
"mcpServers": {
"styx-mcp": {
"command": "/绝对路径/to/styx-mcp/scripts/styx-mcp-wrapper.sh",
"env": {
"STYX_SECRET": "change-me",
"STYX_LISTEN": "0.0.0.0:19137",
"STYX_LOG": "/tmp/styx-mcp-controller.log"
}
}
}
}
```
3. Cursor → **设置 → MCP** → 启用 / 刷新 **styx-mcp**。
4. 在立足点:
```bash
./agent -s change-me -c <控制器-ip>:19137
```
| 环境变量 | 默认值 | 含义 |
| :--- | :--- | :--- |
| `STYX_SECRET` | `secret` | 共享密钥(`-s`) |
| `STYX_LISTEN` | `0.0.0.0:19137` | 控制器上的代理监听地址 |
| `STYX_LOG` | `/tmp/styx-mcp-controller.log` | 控制器日志 |
| `STYX_BIN_DIR` | `release/<os>-<arch>` | 二进制目录覆盖 |
永远不要将真正的密钥提交到公共配置文件中。
## MCP工具
| 工具 | 功能 | 监听/作用于何处 |
| :--- | :--- | :--- |
| `list_nodes` | 拓扑 | — |
| `get_node_detail` | 详情 | — |
| `add_node_memo` / `delete_node_memo` | 备注 | — |
| `start_listener` | 等待子代理 | **代理** |
| `connect_node` | 拨打子节点 | **代理** |
| `start_socks` | 为本地工具提供SOCKS5 | **控制器** → 通过节点退出 |
| `start_forward` | 端口转发 | **代理** 监听 → 目标 |
| `start_backward` | 反向转发 | **控制器** → 通过节点 → 目标 |
| `upload_file` | 上传 | 控制器 → 代理 |
| `pull_file` | 拉取文件到控制器 | 代理 → 控制器路径 |
| `start_cmd` | 非交互式一次性 | 代理 `sh -c`(异步 `task_id`) |
| `get_task_status` | 轮询异步工作 | — |
| `shutdown_node` | 关闭节点 | — |
长运行调用返回 `task_id` → 使用 `get_task_status` 轮询。
### SOCKS vs 转发 vs 反向
| 您想要… | 使用 |
| :--- | :--- |
| 在**控制器主机**上使用 `curl` / 扫描器访问内部网络 | `start_socks` |
| 一个**控制器**端口 → 一个内部 `ip:port` | `start_backward` |
| **在立足点**上一个端口拨打其他地方 | `start_forward` |
`start_forward` **不是**本地SOCKS的直接替代品。
## 示例
<details open>
<summary><strong>SOCKS5</strong></summary>
```json
{ "name": "start_socks", "arguments": { "node_id": 0, "address": "127.0.0.1:10801" } }
```
```bash
curl --socks5-hostname 127.0.0.1:10801 http://<内部主机>/
export ALL_PROXY=socks5h://127.0.0.1:10801
```
</details>
<details>
<summary><strong>两级拓扑</strong></summary>
```bash
./agent -s change-me -l 127.0.0.1:19138 # 子节点, 被动
```
```json
{ "name": "connect_node", "arguments": { "node_id": 0, "address": "127.0.0.1:19138" } }
```
</details>
<details>
<summary><strong>转发 / 反向 / 上传</strong></summary>
```json
{
"name": "start_forward",
"arguments": {
"node_id": 0,
"listen_address": "127.0.0.1:19141",
"target_address": "10.0.0.5:80"
}
}
```
连接到代理主机上的 `listen_address`。
```json
{
"name": "start_backward",
"arguments": {
"node_id": 0,
"local_address": "127.0.0.1:19142",
"target_address": "10.0.0.5:80"
}
}
```
连接到控制器主机上的 `127.0.0.1:19142`。
```json
{
"name": "upload_file",
"arguments": {
"node_id": 0,
"local_path": "/path/to/tool",
"remote_path": "/tmp/tool"
}
}
```
</details>
## CLI标志
<details>
<summary><strong>控制器</strong></summary>
| 标志 | 描述 |
| :--- | :--- |
| `-s` | 共享密钥 |
| `-l` | 监听代理 `[ip]:port` |
| `-c` | 可选主动连接 |
| `-down` | `raw` / `ws` |
| `-tls-enable` | 节点链接上的TLS |
| `-domain` | TLS SNI / WS域名 |
| `-heartbeat` | 心跳到第一个节点 |
</details>
<details>
<summary><strong>代理</strong></summary>
| 标志 | 描述 |
| :--- | :--- |
| `-s` | 共享密钥 |
| `-c` | 连接到父节点/控制器 |
| `-l` | 被动监听 |
| `-up` / `-down` | `raw` / `ws` |
| `-tls-enable` / `-domain` | TLS |
| `-reconnect` | 秒(`0` = 关闭) |
| `-socks5-proxy` / `-socks5-proxyu` / `-socks5-proxyp` | 通过SOCKS5访问父节点 |
| `-http-proxy` | 通过HTTP代理访问父节点 |
</details>
控制器和代理必须共享**相同的密钥**(以及匹配的TLS/WS选项)。
## 安全注意事项
- 将 `-s` / `STYX_SECRET` 视为密码;共享实验室后轮换。
- 除非您故意公开,否则将SOCKS绑定到 `127.0.0.1`。
- 上传路径已消毒;仍然只上传到您控制的主机。
- 编译版本可能在 `/tmp/styx-mcp-mcp.log` 下记录MCP标准输入输出 — 在记录开启时不要在工具参数中输入密钥。
## 项目布局
```text
cmd/controller/ 控制器 + MCP入口
cmd/agent/ 代理入口
scripts/ Cursor MCP包装器
pkg/controller/ 控制平面,SOCKS / 反向
pkg/mcp/ MCP工具
pkg/node/ 代理处理程序
pkg/protocol/ 线路协议
pkg/share/preauth/ HMAC相互预认证
```
## 致谢
多跳代理设计大量借鉴了 [Stowaway](https://github.com/ph4ntonn/Stowaway) (MIT,© ph4ntom)。
MCP服务器栈使用 [mcp-go](https://github.com/mark3labs/mcp-go)。
## 许可证
[MIT](LICENSE)